Summary
A plain integer literal in a query (VALUES ?n { 5 }) lowers to a binding with datatype xsd:long, while the same integer stored in a ledger materializes from the index as xsd:integer. Since term equality includes the datatype, the same number arriving from the two sources is treated as two distinct RDF terms.
Repro
On any ledger containing ex:a ex:n 5:
PREFIX ex: <http://example.org/ns/>
SELECT DISTINCT ?n { { ex:a ex:n ?n } UNION { VALUES ?n { 5 } } }
returns two rows:
[{"n": {"type":"literal","value":"5","datatype":".../XMLSchema#integer"}},
{"n": {"type":"literal","value":"5","datatype":".../XMLSchema#long"}}]
Per SPARQL, the bare literal 5 is "5"^^xsd:integer, so this should dedup to one row. The same mismatch makes joins/MINUS/GROUP BY on integer values miss across the two sources.
Notes
- Independent of binding representation (encoded vs decoded) — it reproduces decoded-vs-decoded, e.g. against novelty-only data. Discovered while building
fluree-db-api/tests/it_mixed_representation.rs (see the NOTE comment there excluding the integer case).
- Value-space comparison paths (FILTER
=, numeric operators) are unaffected; this is about term identity surfaces: DISTINCT, GROUP BY keys, COUNT(DISTINCT), join unification, MINUS.
- Needs a canonicalization decision rather than a point fix: either lower bare integer literals to xsd:integer end-to-end, or canonicalize the int64 datatype family at the term-identity surfaces.
Summary
A plain integer literal in a query (
VALUES ?n { 5 }) lowers to a binding with datatype xsd:long, while the same integer stored in a ledger materializes from the index as xsd:integer. Since term equality includes the datatype, the same number arriving from the two sources is treated as two distinct RDF terms.Repro
On any ledger containing
ex:a ex:n 5:returns two rows:
[{"n": {"type":"literal","value":"5","datatype":".../XMLSchema#integer"}}, {"n": {"type":"literal","value":"5","datatype":".../XMLSchema#long"}}]Per SPARQL, the bare literal
5is"5"^^xsd:integer, so this should dedup to one row. The same mismatch makes joins/MINUS/GROUP BY on integer values miss across the two sources.Notes
fluree-db-api/tests/it_mixed_representation.rs(see the NOTE comment there excluding the integer case).=, numeric operators) are unaffected; this is about term identity surfaces: DISTINCT, GROUP BY keys, COUNT(DISTINCT), join unification, MINUS.