Hi, when I execute queries that compare against the collection variable inside not-join then the result looks like not-join is skipped from processing. The next steps will help to reproduce the case I mean
(require '[datomic.api :as d])
(d/create-database "datomic:dev://localhost:4334/not-join?password=datomic")
(def conn (d/connect "datomic:dev://localhost:4334/not-join?password=datomic"))
(def user-schema [
{
:db/ident :User/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/unique :db.unique/value
}
])
(d/transact conn user-schema)
(def user-data [
{ :User/name "User_1" }
{ :User/name "User_2" }
{ :User/name "User_3" }
])
(d/transact conn user-data)
Query 1
Firstly I want to show that the collection variable is treated correctly.
The query imitates SQL query:
name IN (“User_1”, “User_2”) or name = “User_1” OR name = “User_2”
(d/q '[:find
?user ?name
:in
$
[?user_names ...]
:where
[?user :User/name ?user_names]
[?user :User/name ?name]
]
(d/db conn) ["User_1" "User_2"])
#Result is: #{[17592186045418 "User_1"] [17592186045419 "User_2"]}
Query 2
What is equal to Query 1 but without using input variables.
If would want to use a filter on user’s names without passing an input variable then it could look like the result is like from the query above.
(d/q '[:find
?user ?name
:in
$
:where
(or-join [?user]
[?user :User/name "User_1"]
[?user :User/name "User_2"]
)
[?user :User/name ?name]
]
(d/db conn) ["User_1" "User_2"])
#Result is: #{[17592186045418 "User_1"] [17592186045419 "User_2"]}
Query 3
Inversion to Query 1 but for some reason, the result is not inversed.
To inverse the result, I used not-join which corresponds to the SQL queries
name NOT IN (“User_1”, “User_2”) or name != “User_1” AND name != “User_2”
But you will see that the result still contains the entities from Query 1.
(d/q '[:find
?user ?name
:in
$
[?user_names ...]
:where
(not-join [?user ?user_names]
[?user :User/name ?user_names]
)
[?user :User/name ?name]
]
(d/db conn) ["User_1" "User_2"])
# Result is: #{[17592186045420 "User_3"] [17592186045419 "User_2"] [17592186045418 "User_1"]}
Query 4
Inversion to Query 2 without using input variables.
And we see it works as expected but its analog Query 3 does not do the same
(d/q '[:find
?user ?name
:in
$
[?user_names ...]
:where
(not-join [?user]
(or-join [?user]
[?user :User/name "User_1"]
[?user :User/name "User_2"]
)
)
[?user :User/name ?name]
]
(d/db conn) ["User_1" "User_2"])
# The result is: #{[17592186045420 "User_3"]}
Query 5
I noticed an interesting behavior if ?user_names contains only one element then it works correctly
(d/q '[:find
?user ?name
:in
$
[?user_names ...]
:where
(not-join [?user ?user_names]
[?user :User/name ?user_names]
)
[?user :User/name ?name]
]
(d/db conn) ["User_1"])
# Result is: #{[17592186045420 "User_3"] [17592186045419 "User_2"]}
Datomic on-prem: 1.0.6397
P.S. @jaret Might it be related to Not possible to pass more then one vector variable to or-join ?