Comparing URNs across SERVICE boundaries does not work correctly
While implementing a private database for storing Nautilus tags, I've discovered an error in the SPARQL translator.
To reproduce, first build and run Nautilus from my branch, then do something like this:
$ DATABASE=/home/sam/.local/share/nautilus/tags/
$ tracker3 sparql --database=$DATABASE -q 'SELECT ?file_url ?content_urn { SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> { ?content_urn nie:isStoredAs ?file_url } } LIMIT 1'
Results:
file:///home/sam/Music/BBC%20Music.html, urn:bnode:af187143-c3a5-48e2-a2ff-4f557018f189
$ tracker3 sparql --database=$DATABASE -u -q 'INSERT { ?content_urn a rdfs:Resource . ?content_urn nautilus:starred true . } WHERE { SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> { ?content_urn nie:isStoredAs ?file_url . FILTER (?file_url = "file:///home/sam/Music/BBC%20Music.html") } }'
$ tracker3 sparql --database=$DATABASE -q 'SELECT ?content_urn { ?content_urn nautilus:starred true . }'
Results:
urn:bnode:67e5f25b-8e3f-489a-9b0c-f756028be59f
$ tracker3 sparql --database=$DATABASE -q 'SELECT ?file_url ?content_id ?content_urn ?v { SERVICE <dbus:org.freedesktop.Tracker3.Miner.Files> { ?content_urn nie:isStoredAs ?file_url . BIND (tracker:id (?content_urn) AS ?content_id) } . ?content_urn nautilus:starred ?v . }'
Results:
None
This last query is producing a wrong result.
running with TRACKER_DEBUG=sql-statements
gave me this (formatted) SQL output for the last query:
WITH
"unionGraph_rdfs:Resource_nautilus:starred"(ID, "nautilus:starred", graph) AS
(SELECT ID, "nautilus:starred", 0 AS graph FROM "main"."rdfs:Resource_nautilus:starred" )
SELECT CAST ("v_file_url" AS TEXT) , CAST ("v_content_id" AS TEXT) , CAST ("v_content_urn" AS TEXT) ,
CASE "v_v" WHEN 1 THEN 'true' WHEN 0 THEN 'false' ELSE NULL END
FROM
(SELECT * FROM (SELECT col0 AS "v_content_id" , col1 AS "v_content_urn" , col2 AS "v_file_url" , col3 AS "v_content_urn"
FROM tracker_service
WHERE service="dbus:org.freedesktop.Tracker3.Miner.Files"
AND query="SELECT ?content_id ?content_urn ?file_url ?content_urn { ?content_urn nie:isStoredAs ?file_url . BIND (tracker:id (?content_urn) AS ?content_id) }"
AND silent=0 )
NATURAL INNER JOIN
(SELECT "rdfs:Resource_nautilus:starred1"."ID" AS "v_content_urn" , "rdfs:Resource_nautilus:starred1"."nautilus:starred" AS "v_v"
FROM (SELECT * FROM "unionGraph_rdfs:Resource_nautilus:starred" ) AS "rdfs:Resource_nautilus:starred1" ) )
I think the problem is that v_content_urn
from the service query is a string containing a URI, while v_content_urn
from the local query is a numeric ID. They represent the same thing, but internally the values are different.
Edited by Sam Thursfield