marklogic/java-client-api

SparQL query throws unexpected error

uniqueR-7 opened this issue · 3 comments

Version of MarkLogic Java Client API

5.5.3

Version of MarkLogic Server

10.0-9.5

Java version

java 11.0.16.1 2022-08-18 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.16.1+1-LTS-1)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.16.1+1-LTS-1, mixed mode)

OS and version

OS name: Microsoft Windows 11
OS version: 10.0.22000

Input: Some code to illustrate the problem, preferably in a state that can be independently reproduced on our end

Executing the following SparQL query will report a syntax error:

SELECT *
WHERE { ?var1 ?var2 12.
               <http://JohnSmith> <http://livesIn> ?var3.
      }

Corresponding Java code:

package org.example.marklogic;

import java.io.File;
import java.io.IOException;
import com.marklogic.client.DatabaseClient;
import com.marklogic.client.DatabaseClientFactory;
import com.marklogic.client.io.*;
import com.marklogic.client.semantics.*;

public class MarkLogic_Test {
    static DatabaseClient client = DatabaseClientFactory.newClient(
            "localhost", 8000, "Documents",
            new DatabaseClientFactory.DigestAuthContext(
                    "root", "123"));
    static private GraphManager graphMgr = client.newGraphManager();
    static private String graphURI = GraphManager.DEFAULT_GRAPH;
    static private String tripleFilename = "./example.ttl";

    // Load managed triples from a file into a graph in MarkLogic
    public static void loadGraph(String filename, String graphURI, String format) {
        FileHandle tripleHandle = new FileHandle(new File(filename)).withMimetype(format);
        graphMgr.write(graphURI, tripleHandle);
    }

    // Evaluate a SPARQL query.
    public static void sparqlQuery() throws IOException {
        SPARQLQueryManager qm = client.newSPARQLQueryManager();
        SPARQLQueryDefinition query = qm.newQueryDefinition(
                "SELECT *\n" +
                        "WHERE { ?var1 ?var2 12.\n" +
                        "<http://JohnSmith> <http://livesIn> ?var3.\n" +
                        "}"
        );
        JacksonHandle results = new JacksonHandle();
        results.setMimetype(SPARQLMimeTypes.SPARQL_JSON);
        results = qm.executeSelect(query, results);
        results.write(System.out);
    }

    public static void main(String[] args) throws IOException {
        loadGraph(tripleFilename, graphURI, RDFMimeTypes.TURTLE);
        sparqlQuery();
        client.release();
    }
}

Triple file:
example.ttl

<http://JohnSmith> <http://livesIn> "London".
<http://Mark> <http://age> 12.

Actual output: What did you observe? What errors did you see? Can you attach the logs? (Java logs, MarkLogic logs)

Exception in thread "main" com.marklogic.client.FailedRequestException: Local message: failed to apply resource at /graphs/sparql: Bad Request. Server Message: XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected , expecting }
at com.marklogic.client.impl.OkHttpServices.checkStatus(OkHttpServices.java:4474)
at com.marklogic.client.impl.OkHttpServices.postResource(OkHttpServices.java:3463)
at com.marklogic.client.impl.OkHttpServices.postResource(OkHttpServices.java:3407)
at com.marklogic.client.impl.OkHttpServices.postResource(OkHttpServices.java:3398)
at com.marklogic.client.impl.OkHttpServices.executeSparql(OkHttpServices.java:5435)
at com.marklogic.client.impl.SPARQLQueryManagerImpl.executeQueryImpl(SPARQLQueryManagerImpl.java:107)
at com.marklogic.client.impl.SPARQLQueryManagerImpl.executeQueryImpl(SPARQLQueryManagerImpl.java:100)
at com.marklogic.client.impl.SPARQLQueryManagerImpl.executeSelect(SPARQLQueryManagerImpl.java:60)
at org.example.marklogic.MarkLogic_Test.sparqlQuery(MarkLogic_Test.java:37)
at org.example.marklogic.MarkLogic_Test.main(MarkLogic_Test.java:43)

Expected output: What specifically did you expect to happen?

The SparQL query is executed correctly and the following query result is returned.

?var1 ?var2 ?var3
<http://Mark> <http://age> "London"

Alternatives: What else have you tried, actual/expected?

Executing the SparQL query in Query Console will get the same error.

But If the query statement contains only one triple pattern as the following two, it will work correctly.

SELECT *
WHERE { ?var1 ?var2 12.
      }
SELECT *
WHERE { <http://JohnSmith> <http://livesIn> ?var3.
      }

There should be no syntax errors in this query statement. Why is an error reported?

The syntax error is correct - "12." is interpreted as a symbol, and the syntax error thus occurs because the two lines in your statement run together.

This section from the MarkLogic Semantics docs shows a number of examples for constructing query clauses correctly. I like this Apache Jena tutorial as well for when I need to remember basic SPARQL syntax. Those should help you with constructing your desired SPARQL queries.

The syntax error is correct - "12." is interpreted as a symbol, and the syntax error thus occurs because the two lines in your statement run together.

This section from the MarkLogic Semantics docs shows a number of examples for constructing query clauses correctly. I like this Apache Jena tutorial as well for when I need to remember basic SPARQL syntax. Those should help you with constructing your desired SPARQL queries.

If explicitly declaring the data type of integer "12", the SparQL query can be executed correctly in MarkLogic. Like the following:

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT *
WHERE { 
        ?var1 ?var2 "12"^^xsd:integer.
        <http://JohnSmith> <http://livesIn> ?var3.
      }

Do all integers in a SparQL query need to explicitly declare their data type to execute in MarkLogic?

But the SparQL documentation states that "integers can be written directly (without quotation marks and an explicit datatype IRI) and are interpreted as typed literals of datatype xsd:integer".

And this query can be executed correctly in Apache Jena.

SELECT *
WHERE { 
        ?var1 ?var2 12.
        <http://JohnSmith> <http://livesIn> ?var3.
      }

Does MarkLogic consider to support this feature in the future?

jpcs commented

The grammar production for a decimal number changed between SPARQL 1.0 and SPARQL 1.1:

https://www.w3.org/TR/rdf-sparql-query/#rDECIMAL
https://www.w3.org/TR/sparql11-query/#rDECIMAL

It looks like MarkLogic is still using the SPARQL 1.0 definition of a decimal, which means that the "12." in your query is treated as a decimal literal, rather than "12" followed by ".".