diff --git a/README.md b/README.md index 8a7e49a..f94dd3b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ This allows `cinq` to work with very large relations. ;; Query as if it is a normal collection (c/q [c (:customers db) :when (str/starts-with? c:name "A")] c) ;; => -#cinq/rel [{:name "Alice"}] +[{:name "Alice"}] ;; lmdb database come with a few initial relations for statistics and what not (:lmdb/variables db) @@ -148,7 +148,7 @@ Any changes will be committed together across all relvars at the end of the tran #### `read` ```clojure -(c/read [tx db] (:customers tx)) +(c/read [tx db] (c/q [c (:customers tx) :when (= 42 c:id)] c)) ``` #### `write` diff --git a/dev/imdb.clj b/dev/imdb.clj index e5c556d..21851e9 100644 --- a/dev/imdb.clj +++ b/dev/imdb.clj @@ -60,8 +60,8 @@ (defn parse-id [s] (parse-long (subs s 2))) (def names-tsv - (c/q [{:keys [nconst primaryName birthYear deathYear primaryProfession knownForTitles]} names-tsv*] - {:nconst (parse-id nconst) + (c/rel [{:keys [nconst primaryName birthYear deathYear primaryProfession knownForTitles]} names-tsv*] + {:nconst (parse-id nconst) :primaryName primaryName :birthYear (apply-or-null parse-long birthYear) :deathYear (apply-or-null parse-long deathYear) @@ -69,8 +69,8 @@ :knownForTitles (apply-csv parse-id knownForTitles)})) (def akas-tsv - (c/q [{:keys [titleId ordering title region language types attributes isOriginalTitle]} akas-tsv*] - {:titleId (parse-id titleId) + (c/rel [{:keys [titleId ordering title region language types attributes isOriginalTitle]} akas-tsv*] + {:titleId (parse-id titleId) :ordering (apply-or-null parse-long ordering) :title title :region (apply-or-null keyword region) @@ -80,8 +80,8 @@ :isOriginalTitle (= "1" isOriginalTitle)})) (def titles-tsv - (c/q [{:keys [tconst titleType primaryTitle originalTitle isAdult startYear endYear runtimeMinutes genres]} titles-tsv*] - {:tconst (parse-id tconst) + (c/rel [{:keys [tconst titleType primaryTitle originalTitle isAdult startYear endYear runtimeMinutes genres]} titles-tsv*] + {:tconst (parse-id tconst) :titleType (apply-or-null keyword titleType) :primaryTitle primaryTitle :originalTitle originalTitle @@ -92,21 +92,21 @@ :genres (apply-csv keyword genres)})) (def crew-tsv - (c/q [{:keys [tconst directors writers]} crew-tsv*] - {:tconst (parse-id tconst) + (c/rel [{:keys [tconst directors writers]} crew-tsv*] + {:tconst (parse-id tconst) :directors (apply-csv parse-id directors) :writers (apply-csv parse-id writers)})) (def episodes-tsv - (c/q [{:keys [tconst parentTconst seasonNumber episodeNumber]} episodes-tsv*] - {:tconst (parse-id tconst) + (c/rel [{:keys [tconst parentTconst seasonNumber episodeNumber]} episodes-tsv*] + {:tconst (parse-id tconst) :parentTconst (parse-id parentTconst) :seasonNumber (apply-or-null parse-long seasonNumber) :episodeNumber (apply-or-null parse-long episodeNumber)})) (def principals-tsv - (c/q [{:keys [tconst ordering nconst category job characters]} principals-tsv*] - {:tconst (parse-id tconst) + (c/rel [{:keys [tconst ordering nconst category job characters]} principals-tsv*] + {:tconst (parse-id tconst) :ordering (apply-or-null parse-long ordering) :nconst (parse-id nconst) ;; are these csv? @@ -115,8 +115,8 @@ :characters (apply-or-null str characters)})) (def ratings-tsv - (c/q [{:keys [tconst averageRating numVotes]} ratings-tsv*] - {:tconst (parse-id tconst) + (c/rel [{:keys [tconst averageRating numVotes]} ratings-tsv*] + {:tconst (parse-id tconst) :averageRating (apply-or-null parse-double averageRating) :numVotes (apply-or-null parse-long numVotes)})) @@ -186,20 +186,20 @@ ) (defn film-cast [{:keys [titles principals names]} title] - (c/q [t titles + (c/rel [t titles :when (and (= :movie t:titleType) (= title t:primaryTitle)) :limit 1 :join [p principals (= p:tconst t:tconst)] :join [n names (= p:nconst n:nconst)]] - n:primaryName)) + n:primaryName)) (defn film-cast-nlj [{:keys [titles principals names]} title] - (c/q [t (c/lookup titles :primaryTitle title) + (c/rel [t (c/lookup titles :primaryTitle title) :when (= :movie t:titleType) :limit 1 p (c/lookup principals :tconst t:tconst) n (c/lookup names :nconst p:nconst)] - n:primaryName)) + n:primaryName)) (comment @@ -210,7 +210,7 @@ (require 'clj-async-profiler.core) (clj-async-profiler.core/serve-ui "127.0.0.1" 5001) - (c/q [t titles-tsv + (c/rel [t titles-tsv :when (and (= :movie t:titleType) (= "Alien" t:primaryTitle)) :limit 1 @@ -218,7 +218,7 @@ :when (= p:tconst t:tconst) n names-tsv :when (= p:nconst n:nconst)] - n:primaryName) + n:primaryName) (time (vec (film-cast tsv-db "Alien"))) (time (vec (film-cast lmdb "Alien"))) @@ -231,19 +231,19 @@ (vec (film-cast-nlj lmdb "Blade Runner")) ) - (set (c/q [t titles] t:titleType)) + (set (c/rel [t titles] t:titleType)) - (c/q [t titles + (c/rel [t titles :when (and (= :videoGame t:titleType) (str/starts-with? t:primaryTitle "Star Wars"))] - [t:primaryTitle (c/scalar [r ratings :when (= r:tconst t:tconst)] r:averageRating)]) + [t:primaryTitle (c/scalar [r ratings :when (= r:tconst t:tconst)] r:averageRating)]) - (c/q [t titles + (c/rel [t titles :when (and (= t:titleType :movie) (< 1990 t:startYear 2001)) :join [r ratings (= t:tconst r:tconst)] :when (and (< 8.0 r:averageRating) (< 10000 r:numVotes)) :order [r:averageRating :desc] :limit 10] - t:primaryTitle) + t:primaryTitle) ) diff --git a/dev/scratch2.clj b/dev/scratch2.clj index 66454c4..e0bc467 100644 --- a/dev/scratch2.clj +++ b/dev/scratch2.clj @@ -2,85 +2,317 @@ (:require [clojure.java.io :as io] [com.wotbrew.cinq :as c] [com.wotbrew.cinq.lmdb :as lmdb])) + +(def sf001 @com.wotbrew.cinq.tpch-test/sf-001) +(def nation (vec (:nation sf001))) +(def partsupp (vec (:partsupp sf001))) +(def supplier (vec (:supplier sf001))) +(def lineitem (vec (:lineitem sf001))) + (reify* [clojure.lang.IReduceInit com.wotbrew.cinq.protocols.Scannable] (com.wotbrew.cinq.eager-loop/scan - [this__11466__auto__ f__11467__auto__ init__11468__auto__] + [this__134455__auto__ f__134456__auto__ init__134457__auto__] (clojure.core/let - [rsn24405 (clojure.core/long-array 1)] - (clojure.core/aset rsn24405 0 -1) + [rsn173129 (clojure.core/long-array 1)] + (clojure.core/aset rsn173129 0 -1) (.reduce - this__11466__auto__ + this__134455__auto__ (clojure.core/fn - [acc__11469__auto__ x__11470__auto__] - (f__11467__auto__ - acc__11469__auto__ + [acc__134458__auto__ x__134459__auto__] + (f__134456__auto__ + acc__134458__auto__ nil - (clojure.core/aset rsn24405 0 (clojure.core/unchecked-inc (clojure.core/aget rsn24405 0))) - x__11470__auto__)) - init__11468__auto__))) + (clojure.core/aset rsn173129 0 (clojure.core/unchecked-inc (clojure.core/aget rsn173129 0))) + x__134459__auto__)) + init__134457__auto__))) (clojure.core/reduce - [com.wotbrew.cinq.eager-loop/_ f24406 init__11468__auto__] + [com.wotbrew.cinq.eager-loop/_ f173130 init__134457__auto__] (clojure.core/let - [box24404 (clojure.core/object-array 1)] - (clojure.core/aset box24404 0 init__11468__auto__) + [box173128 (clojure.core/object-array 1)] + (clojure.core/aset box173128 0 init__134457__auto__) ((clojure.core/fn - [box24404] - (com.wotbrew.cinq.eager-loop/run-scan-no-rsn - (clojure.core/reify - clojure.lang.IFn - (com.wotbrew.cinq.eager-loop/invoke - [f__24041__auto__ agg__24042__auto__ rv__24043__auto__ rsn__24044__auto__ o__24045__auto__] - (.apply f__24041__auto__ agg__24042__auto__ rv__24043__auto__ rsn__24044__auto__ o__24045__auto__)) - com.wotbrew.cinq.CinqScanFunction - (clojure.core/filter [___24048__auto__ ___24048__auto__ ___24048__auto__] true) - (com.wotbrew.cinq.eager-loop/nativeFilter - [___24052__auto__ ___24052__auto__] - (clojure.core/reify - com.wotbrew.cinq.CinqScanFunction$NativeFilter - (clojure.core/apply [___24052__auto__ _rsn__24053__auto__ _buf__24054__auto__] true))) - (clojure.core/apply - [___24055__auto__ ___24055__auto__ rv24412 rsn24411 o__24056__auto__] - (clojure.core/let - [o24410 o__24056__auto__] - (clojure.core/prn rsn24411 o24410) + [box173128] + (clojure.core/let + [rs__134931__auto__ + (.toArray + (clojure.core/let + [list173134 (java.util.ArrayList.)] + (clojure.core/let + [ht173137 (java.util.HashMap.)] + (com.wotbrew.cinq.eager-loop/run-scan-no-rsn + (clojure.core/reify + clojure.lang.IFn + (com.wotbrew.cinq.eager-loop/invoke + [f__134301__auto__ agg__134302__auto__ rv__134303__auto__ rsn__134304__auto__ o__134305__auto__] + (if + (.filter f__134301__auto__ rsn__134304__auto__ o__134305__auto__) + (.apply f__134301__auto__ agg__134302__auto__ rv__134303__auto__ rsn__134304__auto__ o__134305__auto__) + agg__134302__auto__)) + com.wotbrew.cinq.CinqScanFunction + (clojure.core/filter + [___134311__auto__ rsn173139 o__134312__auto__] + (clojure.core/let + [o173138 o__134312__auto__] + (clojure.core/let + [l173105:shipdate (.-shipdate o173138)] + (clojure.core/and + (com.wotbrew.cinq.CinqUtil/lte l173105:shipdate #inst"1998-09-02T00:00:00.000-00:00") + true)))) + (com.wotbrew.cinq.eager-loop/nativeFilter + [___134314__auto__ symbol-table173142] + (clojure.core/let + [l173105:shipdate173143 + (com.wotbrew.cinq.nio-codec/encode-heap #inst"1998-09-02T00:00:00.000-00:00" symbol-table173142 false) + l173105:shipdate173144 + (com.wotbrew.cinq.nio-codec/intern-symbol symbol-table173142 :shipdate false)] + (clojure.core/when + (clojure.core/and l173105:shipdate173143 l173105:shipdate173144) + (clojure.core/reify + com.wotbrew.cinq.CinqScanFunction$NativeFilter + (clojure.core/apply + [___134314__auto__ rsn__134315__auto__ buf__134316__auto__] + (clojure.core/let + [valbuf173141 (.slice buf__134316__auto__)] + (clojure.core/and + (com.wotbrew.cinq.CinqUtil/gte + (com.wotbrew.cinq.nio-codec/bufcmp-ksv l173105:shipdate173143 valbuf173141 l173105:shipdate173144) + 0)))))))) + (clojure.core/apply + [___134320__auto__ ___134320__auto__ rv173140 rsn173139 o__134321__auto__] + (clojure.core/let + [o173138 o__134321__auto__] + (clojure.core/let + [l173105 + o173138 + l173105:discount + (.-discount o173138) + l173105:extendedprice + (.-extendedprice o173138) + l173105:linestatus + (.-linestatus o173138) + l173105:quantity + (.-quantity o173138) + l173105:returnflag + (.-returnflag o173138) + l173105:tax + (.-tax o173138) + l173105:shipdate + (.-shipdate o173138)] + (clojure.core/some-> + (clojure.core/let + [k173135 + (new com.wotbrew.cinq.tpch_test.Tuple72840 false l173105:returnflag l173105:linestatus) + f__134756__auto__ + (clojure.core/reify + java.util.function.BiFunction + (clojure.core/apply + [___134757__auto__ ___134757__auto__ arr__134758__auto__] + (clojure.core/let + [arr173136 + (clojure.core/or + arr__134758__auto__ + (clojure.core/doto + (clojure.core/object-array 11) + (clojure.core/aset 0 (clojure.lang.RT/box 0.0)) + (clojure.core/aset 1 (clojure.lang.RT/box 0.0)) + (clojure.core/aset 2 (clojure.lang.RT/box 0.0)) + (clojure.core/aset 3 (clojure.lang.RT/box (java.lang.Long/valueOf 0))) + (clojure.core/aset 4 (clojure.lang.RT/box 0.0)) + (clojure.core/aset 5 (clojure.lang.RT/box 0)) + (clojure.core/aset 6 (clojure.lang.RT/box 0.0)) + (clojure.core/aset 7 (clojure.lang.RT/box 0)) + (clojure.core/aset 8 (clojure.lang.RT/box 0.0)) + (clojure.core/aset 9 (clojure.lang.RT/box 0)) + (clojure.core/aset 10 (clojure.lang.RT/box 0)))) + acc-0-agg173109173117 + (clojure.core/aget arr173136 0) + acc-0-agg173110173118 + (clojure.core/aget arr173136 1) + acc-0-agg173111173119 + (clojure.core/aget arr173136 2) + acc-0-agg173112173120 + (clojure.core/aget arr173136 3) + acc-0-agg173113173121 + (clojure.core/aget arr173136 4) + acc-1-agg173113173122 + (clojure.core/aget arr173136 5) + acc-0-agg173114173123 + (clojure.core/aget arr173136 6) + acc-1-agg173114173124 + (clojure.core/aget arr173136 7) + acc-0-agg173115173125 + (clojure.core/aget arr173136 8) + acc-1-agg173115173126 + (clojure.core/aget arr173136 9) + acc-0-agg173116173127 + (clojure.core/aget arr173136 10)] + (clojure.core/aset + arr173136 + 0 + (clojure.lang.RT/box (com.wotbrew.cinq.CinqUtil/sumStep acc-0-agg173109173117 l173105:quantity))) + (clojure.core/aset + arr173136 + 1 + (clojure.lang.RT/box + (com.wotbrew.cinq.CinqUtil/sumStep acc-0-agg173110173118 l173105:extendedprice))) + (clojure.core/aset + arr173136 + 2 + (clojure.lang.RT/box + (com.wotbrew.cinq.CinqUtil/sumStep + acc-0-agg173111173119 + (com.wotbrew.cinq.CinqUtil/mul + l173105:extendedprice + (com.wotbrew.cinq.CinqUtil/sub 1.0 l173105:discount))))) + (clojure.core/aset + arr173136 + 3 + (clojure.lang.RT/box + (com.wotbrew.cinq.CinqUtil/sumStep + acc-0-agg173112173120 + (com.wotbrew.cinq.CinqUtil/mul + l173105:extendedprice + (com.wotbrew.cinq.CinqUtil/mul + (com.wotbrew.cinq.CinqUtil/sub 1.0 l173105:discount) + (com.wotbrew.cinq.CinqUtil/add 1.0 l173105:tax)))))) + (clojure.core/aset + arr173136 + 4 + (clojure.lang.RT/box (com.wotbrew.cinq.CinqUtil/sumStep acc-0-agg173113173121 l173105:quantity))) + (clojure.core/aset + arr173136 + 5 + (clojure.lang.RT/box (clojure.core/unchecked-inc acc-1-agg173113173122))) + (clojure.core/aset + arr173136 + 6 + (clojure.lang.RT/box + (com.wotbrew.cinq.CinqUtil/sumStep acc-0-agg173114173123 l173105:extendedprice))) + (clojure.core/aset + arr173136 + 7 + (clojure.lang.RT/box (clojure.core/unchecked-inc acc-1-agg173114173124))) + (clojure.core/aset + arr173136 + 8 + (clojure.lang.RT/box (com.wotbrew.cinq.CinqUtil/sumStep acc-0-agg173115173125 l173105:discount))) + (clojure.core/aset + arr173136 + 9 + (clojure.lang.RT/box (clojure.core/unchecked-inc acc-1-agg173115173126))) + (clojure.core/aset + arr173136 + 10 + (clojure.lang.RT/box (clojure.core/unchecked-inc acc-0-agg173116173127))) + arr173136)))] + (.compute ht173137 k173135 f__134756__auto__) + nil) + clojure.core/reduced)))) + (com.wotbrew.cinq.eager-loop/rootDoesNotEscape [___134320__auto__] false)) + lineitem) + (clojure.core/reduce + (clojure.core/fn + [___134759__auto__ [k173135 arr173136]] + (clojure.core/let + [returnflag173106 + (.-field0 k173135) + linestatus173107 + (.-field1 k173135) + acc-0-agg173109173117 + (clojure.core/aget arr173136 0) + acc-0-agg173110173118 + (clojure.core/aget arr173136 1) + acc-0-agg173111173119 + (clojure.core/aget arr173136 2) + acc-0-agg173112173120 + (clojure.core/aget arr173136 3) + acc-0-agg173113173121 + (clojure.core/aget arr173136 4) + acc-1-agg173113173122 + (clojure.core/aget arr173136 5) + acc-0-agg173114173123 + (clojure.core/aget arr173136 6) + acc-1-agg173114173124 + (clojure.core/aget arr173136 7) + acc-0-agg173115173125 + (clojure.core/aget arr173136 8) + acc-1-agg173115173126 + (clojure.core/aget arr173136 9) + acc-0-agg173116173127 + (clojure.core/aget arr173136 10) + agg173109 + acc-0-agg173109173117 + agg173110 + acc-0-agg173110173118 + agg173111 + acc-0-agg173111173119 + agg173112 + acc-0-agg173112173120 + agg173113 + (com.wotbrew.cinq.CinqUtil/div + acc-0-agg173113173121 + (com.wotbrew.cinq.expr/apply-n2n clojure.core/max 1 acc-1-agg173113173122)) + agg173114 + (com.wotbrew.cinq.CinqUtil/div + acc-0-agg173114173123 + (com.wotbrew.cinq.expr/apply-n2n clojure.core/max 1 acc-1-agg173114173124)) + agg173115 + (com.wotbrew.cinq.CinqUtil/div + acc-0-agg173115173125 + (com.wotbrew.cinq.expr/apply-n2n clojure.core/max 1 acc-1-agg173115173126)) + agg173116 + acc-0-agg173116173127 + col173104173108 + [returnflag173106 + linestatus173107 + agg173109 + agg173110 + agg173111 + agg173112 + agg173113 + agg173114 + agg173115 + agg173116]] + (clojure.core/some-> + (do (.add list173134 (new com.wotbrew.cinq.distinct_test.Tuple16803 false col173104173108)) nil) + clojure.core/reduced))) + nil + ht173137)) + list173134))] + (java.util.Arrays/sort + rs__134931__auto__ + (clojure.core/reify + java.util.Comparator + (clojure.core/compare + [___134928__auto__ a__134929__auto__ b__134930__auto__] (clojure.core/let - [t24402:nconst (:nconst o24410)] - (clojure.core/some-> - (com.wotbrew.cinq.eager-loop/run-scan-no-rsn - (clojure.core/reify - clojure.lang.IFn - (com.wotbrew.cinq.eager-loop/invoke - [f__24041__auto__ agg__24042__auto__ rv__24043__auto__ rsn__24044__auto__ o__24045__auto__] - (.apply f__24041__auto__ agg__24042__auto__ rv__24043__auto__ rsn__24044__auto__ o__24045__auto__)) - com.wotbrew.cinq.CinqScanFunction - (clojure.core/filter [___24048__auto__ ___24048__auto__ ___24048__auto__] true) - (com.wotbrew.cinq.eager-loop/nativeFilter - [___24052__auto__ ___24052__auto__] - (clojure.core/reify - com.wotbrew.cinq.CinqScanFunction$NativeFilter - (clojure.core/apply [___24052__auto__ _rsn__24053__auto__ _buf__24054__auto__] true))) - (clojure.core/apply - [___24055__auto__ ___24055__auto__ rv24409 rsn24408 o__24056__auto__] - (clojure.core/let - [o24407 o__24056__auto__] - (clojure.core/prn rsn24408 o24407) - (clojure.core/let - [n24403 o24407] - (clojure.core/some-> - (clojure.core/let - [col24401 n24403] - (clojure.core/let - [r__11465__auto__ (f24406 (clojure.core/aget box24404 0) (clojure.lang.RT/box col24401))] - (if - (clojure.core/reduced? r__11465__auto__) - (clojure.core/aset box24404 0 (clojure.core/deref r__11465__auto__)) - (do (clojure.core/aset box24404 0 r__11465__auto__) nil)))) - clojure.core/reduced)))) - (com.wotbrew.cinq.eager-loop/rootDoesNotEscape [___24055__auto__] false)) - ((:nconst names) t24402:nconst)) - clojure.core/reduced)))) - (com.wotbrew.cinq.eager-loop/rootDoesNotEscape [___24055__auto__] true)) - ((:tconst principals) 78748))) - box24404) - (clojure.core/aget box24404 0)))) + [t173132 a__134929__auto__ t173133 b__134930__auto__] + (clojure.core/let + [res__134927__auto__ + (clojure.core/compare (clojure.core/let [] returnflag173106) (clojure.core/let [] returnflag173106))] + (if + (clojure.core/= 0 res__134927__auto__) + (clojure.core/let + [res__134927__auto__ + (clojure.core/compare (clojure.core/let [] linestatus173107) (clojure.core/let [] linestatus173107))] + (if (clojure.core/= 0 res__134927__auto__) 0 (clojure.core/* res__134927__auto__ 1))) + (clojure.core/* res__134927__auto__ 1))))))) + (clojure.core/loop + [i__134932__auto__ 0] + (clojure.core/when + (clojure.core/< i__134932__auto__ (clojure.core/alength rs__134931__auto__)) + (clojure.core/let + [t173131 (clojure.core/aget rs__134931__auto__ i__134932__auto__) col173104173108 (.-field0 t173131)] + (clojure.core/or + (clojure.core/let + [col173104 col173104173108] + (clojure.core/let + [r__134454__auto__ (f173130 (clojure.core/aget box173128 0) (clojure.lang.RT/box col173104))] + (if + (clojure.core/reduced? r__134454__auto__) + (clojure.core/aset box173128 0 (clojure.core/deref r__134454__auto__)) + (do (clojure.core/aset box173128 0 r__134454__auto__) nil)))) + (recur (clojure.core/unchecked-inc i__134932__auto__)))))))) + box173128) + (clojure.core/aget box173128 0)))) diff --git a/dev/tpch.clj b/dev/tpch.clj index b7ad4fb..965b3bc 100644 --- a/dev/tpch.clj +++ b/dev/tpch.clj @@ -44,11 +44,11 @@ (println (format "%s - %s records, %.2fms" tname (c/rel-count (tname db)) (* 1e-6 (- end start))))))) (defn q1 [{:keys [lineitem]}] - (c/q [l lineitem + (c/rel [l lineitem :when (<= l:shipdate #inst "1998-09-02") :group [returnflag l:returnflag, linestatus l:linestatus] :order [returnflag :asc, linestatus :asc]] - (c/tuple :l_returnflag returnflag + (c/tuple :l_returnflag returnflag :l_linestatus linestatus :sum_qty (c/sum ^double l:quantity) :sum_base_price (c/sum ^double l:extendedprice) @@ -60,7 +60,7 @@ :count_order (c/count)))) (defn q2 [{:keys [part, supplier, partsupp, nation, region]}] - (c/q [r region + (c/rel [r region n nation s supplier p part @@ -89,7 +89,7 @@ n:name :asc s:name :asc p:partkey :asc]] - (c/tuple + (c/tuple :s_acctbal s:acctbal :s_name s:name :n_name n:name @@ -100,7 +100,7 @@ :s_comment s:comment))) (defn q3 [{:keys [customer orders lineitem]}] - (c/q [c customer + (c/rel [c customer o orders l lineitem :when @@ -115,14 +115,14 @@ :let [revenue (c/sum (* l:extendedprice (- 1 l:discount)))] :order [revenue :desc, orderdate :asc, orderkey :asc] :limit 10] - (c/tuple + (c/tuple :l_orderkey orderkey :revenue revenue :o_orderdate orderdate :o_shippriority shippriority))) (defn q4 [{:keys [orders, lineitem]}] - (c/q [o orders + (c/rel [o orders :when (and (>= o:orderdate #inst "1993-07-01") (< o:orderdate #inst "1993-10-01") (c/exists? [^Lineitem l lineitem @@ -130,12 +130,12 @@ (< l:commitdate l:receiptdate))])) :group [orderpriority o:orderpriority] :order [orderpriority :asc]] - (c/tuple + (c/tuple :o_orderpriority orderpriority :order_count (c/count)))) (defn q5 [{:keys [customer, orders, lineitem, supplier, nation, region]}] - (c/q [o orders + (c/rel [o orders c customer l lineitem s supplier @@ -153,24 +153,24 @@ :group [nation-name n:name] :let [revenue (c/sum (* l:extendedprice (- 1 l:discount)))] :order [revenue :desc]] - (c/tuple :n_name nation-name + (c/tuple :n_name nation-name :revenue revenue))) (defn q6 [{:keys [lineitem]}] - (c/q [l lineitem + (c/rel [l lineitem :when (and (>= l:shipdate #inst "1994-01-01") (< l:shipdate #inst "1995-01-01") (>= l:discount 0.05) (<= l:discount 0.07) (< l:quantity 24.0)) :group []] - (c/tuple :foo (c/sum (* l:extendedprice l:discount))))) + (c/tuple :foo (c/sum (* l:extendedprice l:discount))))) (defn get-year [^Date date] (+ 1900 (.getYear date))) (defn q7 [{:keys [supplier lineitem orders customer nation]}] - (c/q [s supplier + (c/rel [s supplier l lineitem o orders c customer @@ -200,13 +200,13 @@ :order [supp_nation :asc cust_nation :asc year :asc]] - (c/tuple :supp_nation supp_nation + (c/tuple :supp_nation supp_nation :cust_nation cust_nation :l_year year :revenue (c/sum volume)))) (defn q8 [{:keys [part supplier region lineitem orders customer nation]}] - (c/q [r region + (c/rel [r region p part s supplier l lineitem @@ -231,7 +231,7 @@ nation n2:name] :group [o_year o_year] :order [o_year :asc]] - (c/tuple + (c/tuple :o_year o_year :mkt_share (double (/ (c/sum (if (= "BRAZIL" nation) @@ -240,7 +240,7 @@ (c/sum volume)))))) (defn q9 [{:keys [part supplier lineitem partsupp orders nation]}] - (c/q [p part + (c/rel [p part l lineitem s supplier ps partsupp @@ -258,12 +258,12 @@ :group [nation n:name year (get-year o:orderdate)] :order [nation :asc, year :desc]] - (c/tuple :nation nation + (c/tuple :nation nation :o_year year :sum_profit (c/sum amount)))) (defn q10 [{:keys [lineitem customer orders nation]}] - (c/q [n nation + (c/rel [n nation c customer o orders l lineitem @@ -285,7 +285,7 @@ :let [revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))] :order [revenue :desc, c_custkey :asc] :limit 20] - (c/tuple :c_custkey c_custkey + (c/tuple :c_custkey c_custkey :c_name c_name :revenue revenue :c_acctbal c_acctbal @@ -295,7 +295,7 @@ :c_comment c_comment))) (defn q11 [{:keys [partsupp supplier nation]}] - (c/q [n nation + (c/rel [n nation s supplier ps partsupp :when @@ -314,11 +314,11 @@ :group []] (* 0.0001 (c/sum (* ps:supplycost ps:availqty))))) :order [value :desc]] - (c/tuple :ps_partkey ps_partkey + (c/tuple :ps_partkey ps_partkey :value value))) (defn q12 [{:keys [orders lineitem]}] - (c/q [o orders + (c/rel [o orders l lineitem :when (and (= o:orderkey l:orderkey) (contains? #{"MAIL", "SHIP"} l:shipmode) @@ -328,28 +328,28 @@ (< l:receiptdate #inst "1995-01-01")) :group [shipmode l:shipmode] :order [shipmode :asc]] - (c/tuple + (c/tuple :shipmode shipmode :high_line_count (c/sum (case o:orderpriority "1-URGENT" 1 "2-HIGH" 1 0)) :low_line_count (c/sum (case o:orderpriority "1-URGENT" 0 "2-HIGH" 0 1))))) (defn q13 [{:keys [customer orders]}] - (c/q [c customer + (c/rel [c customer :left-join [o orders (and (= c:custkey o:custkey) (not (re-find #"special.*?requests" o:comment)))] :group [custkey c:custkey] :group [order-count (c/count o:orderkey)] :order [(c/count) :desc, order-count :desc]] - (c/tuple :c_count order-count, :custdist (c/count)))) + (c/tuple :c_count order-count, :custdist (c/count)))) (defn q14 [{:keys [lineitem part]}] - (c/q [l lineitem + (c/rel [l lineitem p part :when (and (= l:partkey p:partkey) (>= l:shipdate #inst "1995-09-01") (< l:shipdate #inst "1995-10-01")) :group []] - (c/tuple + (c/tuple :promo_revenue (* 100.0 (/ (c/sum (if (str/starts-with? p:type "PROMO") @@ -358,26 +358,26 @@ (c/sum (* l:extendedprice (- 1.0 l:discount)))))))) (defn q15 [{:keys [lineitem supplier]}] - (let [revenue (c/q [l lineitem + (let [revenue (c/rel [l lineitem :when (and (>= l:shipdate #inst "1996-01-01") (< l:shipdate #inst "1996-04-01")) :group [suppkey l:suppkey] :let [total_revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))]] - {:suppkey suppkey + {:suppkey suppkey :total_revenue total_revenue})] - (c/q [s supplier + (c/rel [s supplier r revenue :when (and (= s:suppkey r:suppkey) (= r:total_revenue (c/scalar [r revenue :group []] (c/max r:total_revenue)))) :order [s:suppkey :asc]] - (c/tuple :s_suppkey s:suppkey + (c/tuple :s_suppkey s:suppkey :s_name s:name :s_address s:address :s_phone s:phone :total_revenue r:total_revenue)))) (defn q16 [{:keys [partsupp part supplier]}] - (c/q [p part + (c/rel [p part ps partsupp :when (and (= p:partkey ps:partkey) (not= p:brand "Brand#45") @@ -391,13 +391,13 @@ :group [brand p:brand, type p:type, size p:size] :let [supplier-cnt (Long/valueOf (count (set ps:suppkey)))] :order [supplier-cnt :desc, brand :asc, type :asc, size :asc]] - (c/tuple :p_brand brand + (c/tuple :p_brand brand :p_type type :p_size size :supplier_cnt supplier-cnt))) (defn q17 [{:keys [lineitem part]}] - (c/q [p part + (c/rel [p part l lineitem :when (and (= p:partkey l:partkey) (= p:brand "Brand#23") @@ -408,15 +408,15 @@ :group []] (* 0.2 (c/avg l2:quantity))))) :group []] - (c/tuple :avg_yearly (when (pos? %count) (/ (c/sum l:extendedprice) 7.0))))) + (c/tuple :avg_yearly (when (pos? %count) (/ (c/sum l:extendedprice) 7.0))))) (defn q18 [{:keys [customer orders lineitem]}] ;; TODO make this a sub query without weirdness - (let [orderkeys (set (c/q [l lineitem + (let [orderkeys (set (c/rel [l lineitem :group [ok l:orderkey] :when (> (c/sum l:quantity) 300)] - ok))] - (c/q [o orders + ok))] + (c/rel [o orders c customer l lineitem :when (and (contains? orderkeys o:orderkey) @@ -429,7 +429,7 @@ totalprice o:totalprice] :order [totalprice :desc, orderdate :asc, orderkey :asc] :limit 100] - (c/tuple :c_name name + (c/tuple :c_name name :c_custkey custkey :c_orderkey orderkey :c_orderdate orderdate @@ -437,7 +437,7 @@ :quantity (c/sum l:quantity))))) (defn q19 [{:keys [lineitem part]}] - (c/q [l lineitem + (c/rel [l lineitem p part :when (and (= l:partkey p:partkey) (= l:shipinstruct "DELIVER IN PERSON") @@ -458,10 +458,10 @@ (<= l:quantity 30) (<= 1 p:size 15)))) :group []] - (c/tuple :revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))))) + (c/tuple :revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))))) (defn q20 [{:keys [supplier, nation, partsupp, lineitem, part]}] - (c/q [n nation + (c/rel [n nation s supplier :when (and (contains? (c/scalar [ps partsupp :when (and (contains? (c/scalar [p part @@ -482,10 +482,10 @@ (= s:nationkey n:nationkey) (= n:name "CANADA")) :order [s:name :asc]] - (c/tuple :name s:name, :address s:address))) + (c/tuple :name s:name, :address s:address))) (defn q21 [{:keys [supplier lineitem orders nation]}] - (c/q [n nation + (c/rel [n nation s supplier o orders l1 lineitem @@ -508,12 +508,12 @@ :let [numwait (c/count)] :order [numwait :desc] :limit 100] - (c/tuple + (c/tuple :name s_name :numwait numwait))) (defn q22 [{:keys [customer orders]}] - (c/q [c customer + (c/rel [c customer :let [cntrycode (subs c:phone 0 2)] :when (and (contains? #{"13", "31", "23", "29", "30", "18", "17"} cntrycode) (> c:acctbal (c/scalar [c customer @@ -524,7 +524,7 @@ (not (c/exists? [o orders :when (= o:custkey c:custkey)]))) :group [cntrycode cntrycode] :order [cntrycode :asc]] - (c/tuple :cntrycode cntrycode, + (c/tuple :cntrycode cntrycode, :numcust (c/count), :totacctbal (c/sum c:acctbal)))) diff --git a/src/com/wotbrew/cinq.clj b/src/com/wotbrew/cinq.clj index 04ebdc8..8b1c8de 100644 --- a/src/com/wotbrew/cinq.clj +++ b/src/com/wotbrew/cinq.clj @@ -33,13 +33,15 @@ (defmacro plan [rel-expr] (list `quote (plan/stack-view (fix-env &env tree* rel-expr)))) -(defmacro q [query body] +(defmacro rel [query body] (binding [parse/*env* &env] (-> (parse/parse-query query body) optimize-plan (plan/prune-cols #{}) compile-plan))) +(defmacro q [query body] `(vec (rel ~query ~body))) + (defmacro with [bindings rel-expr] (binding [parse/*env* &env] (-> (parse/parse-cte bindings rel-expr) @@ -61,7 +63,7 @@ ([rel] (reduce (fn [_ x] (reduced x)) nil rel)) ([rel not-found] (reduce (fn [_ x] (reduced x)) not-found rel))) -(defmacro scalar [query selection] `(rel-first (q ~query ~selection))) +(defmacro scalar [query selection] `(rel-first (rel ~query ~selection))) (defmacro exists? [query] `(boolean (scalar ~query true))) @@ -76,7 +78,7 @@ (defmacro agg [init init-sym query & body] {:pre [(symbol? init-sym)]} - `(clojure.core/reduce (fn [~init-sym f#] (f# ~init-sym)) ~init (q ~query (fn [~init-sym] ~@body)))) + `(clojure.core/reduce (fn [~init-sym f#] (f# ~init-sym)) ~init (rel ~query (fn [~init-sym] ~@body)))) (defmacro run [query & body] (let [srelvar (fn [?alias] (symbol (str ?alias ":cinq") "relvar")) @@ -339,21 +341,21 @@ [idx] (p/sorted-scan idx false)) -(defn top-k [idx n] (q [x (desc idx) :limit n] x)) +(defn top-k [idx n] (rel [x (desc idx) :limit n] x)) -(defn bottom-k [idx n] (q [x (asc idx) :limit n] x)) +(defn bottom-k [idx n] (rel [x (asc idx) :limit n] x)) (defn lookup [relvar indexed-key key] (if-some [idx (get relvar indexed-key)] (getn idx key) - (q [{k indexed-key :as r} :when (= k key)] r))) + (rel [{k indexed-key :as r} :when (= k key)] r))) (defn lookup1 ([relvar indexed-key key] (lookup1 relvar indexed-key key nil)) ([relvar indexed-key key not-found] (if-some [idx (get relvar indexed-key)] (get1 idx key not-found) - (rel-first (q [{k indexed-key :as r} :when (= k key)] r) not-found)))) + (rel-first (rel [{k indexed-key :as r} :when (= k key)] r) not-found)))) (defn swap "Updates rows where (= (indexed-key row) key), by applying a function to the existing row. diff --git a/src/com/wotbrew/cinq/lmdb.clj b/src/com/wotbrew/cinq/lmdb.clj index f7b0682..8e5b3c2 100644 --- a/src/com/wotbrew/cinq/lmdb.clj +++ b/src/com/wotbrew/cinq/lmdb.clj @@ -1002,11 +1002,11 @@ (c/rel-set (:foo db) nil) (c/insert (:foo db) (str (random-uuid))) (c/run [f (:foo db) :when (= 42 f)] (c/replace f "The answer")) - (c/q [f (:foo db) :when (string? f) :limit 10] f) + (c/rel [f (:foo db) :when (string? f) :limit 10] f) (c/del-key (:foo db) string? true) (c/run [f (:foo db) :when (string? f)] (delete f)) (c/write [db db] (c/run [f (:foo db) :when (even? f)] (c/replace f 42))) - (c/q [f (:foo db) :when (odd? f) :limit 10] f) + (c/rel [f (:foo db) :when (odd? f) :limit 10] f) (:foo db) @@ -1042,8 +1042,8 @@ ) (require 'criterium.core) - (criterium.core/quick-bench (c/q [i (:foo db) :limit 10] i)) - (criterium.core/quick-bench (c/q [i (:foo db) :limit 10] i)) + (criterium.core/quick-bench (c/rel [i (:foo db) :limit 10] i)) + (criterium.core/quick-bench (c/rel [i (:foo db) :limit 10] i)) (criterium.core/quick-bench (vec (:foo db))) (def sf005 ((requiring-resolve 'com.wotbrew.cinq.tpch-test/all-tables) 0.05)) @@ -1070,11 +1070,11 @@ (criterium.core/quick-bench (c/agg nil _ [li (:lineitem sf005)] nil)) (defn q1 [{:keys [lineitem]}] - (c/q [l lineitem + (c/rel [l lineitem :when (<= l:shipdate #inst "1998-09-02") :group [returnflag l:returnflag, linestatus l:linestatus] :order [returnflag :asc, linestatus :asc]] - (c/tuple :l_returnflag returnflag + (c/tuple :l_returnflag returnflag :l_linestatus linestatus :sum_qty (c/sum ^double l:quantity) :sum_base_price (c/sum ^double l:extendedprice) @@ -1086,7 +1086,7 @@ :count_order (c/count)))) (defn q2 [{:keys [part, supplier, partsupp, nation, region]}] - (c/q [r region + (c/rel [r region n nation s supplier p part @@ -1115,7 +1115,7 @@ n:name :asc s:name :asc p:partkey :asc]] - (c/tuple + (c/tuple :s_acctbal s:acctbal :s_name s:name :n_name n:name @@ -1125,9 +1125,9 @@ :s_phone s:phone :s_comment s:comment))) - (c/q [l (:lineitem db) + (c/rel [l (:lineitem db) :group [pred-match (<= l:shipdate #inst "1998-09-02")]] - [pred-match (c/count)]) + [pred-match (c/count)]) (clj-async-profiler.core/profile (criterium.core/quick-bench diff --git a/src/com/wotbrew/cinq/parse.clj b/src/com/wotbrew/cinq/parse.clj index 269a469..8b62097 100644 --- a/src/com/wotbrew/cinq/parse.clj +++ b/src/com/wotbrew/cinq/parse.clj @@ -191,9 +191,9 @@ 'com.wotbrew.cinq/count-distinct (into [::plan/count-distinct] ?args) `com.wotbrew.cinq/scalar - [::plan/scalar-sq (parse (list* 'com.wotbrew.cinq/q ?args))] + [::plan/scalar-sq (parse (list* 'com.wotbrew.cinq/rel ?args))] `com.wotbrew.cinq/exists? - [::plan/scalar-sq (parse (list* 'com.wotbrew.cinq/q (concat ?args [true])))] + [::plan/scalar-sq (parse (list* 'com.wotbrew.cinq/rel (concat ?args [true])))] (if (and (n2n-rewrites (some-> (resolve *env* ?sym) .toSymbol)) (seq ?args)) @@ -350,7 +350,7 @@ (when (and (seq? rel-expr) (symbol? (first rel-expr))) (condp = (some-> ^clojure.lang.Var (ns-resolve *ns* *env* (first rel-expr)) .toSymbol) - 'com.wotbrew.cinq/q (parse-query (nth rel-expr 1) (nth rel-expr 2 :cinq/*)) + 'com.wotbrew.cinq/rel (parse-query (nth rel-expr 1) (nth rel-expr 2 :cinq/*)) 'com.wotbrew.cinq/with (parse-cte (nth rel-expr 1) (nth rel-expr 2 :cinq/*)) 'com.wotbrew.cinq/union (parse-union (rest rel-expr)) nil))) @@ -364,13 +364,13 @@ (comment - (parse '(com.wotbrew.cinq/q [a [1, 2, 3]])) - (parse '(com.wotbrew.cinq/q [a [1, 2, 3]] a)) - (parse '(com.wotbrew.cinq/q [a [1, 2, 3]] {:foo a, :bar (inc a)})) - (parse '(com.wotbrew.cinq/q [a [1, 2, 3]] ($select :foo a, :bar (inc a)))) + (parse '(com.wotbrew.cinq/rel [a [1, 2, 3]])) + (parse '(com.wotbrew.cinq/rel [a [1, 2, 3]] a)) + (parse '(com.wotbrew.cinq/rel [a [1, 2, 3]] {:foo a, :bar (inc a)})) + (parse '(com.wotbrew.cinq/rel [a [1, 2, 3]] ($select :foo a, :bar (inc a)))) - (parse '(com.wotbrew.cinq/q [a [1, 2] + (parse '(com.wotbrew.cinq/rel [a [1, 2] :when (not (com.wotbrew.cinq/scalar [b [1] :when (= a b)] true))] - a)) + a)) ) diff --git a/test/com/wotbrew/cinq/cmp_test.clj b/test/com/wotbrew/cinq/cmp_test.clj index f4a7672..443ce59 100644 --- a/test/com/wotbrew/cinq/cmp_test.clj +++ b/test/com/wotbrew/cinq/cmp_test.clj @@ -2,7 +2,7 @@ (:require [clojure.test :refer :all] [com.wotbrew.cinq :as c])) -(defmacro prj [expr] `(c/rel-first (c/q [x# [{}]] ~expr))) +(defmacro prj [expr] `(c/rel-first (c/rel [x# [{}]] ~expr))) (deftest expr-test (are [expr result] diff --git a/test/com/wotbrew/cinq/count_distinct_test.clj b/test/com/wotbrew/cinq/count_distinct_test.clj index 8a0c8e7..a4dd84a 100644 --- a/test/com/wotbrew/cinq/count_distinct_test.clj +++ b/test/com/wotbrew/cinq/count_distinct_test.clj @@ -3,7 +3,7 @@ [com.wotbrew.cinq :as c])) (deftest count-distinct-test - (is (= [2] (vec (c/q [a [1 1 2 nil nil 1 1 2]] (c/count-distinct a))))) - (is (= [2] (vec (c/q [a [{:k 0} {:k 1} {:k 1}]] (c/count-distinct (even? (:k a))))))) - (is (= [1] (vec (c/q [a [1 2 nil 1]] (c/count-distinct 1)))))) + (is (= [2] (c/q [a [1 1 2 nil nil 1 1 2]] (c/count-distinct a)))) + (is (= [2] (c/q [a [{:k 0} {:k 1} {:k 1}]] (c/count-distinct (even? (:k a)))))) + (is (= [1] (c/q [a [1 2 nil 1]] (c/count-distinct 1))))) diff --git a/test/com/wotbrew/cinq/cte_test.clj b/test/com/wotbrew/cinq/cte_test.clj index 7472c8a..a55ae64 100644 --- a/test/com/wotbrew/cinq/cte_test.clj +++ b/test/com/wotbrew/cinq/cte_test.clj @@ -17,7 +17,7 @@ (c/with [a [42] a []] a) [42] (c/with [a [42] a [43]] a) [42, 43] (c/with [a [42] a [43] b a] b) [42, 43] - (c/with [a [42] a (c/q [a a :when (< a 44)] (inc a))] a) [42, 43, 44])) + (c/with [a [42] a (c/rel [a a :when (< a 44)] (inc a))] a) [42, 43, 44])) (deftest ancestor-test (is (= '[["bob" "jim"] @@ -35,10 +35,10 @@ ["bob" "karen"] ["karen" "lois"] ["lois" "eve"]] - ancestor (c/q [[a b] ancestor + ancestor (c/rel [[a b] ancestor [c d] ancestor :when (= b c)] - [a d])] + [a d])] ancestor)) (vec @@ -50,10 +50,10 @@ parent father parent mother ancestor parent - ancestor (c/q [[a b] ancestor + ancestor (c/rel [[a b] ancestor [c d] ancestor :when (= b c)] - [a d])] + [a d])] ancestor)))) (is (= [["bob" "jim" ["bob" "jim"]] @@ -76,13 +76,13 @@ ["bob" "ralph"] ;; thar be a cycle ["ralph" "bob"]] - friend-path (c/q [[a b] friend] [a b [a b]]) - friend-path (c/q [[a b path1] friend-path + friend-path (c/rel [[a b] friend] [a b [a b]]) + friend-path (c/rel [[a b path1] friend-path [c d path2] friend-path :when (and (= b c) ;; cycle gets stopped by this clause (not (some #{a} path2)))] - [a d (conj path1 d)])] + [a d (conj path1 d)])] friend-path))))) (deftest mandlebrot-meme-test @@ -111,32 +111,32 @@ ....#"] (vec (c/with [xaxis [-2.0M] - xaxis (c/q [x xaxis :when (< x 1.2)] (+ x 0.05)) + xaxis (c/rel [x xaxis :when (< x 1.2)] (+ x 0.05)) yaxis [-1.0M] - yaxis (c/q [y yaxis :when (< y 1.0)] (+ y 0.1)) - m (c/q [x xaxis, y yaxis] [0 x y 0.0 0.0]) - m (c/q [[iter cx cy x y] m + yaxis (c/rel [y yaxis :when (< y 1.0)] (+ y 0.1)) + m (c/rel [x xaxis, y yaxis] [0 x y 0.0 0.0]) + m (c/rel [[iter cx cy x y] m :when (and (< (+ (* x x) (* y y)) 4.0) (< iter 28)) :order [cx :asc cy :asc]] - [(inc iter) + [(inc iter) cx cy (+ cx (- (* x x) (* y y))) (+ cy (* 2.0 x y))]) - m2 (c/q [[iter cx cy] m + m2 (c/rel [[iter cx cy] m :group [cx cx, cy cy] :order [cx :asc cy :asc]] - [(c/max iter) cx cy]) - a (c/q [[iter cx cy] m2 + [(c/max iter) cx cy]) + a (c/rel [[iter cx cy] m2 :group [cy cy] :order [cy :desc]] - (str/join "" (map #(let [i (min (quot % 7) 4)] + (str/join "" (map #(let [i (min (quot % 7) 4)] (subs " .+*#" i (inc i))) iter)))] - (c/q [t a + (c/rel [t a :group []] - (str/join "\n" (map str/trimr t)))))))) + (str/join "\n" (map str/trimr t)))))))) (deftest under-alice-test (is (= ["Alice" @@ -155,10 +155,10 @@ ["Fred" "Cindy"] ["Gail" "Cindy"]] under-alice [["Alice" 0]] - under-alice (c/q [[name1 boss] org + under-alice (c/rel [[name1 boss] org [name2 level] under-alice :when (= name2 boss) :order [level :asc]] - [name1 (inc level)])] - (c/q [[name level] under-alice] - (str (subs ".........." 0 (* level 3)) name))))))) + [name1 (inc level)])] + (c/rel [[name level] under-alice] + (str (subs ".........." 0 (* level 3)) name))))))) diff --git a/test/com/wotbrew/cinq/distinct_test.clj b/test/com/wotbrew/cinq/distinct_test.clj index 184135e..dc11d9a 100644 --- a/test/com/wotbrew/cinq/distinct_test.clj +++ b/test/com/wotbrew/cinq/distinct_test.clj @@ -3,8 +3,8 @@ [com.wotbrew.cinq :as c])) (deftest distinct-test - (is (= 1 (c/rel-count (c/q [a [1 2 3 4 5 5 5] :distinct [a] :limit 1] a)))) - (is (= [1 2 3] (vec (c/q [a [1 1 1 2 2 3] :distinct [a]] a)))) - (is (= [2 1] (vec (c/q [a [{:k 1 :n 2} {:k 1 :n 1} {:k 2 :n 1}] + (is (= 1 (c/rel-count (c/rel [a [1 2 3 4 5 5 5] :distinct [a] :limit 1] a)))) + (is (= [1 2 3] (vec (c/rel [a [1 1 1 2 2 3] :distinct [a]] a)))) + (is (= [2 1] (vec (c/rel [a [{:k 1 :n 2} {:k 1 :n 1} {:k 2 :n 1}] :distinct [(even? a:k)]] - a:n))))) + a:n))))) diff --git a/test/com/wotbrew/cinq/first_test.clj b/test/com/wotbrew/cinq/first_test.clj index 59028ea..967b1d4 100644 --- a/test/com/wotbrew/cinq/first_test.clj +++ b/test/com/wotbrew/cinq/first_test.clj @@ -4,7 +4,7 @@ (deftest rel-first-test (is (= nil (c/rel-first []))) - (is (= nil (c/rel-first (c/q [a []] a)))) + (is (= nil (c/rel-first (c/rel [a []] a)))) (is (= 1 (c/rel-first [1 2 3]))) - (is (= 0 (c/rel-first (c/q [a (map (fn [i] (if (= 42 i) (throw (Exception. "foo")) i)) (range 1e6))] a)))) + (is (= 0 (c/rel-first (c/rel [a (map (fn [i] (if (= 42 i) (throw (Exception. "foo")) i)) (range 1e6))] a)))) (is (= 0 (c/scalar [a (map (fn [i] (if (= 42 i) (throw (Exception. "foo")) i)) (range 1e6))] a)))) diff --git a/test/com/wotbrew/cinq/group_test.clj b/test/com/wotbrew/cinq/group_test.clj index 0289409..aaafee6 100644 --- a/test/com/wotbrew/cinq/group_test.clj +++ b/test/com/wotbrew/cinq/group_test.clj @@ -4,12 +4,12 @@ [com.wotbrew.cinq.column])) (deftest accessible-as-coll-test - (is (= [1 2 3] (c/rel-first (c/q [a [1 2 3] :group []] (vec a))))) - (is (= [[1 3] [2]] (vec (c/q [a [1 2 3] :group [even (even? a)] :order [even :asc]] (vec a)))))) + (is (= [1 2 3] (c/rel-first (c/rel [a [1 2 3] :group []] (vec a))))) + (is (= [[1 3] [2]] (vec (c/rel [a [1 2 3] :group [even (even? a)] :order [even :asc]] (vec a)))))) (deftest type-is-column-test - (is (instance? com.wotbrew.cinq.column.Column (c/rel-first (c/q [a [] :group []] a))))) + (is (instance? com.wotbrew.cinq.column.Column (c/rel-first (c/rel [a [] :group []] a))))) (deftest can-mix-aggregate-col-test - (is (= [[1 2 3] 6] (c/rel-first (c/q [a [1 2 3] :group []] [(vec a) (c/sum a)]))))) + (is (= [[1 2 3] 6] (c/rel-first (c/rel [a [1 2 3] :group []] [(vec a) (c/sum a)]))))) diff --git a/test/com/wotbrew/cinq/implicit_group_test.clj b/test/com/wotbrew/cinq/implicit_group_test.clj index 67a88ef..7d41389 100644 --- a/test/com/wotbrew/cinq/implicit_group_test.clj +++ b/test/com/wotbrew/cinq/implicit_group_test.clj @@ -3,12 +3,12 @@ [com.wotbrew.cinq :as c])) (deftest groups-are-added-for-top-level-project-test - (is (= [4] (vec (c/q [a [1 2 3 4]] (c/count))))) - (is (= [3] (vec (c/q [a [1 2 3 nil]] (c/count a))))) - (is (= [3] (vec (c/q [a [1 2]] (c/sum a))))) - (is (= [1] (vec (c/q [a [2 1]] (c/min a))))) - (is (= [2] (vec (c/q [a [1 2]] (c/max a))))) - (is (= [3/2] (vec (c/q [a [1 2]] (c/avg a)))))) + (is (= [4] (vec (c/rel [a [1 2 3 4]] (c/count))))) + (is (= [3] (vec (c/rel [a [1 2 3 nil]] (c/count a))))) + (is (= [3] (vec (c/rel [a [1 2]] (c/sum a))))) + (is (= [1] (vec (c/rel [a [2 1]] (c/min a))))) + (is (= [2] (vec (c/rel [a [1 2]] (c/max a))))) + (is (= [3/2] (vec (c/rel [a [1 2]] (c/avg a)))))) (deftest groups-added-to-let-test - (is (= [1] (vec (c/q [a [] :let [n (+ 1 (c/count))]] n))))) + (is (= [1] (vec (c/rel [a [] :let [n (+ 1 (c/count))]] n))))) diff --git a/test/com/wotbrew/cinq/lmdb_test.clj b/test/com/wotbrew/cinq/lmdb_test.clj index 670591f..ebb5437 100644 --- a/test/com/wotbrew/cinq/lmdb_test.clj +++ b/test/com/wotbrew/cinq/lmdb_test.clj @@ -103,9 +103,9 @@ (c/run [f (idx 42) :limit 1] (c/delete f)) - (is (= [42] (vec (c/q [f (get idx 42)] f:id)))) - (is (= [42] (vec (c/q [f (c/range idx > 40) :when (= f:id 42)] f:id)))) - (is (= [42] (vec (c/q [f (get idx 42) :when (< f:id 43)] f:id))))) + (is (= [42] (vec (c/rel [f (get idx 42)] f:id)))) + (is (= [42] (vec (c/rel [f (c/range idx > 40) :when (= f:id 42)] f:id)))) + (is (= [42] (vec (c/rel [f (get idx 42) :when (< f:id 43)] f:id))))) ) (s/def ::value @@ -153,50 +153,50 @@ (deftest native-eq-test (let [foo (c/create db :foo) _ (c/rel-set foo [{:n 42}])] - (is (= 42 (c/rel-first (c/q [f foo :when (= f:n 42)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (= 42 f:n2)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (= f:n nil)] f:n) ::no-result))))) + (is (= 42 (c/rel-first (c/rel [f foo :when (= f:n 42)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (= 42 f:n2)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (= f:n nil)] f:n) ::no-result))))) (deftest native-cmp-test (let [foo (c/create db :foo) _ (c/rel-set foo [{:n 42, :n3 nil}])] - (is (= ::no-result (c/rel-first (c/q [f foo :when (< f:n 42)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (<= f:n 41)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n 42)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n 43)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n 42)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n 43)] f:n) ::no-result))) - - (is (= ::no-result (c/rel-first (c/q [f foo :when (< f:n nil)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (< f:n2 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (< f:n2 Long/MAX_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (< f:n3 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (< f:n3 Long/MAX_VALUE)] f:n) ::no-result))) - - (is (= ::no-result (c/rel-first (c/q [f foo :when (<= f:n nil)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (<= f:n2 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (<= f:n2 Long/MAX_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (<= f:n3 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (<= f:n3 Long/MAX_VALUE)] f:n) ::no-result))) - - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n nil)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n2 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n2 Long/MAX_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n3 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (> f:n3 Long/MAX_VALUE)] f:n) ::no-result))) - - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n nil)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n2 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n2 Long/MAX_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n3 Long/MIN_VALUE)] f:n) ::no-result))) - (is (= ::no-result (c/rel-first (c/q [f foo :when (>= f:n3 Long/MAX_VALUE)] f:n) ::no-result))) - - (is (= 42 (c/rel-first (c/q [f foo :when (= f:n 42)] f:n)))) - (is (= 42 (c/rel-first (c/q [f foo :when (< f:n 43)] f:n)))) - (is (= 42 (c/rel-first (c/q [f foo :when (> f:n 41)] f:n)))) - (is (= 42 (c/rel-first (c/q [f foo :when (<= f:n 42)] f:n)))) - (is (= 42 (c/rel-first (c/q [f foo :when (>= f:n 42)] f:n)))))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (< f:n 42)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (<= f:n 41)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n 42)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n 43)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n 42)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n 43)] f:n) ::no-result))) + + (is (= ::no-result (c/rel-first (c/rel [f foo :when (< f:n nil)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (< f:n2 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (< f:n2 Long/MAX_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (< f:n3 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (< f:n3 Long/MAX_VALUE)] f:n) ::no-result))) + + (is (= ::no-result (c/rel-first (c/rel [f foo :when (<= f:n nil)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (<= f:n2 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (<= f:n2 Long/MAX_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (<= f:n3 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (<= f:n3 Long/MAX_VALUE)] f:n) ::no-result))) + + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n nil)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n2 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n2 Long/MAX_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n3 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (> f:n3 Long/MAX_VALUE)] f:n) ::no-result))) + + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n nil)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n2 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n2 Long/MAX_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n3 Long/MIN_VALUE)] f:n) ::no-result))) + (is (= ::no-result (c/rel-first (c/rel [f foo :when (>= f:n3 Long/MAX_VALUE)] f:n) ::no-result))) + + (is (= 42 (c/rel-first (c/rel [f foo :when (= f:n 42)] f:n)))) + (is (= 42 (c/rel-first (c/rel [f foo :when (< f:n 43)] f:n)))) + (is (= 42 (c/rel-first (c/rel [f foo :when (> f:n 41)] f:n)))) + (is (= 42 (c/rel-first (c/rel [f foo :when (<= f:n 42)] f:n)))) + (is (= 42 (c/rel-first (c/rel [f foo :when (>= f:n 42)] f:n)))))) (deftest create-relvar-map-resize-test (with-open [db (lmdb/database (File/createTempFile "cinq-test" ".cinq") :map-size (* 128 1024))] diff --git a/test/com/wotbrew/cinq/null_test.clj b/test/com/wotbrew/cinq/null_test.clj index f3e2954..cc713e4 100644 --- a/test/com/wotbrew/cinq/null_test.clj +++ b/test/com/wotbrew/cinq/null_test.clj @@ -5,7 +5,7 @@ (deftest nil-ordering-guarantees-test ;; todo prop with ordering on/off equiv (is (= [[3 {:a 3, :s "fr"}]] - (vec (c/q [a [1, 2, 3] + (vec (c/rel [a [1, 2, 3] b [{:a 1 :s "he"}, {:a 2 :s nil}, {:a 3 :s "fr"}] :when (and (= a b:a) (not= a 2) (= "fr" (subs b:s 0 2)))] - [a b]))))) + [a b]))))) diff --git a/test/com/wotbrew/cinq/relvar_test.clj b/test/com/wotbrew/cinq/relvar_test.clj index 37adbbb..7c6a181 100644 --- a/test/com/wotbrew/cinq/relvar_test.clj +++ b/test/com/wotbrew/cinq/relvar_test.clj @@ -10,10 +10,10 @@ (c/rel-set rv1 [1 2 3 4]) (c/rel-set rv2 [2 4 5 6]) - (is (= [2 4] (vec (c/q [x rv1 + (is (= [2 4] (vec (c/rel [x rv1 y rv2 :when (= x y)] - x)))) + x)))) (is (= 4 (c/insert rv1 5))) (is (= 5 (c/insert rv1 5))) @@ -73,9 +73,9 @@ (c/run [f (idx 42) :limit 1] (c/delete f)) - (is (= [42] (vec (c/q [f (get idx 42)] f:id)))) - (is (= [42] (vec (c/q [f (c/range idx > 40) :when (= f:id 42)] f:id)))) - (is (= [42] (vec (c/q [f (get idx 42) :when (< f:id 43)] f:id)))))) + (is (= [42] (vec (c/rel [f (get idx 42)] f:id)))) + (is (= [42] (vec (c/rel [f (c/range idx > 40) :when (= f:id 42)] f:id)))) + (is (= [42] (vec (c/rel [f (get idx 42) :when (< f:id 43)] f:id)))))) (deftest sorted-scan-test (let [foo (c/relvar) diff --git a/test/com/wotbrew/cinq/semi_join_test.clj b/test/com/wotbrew/cinq/semi_join_test.clj index 1815fcf..dd5d812 100644 --- a/test/com/wotbrew/cinq/semi_join_test.clj +++ b/test/com/wotbrew/cinq/semi_join_test.clj @@ -4,47 +4,47 @@ (deftest semi-join-test (is (= [] - (vec (c/q + (vec (c/rel [a [] :when (c/exists? [b []])] true)))) (is (= [] - (vec (c/q + (vec (c/rel [a [1] :when (c/exists? [b []])] true)))) (is (= [true] - (vec (c/q + (vec (c/rel [a [1] :when (c/exists? [b [1]])] true)))) (is (= [true] (vec - (c/q + (c/rel [a [1] :when (c/exists? [b [1] :when (= a b)])] true)))) (is (= [2] (vec - (c/q [a [1, 2] + (c/rel [a [1, 2] :when (not (c/exists? [b [1] :when (= a b)]))] - a)))) + a)))) (is (= [1] (vec - (c/q [a [1] + (c/rel [a [1] :when (c/exists? [b [a]])] - a)))) + a)))) (is (= [] (vec - (c/q [a [1] + (c/rel [a [1] :when (not (c/exists? [b [a]]))] - a)))) + a)))) ) diff --git a/test/com/wotbrew/cinq/single_join_test.clj b/test/com/wotbrew/cinq/single_join_test.clj index 2c6aec6..eb5260c 100644 --- a/test/com/wotbrew/cinq/single_join_test.clj +++ b/test/com/wotbrew/cinq/single_join_test.clj @@ -4,4 +4,4 @@ (deftest equi-single-re-test (is (= [[1 1] [2 2] [3 3]]) - (vec (c/q [a [1, 2, 3]] [a (c/scalar [b [1, 2, 3] :when (= a b)] b)])))) + (vec (c/rel [a [1, 2, 3]] [a (c/scalar [b [1, 2, 3] :when (= a b)] b)])))) diff --git a/test/com/wotbrew/cinq/tpch_test.clj b/test/com/wotbrew/cinq/tpch_test.clj index 64ffe5b..1fc44b5 100644 --- a/test/com/wotbrew/cinq/tpch_test.clj +++ b/test/com/wotbrew/cinq/tpch_test.clj @@ -3,7 +3,7 @@ [clojure.string :as str] [clojure.test :refer :all] [clojure.instant :as inst] - [com.wotbrew.cinq :as c :refer [q]] + [com.wotbrew.cinq :as c :refer [rel]] [com.wotbrew.cinq.protocols :as p]) (:import (io.airlift.tpch GenerateUtils TpchColumn TpchColumnType$Base TpchEntity TpchTable) (java.util Date))) @@ -157,11 +157,11 @@ :avg_disc (/ (reduce + (map :discount lineitems)) (max 1 (count lineitems))) :count_order (count lineitems))))) - (q [^Lineitem l lineitem + (rel [^Lineitem l lineitem :when (<= l:shipdate #inst "1998-09-02") :group [returnflag l:returnflag, linestatus l:linestatus] :order [returnflag :asc, linestatus :asc]] - (c/tuple :l_returnflag returnflag + (c/tuple :l_returnflag returnflag :l_linestatus linestatus :sum_qty (c/sum l:quantity) :sum_base_price (c/sum l:extendedprice) @@ -185,7 +185,7 @@ ) (defn q2 [{:keys [part, supplier, partsupp, nation, region]}] - (q [^Region r region + (rel [^Region r region ^Nation n nation ^Supplier s supplier ^Part p part @@ -214,7 +214,7 @@ n:name :asc s:name :asc p:partkey :asc]] - (c/tuple + (c/tuple :s_acctbal s:acctbal :s_name s:name :n_name n:name @@ -235,7 +235,7 @@ ;; nested relational calculus (defn q3 [{:keys [customer orders lineitem]}] - (q [^Customer c customer + (rel [^Customer c customer ^Order o orders ^Lineitem l lineitem :when @@ -250,7 +250,7 @@ :let [revenue (c/sum (* l:extendedprice (- 1 l:discount)))] :order [revenue :desc, orderdate :asc, orderkey :asc] :limit 10] - (c/tuple + (c/tuple :l_orderkey orderkey :revenue revenue :o_orderdate orderdate @@ -265,7 +265,7 @@ (defn q4 [{:keys [orders, lineitem]}] ;; needs decor + semijoin - (q [^Order o orders + (rel [^Order o orders :when (and (>= o:orderdate #inst "1993-07-01") (< o:orderdate #inst "1993-10-01") (c/exists? [^Lineitem l lineitem @@ -273,7 +273,7 @@ (< l:commitdate l:receiptdate))])) :group [orderpriority o:orderpriority] :order [orderpriority :asc]] - (c/tuple + (c/tuple :o_orderpriority orderpriority :order_count (c/count)))) @@ -287,7 +287,7 @@ (deftest q4-test (check-answer #'q4 @sf-001)) (defn q5 [{:keys [customer, orders, lineitem, supplier, nation, region]}] - (q [^Order o orders + (rel [^Order o orders ^Customer c customer ^Lineitem l lineitem ^Supplier s supplier @@ -305,7 +305,7 @@ :group [nation-name n:name] :let [revenue (c/sum (* l:extendedprice (- 1 l:discount)))] :order [revenue :desc]] - (c/tuple :n_name nation-name + (c/tuple :n_name nation-name :revenue revenue))) (deftest q5-test (check-answer #'q5 @sf-001)) @@ -318,14 +318,14 @@ ) (defn q6 [{:keys [lineitem]}] - (q [^Lineitem l lineitem + (rel [^Lineitem l lineitem :when (and (>= l:shipdate #inst "1994-01-01") (< l:shipdate #inst "1995-01-01") (>= l:discount 0.05) (<= l:discount 0.07) (< l:quantity 24.0)) :group []] - (c/tuple :foo (c/sum (* l:extendedprice l:discount))))) + (c/tuple :foo (c/sum (* l:extendedprice l:discount))))) (deftest q6-test (check-answer #'q6 @sf-001)) @@ -340,7 +340,7 @@ (+ 1900 (.getYear date))) (defn q7 [{:keys [supplier lineitem orders customer nation]}] - (q [^Supplier s supplier + (rel [^Supplier s supplier ^Lineitem l lineitem ^Order o orders ^Customer c customer @@ -370,7 +370,7 @@ :order [supp_nation :asc cust_nation :asc year :asc]] - (c/tuple :supp_nation supp_nation + (c/tuple :supp_nation supp_nation :cust_nation cust_nation :l_year year :revenue (c/sum volume)))) @@ -384,7 +384,7 @@ ) (defn q8 [{:keys [part supplier region lineitem orders customer nation]}] - (q [^Region r region + (rel [^Region r region ^Part p part ^Supplier s supplier ^Lineitem l lineitem @@ -409,7 +409,7 @@ nation n2:name] :group [o_year o_year] :order [o_year :asc]] - (c/tuple + (c/tuple :o_year o_year :mkt_share (double (/ (c/sum (if (= "BRAZIL" nation) @@ -426,7 +426,7 @@ ) (defn q9 [{:keys [part supplier lineitem partsupp orders nation]}] - (q [^Part p part + (rel [^Part p part ^Lineitem l lineitem ^Supplier s supplier ^Partsupp ps partsupp @@ -444,7 +444,7 @@ :group [nation n:name year (get-year o:orderdate)] :order [nation :asc, year :desc]] - (c/tuple :nation nation + (c/tuple :nation nation :o_year year :sum_profit (c/sum amount)))) @@ -457,7 +457,7 @@ ) (defn q10 [{:keys [lineitem customer orders nation]}] - (q [^Nation n nation + (rel [^Nation n nation ^Customer c customer ^Order o orders ^Lineitem l lineitem @@ -479,7 +479,7 @@ :let [revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))] :order [revenue :desc, c_custkey :asc] :limit 20] - (c/tuple :c_custkey c_custkey + (c/tuple :c_custkey c_custkey :c_name c_name :revenue revenue :c_acctbal c_acctbal @@ -497,7 +497,7 @@ ) (defn q11 [{:keys [partsupp supplier nation]}] - (q [^Nation n nation + (rel [^Nation n nation ^Supplier s supplier ^Partsupp ps partsupp :when @@ -516,7 +516,7 @@ :group []] (* 0.0001 (c/sum (* ps:supplycost ps:availqty))))) :order [value :desc]] - (c/tuple :ps_partkey ps_partkey + (c/tuple :ps_partkey ps_partkey :value value))) (deftest q11-test (check-answer #'q11 @sf-001)) @@ -528,7 +528,7 @@ ) (defn q12 [{:keys [orders lineitem]}] - (q [^Order o orders + (rel [^Order o orders ^Lineitem l lineitem :when (and (= o:orderkey l:orderkey) (contains? #{"MAIL", "SHIP"} l:shipmode) @@ -538,7 +538,7 @@ (< l:receiptdate #inst "1995-01-01")) :group [shipmode l:shipmode] :order [shipmode :asc]] - (c/tuple + (c/tuple :shipmode shipmode :high_line_count (c/sum (case o:orderpriority "1-URGENT" 1 "2-HIGH" 1 0)) :low_line_count (c/sum (case o:orderpriority "1-URGENT" 0 "2-HIGH" 0 1))))) @@ -552,13 +552,13 @@ ) (defn q13 [{:keys [customer orders]}] - (q [^Customer c customer + (rel [^Customer c customer :left-join [o orders (and (= c:custkey o:custkey) (not (re-find #"special.*?requests" o:comment)))] :group [custkey c:custkey] :group [order-count (c/count o:orderkey)] :order [(c/count) :desc, order-count :desc]] - (c/tuple :c_count order-count, :custdist (c/count)))) + (c/tuple :c_count order-count, :custdist (c/count)))) (deftest q13-test (check-answer #'q13 @sf-001)) @@ -569,13 +569,13 @@ ) (defn q14 [{:keys [lineitem part]}] - (q [^Lineitem l lineitem + (rel [^Lineitem l lineitem ^Part p part :when (and (= l:partkey p:partkey) (>= l:shipdate #inst "1995-09-01") (< l:shipdate #inst "1995-10-01")) :group []] - (c/tuple + (c/tuple :promo_revenue (* 100.0 (/ (c/sum (if (str/starts-with? p:type "PROMO") @@ -592,19 +592,19 @@ ) (defn q15 [{:keys [lineitem supplier]}] - (let [revenue (q [l lineitem + (let [revenue (rel [l lineitem :when (and (>= l:shipdate #inst "1996-01-01") (< l:shipdate #inst "1996-04-01")) :group [suppkey l:suppkey] :let [total_revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))]] - {:suppkey suppkey + {:suppkey suppkey :total_revenue total_revenue})] - (q [^Supplier s supplier + (rel [^Supplier s supplier r revenue :when (and (= s:suppkey r:suppkey) (= r:total_revenue (c/scalar [r revenue :group []] (c/max r:total_revenue)))) :order [s:suppkey :asc]] - (c/tuple :s_suppkey s:suppkey + (c/tuple :s_suppkey s:suppkey :s_name s:name :s_address s:address :s_phone s:phone @@ -619,7 +619,7 @@ ) (defn q16 [{:keys [partsupp part supplier]}] - (q [^Part p part + (rel [^Part p part ^Partsupp ps partsupp :when (and (= p:partkey ps:partkey) (not= p:brand "Brand#45") @@ -633,7 +633,7 @@ :group [brand p:brand, type p:type, size p:size] :let [supplier-cnt (Long/valueOf (count (set ps:suppkey)))] :order [supplier-cnt :desc, brand :asc, type :asc, size :asc]] - (c/tuple :p_brand brand + (c/tuple :p_brand brand :p_type type :p_size size :supplier_cnt supplier-cnt))) @@ -647,7 +647,7 @@ ) (defn q17 [{:keys [lineitem part]}] - (q [^Part p part + (rel [^Part p part ^Lineitem l lineitem :when (and (= p:partkey l:partkey) (= p:brand "Brand#23") @@ -658,7 +658,7 @@ :group []] (* 0.2 (c/avg l2:quantity))))) :group []] - (c/tuple :avg_yearly (when (pos? %count) (/ (c/sum l:extendedprice) 7.0))))) + (c/tuple :avg_yearly (when (pos? %count) (/ (c/sum l:extendedprice) 7.0))))) (deftest q17-test (check-answer #'q17 @sf-001)) @@ -670,11 +670,11 @@ (defn q18 [{:keys [customer orders lineitem]}] ;; TODO make this a sub query without weirdness - (let [orderkeys (set (q [^Lineitem l lineitem + (let [orderkeys (set (rel [^Lineitem l lineitem :group [ok l:orderkey] :when (> (c/sum l:quantity) 300)] - ok))] - (q [^Order o orders + ok))] + (rel [^Order o orders ^Customer c customer ^Lineitem l lineitem :when (and (contains? orderkeys o:orderkey) @@ -687,7 +687,7 @@ totalprice o:totalprice] :order [totalprice :desc, orderdate :asc, orderkey :asc] :limit 100] - (c/tuple :c_name name + (c/tuple :c_name name :c_custkey custkey :c_orderkey orderkey :c_orderdate orderdate @@ -705,7 +705,7 @@ ;; allow this with the l:partkey p:partkey condition in the OR as god intended (defn q19 [{:keys [lineitem part]}] - (q [^Lineitem l lineitem + (rel [^Lineitem l lineitem ^Part p part :when (and (= l:partkey p:partkey) (= l:shipinstruct "DELIVER IN PERSON") @@ -726,7 +726,7 @@ (<= l:quantity 30) (<= 1 p:size 15)))) :group []] - (c/tuple :revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))))) + (c/tuple :revenue (c/sum (* l:extendedprice (- 1.0 l:discount)))))) (deftest q19-test (check-answer #'q19 @sf-001)) @@ -737,7 +737,7 @@ ) (defn q20 [{:keys [supplier, nation, partsupp, lineitem, part]}] - (q [^Nation n nation + (rel [^Nation n nation ^Supplier s supplier :when (and (contains? (c/scalar [^Partsupp ps partsupp :when (and (contains? (c/scalar [^Part p part @@ -759,7 +759,7 @@ (= s:nationkey n:nationkey) (= n:name "CANADA")) :order [s:name :asc]] - (c/tuple :name s:name, :address s:address))) + (c/tuple :name s:name, :address s:address))) (deftest q20-test (check-answer #'q20 @sf-001)) @@ -770,7 +770,7 @@ ) (defn q21 [{:keys [supplier lineitem orders nation]}] - (q [^Nation n nation + (rel [^Nation n nation ^Supplier s supplier ^Order o orders ^Lineitem l1 lineitem @@ -793,7 +793,7 @@ :let [numwait (c/count)] :order [numwait :desc] :limit 100] - (c/tuple + (c/tuple :name s_name :numwait numwait))) @@ -807,7 +807,7 @@ ) (defn q22 [{:keys [customer orders]}] - (q [^Customer c customer + (rel [^Customer c customer :let [cntrycode (subs c:phone 0 2)] :when (and (contains? #{"13", "31", "23", "29", "30", "18", "17"} cntrycode) (> c:acctbal (c/scalar [^Customer c customer @@ -818,7 +818,7 @@ (not (c/exists? [o orders :when (= o:custkey c:custkey)]))) :group [cntrycode cntrycode] :order [cntrycode :asc]] - (c/tuple :cntrycode cntrycode, + (c/tuple :cntrycode cntrycode, :numcust (c/count), :totacctbal (c/sum c:acctbal)))) @@ -886,9 +886,13 @@ ) ) + (clj-async-profiler.core/profile + (criterium.core/quick-bench + (c/rel-count (q1 dataset)) + )) (clj-async-profiler.core/profile (run-tpch)) - (time (dotimes [x 1] (count (q1 dataset)))) + (time (dotimes [x 1] (c/rel-count (q1 dataset)))) (time (dotimes [x 1] (count (q1-el dataset)))) (time (dotimes [x 1] (count (q2 dataset)))) (time (dotimes [x 1] (count (q3 dataset)))) diff --git a/test/com/wotbrew/cinq/union_test.clj b/test/com/wotbrew/cinq/union_test.clj index 794c10b..aa34b6d 100644 --- a/test/com/wotbrew/cinq/union_test.clj +++ b/test/com/wotbrew/cinq/union_test.clj @@ -6,5 +6,5 @@ (is (= [] (vec (c/union)))) (is (= [1] (vec (c/union [1])))) (is (= [1, 2, 1] (vec (c/union [1, 2] [1])))) - (is (= [1, 2, 1] (vec (c/union [1, 2] (c/q [a [1]] a))))) - (is (= [1, 2, "1"] (vec (c/union [1, 2] (c/q [a [1]] (str a))))))) + (is (= [1, 2, 1] (vec (c/union [1, 2] (c/rel [a [1]] a))))) + (is (= [1, 2, "1"] (vec (c/union [1, 2] (c/rel [a [1]] (str a))))))) diff --git a/test/com/wotbrew/cinq/unnesting_test.clj b/test/com/wotbrew/cinq/unnesting_test.clj index 3dc2aef..6244985 100644 --- a/test/com/wotbrew/cinq/unnesting_test.clj +++ b/test/com/wotbrew/cinq/unnesting_test.clj @@ -34,9 +34,9 @@ #{l1__3}] [:project {col__1 col__1__5}]] - (c/plan (c/q [l1 lineitem + (c/plan (c/rel [l1 lineitem :when (c/exists? [l2 lineitem :when (= l1:orderkey l2:orderkey)])] - l1))))) + l1))))) ;; todo mark-join: @@ -50,17 +50,17 @@ (defrecord Exam [^long id ^long sid ^long grade]) (defn unnest-q1 [{:keys [students, exams]}] - (c/q [^Student s students + (c/rel [^Student s students :join [^Exam e exams (= s:id e:sid)] :when (= e:grade (c/scalar [^Exam e2 exams :when (= s:id e2:sid) :group []] (c/min e2:grade)))] - e:exam)) + e:exam)) ;; needs dataset (defn unnest-q2 [{:keys [students, exams]}] - (c/plan (c/q [^Student s students + (c/plan (c/rel [^Student s students ^Exam e exams :when (and (= s:id e:sid) (or (= s:major "CS") (= s:major "Games Eng")) @@ -69,7 +69,7 @@ (and (= e2:curriculum s:major) (> s:year e2:date)))] (+ 1 (c/avg e2:grade)))))] - (c/tuple :name s:name, :course e:course)))) + (c/tuple :name s:name, :course e:course)))) (def unnest-dataset {:students (vec (for [i (range 1000)] (->Student i))) diff --git a/test/ds_test.clj b/test/ds_test.clj index f84814f..82b581c 100644 --- a/test/ds_test.clj +++ b/test/ds_test.clj @@ -21,37 +21,37 @@ (def people20k (vec (shuffle (take 20000 people)))) (defn q1 [{:keys [people]}] - (c/q [p people + (c/rel [p people ;; we want to get this straight from the buf! :when (= "Ivan" p:name)] - p:id)) + p:id)) (defn qpred1 [{:keys [people]}] - (c/q [p people + (c/rel [p people :when (> p:salary 50000)] - p:id)) + p:id)) (defn q2 [{:keys [people]}] - (c/q [p people + (c/rel [p people :when (= "Ivan" p:name)] - (c/tuple :id p:id :age p:age))) + (c/tuple :id p:id :age p:age))) (defn q3 [{:keys [people]}] - (c/q [p people + (c/rel [p people :when (and (= "Ivan" p:name) (= :male p:sex))] - (c/tuple :id p:id :last-name p:last-name))) + (c/tuple :id p:id :last-name p:last-name))) (defn q4 [{:keys [people]}] - (c/q [p people + (c/rel [p people :when (and (= "Ivan" p:name) (= :male p:sex))] - (c/tuple :id p:id :last-name p:last-name, :age p:age))) + (c/tuple :id p:id :last-name p:last-name, :age p:age))) (defn q5 [{:keys [people]}] - (c/q [p people + (c/rel [p people p1 people :when (and (= "Ivan" p:name) (= p:age p1:age))] - (c/tuple :id p1:id :last-name p1:last-name, :age p1:age))) + (c/tuple :id p1:id :last-name p1:last-name, :age p1:age))) (comment diff --git a/todo.txt b/todo.txt index 752a1a0..276378a 100644 --- a/todo.txt +++ b/todo.txt @@ -21,18 +21,6 @@ in order to do this, I think we will need to be certain the planner rewrites for --- -rel vs results - -(c/q) currently returns a rel. This might be an awkward default, -- rel definitions will likely escape transactions -- no equality - -idea: -(c/q) returns a vector -(c/rel) returns a rel - ---- - Indexes do not use native filters, does this matter? ---