Federated query with a default graph URI causes error on the remote endpoint

Federated query with a default graph URI causes a SPARQL execution error on the remote endpoint. The same error does not happen if the default graph URI is not defined.

Setup: a local Virtuoso Open Source SPARQL server with the Nobel Prizes dataset loaded into the named graph http://nobelprizes.local .

Graph URI:
http://nobelprizes.local

Federated SPARQL query:

PREFIX nobel: <http://data.nobelprize.org/terms/>

SELECT DISTINCT ?wikidata_uri ?p ?o
WHERE {
    ?laureate_uri a nobel:Laureate .
    ?laureate_uri owl:sameAs ?wikidata_uri .
  SERVICE <https://query.wikidata.org/sparql> {
    ?wikidata_uri ?p ?o .
  }
}
LIMIT 100

It looks like the default graph URI gets sent to the remote SPARQL endpoint (Wikidata), causing it to return an error message.

Error message:

Virtuoso RDFZZ Error DB.DBA.SPARQL_REXEC('https://query.wikidata.org/sparql', ...) returned Content-Type 'text/plain' status 'HTTP/1.1 400 Bad Request
'
SPARQL-QUERY: queryStr= SELECT ?o ?p
 WHERE { 
     GRAPH <http://nobelprizes.local> { <http://www.wikidata.org/entity/Q35149> ?p ?o . } }
java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.bigdata.rdf.sparql.ast.QuadsOperationInTriplesModeException: Use of WITH and GRAPH constructs in query body is not supported in triples mode.
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:206)
	at com.bigdata.rdf.sail.webapp.BigdataServlet.submitApiTask(BigdataServlet.java:292)
	at com.bigdata.rdf.sail.webapp.QueryServlet.doSparqlQuery(QueryServlet.java:678)
	at com.bigdata.rdf.sail.webapp.QueryServlet.doGet(QueryServlet.java:290)
	at com.bigdata.rdf.sail.webapp.RESTServlet.doGet(RESTServlet.java:240)
	at com.bigdata.rdf.sail.webapp.MultiTenancyServlet.doGet(MultiTenancyServlet.java:273)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
	at javax.servlet.http.HttpServlet.servic

SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1
define input:default-graph-uri <http://nobelprizes.local>
PREFIX nobel: <http://data.nobelprize.org/terms/>

SELECT DISTINCT ?wikidata_uri ?p ?o
WHERE {
    ?laureate_uri a nobel:Laureate .
    ?laureate_uri owl:sameAs ?wikidata_uri .
  SERVICE <https://query.wikidata.org/sparql> {
    ?wikidata_uri ?p ?o .
  }
}
LIMIT 100

Please try this modified SPARQL-FED query that only sends subjects containing Wikidata URIs to the remote Wikidata SPARQL Endpoint.

PREFIX nobel: <http://data.nobelprize.org/terms/>

SELECT DISTINCT ?wikidata_uri ?p ?o
WHERE 
    {
      ?laureate_uri a nobel:Laureate .
      ?laureate_uri owl:sameAs ?wikidata_uri .
      
      # Only Send Wikidata URIs to the Wikidata SPARQL Endpoint
      FILTER(CONTAINS(STR(?wikidata_uri),'wikidata'))
      
      SERVICE <https://query.wikidata.org/sparql> 
      {
        ?wikidata_uri ?p ?o .
      }
    }
LIMIT 100

Thanks for looking into this.

I tried the modified query but it is still resulting in the same error message. As a part of the error message you can see that the GRAPH statement is included in the SPARQL query sent to Wikidata (which seems to cause an error on the Wikidata side):

SPARQL-QUERY: queryStr= SELECT ?o ?p
 WHERE { 
     GRAPH <http://nobelprizes.local> { <http://www.wikidata.org/entity/Q35149> ?p ?o . } }

java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.bigdata.rdf.sparql.ast.QuadsOperationInTriplesModeException: Use of WITH and GRAPH constructs in query body is not supported in triples mode.

Could you modify the “Working example via OpenLink Software’s Public URIBurner Instance” query by specifying the default graph URI? This issue only appears when the default graph URI is specified.


Here’s the full Virtuoso response to the modified query (with the default graph URI specified):

Virtuoso RDFZZ Error DB.DBA.SPARQL_REXEC('https://query.wikidata.org/sparql', ...) returned Content-Type 'text/plain' status 'HTTP/1.1 400 Bad Request
'
SPARQL-QUERY: queryStr= SELECT ?o ?p
 WHERE { 
     GRAPH <http://nobelprizes.local> { <http://www.wikidata.org/entity/Q35149> ?p ?o . } }
java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.bigdata.rdf.sparql.ast.QuadsOperationInTriplesModeException: Use of WITH and GRAPH constructs in query body is not supported in triples mode.
	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:206)
	at com.bigdata.rdf.sail.webapp.BigdataServlet.submitApiTask(BigdataServlet.java:292)
	at com.bigdata.rdf.sail.webapp.QueryServlet.doSparqlQuery(QueryServlet.java:678)
	at com.bigdata.rdf.sail.webapp.QueryServlet.doGet(QueryServlet.java:290)
	at com.bigdata.rdf.sail.webapp.RESTServlet.doGet(RESTServlet.java:240)
	at com.bigdata.rdf.sail.webapp.MultiTenancyServlet.doGet(MultiTenancyServlet.java:273)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
	at javax.servlet.http.HttpServlet.servic

SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1
define input:default-graph-uri <http://nobelprizes.local>
PREFIX nobel: <http://data.nobelprize.org/terms/>

SELECT DISTINCT ?wikidata_uri ?p ?o
WHERE 
    {
      ?laureate_uri a nobel:Laureate .
      ?laureate_uri owl:sameAs ?wikidata_uri .
      
      # Only Send Wikidata URIs to the Wikidata SPARQL Endpoint
      FILTER(CONTAINS(STR(?wikidata_uri),'wikidata'))
      
      SERVICE <https://query.wikidata.org/sparql> 
      {
        ?wikidata_uri ?p ?o .
      }
    }
LIMIT 100

The query in your error output using http://nobelprizes.local as the default graph URI works on the same URI Burner Instance

Which version of Virtuoso are you running? Please run the following SPARQL query against your Virtuoso instance, and reply with the result:

SELECT
      ( bif:sys_stat('st_dbms_name')          AS ?name )
      ( bif:sys_stat('st_dbms_ver')           AS ?version )
      ( bif:sys_stat('st_build_thread_model') AS ?thread )
      ( bif:sys_stat('st_build_opsys_id')     AS ?opsys )
      ( bif:sys_stat('st_build_date')         AS ?date )
      ( bif:sys_stat('git_head')              AS ?git_head )   
    
WHERE
      {  ?s  ?p  ?o  }
LIMIT 1