Discussion:
Multiple databases in or
Leon Grapenthin
2015-06-08 11:17:26 UTC
Permalink
I can't use multiple databases with or.

(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)

An exception complains about missing data sources, as if I forgot to pass
db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Guillermo Winkler
2015-06-08 12:39:41 UTC
Permalink
It’s not possible to use multiple databases in or.

Even if you use rules to compose a logical or, you can only use one database, since database cannot be used as argument in a rule.

Not entirely sure about the underlying causes for the restriction none the less.

G.-
Post by Leon Grapenthin
I can't use multiple databases with or.
(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)
An exception complains about missing data sources, as if I forgot to pass db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
For more options, visit https://groups.google.com/d/optout <https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roman Pearah
2015-06-09 23:54:52 UTC
Permalink
An 'or' clause "constrains the result to tuples that satisfy at least one
of the clauses in the *or* clause." It's impossible for a tuple to exist in
more than one database at a time, so I'm not sure how that query makes
sense, considering. You're saying "If the value of its :foo in $1 is 42 or
the value of its :foo in $2 is 42".
Post by Leon Grapenthin
I can't use multiple databases with or.
(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)
An exception complains about missing data sources, as if I forgot to pass
db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Leon Grapenthin
2015-06-10 11:40:51 UTC
Permalink
It is not impossible.

Consider the same database at different points in time: The query would
mean: Was there a ?e :foo 42 at this point or was there one at that point
which is completely reasonable to be asking for.
Post by Roman Pearah
An 'or' clause "constrains the result to tuples that satisfy at least one
of the clauses in the *or* clause." It's impossible for a tuple to exist
in more than one database at a time, so I'm not sure how that query makes
sense, considering. You're saying "If the value of its :foo in $1 is 42 or
the value of its :foo in $2 is 42".
Post by Leon Grapenthin
I can't use multiple databases with or.
(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)
An exception complains about missing data sources, as if I forgot to pass
db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roman Pearah
2015-06-10 15:12:29 UTC
Permalink
I didn't say it wasn't a reasonable question; of course it is. I'm saying
it's not a reasonable *query. *The form of an `or` clause is:

(src-var? 'or' clause+)

By default, src-var? is matched to an implicit $ source. By naming $1 and
$2, you have thrown that away, and so must now explicitly pass a src-var
*before* the or, either $1 or $2. Without that, you will get

:db.error/invalid-data-source Nil or missing data source. Did you forget to
pass a database argument?

That's true whether or not you try to do anything with multiple databases.
For example, try:

(d/q '[:find ?e
:in $1
:where (or [?e :foo 42] [?e :foo 43])]
db1)

It will fail with the same error.

Now, the fact that the `or` clause itself requires (implicitly or
otherwise) a single source, you cannot expect the clauses can have sources
that differ from it or from each other. Logically, this makes sense when
you think about how binding of the ?e works. The `or` clause has to bind ?e
to fully evaluate, and all occurrences of ?e bind "simultaneously" to the
same value. That's what I mean when I say it's impossible for that query to
refer to multiple databases, either actually difference databases or the
same database at different times. To get what you're after, I think you'll
have to query each db separately and sort out the union in your code.

Note the difference in language between my example and yours. I used "its"
which implies the same entity and exposes the logical problem. You used "a"
and "one" which implies difference of a kind, i.e. some entity but not
necessarily the same entity, which goes against binding semantics.
Post by Leon Grapenthin
It is not impossible.
Consider the same database at different points in time: The query would
mean: Was there a ?e :foo 42 at this point or was there one at that point
which is completely reasonable to be asking for.
Post by Roman Pearah
An 'or' clause "constrains the result to tuples that satisfy at least one
of the clauses in the *or* clause." It's impossible for a tuple to exist
in more than one database at a time, so I'm not sure how that query makes
sense, considering. You're saying "If the value of its :foo in $1 is 42 or
the value of its :foo in $2 is 42".
Post by Leon Grapenthin
I can't use multiple databases with or.
(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)
An exception complains about missing data sources, as if I forgot to
pass db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Leon Grapenthin
2015-06-10 16:26:18 UTC
Permalink
Thanks you for the explanation.

I must have mistaken your statement for saying that the query can't have
utility. I did read "tuple" as datom, since they are the only tuples in a
Datomic database, but now I see that you were referring to tuples in or
clauses (called data-patterns in the docs).

Here is a quote from the query docs: As with rules, *src-vars* are not
currently supported within the clauses of *or*, ...

So maybe my query will run some day :)
Post by Roman Pearah
I didn't say it wasn't a reasonable question; of course it is. I'm saying
(src-var? 'or' clause+)
By default, src-var? is matched to an implicit $ source. By naming $1 and
$2, you have thrown that away, and so must now explicitly pass a src-var
*before* the or, either $1 or $2. Without that, you will get
:db.error/invalid-data-source Nil or missing data source. Did you forget
to pass a database argument?
That's true whether or not you try to do anything with multiple databases.
(d/q '[:find ?e
:in $1
:where (or [?e :foo 42] [?e :foo 43])]
db1)
It will fail with the same error.
Now, the fact that the `or` clause itself requires (implicitly or
otherwise) a single source, you cannot expect the clauses can have sources
that differ from it or from each other. Logically, this makes sense when
you think about how binding of the ?e works. The `or` clause has to bind ?e
to fully evaluate, and all occurrences of ?e bind "simultaneously" to the
same value. That's what I mean when I say it's impossible for that query to
refer to multiple databases, either actually difference databases or the
same database at different times. To get what you're after, I think you'll
have to query each db separately and sort out the union in your code.
Note the difference in language between my example and yours. I used "its"
which implies the same entity and exposes the logical problem. You used "a"
and "one" which implies difference of a kind, i.e. some entity but not
necessarily the same entity, which goes against binding semantics.
Post by Leon Grapenthin
It is not impossible.
Consider the same database at different points in time: The query would
mean: Was there a ?e :foo 42 at this point or was there one at that point
which is completely reasonable to be asking for.
Post by Roman Pearah
An 'or' clause "constrains the result to tuples that satisfy at least
one of the clauses in the *or* clause." It's impossible for a tuple to
exist in more than one database at a time, so I'm not sure how that query
makes sense, considering. You're saying "If the value of its :foo in $1 is
42 or the value of its :foo in $2 is 42".
Post by Leon Grapenthin
I can't use multiple databases with or.
(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)
An exception complains about missing data sources, as if I forgot to
pass db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Roman Pearah
2015-06-11 00:12:24 UTC
Permalink
No worries. To be clear, I *was* talking about datoms, referring to the way
that binding variables have to "unify" in Datomic queries. I suspect that
will make it fundamentally difficult to make it possible to support your
query without changing something core about the way Datomic queries work. I
agree that the "not currently" language seems to hint at some sort of
possibility, but I cannot see how that can be supported as long as "unity"
the name of the game.
Post by Leon Grapenthin
Thanks you for the explanation.
I must have mistaken your statement for saying that the query can't have
utility. I did read "tuple" as datom, since they are the only tuples in a
Datomic database, but now I see that you were referring to tuples in or
clauses (called data-patterns in the docs).
Here is a quote from the query docs: As with rules, *src-vars* are not
currently supported within the clauses of *or*, ...
So maybe my query will run some day :)
Post by Roman Pearah
I didn't say it wasn't a reasonable question; of course it is. I'm saying
(src-var? 'or' clause+)
By default, src-var? is matched to an implicit $ source. By naming $1 and
$2, you have thrown that away, and so must now explicitly pass a src-var
*before* the or, either $1 or $2. Without that, you will get
:db.error/invalid-data-source Nil or missing data source. Did you forget
to pass a database argument?
That's true whether or not you try to do anything with multiple
(d/q '[:find ?e
:in $1
:where (or [?e :foo 42] [?e :foo 43])]
db1)
It will fail with the same error.
Now, the fact that the `or` clause itself requires (implicitly or
otherwise) a single source, you cannot expect the clauses can have sources
that differ from it or from each other. Logically, this makes sense when
you think about how binding of the ?e works. The `or` clause has to bind ?e
to fully evaluate, and all occurrences of ?e bind "simultaneously" to the
same value. That's what I mean when I say it's impossible for that query to
refer to multiple databases, either actually difference databases or the
same database at different times. To get what you're after, I think you'll
have to query each db separately and sort out the union in your code.
Note the difference in language between my example and yours. I used
"its" which implies the same entity and exposes the logical problem. You
used "a" and "one" which implies difference of a kind, i.e. some entity but
not necessarily the same entity, which goes against binding semantics.
Post by Leon Grapenthin
It is not impossible.
Consider the same database at different points in time: The query would
mean: Was there a ?e :foo 42 at this point or was there one at that point
which is completely reasonable to be asking for.
Post by Roman Pearah
An 'or' clause "constrains the result to tuples that satisfy at least
one of the clauses in the *or* clause." It's impossible for a tuple to
exist in more than one database at a time, so I'm not sure how that query
makes sense, considering. You're saying "If the value of its :foo in $1 is
42 or the value of its :foo in $2 is 42".
Post by Leon Grapenthin
I can't use multiple databases with or.
(d/q '[:find ?e
:in $1 $2
:where (or [$1 ?e :foo 42] [$2 ?e :foo 42])]
db1 db2)
An exception complains about missing data sources, as if I forgot to
pass db1 and db2.
--
You received this message because you are subscribed to the Google Groups "Datomic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to datomic+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...