Surprisingly, jena qparse thinks trailing HAVING without GROUP is valid. Maybe I need qparse --strict? Still thinks it's valid.
qparse --query validate/shacl-sparql/PowerTransformerEnd.ratedS-valueRange2winding.rq
PREFIX adms: <http://www.w3.org/ns/adms#>
PREFIX cim: <https://cim.ucaiug.io/ns#>
PREFIX cim16: <http://iec.ch/TC57/2013/CIM-schema-cim16#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX cim17: <http://iec.ch/TC57/CIM100#>
PREFIX dm: <http://iec.ch/TC57/61970-552/DifferenceModel/1#>
PREFIX eu: <https://cim.ucaiug.io/ns/eu#>
PREFIX nc: <https://cim4.eu/ns/nc#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX md: <http://iec.ch/TC57/61970-552/ModelDescription/1#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX dcatcim: <https://cim4.eu/ns/dcatcim#>
PREFIX dcat: <http://www.w3.org/ns/dcat#>
PREFIX prov: <http://www.w3.org/ns/prov#>
SELECT ?this ?value ?ends
WHERE
{ { SELECT ?this (COUNT(?typeend) AS ?ends)
WHERE
{ ?this ^cim:PowerTransformerEnd.PowerTransformer/rdf:type ?typeend }
GROUP BY ?this ?typeend
}
?end1 cim:PowerTransformerEnd.PowerTransformer ?this ;
cim:TransformerEnd.endNumber 1 ;
cim:PowerTransformerEnd.ratedS ?value
BIND(EXISTS { ?end1 cim:PowerTransformerEnd.ratedS ?v } AS ?hasvalue)
?end2 cim:PowerTransformerEnd.PowerTransformer ?this ;
cim:TransformerEnd.endNumber 2 ;
cim:PowerTransformerEnd.ratedS ?ratedsend2
BIND(EXISTS { ?end2 cim:PowerTransformerEnd.ratedS ?r } AS ?hasratedsend2)
FILTER ( ( ( ( ?hasvalue = true ) && ( ?hasratedsend2 = true ) ) && ( ?end1 != ?end2 ) ) && ( ?value != ?ratedsend2 ) )
}
HAVING ( ?ends = 2 )
@haigutis quotes the SPARQL spec
SPARQL 1.1 defines HAVING only over grouped solution sets (§11.3: "HAVING operates over grouped solution sets, in the same way that FILTER operates over un-grouped ones"). Both affected queries use a trailing HAVING with no GROUP BY, no aggregate inside the HAVING expression, and a non-aggregate projection — a construct with no conforming interpretation (a grouped reading would also violate the §11.4 projection restriction, which allows only aggregates/constants/group keys to be projected).
I was just about to submit a jena bug but checked the grammar and indeed HAVING doesn't necessarily require GROUP BY
Eg this query is valid in GraphDB.
select (1 as ?x) where {} having(true)
Guess the meaning is the same as filter(true) inside the where.
This parallels the fact that you CAN use aggregate functions without GROUP BY, as soon as all SELECT variables are aggregated.
Anyway: we need to pick a stricter SPARQL validator. Preferably one to be called from an API or from the command line.
Positive:
- QLever reports eror:
Invalid SPARQL query: A HAVING clause is only supported in queries with GROUP BY
- rdf4j (GraphDB) reports error
variable 'this' in projection not present in GROUP BY.
Negative (searching for "sparql validator"):
Surprisingly, jena
qparsethinks trailing HAVING without GROUP is valid. Maybe I needqparse --strict? Still thinks it's valid.@haigutis quotes the SPARQL spec
I was just about to submit a jena bug but checked the grammar and indeed HAVING doesn't necessarily require GROUP BY
Eg this query is valid in GraphDB.
select (1 as ?x) where {} having(true)Guess the meaning is the same as
filter(true)inside thewhere.This parallels the fact that you CAN use aggregate functions without GROUP BY, as soon as all SELECT variables are aggregated.
Anyway: we need to pick a stricter SPARQL validator. Preferably one to be called from an API or from the command line.
Positive:
Invalid SPARQL query: A HAVING clause is only supported in queries with GROUP BYvariable 'this' in projection not present in GROUP BY.Negative (searching for "sparql validator"):