[tracker/wip/carlosg/sparql-fixes: 5/6] libtracker-sparql: Differentiate property path elements by graph




commit e8309cbd2439608dc7e07916a5a1b2780955154d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Aug 27 14:05:36 2020 +0200

    libtracker-sparql: Differentiate property path elements by graph
    
    Without a way to distinguish between property paths from different graphs,
    those subqueries may get reused across those, even though then inner queries
    use graph tables and are thus graph-specific.
    
    Add graph checks to property path lookups, so queries like the following
    don't result in mistaken results from the wrong graph:
    
      SELECT ?u ?f {
        GRAPH tracker:Audio {
          ?u nie:isStoredAs/nfo:fileName ?f
        }
        GRAPH tracker:Video {
          ?u nie:isStoredAs/nfo:fileName ?f
        }
      }

 src/libtracker-data/tracker-sparql-types.c |  8 ++++++++
 src/libtracker-data/tracker-sparql-types.h |  4 ++++
 src/libtracker-data/tracker-sparql.c       | 22 +++++++++++++++++++---
 3 files changed, 31 insertions(+), 3 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index 254523238..a029a275e 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -530,11 +530,13 @@ static void
 tracker_path_element_free (TrackerPathElement *elem)
 {
        g_free (elem->name);
+       g_free (elem->graph);
        g_free (elem);
 }
 
 TrackerPathElement *
 tracker_path_element_property_new (TrackerPathOperator  op,
+                                   const gchar         *graph,
                                    TrackerProperty     *prop)
 {
        TrackerPathElement *elem;
@@ -545,6 +547,7 @@ tracker_path_element_property_new (TrackerPathOperator  op,
 
        elem = g_new0 (TrackerPathElement, 1);
        elem->op = op;
+       elem->graph = g_strdup (graph);
        elem->type = tracker_property_get_data_type (prop);
        elem->data.property = prop;
 
@@ -553,6 +556,7 @@ tracker_path_element_property_new (TrackerPathOperator  op,
 
 TrackerPathElement *
 tracker_path_element_operator_new (TrackerPathOperator  op,
+                                   const gchar         *graph,
                                    TrackerPathElement  *child1,
                                    TrackerPathElement  *child2)
 {
@@ -568,6 +572,7 @@ tracker_path_element_operator_new (TrackerPathOperator  op,
 
        elem = g_new0 (TrackerPathElement, 1);
        elem->op = op;
+       elem->graph = g_strdup (graph);
        elem->data.composite.child1 = child1;
        elem->data.composite.child2 = child2;
        elem->type = child2 ? child2->type : child1->type;
@@ -614,6 +619,7 @@ tracker_path_element_set_unique_name (TrackerPathElement *elem,
        }
 
        elem->name = g_strdup_printf ("p%d_%s", id, name);
+
 }
 
 /* Context */
@@ -844,6 +850,7 @@ tracker_select_context_add_path_element (TrackerSelectContext *context,
 
 TrackerPathElement *
 tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *context,
+                                                         const gchar          *graph,
                                                          TrackerProperty      *property)
 {
        guint i;
@@ -857,6 +864,7 @@ tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *c
                path_elem = g_ptr_array_index (context->path_elements, i);
 
                if (path_elem->op == TRACKER_PATH_OPERATOR_NONE &&
+                   g_strcmp0 (path_elem->graph, graph) == 0 &&
                    path_elem->data.property == property)
                        return path_elem;
        }
diff --git a/src/libtracker-data/tracker-sparql-types.h b/src/libtracker-data/tracker-sparql-types.h
index 1a660cfd7..fc79798b7 100644
--- a/src/libtracker-data/tracker-sparql-types.h
+++ b/src/libtracker-data/tracker-sparql-types.h
@@ -164,6 +164,7 @@ typedef enum {
 struct _TrackerPathElement {
        TrackerPathOperator op;
        TrackerPropertyType type;
+       gchar *graph;
        gchar *name;
 
        union {
@@ -326,8 +327,10 @@ GHashTable      * tracker_solution_get_bindings    (TrackerSolution *solution);
 
 /* Property path element */
 TrackerPathElement * tracker_path_element_property_new (TrackerPathOperator  op,
+                                                        const gchar         *graph,
                                                         TrackerProperty     *prop);
 TrackerPathElement * tracker_path_element_operator_new (TrackerPathOperator  op,
+                                                        const gchar         *graph,
                                                         TrackerPathElement  *child1,
                                                         TrackerPathElement  *child2);
 
@@ -361,6 +364,7 @@ void tracker_select_context_add_path_element (TrackerSelectContext *context,
                                               TrackerPathElement   *path_elem);
 TrackerPathElement *
      tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *context,
+                                                              const gchar          *graph,
                                                               TrackerProperty      *property);
 
 /* Triple context */
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 574df9f4e..5a2795af9 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -6184,6 +6184,7 @@ translate_PathAlternative (TrackerSparql  *sparql,
                gint i;
 
                path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_ALTERNATIVE,
+                                                              tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                               g_ptr_array_index (path_elems, 0),
                                                               g_ptr_array_index (path_elems, 1));
                tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6195,6 +6196,7 @@ translate_PathAlternative (TrackerSparql  *sparql,
 
                        child = g_ptr_array_index (path_elems, i);
                        path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_ALTERNATIVE,
+                                                                      tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                                       child, path_elem);
                        tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
                                                                 path_elem);
@@ -6235,6 +6237,7 @@ translate_PathSequence (TrackerSparql  *sparql,
                 * the path element created in the previous step.
                 */
                path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_SEQUENCE,
+                                                              tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                               g_ptr_array_index (path_elems, path_elems->len 
- 2),
                                                               g_ptr_array_index (path_elems, path_elems->len 
- 1));
                tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6246,6 +6249,7 @@ translate_PathSequence (TrackerSparql  *sparql,
 
                        child = g_ptr_array_index (path_elems, i);
                        path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_SEQUENCE,
+                                                                      tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                                       child, path_elem);
                        tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
                                                                 path_elem);
@@ -6277,6 +6281,7 @@ translate_PathEltOrInverse (TrackerSparql  *sparql,
                TrackerPathElement *path_elem;
 
                path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INVERSE,
+                                                              tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                               sparql->current_state.path,
                                                               NULL);
                tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6322,7 +6327,9 @@ translate_PathMod (TrackerSparql  *sparql,
                return TRUE;
        }
 
-       path_elem = tracker_path_element_operator_new (op, sparql->current_state.path, NULL);
+       path_elem = tracker_path_element_operator_new (op,
+                                                      tracker_token_get_idstring 
(&sparql->current_state.graph),
+                                                      sparql->current_state.path, NULL);
        tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
                                                 path_elem);
        _prepend_path_element (sparql, path_elem);
@@ -6366,10 +6373,13 @@ translate_PathPrimary (TrackerSparql  *sparql,
 
                path_elem =
                        tracker_select_context_lookup_path_element_for_property (TRACKER_SELECT_CONTEXT 
(sparql->context),
+                                                                                tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                                                 prop);
 
                if (!path_elem) {
-                       path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NONE, prop);
+                       path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NONE,
+                                                                      tracker_token_get_idstring 
(&sparql->current_state.graph),
+                                                                      prop);
                        tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
                                                                 path_elem);
                        _prepend_path_element (sparql, path_elem);
@@ -6411,6 +6421,7 @@ translate_PathNegatedPropertySet (TrackerSparql  *sparql,
                        gint i;
 
                        path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INTERSECTION,
+                                                                      tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                                       g_ptr_array_index (path_elems, 0),
                                                                       g_ptr_array_index (path_elems, 1));
                        tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6422,6 +6433,7 @@ translate_PathNegatedPropertySet (TrackerSparql  *sparql,
 
                                child = g_ptr_array_index (path_elems, i);
                                path_elem = tracker_path_element_operator_new 
(TRACKER_PATH_OPERATOR_INTERSECTION,
+                                                                              tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                                               child, path_elem);
                                tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT 
(sparql->context),
                                                                         path_elem);
@@ -6474,10 +6486,13 @@ translate_PathOneInPropertySet (TrackerSparql  *sparql,
 
                path_elem =
                        tracker_select_context_lookup_path_element_for_property (TRACKER_SELECT_CONTEXT 
(sparql->context),
+                                                                                tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                                                 prop);
 
                if (!path_elem) {
-                       path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NEGATED, prop);
+                       path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NEGATED,
+                                                                      tracker_token_get_idstring 
(&sparql->current_state.graph),
+                                                                      prop);
                        tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
                                                                 path_elem);
                        _prepend_path_element (sparql, path_elem);
@@ -6491,6 +6506,7 @@ translate_PathOneInPropertySet (TrackerSparql  *sparql,
 
        if (inverse) {
                path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INVERSE,
+                                                              tracker_token_get_idstring 
(&sparql->current_state.graph),
                                                               sparql->current_state.path,
                                                               NULL);
                tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),


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