Skip to content

Commit

Permalink
Add iid-fast path for non sequential in args
Browse files Browse the repository at this point in the history
  • Loading branch information
FiV0 committed Aug 28, 2023
1 parent a7939a1 commit eb34b39
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 13 deletions.
23 changes: 14 additions & 9 deletions core/src/main/clojure/xtdb/operator/scan.clj
Original file line number Diff line number Diff line change
Expand Up @@ -623,11 +623,18 @@
:current-iid-ptr (ArrowBufPointer.)}
(at-point-point? scan-opts) (assoc :point-point? true))))))

(defn selects->iid-byte-buffer ^ByteBuffer [selects]
(defn selects->iid-byte-buffer ^ByteBuffer [selects ^RelationReader params-rel]
(when-let [eid-select (or (get selects 'xt/id) (get selects 'xt$id))]
(let [eid (nth eid-select 2)]
(when (and (= '= (first eid-select)) (s/valid? ::lp/value eid))
(trie/->iid eid)))))
(when (= '= (first eid-select))
(cond
(s/valid? ::lp/value eid)
(trie/->iid eid)

(s/valid? ::lp/param eid)
(let [eid-rdr (.readerForName params-rel (name eid))]
(when (= 1 (.valueCount eid-rdr))
(trie/->iid (.getObject eid-rdr 0)))))))))

(defmethod ig/prep-key ::scan-emitter [_ opts]
(merge opts
Expand Down Expand Up @@ -693,17 +700,12 @@
(first arg))
(into {}))

iid-bb (selects->iid-byte-buffer selects)

col-preds (->> (for [[col-name select-form] selects]
;; for temporal preds, we may not need to re-apply these if they can be represented as a temporal range.
(MapEntry/create (str col-name)
(expr/->expression-relation-selector select-form {:col-types col-types, :param-types param-types})))
(into {}))

col-preds (cond-> col-preds
iid-bb
(assoc "xt$iid" (iid-selector iid-bb)))

metadata-args (vec (for [[col-name select] selects
:when (not (types/temporal-column? (util/str->normal-form-str (str col-name))))]
Expand All @@ -718,7 +720,10 @@
{:col-types col-types
:stats {:row-count row-count}
:->cursor (fn [{:keys [allocator, ^IWatermark watermark, basis, params default-all-valid-time?]}]
(let [metadata-pred (expr.meta/->metadata-selector (cons 'and metadata-args) col-types params)
(let [iid-bb (selects->iid-byte-buffer selects params)
col-preds (cond-> col-preds
iid-bb (assoc "xt$iid" (iid-selector iid-bb)))
metadata-pred (expr.meta/->metadata-selector (cons 'and metadata-args) col-types params)
scan-opts (-> scan-opts
(update :for-valid-time
(fn [fvt]
Expand Down
25 changes: 21 additions & 4 deletions src/test/clojure/xtdb/operator/scan_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
[xtdb.operator.scan :as scan]
[xtdb.test-util :as tu]
[xtdb.util :as util]
[xtdb.vector.reader :as vr]
[xtdb.vector.writer :as vw])
(:import (java.util LinkedList)
xtdb.operator.IRaQuerySource
xtdb.operator.IRelationSelector
(xtdb.operator.scan RowConsumer)))
(xtdb.operator.scan RowConsumer)
xtdb.vector.RelationReader))

(t/use-fixtures :each tu/with-mock-clock tu/with-allocator)

Expand Down Expand Up @@ -446,17 +448,32 @@
[:put :xt-docs {:xt/id after-uuid :version 1}]])
(xt/submit-tx node [[:put :xt-docs {:xt/id search-uuid :version 2}]])

(t/is (nil? (scan/selects->iid-byte-buffer {})))
(t/is (nil? (scan/selects->iid-byte-buffer {} vw/empty-params)))

(t/is (= (util/uuid->byte-buffer search-uuid)
(scan/selects->iid-byte-buffer {'xt/id (list '= 'xt/id search-uuid)})))
(scan/selects->iid-byte-buffer {'xt/id (list '= 'xt/id search-uuid)} vw/empty-params)))

(t/is (nil? (scan/selects->iid-byte-buffer {'xt/id (list '< 'xt/id search-uuid)})))
(t/is (nil? (scan/selects->iid-byte-buffer {'xt/id (list '< 'xt/id search-uuid)} vw/empty-params)))

(with-open [^RelationReader params-rel (vw/open-params tu/*allocator* {'?search-uuid #uuid "80000000-0000-0000-0000-000000000000"})]
(t/is (= (util/uuid->byte-buffer search-uuid)
(scan/selects->iid-byte-buffer '{xt/id (= xt/id ?search-uuid)}
params-rel))))

(with-open [search-uuid-vec (vw/open-vec tu/*allocator* (name '?search-uuid) [#uuid "00000000-0000-0000-0000-000000000000"
#uuid "80000000-0000-0000-0000-000000000000"])
^RelationReader params-rel (vw/open-rel [search-uuid-vec])]
(t/is (nil? (scan/selects->iid-byte-buffer '{xt/id (= xt/id ?search-uuid)}
params-rel))))

(t/is (= [{:version 2, :xt/id search-uuid}]
(tu/query-ra [:scan {:table 'xt_docs} ['version {'xt/id (list '= 'xt/id search-uuid)}]]
{:node node})))

(t/is (= [{:version 2, :xt/id search-uuid}]
(tu/query-ra '[:scan {:table xt_docs} [version {xt/id (= xt/id ?search-uuid)}]]
{:node node :params {'?search-uuid #uuid "80000000-0000-0000-0000-000000000000"}})))

(t/is (= [{:version 2, :xt/id search-uuid}
{:version 1, :xt/id search-uuid}]
(tu/query-ra [:scan {:table 'xt_docs
Expand Down

0 comments on commit eb34b39

Please sign in to comment.