Add tests and comments for clause ordering.

This commit is contained in:
Richard Newman 2016-07-26 11:19:51 -07:00
parent feaca75a74
commit 1ad67a03eb
2 changed files with 50 additions and 2 deletions

View file

@ -101,7 +101,10 @@
once will result in duplicate clauses." once will result in duplicate clauses."
[cc] [cc]
(impose-external-bindings (impose-external-bindings
(assoc cc :wheres (concat (bindings->where (:bindings cc)) (assoc cc :wheres
;; Note that the order of clauses here means that cross-pattern var bindings
;; come first. That's OK: the SQL engine considers these altogether.
(concat (bindings->where (:bindings cc))
(:wheres cc))))) (:wheres cc)))))
;; Pattern building is recursive, so we need forward declarations. ;; Pattern building is recursive, so we need forward declarations.

View file

@ -80,3 +80,48 @@
[?page :page/starred true ?t] [?page :page/starred true ?t]
[?t :db/txInstant ?timestampMicros] [?t :db/txInstant ?timestampMicros]
(not [?page :foo/bar _])])))) (not [?page :foo/bar _])]))))
;; Note that clause ordering is not directly correlated to the output: cross-bindings end up
;; at the front. The SQL engine will do its own analysis. See `clauses/expand-where-from-bindings`.
(deftest test-not-clause-ordering-preserved
(is (= {:select '([:datoms1.v :timestampMicros] [:datoms0.e :page]),
:modifiers [:distinct],
:from '[[:datoms datoms0]
[:datoms datoms1]],
:where (list
:and
[:= :datoms1.e :datoms0.tx]
[:= :datoms0.a "page/starred"]
[:= :datoms0.v 1]
[:not
(list :and (list :> :datoms0.tx (sql/param :latest)))]
[:= :datoms1.a "db/txInstant"])}
(expand
'[:find ?timestampMicros ?page :in $ ?latest :where
[?page :page/starred true ?t]
(not [(> ?t ?latest)])
[?t :db/txInstant ?timestampMicros]]))))
(deftest test-pattern-not-join-ordering-preserved
(is (= '{:select ([:datoms2.v :timestampMicros] [:datoms0.e :page]),
:modifiers [:distinct],
:from [[:datoms datoms0]
[:datoms datoms2]],
:where (:and
[:= :datoms2.e :datoms0.tx]
[:= :datoms0.a "page/starred"]
[:= :datoms0.v 1]
[:not
[:exists
{:select [1],
:from [[:datoms datoms1]],
:where (:and
[:= :datoms1.a "foo/bar"]
[:= :datoms0.e :datoms1.e])}]]
[:= :datoms2.a "db/txInstant"]
)}
(expand
'[:find ?timestampMicros ?page :in $ ?latest :where
[?page :page/starred true ?t]
(not [?page :foo/bar _])
[?t :db/txInstant ?timestampMicros]]))))