Skip to content

select a SPARQL query parser/validator #86

Description

@VladimirAlexiev

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

Image

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"):

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions