Skip to content

Commit

Permalink
Fixed a bug when fn inside a query on empty relation returned non-emp…
Browse files Browse the repository at this point in the history
…ty result
  • Loading branch information
tonsky committed Dec 15, 2014
1 parent a36dd5d commit 1fdf9dd
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@
- `(datascript/datom e a v & [tx added])` call for creating new datoms
- Added missing aggregate funs: `avg`, `median`, `variance`, `stddev` and `count-distinct` (issue #42, thx [@montyxcantsin](https://github.com/montyxcantsin))
- `min` and `max` aggregates use comparator instead of default js `<` comparison
- Fixed a bug when fn inside a query on empty relation returned non-empty result

# 0.6.0

Expand Down
47 changes: 27 additions & 20 deletions src/datascript/query.cljs
Expand Up @@ -181,19 +181,26 @@

;;

(defn in->rel [form value]
(condp looks-like? form
'[_ ...] ;; collection binding [?x ...]
(reduce sum-rel
(map #(in->rel (first form) %) value))
'[[*]] ;; relation binding [[?a ?b]]
(reduce sum-rel
(map #(in->rel (first form) %) value))
'[*] ;; tuple binding [?a ?b]
(reduce prod-rel
(map #(in->rel %1 %2) form value))
'_ ;; regular binding ?x
(Relation. {form 0} [#js [value]])))
(defn in->rel
([form]
(let [attrs (as-> form form
(flatten form)
(filter #(and (symbol? %) (not= '... %) (not= '_ %)) form)
(zipmap form (range)))]
(Relation. attrs ())))
([form value]
(condp looks-like? form
'[_ ...] ;; collection binding [?x ...]
(reduce sum-rel
(map #(in->rel (first form) %) value))
'[[*]] ;; relation binding [[?a ?b]]
(reduce sum-rel
(map #(in->rel (first form) %) value))
'[*] ;; tuple binding [?a ?b]
(reduce prod-rel
(map #(in->rel %1 %2) form value))
'_ ;; regular binding ?x
(Relation. {form 0} [#js [value]]))))

(defn parse-rules [rules]
(let [rules (if (string? rules) (cljs.reader/read-string rules) rules)] ;; for datascript.js interop
Expand Down Expand Up @@ -347,15 +354,15 @@
(context-resolve-val context f))
[context production] (rel-prod-by-attrs context (filter symbol? args))
tuple-fn (-call-fn context production fun args)
new-rel (->> (:tuples production)
(map #(let [val (tuple-fn %)
rel (in->rel out val)]
(prod-rel (Relation. (:attrs production) [%]) rel)))
(reduce sum-rel))]
new-rel (if-let [tuples (not-empty (:tuples production))]
(->> tuples
(map #(let [val (tuple-fn %)
rel (in->rel out val)]
(prod-rel (Relation. (:attrs production) [%]) rel)))
(reduce sum-rel))
(prod-rel production (in->rel out)))]
(update-in context [:rels] conj new-rel)))



;;; RULES

(defn rule? [context clause]
Expand Down
11 changes: 10 additions & 1 deletion test/test/datascript.cljs
Expand Up @@ -569,7 +569,15 @@
[(+ ?a1 ?a2) ?a12]
[(= ?a12 ?a3)]]
db)
#{[1 2 3] [2 1 3]})))))
#{[1 2 3] [2 1 3]})))

(testing "Function on empty rel"
(is (= (d/q '[:find ?e ?y
:where [?e :salary ?x]
[(+ ?x 100) ?y]]
[[0 :age 15] [1 :age 35]])
#{})))
))


(deftest test-rules
Expand Down Expand Up @@ -960,3 +968,4 @@
(is (= db (cljs.reader/read-string (pr-str db)))))))

;; (t/test-ns 'test.datascript)

0 comments on commit 1fdf9dd

Please sign in to comment.