Extension: allow non-constant attributes in fulltext expressions. Fixes #42.

This change breaks compatibility with Datomic, but is useful when we simply want
to find entities linked somehow to matching content.
This commit is contained in:
Richard Newman 2016-08-18 14:51:02 -07:00
parent 31e354ae61
commit 7d684216f0
2 changed files with 32 additions and 14 deletions

View file

@ -190,12 +190,15 @@
(concat (:wheres cc)
(bindings->where (:bindings cc))))))
(defn binding-for-symbol-or-throw [cc symbol]
(defn binding-for-symbol [cc symbol]
(let [internal-bindings (symbol (:bindings cc))
external-bindings (symbol (:external-bindings cc))]
(or (first internal-bindings)
(first external-bindings)
(raise-str "No bindings yet for " symbol))))
(first external-bindings))))
(defn binding-for-symbol-or-throw [cc symbol]
(or (binding-for-symbol cc symbol)
(raise-str "No bindings yet for " symbol)))
(defn argument->value
"Take a value from an argument list and resolve it against the CC.

View file

@ -71,10 +71,8 @@
(when-not (and (instance? SrcVar src)
(= "$" (name (:symbol src))))
(raise "Non-default sources not supported." {:arg src}))
(when-not (instance? Constant attr)
(raise "Non-constant fulltext attributes not supported." {:arg attr}))
(when-not (fulltext-attribute? (:source cc) (:value attr))
(when (and (instance? Constant attr)
(not (fulltext-attribute? (:source cc) (:value attr))))
(raise-str "Attribute " (:value attr) " is not a fulltext-indexed attribute."))
(when-not (and (instance? BindColl bind-coll)
@ -94,6 +92,18 @@
;; We do not currently support scoring; the score value will always be 0.
(let [[src attr search] (:args function)
;; Note that DataScript's parser won't allow us to write a term like
;;
;; [(fulltext $ _ "foo") [[?x]]]
;;
;; so we instead have a placeholder attribute. Sigh.
attr-constant (or
(and (instance? Constant attr)
(not (= :any (:value attr)))
(source/attribute-in-source (:source cc) (:value attr)))
(and (instance? Variable attr)
(cc/binding-for-symbol-or-throw cc (:symbol attr))))
;; Pull out the symbols for the binding array.
[entity value tx score]
(map (comp :symbol :variable) ; This will nil-out placeholders.
@ -112,22 +122,27 @@
from [[fulltext-table fulltext-alias]
[datom-table datom-alias]]
wheres [[:match match-column match-value] ; The FTS match.
extracted-types {} ; TODO
wheres (concat
[[:match match-column match-value] ; The FTS match.
;; The fulltext rowid-to-datom correspondence.
[:=
(sql/qualify datom-alias :v)
(sql/qualify fulltext-alias :rowid)]
(sql/qualify fulltext-alias :rowid)]]
;; The attribute itself must match.
[:=
(sql/qualify datom-alias :a)
(source/attribute-in-source (:source cc) (:value attr))]]
(when attr-constant
;; If known, the attribute itself must match.
[[:=
(sql/qualify datom-alias :a)
attr-constant]]))
;; Now compose any bindings for entity, value, tx, and score.
;; TODO: do we need to examine existing bindings to capture
;; wheres for any of these? We shouldn't, because the CC will
;; be internally cross-where'd when everything is done...
;; TODO: bind attribute?
bindings (into {}
(filter
(comp not nil? first)
@ -139,7 +154,7 @@
;; if this is a variable rather than a placeholder.
[score [0]]]))]
(cc/augment-cc cc from bindings wheres)))
(cc/augment-cc cc from bindings extracted-types wheres)))
;; get-else is how Datalog handles optional attributes.
;;