node-solid-server
node-solid-server copied to clipboard
NSS can't PATCH booleans represented as "true" or "false"
Issue can be seen in action here (view the Network requests in your browser's DevTools): https://codesandbox.io/s/inruptsolid-client-js-sandbox-forked-xyvbg?file=/src/index.ts
GET https://vincent-test.inrupt.net/public/booleantest.ttl:
@prefix : <#>.
@prefix n0: <http://example.com/>.
:me n0:testbool true.
Alright, now let's try to turn that true to false:
PATCH to https://vincent-test.inrupt.net/public/booleantest.ttl with request body:
DELETE DATA {<https://vincent-test.inrupt.net/public/booleantest.ttl#me> <http://example.com/testbool> "true"^^<http://www.w3.org/2001/XMLSchema#boolean>.}; INSERT DATA {<https://vincent-test.inrupt.net/public/booleantest.ttl#me> <http://example.com/testbool> "false"^^<http://www.w3.org/2001/XMLSchema#boolean>.};
Response: 409 Conflict:
The patch could not be applied. Could not find to delete: <https://vincent-test.inrupt.net/public/booleantest.ttl#me> <http://example.com/testbool> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .
Trying it again with this request body does work (i.e. "true" replaced by "1"):
DELETE DATA {<https://vincent-test.inrupt.net/public/booleantest.ttl#me> <http://example.com/testbool> "1"^^<http://www.w3.org/2001/XMLSchema#boolean>.}; INSERT DATA {<https://vincent-test.inrupt.net/public/booleantest.ttl#me> <http://example.com/testbool> "false"^^<http://www.w3.org/2001/XMLSchema#boolean>.};
I think it's probably the mismatch between "true" and "true"^^<http://www.w3.org/2001/XMLSchema#boolean>?
The error message says it's looking for a triple
<https://vincent-test.inrupt.net/public/booleantest.ttl#me> <http://example.com/testbool> "true"^^<http://www.w3.org/2001/XMLSchema#boolean>
and can't find that.
What you can do is find where that error is thrown, and log all the statements from the store, to see which triples it does have in store.
@michielbdejong Aren't the two equivalent? true being syntactic sugar for an RDF literal with the value true and of type boolean, and "true"^^<http://www.w3.org/2001/XMLSchema#boolean> explicitly being an RDF literal with the value true and of type boolean?
What do you mean by the store? The data at https://vincent-test.inrupt.net/public/booleantest.ttl? Because the GET already shows me what triples are in there, right? (i.e. :me n0:testbool true., which as far as I can see is exactly the Triple that the error message says it can't find.)
FYI I noticed that rdflib.js parses true as 1 (the number) but the long version of the literal as "true" (the untyped string). So definitely already a bug there.
Incorrect handling of INSERT PATCH, I tried to save true but false was saved. Currently I am using the solid.community server with version solid-server/5.5.2. I am trying to save that boolean with query-ldflex.
When performing following code:
import data from "@solid/query-ldflex";
import {namedNode, literal} from "rdflib";
data["https://jowieme.solid.community/private/workflowProfile.ttl#user"]["wasteInfoShownToUser"]
.add(literal(true, namedNode('http://www.w3.org/2001/XMLSchema#boolean')));
Where the PATCH payload is:
INSERT DATA {
<https://jowieme.solid.community/private/workflowProfile.ttl#user>
<https://example.org/ns/example#wasteInfoShownToUser>
"true"^^<http://www.w3.org/2001/XMLSchema#boolean>.
}
My https://jowieme.solid.community/private/workflowProfile.ttl looks like this:
@prefix : <#>.
@prefix XML: <http://www.w3.org/2001/XMLSchema#>.
@prefix ex: <https://example.org/ns/example#>.
:user ex:wasteInfoShownToUser false.
Meanwhile doing the same but with 1 instead of true:
import data from "@solid/query-ldflex";
import {namedNode, literal} from "rdflib";
data["https://jowieme.solid.community/private/workflowProfile.ttl#user"]["wasteInfoShownToUser"]
.add(literal(1, namedNode('http://www.w3.org/2001/XMLSchema#boolean')));
The PATCH:
INSERT DATA {
<https://jowieme.solid.community/private/workflowProfile.ttl#user>
<https://example.org/ns/example#wasteInfoShownToUser>
"1"^^<http://www.w3.org/2001/XMLSchema#boolean>.
}
Resulting into:
@prefix : <#>.
@prefix XML: <http://www.w3.org/2001/XMLSchema#>.
@prefix ex: <https://example.org/ns/example#>.
:user ex:wasteInfoShownToUser true.
Just wanted to chime in that I've come across this bug as well. I suspect the problem is how rdflib.js handles boolean values, and that true and "true"^^<http://www.w3.org/2001/XMLSchema#boolean> are handled differently.
This means that given the following Turtle resource:
@prefix : <#>.
@prefix todo: <https://icanhasweb.net/vocab/todo.ttl#>.
:defaultList
a todo:List;
todo:task :task-1, :task-2;
todo:name "Todo list".
:task-1 a todo:Task; todo:description "Foo"; todo:done true.
:task-2 a todo:Task; todo:description "Bar".
The following SPARQL UPDATE will fail:
INSERT DATA {
<https://solidweb.me/megoth-capgemini/todo.ttl#task-2> <https://icanhasweb.net/vocab/todo.ttl#done> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> .
};
DELETE DATA {
<https://solidweb.me/megoth-capgemini/todo.ttl#task-2> <https://icanhasweb.net/vocab/todo.ttl#done> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .
}
While the following SPARQL UPDATE will succeed:
INSERT DATA {
<https://solidweb.me/megoth-capgemini/todo.ttl#task-2> <https://icanhasweb.net/vocab/todo.ttl#done> false .
};
DELETE DATA {
<https://solidweb.me/megoth-capgemini/todo.ttl#task-2> <https://icanhasweb.net/vocab/todo.ttl#done> true .
}
This bug has forced me to design my vocabulary to not use boolean values.
Let's look at the spec for the XSD Boolean type.
It says that the lexical space of the type is any of 0, 1, false, true. There are two ways of representing each of the two boolean states. I guess for some, Boolean is a subset of Integer...
So @RubenVerborgh RDFlib is correct in parsing the turtle keyword true as "1"^^xsd:Boolean.
For example here you see it using the "0" "1" form when generating a literal.
Obviously in the quadstore we need to do some canonicalization, or queries will fail.
The authoritative spec here is the Turtle specification.
So @RubenVerborgh RDFlib is correct in parsing the turtle keyword
trueas"1"^^xsd:Boolean.
It is not, because the Turtle spec says:
The literal has a lexical form of the
trueorfalse, depending on which matched the input, and a datatype ofxsd:boolean.
Therefore, "1"^^xsd:boolean and "0"^^xsd:boolean are not valid parsings of true and false in Turtle, despite their equivalence under the XSD spec.