From 2b2655247d68de7492ae509aefb05cc31818d20b Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Fri, 10 May 2024 12:09:22 +0100 Subject: [PATCH 01/11] CSV uploads --- src/metabase/driver/clickhouse.clj | 77 +++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index 6c8750a..a8d0966 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -2,6 +2,7 @@ "Driver for ClickHouse databases" #_{:clj-kondo/ignore [:unsorted-required-namespaces]} (:require [clojure.string :as str] + [honey.sql :as sql] [metabase [config :as config]] [metabase.driver :as driver] [metabase.driver.clickhouse-introspection] @@ -12,7 +13,11 @@ [metabase.driver.sql-jdbc [common :as sql-jdbc.common] [connection :as sql-jdbc.conn]] [metabase.driver.sql-jdbc.execute :as sql-jdbc.execute] + [metabase.driver.sql.query-processor :as sql.qp] [metabase.driver.sql.util :as sql.u] + [metabase.query-processor.writeback :as qp.writeback] + [metabase.test.data.sql :as sql.tx] + [metabase.upload :as upload] [metabase.util.log :as log])) (set! *warn-on-reflection* true) @@ -32,7 +37,9 @@ :test/jvm-timezone-setting false :connection-impersonation false :schemas true - :datetime-diff true}] + :uploads true + :datetime-diff true + :upload-with-auto-pk false}] (defmethod driver/database-supports? [:clickhouse feature] [_driver _feature _db] supported?)) @@ -112,6 +119,74 @@ :semantic-version {:major (.getInt rset 2) :minor (.getInt rset 3)}}))))) +(defmethod driver/upload-type->database-type :clickhouse + [_driver upload-type] + (case upload-type + ::upload/varchar-255 "Nullable(String)" + ::upload/text "Nullable(String)" + ::upload/int "Nullable(Int64)" + ::upload/float "Nullable(Float64)" + ::upload/boolean "Nullable(Boolean)" + ::upload/date "Nullable(Date32)" + ::upload/datetime "Nullable(DateTime64(3))" + ;; FIXME: should be `Nullable(DateTime64(3))` + ::upload/offset-datetime nil)) + +(defmethod driver/table-name-length-limit :clickhouse + [_driver] + ;; FIXME: This is a lie because you're really limited by a filesystems' limits, because Clickhouse uses + ;; filenames as table/column names. But its an approximation + 206) + +(defn- quote-name [s] + (let [parts (str/split (name s) #"\.")] + (str/join "." (map #(str "`" % "`") parts)))) + +(defn- create-table!-sql + [driver table-name column-definitions & {:keys [primary-key]}] + (str/join "\n" + [(first (sql/format {:create-table (keyword table-name) + :with-columns (mapv (fn [[name type-spec]] + (vec (cons name [[:raw type-spec]]))) + column-definitions)} + :quoted true + :dialect (sql.qp/quote-style driver))) + "ENGINE = MergeTree" + (format "PRIMARY KEY (%s)" (str/join ", " (map quote-name primary-key))) + "ORDER BY ()"])) + +(defmethod driver/create-table! :clickhouse + [driver db-id table-name column-definitions & {:keys [primary-key]}] + (let [sql (create-table!-sql driver table-name column-definitions :primary-key primary-key)] + (qp.writeback/execute-write-sql! db-id sql))) + +(defmethod driver/insert-into! :clickhouse + [driver db-id table-name column-names values] + (when (seq values) + (sql-jdbc.execute/do-with-connection-with-options + driver + db-id + {:write? true} + (fn [^java.sql.Connection conn] + (let [sql (format "insert into %s (%s)" (quote-name table-name) (str/join ", " (map quote-name column-names)))] + (with-open [ps (.prepareStatement conn sql)] + (doseq [row values] + (when (seq row) + (doseq [[idx v] (map-indexed (fn [x y] [(inc x) y]) row)] + (condp isa? (type v) + java.lang.String (.setString ps idx v) + java.lang.Boolean (.setBoolean ps idx v) + java.lang.Long (.setLong ps idx v) + java.lang.Double (.setFloat ps idx v) + java.math.BigInteger (.setObject ps idx v) + java.time.LocalDate (.setObject ps idx v) + java.time.LocalDateTime (.setObject ps idx v) + (.setString ps idx v))) + (.addBatch ps))) + (doall (.executeBatch ps)))))))) + +(defmethod sql.tx/session-schema :clickhouse [_] "default") + ;;; ------------------------------------------ User Impersonation ------------------------------------------ (defmethod driver.sql/set-role-statement :clickhouse From 7ad64a0217f634d1654e224285f6f827448d0fac Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Fri, 10 May 2024 20:42:39 +0100 Subject: [PATCH 02/11] ~ move function --- src/metabase/driver/clickhouse.clj | 2 -- test/metabase/test/data/clickhouse.clj | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index a8d0966..d764ef9 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -185,8 +185,6 @@ (.addBatch ps))) (doall (.executeBatch ps)))))))) -(defmethod sql.tx/session-schema :clickhouse [_] "default") - ;;; ------------------------------------------ User Impersonation ------------------------------------------ (defmethod driver.sql/set-role-statement :clickhouse diff --git a/test/metabase/test/data/clickhouse.clj b/test/metabase/test/data/clickhouse.clj index 7b656ca..4a1deb0 100644 --- a/test/metabase/test/data/clickhouse.clj +++ b/test/metabase/test/data/clickhouse.clj @@ -113,6 +113,8 @@ (defmethod sql.tx/add-fk-sql :clickhouse [& _] nil) ; TODO - fix me +(defmethod sql.tx/session-schema :clickhouse [_] "default") + (defmethod tx/supports-time-type? :clickhouse [_driver] false) (defn rows-without-index From 7fb82066c911b8cc3a66f1dc5b992e6f7c6e01f2 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Tue, 14 May 2024 20:38:19 -0600 Subject: [PATCH 03/11] Set `wait_end_of_query=1` for clickhouse cloud when creating the table --- src/metabase/driver/clickhouse.clj | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index d764ef9..7fafc1d 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -1,7 +1,8 @@ (ns metabase.driver.clickhouse "Driver for ClickHouse databases" #_{:clj-kondo/ignore [:unsorted-required-namespaces]} - (:require [clojure.string :as str] + (:require [clojure.java.jdbc :as jdbc] + [clojure.string :as str] [honey.sql :as sql] [metabase [config :as config]] [metabase.driver :as driver] @@ -15,10 +16,9 @@ [metabase.driver.sql-jdbc.execute :as sql-jdbc.execute] [metabase.driver.sql.query-processor :as sql.qp] [metabase.driver.sql.util :as sql.u] - [metabase.query-processor.writeback :as qp.writeback] - [metabase.test.data.sql :as sql.tx] [metabase.upload :as upload] - [metabase.util.log :as log])) + [metabase.util.log :as log]) + (:import [com.clickhouse.jdbc.internal ClickHouseStatementImpl])) (set! *warn-on-reflection* true) @@ -142,7 +142,13 @@ (let [parts (str/split (name s) #"\.")] (str/join "." (map #(str "`" % "`") parts)))) +(defn- cloud? [conn] + (let [sql "SELECT value='1' FROM system.settings WHERE name='cloud_mode'"] + (= 1 (val (ffirst (jdbc/query {:connection conn} sql)))))) + (defn- create-table!-sql + "Creates a ClickHouse table with the given name and column definitions. It assumes the engine is MergeTree, + so it only works with Clickhouse Cloud and single node on-premise deployments at the moment." [driver table-name column-definitions & {:keys [primary-key]}] (str/join "\n" [(first (sql/format {:create-table (keyword table-name) @@ -157,8 +163,20 @@ (defmethod driver/create-table! :clickhouse [driver db-id table-name column-definitions & {:keys [primary-key]}] - (let [sql (create-table!-sql driver table-name column-definitions :primary-key primary-key)] - (qp.writeback/execute-write-sql! db-id sql))) + (sql-jdbc.execute/do-with-connection-with-options + driver + db-id + {:write? true} + (fn [^java.sql.Connection conn] + (if (cloud? conn) + (throw (Exception. "Only supported for ClickHouse Cloud")) + (with-open [stmt (.createStatement conn)] + (let [stmt (.unwrap stmt ClickHouseStatementImpl) + request (.getRequest stmt)] + (.set request "wait_end_of_query" 1) + (with-open [_response (-> request + (.query (create-table!-sql driver table-name column-definitions :primary-key primary-key)) + (.executeAndWait))]))))))) (defmethod driver/insert-into! :clickhouse [driver db-id table-name column-names values] From 6b8935b9fe191220a299542295ab49c530e241d6 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Wed, 15 May 2024 21:34:26 -0600 Subject: [PATCH 04/11] Only support uploads for CH Cloud DBs --- src/metabase/driver/clickhouse.clj | 44 ++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index 7fafc1d..f4c45a1 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -1,10 +1,11 @@ (ns metabase.driver.clickhouse "Driver for ClickHouse databases" #_{:clj-kondo/ignore [:unsorted-required-namespaces]} - (:require [clojure.java.jdbc :as jdbc] + (:require [clojure.core.memoize :as memoize] [clojure.string :as str] [honey.sql :as sql] [metabase [config :as config]] + [metabase.db.connection :as mdb.connection] [metabase.driver :as driver] [metabase.driver.clickhouse-introspection] [metabase.driver.clickhouse-nippy] @@ -37,12 +38,31 @@ :test/jvm-timezone-setting false :connection-impersonation false :schemas true - :uploads true :datetime-diff true :upload-with-auto-pk false}] (defmethod driver/database-supports? [:clickhouse feature] [_driver _feature _db] supported?)) +(def ^:private ^{:arglists '([db])} cloud? + "Is this a cloud DB?" + (memoize/ttl + ^{::memoize/args-fn (fn [[db]] + [(mdb.connection/unique-identifier) (:details db)])} + (fn [db] + (sql-jdbc.execute/do-with-connection-with-options + :clickhouse db nil + (fn [^java.sql.Connection conn] + (with-open [stmt (.prepareStatement conn "SELECT value='1' FROM system.settings WHERE name='cloud_mode'") + rset (.executeQuery stmt)] + (when (.next rset) + (.getBoolean rset 1)))))) + ;; cache the results for 60 minutes; TTL is here only to eventually clear out old entries/keep it from growing too + ;; large + :ttl/threshold (* 60 60 1000))) + +(defmethod driver/database-supports? [:clickhouse :uploads] [_driver _feature db] + (cloud? db)) + (def ^:private default-connection-details {:user "default" :password "" :dbname "default" :host "localhost" :port "8123"}) @@ -142,10 +162,6 @@ (let [parts (str/split (name s) #"\.")] (str/join "." (map #(str "`" % "`") parts)))) -(defn- cloud? [conn] - (let [sql "SELECT value='1' FROM system.settings WHERE name='cloud_mode'"] - (= 1 (val (ffirst (jdbc/query {:connection conn} sql)))))) - (defn- create-table!-sql "Creates a ClickHouse table with the given name and column definitions. It assumes the engine is MergeTree, so it only works with Clickhouse Cloud and single node on-premise deployments at the moment." @@ -168,15 +184,13 @@ db-id {:write? true} (fn [^java.sql.Connection conn] - (if (cloud? conn) - (throw (Exception. "Only supported for ClickHouse Cloud")) - (with-open [stmt (.createStatement conn)] - (let [stmt (.unwrap stmt ClickHouseStatementImpl) - request (.getRequest stmt)] - (.set request "wait_end_of_query" 1) - (with-open [_response (-> request - (.query (create-table!-sql driver table-name column-definitions :primary-key primary-key)) - (.executeAndWait))]))))))) + (with-open [stmt (.createStatement conn)] + (let [stmt (.unwrap stmt ClickHouseStatementImpl) + request (.getRequest stmt)] + (.set request "wait_end_of_query" 1) + (with-open [_response (-> request + (.query (create-table!-sql driver table-name column-definitions :primary-key primary-key)) + (.executeAndWait))])))))) (defmethod driver/insert-into! :clickhouse [driver db-id table-name column-names values] From d1c025da93dfc79681a31590c9687b439c7eaa5b Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Wed, 15 May 2024 21:42:56 -0600 Subject: [PATCH 05/11] Fix reflection warnings --- src/metabase/driver/clickhouse.clj | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index f4c45a1..e6e19b0 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -19,7 +19,8 @@ [metabase.driver.sql.util :as sql.u] [metabase.upload :as upload] [metabase.util.log :as log]) - (:import [com.clickhouse.jdbc.internal ClickHouseStatementImpl])) + (:import [com.clickhouse.client ClickHouseRequest] + [com.clickhouse.jdbc.internal ClickHouseStatementImpl])) (set! *warn-on-reflection* true) @@ -185,11 +186,11 @@ {:write? true} (fn [^java.sql.Connection conn] (with-open [stmt (.createStatement conn)] - (let [stmt (.unwrap stmt ClickHouseStatementImpl) + (let [^ClickHouseStatementImpl stmt (.unwrap stmt ClickHouseStatementImpl) request (.getRequest stmt)] - (.set request "wait_end_of_query" 1) + (.set request "wait_end_of_query" "1") (with-open [_response (-> request - (.query (create-table!-sql driver table-name column-definitions :primary-key primary-key)) + (.query ^String (create-table!-sql driver table-name column-definitions :primary-key primary-key)) (.executeAndWait))])))))) (defmethod driver/insert-into! :clickhouse From 2cec4110a425a910ea515731fa051fc4479b8d88 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Thu, 16 May 2024 14:00:37 -0600 Subject: [PATCH 06/11] Use order by to specify primary key --- src/metabase/driver/clickhouse.clj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index e6e19b0..a59e19b 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -175,8 +175,7 @@ :quoted true :dialect (sql.qp/quote-style driver))) "ENGINE = MergeTree" - (format "PRIMARY KEY (%s)" (str/join ", " (map quote-name primary-key))) - "ORDER BY ()"])) + (format "ORDER BY (%s)" (str/join ", " (map quote-name primary-key)))])) (defmethod driver/create-table! :clickhouse [driver db-id table-name column-definitions & {:keys [primary-key]}] From a51c32e95b1049d3c3d72d6c0a18d5e7d29a3e54 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Thu, 16 May 2024 17:02:35 -0600 Subject: [PATCH 07/11] set select_sequential_consistency in connection details --- src/metabase/driver/clickhouse.clj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index a59e19b..954fddd 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -86,6 +86,9 @@ :ssl (boolean ssl) :use_no_proxy (boolean use-no-proxy) :use_server_time_zone_for_dates true + ;; select_sequential_consistency is needed to guarantee that we can query data from any replica in CH Cloud + ;; immediately after it is written + :select_sequential_consistency true :product_name product-name} (sql-jdbc.common/handle-additional-options details :separator-style :url)))) From 847b80f6d2778c98a2aeac83df00db74bf215a7d Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Thu, 16 May 2024 21:34:01 -0600 Subject: [PATCH 08/11] Avoid setting select_sequential_consistency for on-premise --- src/metabase/driver/clickhouse.clj | 59 ++++++++++++++++-------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index 954fddd..a01e8e0 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -44,33 +44,12 @@ (defmethod driver/database-supports? [:clickhouse feature] [_driver _feature _db] supported?)) -(def ^:private ^{:arglists '([db])} cloud? - "Is this a cloud DB?" - (memoize/ttl - ^{::memoize/args-fn (fn [[db]] - [(mdb.connection/unique-identifier) (:details db)])} - (fn [db] - (sql-jdbc.execute/do-with-connection-with-options - :clickhouse db nil - (fn [^java.sql.Connection conn] - (with-open [stmt (.prepareStatement conn "SELECT value='1' FROM system.settings WHERE name='cloud_mode'") - rset (.executeQuery stmt)] - (when (.next rset) - (.getBoolean rset 1)))))) - ;; cache the results for 60 minutes; TTL is here only to eventually clear out old entries/keep it from growing too - ;; large - :ttl/threshold (* 60 60 1000))) - -(defmethod driver/database-supports? [:clickhouse :uploads] [_driver _feature db] - (cloud? db)) - (def ^:private default-connection-details {:user "default" :password "" :dbname "default" :host "localhost" :port "8123"}) -(defmethod sql-jdbc.conn/connection-details->spec :clickhouse - [_ details] - ;; ensure defaults merge on top of nils - (let [details (reduce-kv (fn [m k v] (assoc m k (or v (k default-connection-details)))) +(defn- connection-details->spec* [details] + (let [;; ensure defaults merge on top of nils + details (reduce-kv (fn [m k v] (assoc m k (or v (k default-connection-details)))) default-connection-details details) {:keys [user password dbname host port ssl use-no-proxy]} details @@ -86,12 +65,36 @@ :ssl (boolean ssl) :use_no_proxy (boolean use-no-proxy) :use_server_time_zone_for_dates true - ;; select_sequential_consistency is needed to guarantee that we can query data from any replica in CH Cloud - ;; immediately after it is written - :select_sequential_consistency true :product_name product-name} (sql-jdbc.common/handle-additional-options details :separator-style :url)))) +(def ^:private ^{:arglists '([db-details])} cloud? + "Is this a cloud DB?" + (memoize/ttl + (fn [db-details] + (sql-jdbc.execute/do-with-connection-with-options + :clickhouse + (connection-details->spec* db-details) + nil + (fn [^java.sql.Connection conn] + (with-open [stmt (.prepareStatement conn "SELECT value='1' FROM system.settings WHERE name='cloud_mode'") + rset (.executeQuery stmt)] + (when (.next rset) + (.getBoolean rset 1)))))) + ;; cache the results for 48 hours; TTL is here only to eventually clear out old entries + :ttl/threshold (* 48 60 60 1000))) + +(defmethod sql-jdbc.conn/connection-details->spec :clickhouse + [_ details] + (cond-> (connection-details->spec* details) + (cloud? details) + ;; select_sequential_consistency guarantees that we can query data from any replica in CH Cloud + ;; immediately after it is written + (assoc :select_sequential_consistency true))) + +(defmethod driver/database-supports? [:clickhouse :uploads] [_driver _feature db] + (cloud? (:details db))) + (defmethod driver/can-connect? :clickhouse [driver details] (if config/is-test? @@ -203,7 +206,7 @@ db-id {:write? true} (fn [^java.sql.Connection conn] - (let [sql (format "insert into %s (%s)" (quote-name table-name) (str/join ", " (map quote-name column-names)))] + (let [sql (format "INSERT INTO %s (%s)" (quote-name table-name) (str/join ", " (map quote-name column-names)))] (with-open [ps (.prepareStatement conn sql)] (doseq [row values] (when (seq row) From 5554a61cd352cfb764fc92600f6ba75219152395 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Thu, 16 May 2024 21:35:16 -0600 Subject: [PATCH 09/11] Remove unused imports --- src/metabase/driver/clickhouse.clj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/metabase/driver/clickhouse.clj b/src/metabase/driver/clickhouse.clj index a01e8e0..2684ca2 100644 --- a/src/metabase/driver/clickhouse.clj +++ b/src/metabase/driver/clickhouse.clj @@ -5,7 +5,6 @@ [clojure.string :as str] [honey.sql :as sql] [metabase [config :as config]] - [metabase.db.connection :as mdb.connection] [metabase.driver :as driver] [metabase.driver.clickhouse-introspection] [metabase.driver.clickhouse-nippy] @@ -19,8 +18,7 @@ [metabase.driver.sql.util :as sql.u] [metabase.upload :as upload] [metabase.util.log :as log]) - (:import [com.clickhouse.client ClickHouseRequest] - [com.clickhouse.jdbc.internal ClickHouseStatementImpl])) + (:import [com.clickhouse.jdbc.internal ClickHouseStatementImpl])) (set! *warn-on-reflection* true) From eb3cdc7d828ad7cf23bf5b5b7b8bc8c9746478f7 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Fri, 17 May 2024 09:49:20 -0600 Subject: [PATCH 10/11] ~ 49.11 --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 42f7e9f..b20598d 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@v2 with: repository: metabase/metabase - ref: v0.49.6 + ref: v0.49.11 - name: Remove incompatible tests # dataset-definition-test tests test data definition, From 490a558354cdd12f14313acccbf3defb3e791d66 Mon Sep 17 00:00:00 2001 From: Cal Herries Date: Fri, 17 May 2024 10:41:04 -0600 Subject: [PATCH 11/11] ~ fix test and add test for `select_sequential_consistency` --- test/metabase/driver/clickhouse_test.clj | 70 ++++++++++++++---------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/test/metabase/driver/clickhouse_test.clj b/test/metabase/driver/clickhouse_test.clj index 663a561..7d60f29 100644 --- a/test/metabase/driver/clickhouse_test.clj +++ b/test/metabase/driver/clickhouse_test.clj @@ -6,6 +6,7 @@ [cljc.java-time.temporal.chrono-unit :as chrono-unit] [clojure.test :refer :all] [metabase.driver :as driver] + [metabase.driver.clickhouse :as clickhouse] [metabase.driver.clickhouse-data-types-test] [metabase.driver.clickhouse-introspection-test] [metabase.driver.clickhouse-substitution-test] @@ -56,34 +57,47 @@ (offset-date-time/parse shanghai-now date-time-formatter/iso-offset-date-time)))))))) (deftest ^:parallel clickhouse-connection-string - (testing "connection with no additional options" - (is (= ctd/default-connection-params - (sql-jdbc.conn/connection-details->spec - :clickhouse - {})))) - (testing "custom connection with additional options" - (is (= (merge - ctd/default-connection-params - {:subname "//myclickhouse:9999/foo?sessionTimeout=42" - :user "bob" - :password "qaz" - :use_no_proxy true - :ssl true}) - (sql-jdbc.conn/connection-details->spec - :clickhouse - {:host "myclickhouse" - :port 9999 - :user "bob" - :password "qaz" - :dbname "foo" - :use-no-proxy true - :additional-options "sessionTimeout=42" - :ssl true})))) - (testing "nil dbname handling" - (is (= ctd/default-connection-params - (sql-jdbc.conn/connection-details->spec - :clickhouse - {:dbname nil}))))) + (mt/with-dynamic-redefs [;; This function's implementation requires the connection details to actually connect to the + ;; database, which is orthogonal to the purpose of this test. + clickhouse/cloud? (constantly false)] + (testing "connection with no additional options" + (is (= ctd/default-connection-params + (sql-jdbc.conn/connection-details->spec + :clickhouse + {})))) + (testing "custom connection with additional options" + (is (= (merge + ctd/default-connection-params + {:subname "//myclickhouse:9999/foo?sessionTimeout=42" + :user "bob" + :password "qaz" + :use_no_proxy true + :ssl true}) + (sql-jdbc.conn/connection-details->spec + :clickhouse + {:host "myclickhouse" + :port 9999 + :user "bob" + :password "qaz" + :dbname "foo" + :use-no-proxy true + :additional-options "sessionTimeout=42" + :ssl true})))) + (testing "nil dbname handling" + (is (= ctd/default-connection-params + (sql-jdbc.conn/connection-details->spec + :clickhouse + {:dbname nil})))))) + +(deftest ^:parallel clickhouse-connection-string-select-sequential-consistency + (mt/with-dynamic-redefs [;; This function's implementation requires the connection details to actually + ;; connect to the database, which is orthogonal to the purpose of this test. + clickhouse/cloud? (constantly true)] + (testing "connection with no additional options" + (is (= (assoc ctd/default-connection-params :select_sequential_consistency true) + (sql-jdbc.conn/connection-details->spec + :clickhouse + {})))))) (deftest ^:parallel clickhouse-tls (mt/test-driver