This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hi to everybody! explain
is crashing 😞
Stacktrace:
:exception #error
{:cause "Cannot invoke \"java.lang.Number.doubleValue()\" because \"x\" is null",
:trace [[clojure.lang.RT longCast "RT.java" 1282]
[datalevin.query$result_explain invokeStatic "query.clj" 1849]
[datalevin.query$result_explain invoke "query.clj" 1844]
[datalevin.query$plan_only invokeStatic "query.clj" 1915]
[datalevin.query$plan_only doInvoke "query.clj" 1905]
[clojure.lang.RestFn applyTo "RestFn.java" 139]
[clojure.core$apply invokeStatic "core.clj" 667]
[clojure.core$apply invoke "core.clj" 662]
[datalevin.query$explain invokeStatic "query.clj" 1923]
[datalevin.query$explain doInvoke "query.clj" 1917]
[clojure.lang.RestFn applyTo "RestFn.java" 139]
[clojure.core$apply invokeStatic "core.clj" 671]
[clojure.core$apply invoke "core.clj" 662]
[datalevin.core$explain invokeStatic "core.clj" 477]
[datalevin.core$explain doInvoke "core.clj" 422]
[clojure.lang.RestFn invoke "RestFn.java" 521]
And by the way the query doesn't works as expected also if use d/q
That is actually why I tried explain
.
What can be wrong? I am struggling with this query whole the night.
In snippet:
(:user/id user)
: 1
mid
: 2
uuids
: something like *[*#uuid *"c2c21781-3699-4f6a-949b-32411d0c4013"* #uuid *"213bfbfa-c90a-403b-9b71-6ba5a0a7fc17"]*
Okay! I see in source, that explain
is only for remote stores (why nothing about it in docs or change log?). But why it crashing then instead of returning nil
?
Anyway, what can be wrong with the query? Only what I need i to get all existing :callback
entities, who related to certain :user
, have certain :callback/message-id
attribute and have any :callback/uuid
except listed in uuids
vector.
But it always returns empty sequence.
Thank you!
Try set :run? to true, it might tell you why you’re getting empty results, i.e. you may see one of the :count is zero
I am curious what condition would trigger this exception you are seeing, doesn't seem to be possible from the code.
*explain*
and *start-time*
are bound at the same time, it doesn't seem to be possible for *explain*
to be bound and *start-time*
is nil
, hence it is not possible to get that exception.
Thank you for answers.
With {:run? true}
there is the same error.
Environment:
Apple M2 Pro
MacOS 14.3.1 (23D60)
▸ lein version
Leiningen 2.10.0 on Java 21.0.2 OpenJDK 64-Bit Server VM
[org.clojure/clojure "1.11.2"]
[datalevin "0.9.4"]
:jvm-opts ["--add-opens=java.base/java.nio=ALL-UNNAMED"
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"]
Datalevin connection:
(d/conn "/tmp/dlvn" schema {:validate-data? true :closed-schema? true})
With query i can be wrong in something, but if i use just :where [?cb :callback/uuid]
i am getting the list of entities and there are some that are suitable for my query. At least it looks alike that for me...
Can you take a look once again? Is syntax correct? Especially regarding not
clause and looking for :callback/uuid
in ?uuids
collection...
Okay. I will inform you in a hour
Right now, I am in a hotel that blocked SSH traffic, so I can't really push code. If you are willing, you can try to fix it yourself, I can tell you which line to change.
Oh thank you. Tell me what line to fix then. Possible in PM
Or create issue maybe?
The fix is an one line change: in query.clj
line 1666, replace that line with (do (plan-explain) context)
basically, I forgot to update :planning-time
when the planner pre-terminated due to counting to 0 for one of the entity class
after the query graph is built, we already knew the result is empty. this is the case where I missed the call of (plan-explain)
to update planning-time
, hence the error you saw
well, after you fix explain, you will not see the query graph, for we are not adding the query graph to the explain result. I can remedy this in the next release.
in any case, please check your query, your other 3 clauses are returning 0 results. It has nothing to do with the not
clause.
Interesting moment.... after this fix my query started to return one result. Despite I need two..
How :actual-result-size
became 1
when on last step there is :actual-size 2
?
{:actual-result-size 1,
:execution-time "5.501 ms",
:late-clauses [],
:opt-clauses [[?u :user/id 1] [?cb :callback/user ?u] [?cb :callback/message-id 2]],
:plan {$ [(#datalevin.query.Plan
{:actual-size 1,
:cost 1,
:size 1,
:steps ["Initialize [?u] by :user/id = 1."]}
#datalevin.query.Plan
{:actual-size 2,
:cost 5,
:size 2,
:steps ["Merge ?cb by scanning reverse reference of :callback/user."
"Merge [?cb] by scanning [:callback/message-id]."]})]},
:planning-time "14.092 ms"}
Hm. I found a solution. I need instead of this
:where
[?u :user/id ?uid]
[?cb :callback/user ?u]
[?cb :callback/message-id ?mid]
do this
:where
[?cb :callback/user [:user/id ?uid]]
[?cb :callback/message-id ?mid]
First query returns one callback, second - two as expected.
But why?If you think you found a bug, create a minimal reproducible case, and file an issue. Better yet, send a PR of fix
So :user/id
and :callback/uuid
both are :db.unique/identity
.
:callback/user
is :db.type/ref
All another fields are absolutely usual fields