[tracker/wip/carlosg/fix-blank-node-labels: 1/2] libtracker-data: Fix (again) blank node lifetime handling



commit 900b82d9cd625927a9377d4becefd07b9630307b
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon May 18 21:43:21 2020 +0200

    libtracker-data: Fix (again) blank node lifetime handling
    
    Commit a6013fe3d92 sloppily tried to fix blank node lifetimes.
    However I missed that the Update rule is defined in a recursive
    manner, so this in essence resulted on the hashtable still being
    created before each individual update, but also leaked and
    overwritten.
    
    Sadly, we additionally need to keep per-update blank node
    accounting for tracker_sparql_connection_update_blank(), so
    partially revert that commit, and carry this accounting in 2
    distinct hashtables. One will truly stay alive for the full
    parsing stage, the other dropped per-insert.

 src/libtracker-data/tracker-sparql.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 130a7072d..4fb0a8e63 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -155,6 +155,7 @@ struct _TrackerSparql
                TrackerPathElement *path;
 
                GHashTable *blank_node_map;
+               GHashTable *update_blank_nodes;
                TrackerVariableBinding *as_in_group_by;
 
                GHashTable *union_views;
@@ -194,6 +195,8 @@ tracker_sparql_finalize (GObject *object)
        tracker_token_unset (&sparql->current_state.subject);
        tracker_token_unset (&sparql->current_state.predicate);
        tracker_token_unset (&sparql->current_state.object);
+       g_clear_pointer (&sparql->current_state.blank_node_map,
+                        g_hash_table_unref);
        g_clear_pointer (&sparql->current_state.union_views, g_hash_table_unref);
        g_clear_pointer (&sparql->current_state.construct_query,
                         tracker_string_builder_free);
@@ -2320,8 +2323,11 @@ translate_Update (TrackerSparql  *sparql,
         */
        _call_rule (sparql, NAMED_RULE_Prologue, error);
 
-       sparql->current_state.blank_node_map =
-               g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+       if (!sparql->current_state.blank_node_map) {
+               sparql->current_state.blank_node_map =
+                       g_hash_table_new_full (g_str_hash, g_str_equal,
+                                              g_free, g_free);
+       }
 
        if (_check_in_rule (sparql, NAMED_RULE_Update1)) {
                if (sparql->blank_nodes)
@@ -2338,9 +2344,6 @@ translate_Update (TrackerSparql  *sparql,
                        _call_rule (sparql, NAMED_RULE_Update, error);
        }
 
-       g_clear_pointer (&sparql->current_state.blank_node_map,
-                        g_hash_table_unref);
-
        return TRUE;
 }
 
@@ -3848,6 +3851,8 @@ translate_InsertData (TrackerSparql  *sparql,
        _expect (sparql, RULE_TYPE_LITERAL, LITERAL_DATA);
 
        if (sparql->blank_nodes) {
+               sparql->current_state.update_blank_nodes =
+                       g_hash_table_new (g_str_hash, g_str_equal);
                g_variant_builder_open (sparql->blank_nodes, G_VARIANT_TYPE ("a{ss}"));
        }
 
@@ -3855,6 +3860,8 @@ translate_InsertData (TrackerSparql  *sparql,
        _call_rule (sparql, NAMED_RULE_QuadData, error);
 
        if (sparql->blank_nodes) {
+               g_clear_pointer (&sparql->current_state.update_blank_nodes,
+                                g_hash_table_unref);
                g_variant_builder_close (sparql->blank_nodes);
        }
 
@@ -4179,6 +4186,8 @@ translate_InsertClause (TrackerSparql  *sparql,
         * 'INSERT' ('OR' 'REPLACE')? ('SILENT')? ('INTO' iri)?
         */
        if (sparql->blank_nodes) {
+               sparql->current_state.update_blank_nodes =
+                       g_hash_table_new (g_str_hash, g_str_equal);
                g_variant_builder_open (sparql->blank_nodes, G_VARIANT_TYPE ("a{ss}"));
        }
 
@@ -4210,6 +4219,8 @@ translate_InsertClause (TrackerSparql  *sparql,
        }
 
        if (sparql->blank_nodes) {
+               g_clear_pointer (&sparql->current_state.update_blank_nodes,
+                                g_hash_table_unref);
                g_variant_builder_close (sparql->blank_nodes);
        }
 
@@ -8494,8 +8505,13 @@ translate_BlankNode (TrackerSparql  *sparql,
                                        bnode_id = tracker_data_query_unused_uuid (sparql->data_manager, 
iface);
                                        g_hash_table_insert (sparql->current_state.blank_node_map,
                                                             g_strdup (str), bnode_id);
-                                       if (sparql->blank_nodes)
-                                               g_variant_builder_add (sparql->blank_nodes, "{ss}", str, 
bnode_id);
+                               }
+
+                               if (sparql->blank_nodes &&
+                                   sparql->current_state.update_blank_nodes &&
+                                   !g_hash_table_contains (sparql->current_state.update_blank_nodes, str)) {
+                                       g_hash_table_add (sparql->current_state.update_blank_nodes, str);
+                                       g_variant_builder_add (sparql->blank_nodes, "{ss}", str, bnode_id);
                                }
 
                                tracker_token_literal_init (sparql->current_state.token, bnode_id, -1);


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