fluree / core

Fluree releases and public bug reports
0 stars 0 forks source link

Certain `Number` datatypes get unexpected `sh:datatype` validation errors #52

Open aaj3f opened 8 months ago

aaj3f commented 8 months ago

Description

When setting sh:datatype on a PropertyShape, certain numeric datatypes throw validation errors against what should be valid, coercible numbers. For example if transacting "schema:age": 8, PropertyShapes with sh:datatype of xsd:integer, xsd:int, and xsd:float throw invalid datatype errors (whereas, for example, an sh:datatype of xsd:long does not throw an error).

We have plenty of coerce tests in datatype_test.cljc, so perhaps the issue has more to do with the representation of the JSON numeric value as its processed by server's HTTP API?

Steps to Reproduce

Create Ledger (note that the example below uses xsd:integer but tests against xsd:int and xsd:float produce the same behavior)

{
  "@context": "https://ns.flur.ee",
  "ledger": "sh-datatype-bug",
  "insert": {
      "@id": "ex:NodeShape/Yeti",
      "@type": "sh:NodeShape",
      "sh:targetClass": { "@id": "ex:Yeti" },
      "sh:property": [
        {
          "@id": "ex:PropertyShape/age",
          "sh:path": { "@id": "schema:age" },
          "sh:datatype": { "@id": "xsd:integer" }
        }
      ]
    },
  "opts": {
    "defaultContext": {
      "ex": "http://example.org/",
      "f": "https://ns.flur.ee/ledger#",
      "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
      "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
      "schema": "http://schema.org/",
      "sh": "http://www.w3.org/ns/shacl#",
      "xsd": "http://www.w3.org/2001/XMLSchema#"
    }
  }
}

Transaction of schema:age data on ex:Yeti

{
    "@context": "https://ns.flur.ee",
    "ledger": "sh-datatype-bug",
    "insert": {
        "@id": "ex:freddy",
        "@type": "ex:Yeti",
        "schema:name": "Freddy",
        "schema:age": 8
    }
}

Error result:

{
    "error": "db/shacl-validation",
    "message": "SHACL PropertyShape exception - sh:datatype: every datatype must be 7."
}
dpetran commented 8 months ago

The reason this is happening is that we no longer use sh:datatype constraints to coerce the object at flake creation - we only pay attention to explicit @type annotations or fall back to datatype inference - which in this case is an xsd:long.

The reason we don't do that anymore is we don't have access to shacl shapes during the flake creation process. However, I have an idea that may allow us to cache that specific constraint in the db, at least for simple property paths - I'm not sure what the implication is for, say, inverse paths.

dpetran commented 8 months ago

So the workaround in the meantime is to specify "schema:age" {"@type" "xsd:integer" "@value" 8} if you want the object to be an integer.