Is the use of BIND
valid?
# Query 1
SELECT * {
BIND (<http://ex/p2> as ?p)
{
BIND (<http://ex/p1> as ?p)
?s ?p ?o
}
}
When run on turtle data:
@prefix h: <http://ex/> .
h:s1 h:p1 h:o1 .
h:s2 h:p2 h:o2 .
arq 3.11.0 gives as result:
-------------
| p | s | o |
=============
-------------
without throwing an error (not even when using --strict
).
But removing the group or changing the order does give an error:
# Query 2
SELECT * {
BIND (<http://ex/p2> as ?p)
BIND (<http://ex/p1> as ?p)
?s ?p ?o
}
BIND: Variable used when already in-scope: ?p in BIND(<http://ex/p1> AS ?p)
and:
# Query 3
SELECT * {
{
BIND (<http://ex/p1> as ?p)
?s ?p ?o
}
BIND (<http://ex/p2> as ?p)
}
BIND: Variable used when already in-scope: ?p in BIND(<http://ex/p2> AS ?p)
Questions:
Does Query 1 violate 10.1 BIND which states:
The variable introduced by the BIND clause must not have been used in the group graph pattern up to the point of use in BIND.
My reading of 18.2.1 Variable Scope
is that in Query 1, the variable ?p
is in-scope inside
the inner group and therefore also in-scope outside the group.
Would the arq error message for Query 2 also be applicable to the
Query 1?
I would be grateful for a clarification.
BIND
, and the query is valid. That is because query evaluation of groups in SPARQL is defined inside-out. Inner groups are evaluated separately, and before outer groups. If the inner group is taken on its own, the use of BIND
in it is obviously fine, because ?p
has not yet been bound in the group. In the spec text you quote, the two key parts are: “must not have been used … in the group graph pattern … up to the point of use in BIND.”BIND
, no variables are in scope, and hence the BIND
is valid. After the BIND
, ?p
is in scope, which is why a second BIND
gives an error in Query 2. One way to think about this: A group starts with an empty scope, and each clause may contribute variables to the group. If a variable has already been contributed by a preceding clause, BIND
may not assign that variable.