From e1f15baa02651a383cb298df65a783b73db1f4a2 Mon Sep 17 00:00:00 2001 From: Oleksandr Yakushev Date: Sat, 5 Oct 2024 14:57:47 +0300 Subject: [PATCH] [select] Use transients in select-reducing functions --- src/toucan2/jdbc/mysql_mariadb.clj | 2 +- src/toucan2/pipeline.clj | 9 +++++++++ src/toucan2/select.clj | 6 +++--- test/toucan2/execute_test.clj | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/toucan2/jdbc/mysql_mariadb.clj b/src/toucan2/jdbc/mysql_mariadb.clj index 18cb590..f819e1e 100644 --- a/src/toucan2/jdbc/mysql_mariadb.clj +++ b/src/toucan2/jdbc/mysql_mariadb.clj @@ -107,7 +107,7 @@ _ (log/debugf "update-returning-pks workaround: doing SELECT with conditions %s" conditions-map) parsed-args (update pipeline/*parsed-args* :kv-args merge conditions-map) - select-rf (pipeline/with-init conj []) + select-rf (pipeline/conj-with-init! []) xform (map (model/select-pks-fn model)) pks (pipeline/transduce-query (xform select-rf) :toucan.query-type/select.instances.fns diff --git a/src/toucan2/pipeline.clj b/src/toucan2/pipeline.clj index 12f3a60..842eab8 100644 --- a/src/toucan2/pipeline.clj +++ b/src/toucan2/pipeline.clj @@ -326,6 +326,15 @@ ([x] (rf x)) ([x y] (rf x y)))) +(defn ^:no-doc conj!-with-init + "Returns a reducing function with a zero-arity (initial value arity) that returns transient version of `init`, `conj!`s + values into it, and finally returns a persistent collection in 1-arity." + [init] + (fn + ([] (transient init)) + ([acc] (persistent! acc)) + ([acc y] (conj! acc y)))) + (m/defmulti default-rf "The default reducing function for queries of `query-type`. Used for non-reducible operations like [[toucan2.select/select]] or [[toucan2.execute/query]]." diff --git a/src/toucan2/select.clj b/src/toucan2/select.clj index 76f17d0..0111abc 100644 --- a/src/toucan2/select.clj +++ b/src/toucan2/select.clj @@ -78,7 +78,7 @@ [f :conn connectable modelable-columns & kv-args? query?])} [f & unparsed-args] (let [f (comp realize/realize f) - rf (pipeline/with-init conj #{}) + rf (pipeline/conj-with-init! #{}) xform (map f)] (not-empty (pipeline/transduce-unparsed (xform rf) :toucan.query-type/select.instances.fns unparsed-args)))) @@ -98,7 +98,7 @@ [f :conn connectable modelable-columns & kv-args? query?])} [f & unparsed-args] (let [f (comp realize/realize f) - rf (pipeline/with-init conj []) + rf (pipeline/conj-with-init! []) xform (map f)] (not-empty (pipeline/transduce-unparsed (xform rf) :toucan.query-type/select.instances.fns unparsed-args)))) @@ -190,7 +190,7 @@ [f1 f2 & unparsed-args] (let [f1 (comp realize/realize f1) f2 (comp realize/realize f2) - rf (pipeline/with-init conj {}) + rf (pipeline/conj-with-init! {}) xform (map (juxt f1 f2))] (pipeline/transduce-unparsed (xform rf) :toucan.query-type/select.instances unparsed-args))) diff --git a/test/toucan2/execute_test.clj b/test/toucan2/execute_test.clj index 5e3dfb4..182ee4b 100644 --- a/test/toucan2/execute_test.clj +++ b/test/toucan2/execute_test.clj @@ -186,7 +186,7 @@ #_query-type :default #_model :default] [rf _conn _query-type _model [{k :key}, :as _compiled-query]] - (reduce rf (rf) [{k 1} {k 2} {k 3}])) + (transduce identity rf [{k 1} {k 2} {k 3}])) (deftest ^:parallel wow-dont-even-need-to-use-jdbc-test (is (= [{:a 1} {:a 2} {:a 3}] @@ -203,7 +203,7 @@ #_query-type :default #_model ::model.not-even-jdbc] [rf _conn _query-type _model {k :key, :as _compiled-query}] - (reduce rf (rf) [{k 4} {k 5} {k 6}])) + (transduce identity rf [{k 4} {k 5} {k 6}])) (deftest ^:parallel wow-dont-even-need-to-use-jdbc-custom-model-test (is (= [{:a 4} {:a 5} {:a 6}]