[tracker/wip/carlosg/anonymous-nodes: 54/56] libtracker-data: Implement anonymous blank nodes




commit 7808e5a77a6c153ff46ec10efc531f9b0b046a59
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Sep 28 12:01:40 2021 +0200

    libtracker-data: Implement anonymous blank nodes
    
    Now that resources are dealt with as ROWIDs despite them being
    named or blank nodes, and that blank nodes don't actually get
    a generated URN that is stored in the database, we can make this
    a switch to either query on URI + bnode name, or just URI.
    
    This flag enables the blank node semantics defined by the SPARQL
    spec, where blank nodes cannot be matched by name.
    
    This is exposed as a TrackerDBManager flag, unused at the moment.

 src/libtracker-data/tracker-data-update.c  | 14 ++++++++++++
 src/libtracker-data/tracker-db-manager.h   |  1 +
 src/libtracker-data/tracker-sparql.c       | 35 +++++++++++++++++++++++-------
 src/libtracker-data/tracker-vtab-triples.c |  2 +-
 4 files changed, 43 insertions(+), 9 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 26cd393e8..d0b68edce 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -685,6 +685,8 @@ tracker_data_update_ensure_resource (TrackerData  *data,
                                      const gchar  *uri,
                                      GError      **error)
 {
+       TrackerDBManager *db_manager;
+       TrackerDBManagerFlags db_flags;
        TrackerDBInterface *iface;
        TrackerDBStatement *stmt = NULL;
        GError *inner_error = NULL;
@@ -697,6 +699,18 @@ tracker_data_update_ensure_resource (TrackerData  *data,
                return *value;
        }
 
+       db_manager = tracker_data_manager_get_db_manager (data->manager);
+       db_flags = tracker_db_manager_get_flags (db_manager, NULL, NULL);
+
+       if ((db_flags & TRACKER_DB_MANAGER_ANONYMOUS_BNODES) == 0 &&
+           g_str_has_prefix (uri, "urn:bnode:")) {
+               gchar *end;
+
+               id = g_ascii_strtoll (&uri[strlen ("urn:bnode:")], &end, 10);
+               if (id != 0 && end == &uri[strlen (uri)])
+                       return id;
+       }
+
        iface = tracker_data_manager_get_writable_db_interface (data->manager);
 
        stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, 
&inner_error,
diff --git a/src/libtracker-data/tracker-db-manager.h b/src/libtracker-data/tracker-db-manager.h
index e6d76e26e..664b55362 100644
--- a/src/libtracker-data/tracker-db-manager.h
+++ b/src/libtracker-data/tracker-db-manager.h
@@ -48,6 +48,7 @@ typedef enum {
        TRACKER_DB_MANAGER_FTS_IGNORE_NUMBERS    = 1 << 7,
        TRACKER_DB_MANAGER_IN_MEMORY             = 1 << 8,
        TRACKER_DB_MANAGER_SKIP_VERSION_CHECK    = 1 << 9,
+       TRACKER_DB_MANAGER_ANONYMOUS_BNODES      = 1 << 10,
 } TrackerDBManagerFlags;
 
 typedef enum {
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index fd6028c27..74de1856e 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -510,6 +510,25 @@ _append_resource_rowid_access_check (TrackerSparql *sparql)
        g_list_free (names);
 }
 
+static inline void
+_append_resource_uri_check (TrackerSparql *sparql)
+{
+       TrackerDBManager *db_manager;
+       TrackerDBManagerFlags flags;
+
+       db_manager = tracker_data_manager_get_db_manager (sparql->data_manager);
+       flags = tracker_db_manager_get_flags (db_manager, NULL, NULL);
+
+       if (flags & TRACKER_DB_MANAGER_ANONYMOUS_BNODES) {
+               _append_string_printf (sparql,
+                                      "SELECT ID FROM Resource WHERE Uri = ");
+       } else {
+               _append_string_printf (sparql,
+                                      "SELECT ID FROM Resource "
+                                      " WHERE COALESCE(Uri, 'urn:bnode:' || ID) = ");
+       }
+}
+
 static inline void
 _append_literal_sql (TrackerSparql         *sparql,
                      TrackerLiteralBinding *binding)
@@ -524,8 +543,8 @@ _append_literal_sql (TrackerSparql         *sparql,
        }
 
        if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_RESOURCE) {
-               _append_string_printf (sparql,
-                                      "COALESCE ((SELECT ID FROM Resource WHERE COALESCE(Uri, 'urn:bnode:' 
|| ID) = ");
+               _append_string_printf (sparql, "COALESCE ((");
+               _append_resource_uri_check (sparql);
        }
 
        if (!sparql->cacheable) {
@@ -2597,9 +2616,9 @@ _end_triples_block (TrackerSparql  *sparql,
 
                        if (binding1->data_type == TRACKER_PROPERTY_TYPE_STRING &&
                            binding2->data_type == TRACKER_PROPERTY_TYPE_RESOURCE) {
-                               _append_string_printf (sparql,
-                                                      "(SELECT ID FROM Resource WHERE COALESCE(Uri, 
'urn:bnode:' || ID) = %s) ",
-                                                      expression1);
+                               _append_string (sparql, "(");
+                               _append_resource_uri_check (sparql);
+                               _append_string_printf (sparql, "= %s)", expression1);
                        } else {
                                _append_string_printf (sparql, "%s ", expression1);
                        }
@@ -2608,9 +2627,9 @@ _end_triples_block (TrackerSparql  *sparql,
 
                        if (binding1->data_type == TRACKER_PROPERTY_TYPE_RESOURCE &&
                            binding2->data_type == TRACKER_PROPERTY_TYPE_STRING) {
-                               _append_string_printf (sparql,
-                                                      "(SELECT ID FROM Resource WHERE COALESCE(Uri, 
'urn:bnode:' || ID)) = %s) ",
-                                                      expression2);
+                               _append_string (sparql, "(");
+                               _append_resource_uri_check (sparql);
+                               _append_string_printf (sparql, "= %s)", expression2);
                        } else {
                                _append_string_printf (sparql, "%s ", expression2);
                        }
diff --git a/src/libtracker-data/tracker-vtab-triples.c b/src/libtracker-data/tracker-vtab-triples.c
index d91a2c66e..e6316b3a5 100644
--- a/src/libtracker-data/tracker-vtab-triples.c
+++ b/src/libtracker-data/tracker-vtab-triples.c
@@ -365,7 +365,7 @@ convert_to_string (const gchar         *table_name,
        case TRACKER_PROPERTY_TYPE_INTEGER:
                return g_strdup_printf ("t.\"%s\"", table_name);
        case TRACKER_PROPERTY_TYPE_RESOURCE:
-               return g_strdup_printf ("(SELECT Uri FROM Resource WHERE ID = t.\"%s\")",
+               return g_strdup_printf ("(SELECT COALESCE(Uri, 'urn:bnode:' || ID) FROM Resource WHERE ID = 
t.\"%s\")",
                                        table_name);
        case TRACKER_PROPERTY_TYPE_BOOLEAN:
                return g_strdup_printf ("CASE t.\"%s\" "


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]