File tree Expand file tree Collapse file tree 3 files changed +46
-1
lines changed
Expand file tree Collapse file tree 3 files changed +46
-1
lines changed Original file line number Diff line number Diff line change 1+ # WIP
2+
3+ - Implement “constant substitution” optimization for queries #462
4+
15# 1.6.3
26
37- Fix regression in 1.6.2 #460 via @galdre
Original file line number Diff line number Diff line change 526526 (prod-rel (assoc production :tuples []) (empty-rel binding )))]
527527 (update context :rels collapse-rels new-rel)))
528528
529+ (defn substitute-constant [context pattern-el]
530+ (when (free-var? pattern-el)
531+ (when-some [rel (rel-with-attr context pattern-el)]
532+ (when-some [tuple (first (:tuples rel))]
533+ (when (nil? (fnext (:tuples rel)))
534+ (let [idx (get (:attrs rel) pattern-el)]
535+ (#?(:cljs da/aget :clj get) tuple idx)))))))
536+
537+ (defn substitute-constants [context pattern]
538+ (mapv #(or (substitute-constant context %) %) pattern))
539+
529540; ;; RULES
530541
531542(defn rule? [context clause]
790801
791802 '[*] ; ; pattern
792803 (let [source *implicit-source*
793- pattern (resolve-pattern-lookup-refs source clause)
804+ pattern (->> clause
805+ (substitute-constants context)
806+ (resolve-pattern-lookup-refs source))
794807 relation (lookup-pattern source pattern)]
795808 (binding [*lookup-attrs* (if (satisfies? db/IDB source)
796809 (dynamic-lookup-attrs source pattern)
Original file line number Diff line number Diff line change 265265 :where [?e :s b]]
266266 db)))))
267267
268+ (deftest ^{:doc " issue-462" } test-constant-substitution
269+ (let [cnt+q (fn [query db & sources]
270+ (let [*cnt (volatile! 0 )
271+ db' (d/filter db
272+ (fn [db datom]
273+ (vswap! *cnt inc)
274+ true ))
275+ res (apply d/q query db' sources)]
276+ [@*cnt res]))
277+ schema {:a {:db/index true }
278+ :b {:db/index true }
279+ :c {:db/index true }}
280+ db (-> (d/empty-db schema)
281+ (d/db-with
282+ (for [eid (range 1 11 )
283+ attr [:a :b :c ]]
284+ [:db/add eid attr (str eid (name attr))])))]
285+ (is (= [1 #{[" 5b" ]}] (cnt+q '[:find ?v :where [5 :b ?v]] db)))
286+ (is (= [1 #{[:b ]}] (cnt+q '[:find ?a :where [5 ?a " 5b" ]] db)))
287+ (is (= [1 #{[5 ]}] (cnt+q '[:find ?e :where [?e :b " 5b" ]] db)))
288+ (is (= [1 #{[5 :b " 5b" ]}] (cnt+q '[:find ?e ?a ?v :in $ ?e ?a :where [?e ?a ?v]] db 5 :b )))
289+ (is (= [2 #{[5 :b " 5b" ]}] (cnt+q '[:find ?e2 ?a ?v :in $ ?a ?v :where [?e ?a ?v] [?e2 ?a ?v]] db :b " 5b" )))
290+ (is (= [3 #{[:a " 5a" ] [:b " 5b" ] [:c " 5c" ]}] (cnt+q '[:find ?a ?v :in $ ?e :where [?e ?a ?v]] db 5 )))
291+ (is (= [1 #{[5 :b ]}] (cnt+q '[:find ?e ?a :where [?e ?a " 5b" ]] db)))
292+ (is (= [1 #{[5 :b ]}] (cnt+q '[:find ?e ?a :in $ ?v :where [?e ?a ?v]] db " 5b" )))
293+ (is (= [1 #{[5 :b ]}] (cnt+q '[:find ?e ?a :in $ [?v ...] :where [?e ?a ?v]] db [" 5b" ])))
294+ (is (= [1 #{[5 :b ]}] (cnt+q '[:find ?e ?a :where [(ground " 5b" ) ?v] [?e ?a ?v]] db)))))
295+
268296#_(require 'datascript.test.query :reload )
269297#_(clojure.test/test-ns 'datascript.test.query)
You can’t perform that action at this time.
0 commit comments