Hi Andy,
I don't know what the expected behaviour should be so it's hard to define a
test with an assertion.
But here is an executable example:
import java.util.List;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecutionDatasetBuilder;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.sparql.core.Var;
import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.vocabulary.OWL;
import org.apache.jena.vocabulary.RDF;
import org.apache.jena.vocabulary.RDFS;
public class SelectStarSubstitutionTest {
public static void main(String[] args) {
Model model = ModelFactory.createDefaultModel();
model.add(OWL.Thing, RDF.type, OWL.Class);
model.add(OWL.Nothing, RDF.type, RDFS.Class);
Query query = QueryFactory.create("SELECT * { ?this a ?type }");
ResultSet rs = QueryExecutionDatasetBuilder.create().
query(query).
model(model).
//initialBinding(Binding.builder().add(Var.alloc("this"),
OWL.Thing.asNode()).build()).
substitution("this", OWL.Thing).
select();
List<String> vars = rs.getResultVars();
System.out.println(vars.size());
}
}
The output as shown is 1. If we use initialBinding instead of substitution, the
output is 2.
Do you agree that it would be better if substitution would expand SELECT * to
how initialBinding behaves?
One reason is that this would return 0 results if ?type is replaced with a
constant.
Another reason is that it makes the behaviour inconsistent when it returns
different variables depending on whether
a variable is pre-bound or not, e.g. when people use such SPARQL queries with
optional parameters.
(Needless to say this impacts SHACL-SPARQL).
Thanks
Holger
> On 17 Oct 2024, at 1:42 PM, Andy Seaborne <[email protected]> wrote:
>
>
>
> On 17/10/2024 11:35, Holger Knublauch wrote:
>> Hi all,
>> we are trying to switch to Jena 5 and from using setInitialBindings to
>> substitution.
>> There is a change in behaviour of SELECT *
>> Consider a query such as
>> SELECT *
>> WHERE
>> { ?this ?PATH ?value
>> FILTER EXISTS { ?value (rdfs:subClassOf)* ?class
>> FILTER ( ?class IN (rdfs:Class, rdf:Property, sh:Shape) )
>> }
>> }
>> where ?this and ?PATH have initial bindings.
>> Using initialBindings, the result variables include ?this, but with
>> substitution semantics, only ?value is returned.
>> Does this mean that queries need to be rewritten to explicitly state SELECT
>> ?this ?value ... ?
>> Thanks,
>> Holger
>
> Hi Holger,
>
> Minimal, complete test case please.
>
> (Presumably ?PATH is a property not a more general path)
>
> Andy
>