diff --git a/src/common/datomish/query/cc.cljc b/src/common/datomish/query/cc.cljc index 021e9bf1..c4a4f994 100644 --- a/src/common/datomish/query/cc.cljc +++ b/src/common/datomish/query/cc.cljc @@ -132,10 +132,18 @@ [:= (sql/qualify table-alias (name :v)) (constant-in-source (:source cc) value)]]))) -(defn augment-cc [cc from bindings extracted-types wheres] +(defn combine-known-types [left right] + (merge-with (fn [lt rt] + (if (= lt rt) + lt + (raise "Incompatible types: " lt " != " rt {:types [lt rt]}))) + left right)) + +(defn augment-cc [cc from bindings known-types extracted-types wheres] (assoc cc :from (concat (:from cc) from) :bindings (merge-with concat (:bindings cc) bindings) + :known-types (combine-known-types (:known-types cc) known-types) :extracted-types (merge (:extracted-types cc) extracted-types) :wheres (concat (:wheres cc) wheres))) @@ -143,6 +151,7 @@ (augment-cc left (:from right) (:bindings right) + (:known-types right) (:extracted-types right) (:wheres right))) diff --git a/src/common/datomish/query/clauses.cljc b/src/common/datomish/query/clauses.cljc index 8406dbbb..a6a6fc58 100644 --- a/src/common/datomish/query/clauses.cljc +++ b/src/common/datomish/query/clauses.cljc @@ -469,12 +469,15 @@ bindings (into {} (map (fn [var] (let [sym (:symbol var)] [sym [(sql/qualify alias (util/var->sql-var sym))]])) - free-vars))] + free-vars)) + + known-types + (reduce cc/combine-known-types {} (map :known-types ccs))] (cc/map->ConjoiningClauses {:source source :from [[subqueries alias]] - :known-types (apply merge (map :known-types ccs)) + :known-types known-types :extracted-types (apply merge (map :extracted-types ccs)) :external-bindings {} ; No need: caller will merge. :bindings bindings diff --git a/src/common/datomish/query/functions.cljc b/src/common/datomish/query/functions.cljc index 3c0c27e9..946e1fa2 100644 --- a/src/common/datomish/query/functions.cljc +++ b/src/common/datomish/query/functions.cljc @@ -146,7 +146,8 @@ from [[fulltext-table fulltext-alias] [datom-table datom-alias]] - extracted-types {} ; TODO + extracted-types {} ; TODO + known-types {entity :db.type/ref} ; All entities are refs. wheres (concat [[:match match-column match-value] ; The FTS match. @@ -181,7 +182,7 @@ ;; if this is a variable rather than a placeholder. [score [0]]]))] - (cc/augment-cc cc from bindings extracted-types wheres))) + (cc/augment-cc cc from bindings known-types extracted-types wheres))) ;; get-else is how Datalog handles optional attributes. ;; diff --git a/test/datomish/test/query.cljc b/test/datomish/test/query.cljc index c2cf5ae2..4b6688b0 100644 --- a/test/datomish/test/query.cljc +++ b/test/datomish/test/query.cljc @@ -824,3 +824,78 @@ '[?save :save/excerpt ?excerpt]]))] (is (or (= ["Some page title" "Some page excerpt"] result) (= ["A different page" "A different excerpt"] result)))))) + +(deftest-db test-or-join-real-world conn + ;; This tests the simplest cause of https://github.com/mozilla/datomish/issues/84. + (testing "or-join with fulltext expressions doesn't leak type_tag columns." + (let [attrs (