STRDT() ignores xsd:nonNegativeInteger datatypes

Hello, I am using the STRDT() to construct some RDF data and the function ignores the xsd:nonNegativeInteger parameters

To reproduce the problem you can run the following:

insert data {<http://ex.com/s> <http://ex.com/p> 1}
INSERT {
    <http://ex.com/s2>  <http://ex.com/p> ?o .
} WHERE {
        <http://ex.com/s> <http://ex.com/p> ?o_raw .
        BIND( STRDT(STR(?o_raw), xsd:nonNegativeInteger) AS ?o)
}

running

select * where  {?s <http://ex.com/p> ?o}

return values with xsd:integer datatype only

is this behavior expected?

Interestingly, anything that is not an integer comes back with the given datatype.

stardog query test 'select * where {bind(strdt("test", xsd:nonNegativeInteger) as ?o)}'

"test"^^xsd:nonNegativeInteger

Anything that is an integer comes back as an integer

stardog query test 'select * where {bind(strdt("1", xsd:nonNegativeInteger) as ?o)}'

1

It also behaves similarly for the subtypes xsd:nonPositiveInteger, xsd:long, xsd:nonNegativeInteger. I suspect that it is correct and has something to do with D-Interpretations and Datatype Entailment https://www.w3.org/TR/2014/REC-rdf11-mt-20140225/#D_interpretations but I’m not familiar with all the details there.

This is the expected result because Stardog canonicalizes literals. All integer subtypes map to the same value space in the XSD spec so they are equivalent values which is why we do this canonicalization. See the index.literals.canonical option mentioned in [1] and described in more detail at [2]. If you disable this option then all literals will use the assigned types. Note that, without this option your queries will need to use the exact same datatypes to match your data or you’ll need to rely on = FILTERs.

Best,
Evren

[1] http://www.stardog.com/docs/#_configuration_options
[2] http://www.stardog.com/docs/java/snarl/com/complexible/stardog/index/indexoptions#CANONICAL_LITERALS