node-solid-server icon indicating copy to clipboard operation
node-solid-server copied to clipboard

NSS can't PATCH booleans represented as "true" or "false"

Open Vinnl opened this issue 5 years ago • 8 comments

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>.};

Vinnl avatar Aug 20 '20 19:08 Vinnl

I think it's probably the mismatch between "true" and "true"^^<http://www.w3.org/2001/XMLSchema#boolean>?

michielbdejong avatar Aug 21 '20 07:08 michielbdejong

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 avatar Aug 21 '20 07:08 michielbdejong

@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.)

Vinnl avatar Aug 21 '20 08:08 Vinnl

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.

RubenVerborgh avatar Sep 11 '20 08:09 RubenVerborgh

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.

JorgWieme avatar Sep 11 '20 09:09 JorgWieme

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.

megoth avatar Feb 13 '23 12:02 megoth

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.

timbl avatar Mar 02 '23 09:03 timbl

The authoritative spec here is the Turtle specification.

So @RubenVerborgh RDFlib is correct in parsing the turtle keyword true as "1"^^xsd:Boolean.

It is not, because the Turtle spec says:

The literal has a lexical form of the true or false, depending on which matched the input, and a datatype of xsd: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.

RubenVerborgh avatar Mar 06 '23 10:03 RubenVerborgh