Fork me on GitHub
#xtdb
<
2021-05-08
>
Jacob O'Bryant03:05:07

TIL that :crux.tx/match is affected by operations that precede it in the same transaction, rather than matching against against the doc value from before the tx (which is what I assumed it did). In other words, this works:

(with-open [node (crux/start-node {})]
  (crux/submit-tx
    node
    [[:crux.tx/match :a nil]
     [:crux.tx/put      {:crux.db/id :a, :a "a"}]
     [:crux.tx/match :a {:crux.db/id :a, :a "a"}]
     [:crux.tx/put      {:crux.db/id :a, :a "b"}]
     [:crux.tx/match :a {:crux.db/id :a, :a "b"}]])
  (crux/sync node)
  (crux/entity (crux/db node) :a)) ; {:crux.db/id :a, :a "b"}
But this doesn't:
(with-open [node (crux/start-node {})]
  (crux/submit-tx
    node
    [[:crux.tx/put      {:crux.db/id :a, :a "a"}]])
  (crux/submit-tx
    node
    ; This doesn't work. Either the match should come first or it should have :a "b"
    [[:crux.tx/put      {:crux.db/id :a, :a "b"}]
     [:crux.tx/match :a {:crux.db/id :a, :a "a"}]])
  (crux/sync node)
  (crux/entity (crux/db node) :a)) ; {:crux.db/id :a, :a "a"}
I guess this does make it more powerful--you can always just put all the matches at the beginning if you don't need this behavior. I think it'd be nice to add an explanation about it to https://www.opencrux.com/reference/transactions.html#match though.

👍 6
jarohen14:05:38

It used to behave that way - that matches saw the pre-tx version of the documents they were matching against. We changed it because we considered the old behaviour counter-intuitive for people used to SQL transactions (for example)

👌 3
Steven Deobald20:05:35

@foo We chatted about this and decided the note probably doesn't belong directly in the reference docs, since the behaviour hopefully matches up with peoples' default expectations. I've added this to the FAQ using your code example. Hope that's alright! https://opencrux.com/community/faq.html#matchsemantics

Jacob O'Bryant20:05:23

Sounds good!

🙏 3
Steven Deobald20:05:35
replied to a thread:TIL that `:crux.tx/match` is affected by operations that precede it in the same transaction, rather than matching against against the doc value from before the tx (which is what I assumed it did). In other words, this works: (with-open [node (crux/start-node {})] (crux/submit-tx node [[:crux.tx/match :a nil] [:crux.tx/put {:crux.db/id :a, :a "a"}] [:crux.tx/match :a {:crux.db/id :a, :a "a"}] [:crux.tx/put {:crux.db/id :a, :a "b"}] [:crux.tx/match :a {:crux.db/id :a, :a "b"}]]) (crux/sync node) (crux/entity (crux/db node) :a)) ; {:crux.db/id :a, :a "b"} But this doesn't: (with-open [node (crux/start-node {})] (crux/submit-tx node [[:crux.tx/put {:crux.db/id :a, :a "a"}]]) (crux/submit-tx node ; This doesn't work. Either the match should come first or it should have :a "b" [[:crux.tx/put {:crux.db/id :a, :a "b"}] [:crux.tx/match :a {:crux.db/id :a, :a "a"}]]) (crux/sync node) (crux/entity (crux/db node) :a)) ; {:crux.db/id :a, :a "a"} I guess this does make it more powerful--you can always just put all the matches at the beginning if you don't need this behavior. I think it'd be nice to add an explanation about it to https://www.opencrux.com/reference/transactions.html#match though.

@foo We chatted about this and decided the note probably doesn't belong directly in the reference docs, since the behaviour hopefully matches up with peoples' default expectations. I've added this to the FAQ using your code example. Hope that's alright! https://opencrux.com/community/faq.html#matchsemantics