Skip to content

Commit

Permalink
Fix/names (#4)
Browse files Browse the repository at this point in the history
* fix: bad aliasing

* feat: utilities + version

* chore: handle databricks V2

* chore :added ignore

* remove jar

* fix: respect metabase version guideline

* fix: class naming and loading for name clashes

---------

Co-authored-by: Stefani <>
  • Loading branch information
shrodingers authored Feb 2, 2024
1 parent 514d271 commit c5b2560
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
8 changes: 5 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,19 @@ RUN clojure \
-Sdeps "{:aliases {:sparksql-databricks-v2 {:extra-deps {com.metabase/sparksql-databricks {:local/root \"/build/driver\"}}}}}" \
-X:build:sparksql-databricks-v2 \
build-drivers.build-driver/build-driver! \
"{:driver :sparksql-databricks, :project-dir \"/build/driver\", :target-dir \"/build/driver/target\"}"
"{:driver :sparksql-databricks-v2, :project-dir \"/build/driver\", :target-dir \"/build/driver/target\"}"

# We create an export stage to make it easy to export the driver
FROM scratch as stg_export
COPY --from=stg_build /build/driver/target/sparksql-databricks.metabase-driver.jar /
COPY --from=stg_build /build/driver/target/sparksql-databricks-v2.metabase-driver.jar /

# Now we can run Metabase with our built driver
FROM metabase/metabase:${METABASE_VERSION} AS stg_runner

# A metabase user/group is manually added in https://github.com/metabase/metabase/blob/master/bin/docker/run_metabase.sh
# Make the UID and GID match
COPY --chown=2000:2000 --from=stg_build \
/build/driver/target/sparksql-databricks.metabase-driver.jar \
/build/driver/target/sparksql-databricks-v2.metabase-driver.jar \
/plugins/sparksql-databricks.metabase-driver.jar

RUN wget https://github.com/relferreira/metabase-sparksql-databricks-driver/releases/download/1.6.0/sparksql-databricks.metabase-driver.jar -O /plugins/sparksql-databricks.metabase-driver-old.jar
2 changes: 1 addition & 1 deletion resources/metabase-plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ driver:
connection-properties-include-tunnel-config: false
init:
- step: load-namespace
namespace: metabase.driver.sparksql-databricks
namespace: metabase.driver.sparksql-databricks-v2
- step: register-jdbc-driver
class: metabase.driver.FixedSparkDriver
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(ns metabase.driver.sparksql-databricks
(ns metabase.driver.sparksql-databricks-v2
(:require [clojure.java.jdbc :as jdbc]
[clojure.string :as str]
[clojure
Expand Down Expand Up @@ -44,7 +44,7 @@
;; ((get-method sql.qp/->honeysql [:hive-like :field]) driver field)))


(defmethod sql.qp/->honeysql [:sparksql-databricks :field]
(defmethod sql.qp/->honeysql [:sparksql-databricks-v2 :field]
[driver [_ _ {::params.substitution/keys [compiling-field-filter?]} :as field-clause]]
;; use [[source-table-alias]] instead of the usual `schema.table` to qualify fields e.g. `t1.field` instead of the
;; normal `schema.table.field`
Expand All @@ -65,7 +65,7 @@
:else source-table)))]
(parent-method driver field-clause)))

(defmethod sql.qp/apply-top-level-clause [:sparksql-databricks :page]
(defmethod sql.qp/apply-top-level-clause [:sparksql-databricks-v2 :page]
[_driver _clause honeysql-form {{:keys [items page]} :page}]
(let [offset (* (dec page) items)]
(if (zero? offset)
Expand All @@ -78,7 +78,7 @@
(sql.helpers/where [:> :__rownum__ [:inline offset]])
(sql.helpers/limit [:inline items]))))))

(defmethod sql.qp/apply-top-level-clause [:sparksql-databricks :source-table]
(defmethod sql.qp/apply-top-level-clause [:sparksql-databricks-v2 :source-table]
[driver _ honeysql-form {source-table-id :source-table}]
(let [{table-name :name, schema :schema} (lib.metadata/table (qp.store/metadata-provider) source-table-id)]
(sql.helpers/from honeysql-form [(sql.qp/->honeysql driver (h2x/identifier :table schema table-name))
Expand All @@ -95,7 +95,7 @@
;; :ssl true}
;; (dissoc opts :host :port :db :jdbc-flags)))

(defn- sparksql-databricks
(defn- sparksql-databricks-v2
"Create a database specification for a Spark SQL database."
[{:keys [host port http-path jdbc-flags app-id app-secret catalog db]
:or {host "localhost", port 10000, db "", jdbc-flags ""}
Expand All @@ -114,9 +114,7 @@
:OAuth2Secret app-secret}
(dissoc opts :host :port :db :jdbc-flags :http-path :app-id :app-secret :catalog)))

(defn sparksql-databricks-v2 [params] (sparksql-databricks params))

(defmethod sql-jdbc.conn/connection-details->spec :sparksql-databricks
(defmethod sql-jdbc.conn/connection-details->spec :sparksql-databricks-v2
[_ details]
(-> details
(update :port (fn [port]
Expand All @@ -125,15 +123,15 @@
port)))
(set/rename-keys {:dbname :db})
(select-keys [:host :port :db :jdbc-flags :dbname :http-path :app-id :app-secret :catalog])
sparksql-databricks
sparksql-databricks-v2
(sql-jdbc.common/handle-additional-options details)))

(defn- dash-to-underscore [s]
(when s
(str/replace s #"-" "_")))

;; workaround for SPARK-9686 Spark Thrift server doesn't return correct JDBC metadata
(defmethod driver/describe-database :sparksql-databricks
(defmethod driver/describe-database :sparksql-databricks-v2
[_ database]
{:tables
(with-open [conn (jdbc/get-connection (sql-jdbc.conn/db->pooled-connection-spec database))]
Expand All @@ -151,7 +149,7 @@
[col_name data_type]))

;; workaround for SPARK-9686 Spark Thrift server doesn't return correct JDBC metadata
(defmethod driver/describe-table :sparksql-databricks
(defmethod driver/describe-table :sparksql-databricks-v2
[driver database {table-name :name, schema :schema}]
{:name table-name
:schema schema
Expand All @@ -171,10 +169,10 @@
:database-position idx}))))})

;; bound variables are not supported in Spark SQL (maybe not Hive either, haven't checked)
(defmethod driver/execute-reducible-query :sparksql-databricks
(defmethod driver/execute-reducible-query :sparksql-databricks-v2
[driver {{sql :query, :keys [params], :as inner-query} :native, :as outer-query} context respond]
(let [inner-query (-> (assoc inner-query
:remark (qputil/query->remark :sparksql-databricks outer-query)
:remark (qputil/query->remark :sparksql-databricks-v2 outer-query)
:query (if (seq params)
(binding [hive-like/*param-splice-style* :paranoid]
(unprepare/unprepare driver (cons sql params)))
Expand All @@ -188,7 +186,7 @@
;; 2. SparkSQL doesn't support session timezones (at least our driver doesn't support it)
;; 3. SparkSQL doesn't support making connections read-only
;; 4. SparkSQL doesn't support setting the default result set holdability
(defmethod sql-jdbc.execute/do-with-connection-with-options :sparksql-databricks
(defmethod sql-jdbc.execute/do-with-connection-with-options :sparksql-databricks-v2
[driver db-or-id-or-spec options f]
(sql-jdbc.execute/do-with-resolved-connection
driver
Expand All @@ -200,7 +198,7 @@
(f conn))))

;; 1. SparkSQL doesn't support setting holdability type to `CLOSE_CURSORS_AT_COMMIT`
(defmethod sql-jdbc.execute/prepared-statement :sparksql-databricks
(defmethod sql-jdbc.execute/prepared-statement :sparksql-databricks-v2
[driver ^Connection conn ^String sql params]
(let [stmt (.prepareStatement conn sql
ResultSet/TYPE_FORWARD_ONLY
Expand All @@ -214,7 +212,7 @@
(throw e)))))

;; the current HiveConnection doesn't support .createStatement
(defmethod sql-jdbc.execute/statement-supported? :sparksql-databricks [_] false)
(defmethod sql-jdbc.execute/statement-supported? :sparksql-databricks-v2 [_] false)

(doseq [feature [:basic-aggregations
:binning
Expand All @@ -223,11 +221,11 @@
:native-parameters
:nested-queries
:standard-deviation-aggregations]]
(defmethod driver/supports? [:sparksql-databricks feature] [_ _] true))
(defmethod driver/supports? [:sparksql-databricks-v2 feature] [_ _] true))

;; only define an implementation for `:foreign-keys` if none exists already. In test extensions we define an alternate
;; implementation, and we don't want to stomp over that if it was loaded already
(when-not (get (methods driver/supports?) [:sparksql-databricks :foreign-keys])
(defmethod driver/supports? [:sparksql-databricks :foreign-keys] [_ _] true))
(when-not (get (methods driver/supports?) [:sparksql-databricks-v2 :foreign-keys])
(defmethod driver/supports? [:sparksql-databricks-v2 :foreign-keys] [_ _] true))

(defmethod sql.qp/quote-style :sparksql-databricks [_] :mysql)
(defmethod sql.qp/quote-style :sparksql-databricks-v2 [_] :mysql)

0 comments on commit c5b2560

Please sign in to comment.