Skip to content

Commit a536e91

Browse files
galdretonsky
authored andcommitted
Fix bug in same-keys? / sum-rel
1 parent 251ac43 commit a536e91

File tree

2 files changed

+37
-30
lines changed

2 files changed

+37
-30
lines changed

src/datascript/query.cljc

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
(defn same-keys? [a b]
6262
(and (= (count a) (count b))
6363
(every? #(contains? b %) (keys a))
64-
(every? #(contains? b %) (keys a))))
64+
(every? #(contains? a %) (keys b))))
6565

6666
(defn- looks-like? [pattern form]
6767
(cond
@@ -126,38 +126,43 @@
126126

127127
#?(:clj (set! *unchecked-math* false))
128128

129+
(defn- sum-rel* [attrs-a tuples-a attrs-b tuples-b]
130+
(let [idxb->idxa (vec (for [[sym idx-b] attrs-b]
131+
[idx-b (attrs-a sym)]))
132+
tlen (->> (vals attrs-a) (reduce max) (inc))
133+
tuples' (persistent!
134+
(reduce
135+
(fn [acc tuple-b]
136+
(let [tuple' (da/make-array tlen)]
137+
(doseq [[idx-b idx-a] idxb->idxa]
138+
(aset tuple' idx-a (#?(:cljs da/aget :clj get) tuple-b idx-b)))
139+
(conj! acc tuple')))
140+
(transient (vec tuples-a))
141+
tuples-b))]
142+
(Relation. attrs-a tuples')))
143+
129144
(defn sum-rel [a b]
130145
(let [{attrs-a :attrs, tuples-a :tuples} a
131146
{attrs-b :attrs, tuples-b :tuples} b]
132147
(cond
133148
(= attrs-a attrs-b)
134149
(Relation. attrs-a (into (vec tuples-a) tuples-b))
135150

136-
(and (not (same-keys? attrs-a attrs-b))
137-
(seq tuples-a) ; could be empty because
138-
(seq tuples-b)) ; a query short-circuited
151+
;; BEFORE checking same-keys
152+
;; because one rel could have had its resolution shortcircuited
153+
(empty? tuples-a) b
154+
(empty? tuples-b) a
155+
156+
(not (same-keys? attrs-a attrs-b))
139157
(raise "Can’t sum relations with different attrs: " attrs-a " and " attrs-b
140158
{:error :query/where})
141159

142160
(every? number? (vals attrs-a)) ;; can’t conj into BTSetIter
143-
(let [idxb->idxa (vec (for [[sym idx-b] attrs-b]
144-
[idx-b (attrs-a sym)]))
145-
tlen (->> (vals attrs-a) (reduce max) (inc))
146-
tuples' (persistent!
147-
(reduce
148-
(fn [acc tuple-b]
149-
(let [tuple' (da/make-array tlen)]
150-
(doseq [[idx-b idx-a] idxb->idxa]
151-
(aset tuple' idx-a (#?(:cljs da/aget :clj get) tuple-b idx-b)))
152-
(conj! acc tuple')))
153-
(transient (vec tuples-a))
154-
tuples-b))]
155-
(Relation. attrs-a tuples'))
161+
(sum-rel* attrs-a tuples-a attrs-b tuples-b)
156162

157163
:else
158-
(let [all-attrs (zipmap (keys (merge attrs-a attrs-b)) (range))]
159-
(-> (Relation. all-attrs [])
160-
(sum-rel a)
164+
(let [number-attrs (zipmap (keys attrs-a) (range))]
165+
(-> (sum-rel* number-attrs [] attrs-a tuples-a)
161166
(sum-rel b))))))
162167

163168
(defn prod-rel

test/datascript/test/query_or.cljc

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,16 @@
6565
(and [2 :age ?a]
6666
[?e :name "Oleg"]))
6767
[?e :age ?a]]
68-
#{1 5 4}))
68+
#{1 5 4}
69+
70+
;; One branch of or short-circuits resolution
71+
[(or
72+
(and [?e :age 30] ; no matches in db
73+
[?e :name ?n])
74+
(and [?e :age 20]
75+
[?e :name ?n]))
76+
[(ground "Ivan") ?n]]
77+
#{2 6}))
6978

7079
(deftest test-or-join
7180
(are [q res] (= (d/q (concat '[:find ?e :where] (quote q)) @test-db)
@@ -83,16 +92,9 @@
8392
[?e2 :age ?a]))]
8493
#{1 2 3 4 5 6}
8594

95+
;; One branch of or-join short-circuits resolution
8696
[(or-join [?e ?n]
87-
(and [?e :age 30] ; no matches, so this branch short-circuits
88-
[?e :name ?n])
89-
(and [?e :age 20]
90-
[?e :name ?n]))
91-
[(ground "Ivan") ?n]]
92-
#{2 6}
93-
94-
[(or
95-
(and [?e :age 30] ; no matches, so this branch short-circuits
97+
(and [?e :age 30] ; no matches in db
9698
[?e :name ?n])
9799
(and [?e :age 20]
98100
[?e :name ?n]))

0 commit comments

Comments
 (0)