On 19/10/2024 12:43, Holger Knublauch wrote:
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:

Excellent.

The simple query shows it isn't FILTER or EXISTS related.

> Do you agree that it would be better if substitution would expand SELECT * to how initialBinding behaves?

I neither agree nor disagree at the moment. It looks OK, but there are other use cases to consider. InitialBindings was limiting from both a query optimizer point-of-view and parametrized queries for remote execution.

A workaround for the current release seems to be:

  Query query = QueryFactory.create(....)
  query.setQueryResultStar(false);

I haven't looked at nested SELECTs yet.

> (Needless to say this impacts SHACL-SPARQL).

That's a whole subject in itself.

This syntax-based substitution is very similar to SEP-0007 [1] but that is injection into the algebra. It keeps the variables names in place (e.g. BOUND).

    Andy

[1]
https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0007/sep-0007.md



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 <a...@apache.org> 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




Reply via email to