Query variable binding error

I have two queries with variable bindings (running in python with pystardog).

The first has only numeric values for the bound variables and works correctly. The following returns an error that the bound value is malformed. Here is the query:

PREFIX : <urn:xxx:ontology:> 
SELECT ?propValue WHERE { 
       BIND(IRI(CONCAT("urn:xxx:ontology:", ?prop)) as ?predicate) . 
      ?s ?predicate ?propValue } LIMIT 10

And the binding:

 encoder = json.JSONEncoder()
 queryBindings = encoder.encode({ "prop": "foo" })

And, here is the dump from the stardog.log:

WARN  2020-06-23 15:40:55,075 [stardog-user-3] com.complexible.stardog.protocols.http.server.StardogUndertowErrorHandler:accept(64): Unexpected exception was handled by the server
java.lang.IllegalArgumentException: The query binding 'foo' is a malformed Turtle value
        at com.complexible.stardog.protocols.http.server.ProtocolUtils.parseValue(ProtocolUtils.java:979) ~[stardog-protocols-http-server-7.3.1.jar:?]
        at com.complexible.stardog.protocols.http.server.ProtocolUtils.lambda$parseQuery$22(ProtocolUtils.java:967) ~[stardog-protocols-http-server-7.3.1.jar:?]
        at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) ~[?:1.8.0_252]
        at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[?:1.8.0_252]
        at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[?:1.8.0_252]
        at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419) ~[?:1.8.0_252]
        at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647) ~[?:1.8.0_252]
        at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272) ~[?:1.8.0_252]
        at java.util.TreeMap$EntrySpliterator.forEachRemaining(TreeMap.java:2969) ~[?:1.8.0_252]
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[?:1.8.0_252]
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_252]
        at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[?:1.8.0_252]
        at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[?:1.8.0_252]

Obviously, I am missing something obvious. What is it?

Andrea

Try passing your query bindings as a dict rather than json.

Sorry, I wasn't clear and copied the wrong lines ... My query and parameters are passed via a REST API interface to the PyStardog code that calls the Stardog server.

I have to encode a Python dictionary to a JSON string to pass it (that's the JSONEncode code above) and then I have to decode it before I make the .graph call. Here is that code:

decoder = json.JSONDecoder()
queryDict = decoder.decode(queryBindings)
selectResults = conn.select(selectQuery, content_type='application/sparql-results+json',
                                        bindings=queryDict)

queryDict is indeed a dictionary and the code works for numeric bindings.

Andrea

The binding substitution must be syntactically valid SPARQL. foo is not. You will need to quote it or use prefix/brackets if it's an IRI, eg. "foo" or p:foo.

Jess, I am using the value "foo" as a string and it is quoted in the Python dictionary. I was hoping that the following BIND could be used to create the predicate part of a triple in a WHERE clause ...

BIND(IRI(CONCAT("urn:xxx:ontology:", ?prop)) as ?predicate.

I thought with the variable binding that would create an IRI of urn:xxx:ontology:volume which is indeed a valid predicate in our ontology.

What am I missing? Do you mean that I should define the dictionary value as "'foo'" (using both single and double quotes)? That seems very odd.

Andrea

Just imagine that the string value you provide is substituted syntactically in the query. If you provide foo (which must be quoted in Python as 'foo'), then the SPARQL you get would be BIND(..., foo). This is not valid SPARQL syntax. For this reason, you must add quotes if it's a string. Written in Python, this could be look like '"foo"'. When placed in your SPARQL query, you would then expect something like BIND(..., "foo") which is valid syntax.

OK. Obviously, I totally spaced on that.

Will give it a try and report back.

Sorry to be dense!

Andrea

Just to close this out .... Adding quotes worked.

Andrea

Thanks for the update. Glad it's working!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.