[tracker/wip/carlosg/sparql-corners: 1/12] libtracker-data: Check BIND variable in the current context




commit 986b5fea356dbdbb1a9af399f4ef83874166f619
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Feb 26 14:55:29 2021 +0100

    libtracker-data: Check BIND variable in the current context
    
    As per https://www.w3.org/TR/sparql11-query/#bind:
    "The variable introduced by the BIND clause must not have been
    used in the group graph pattern up to the point of use in BIND."
    
    We are currently checking that the variable has bindings, but
    that's also true if the variable was used in other graph patterns
    prior to the current one.
    
    We must check here only in the current context to match that
    behavior. This makes queries like:
    
      SELECT ?u { { BIND (1 AS ?u) } UNION { BIND (2 AS ?u) } }
    
    work as expected.

 src/libtracker-data/tracker-sparql.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 8091aea23..6278978ab 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -5312,7 +5312,8 @@ translate_Bind (TrackerSparql  *sparql,
        TrackerVariable *variable;
        TrackerBinding *binding;
        TrackerPropertyType type;
-       gboolean is_empty;
+       gboolean is_empty, already_defined;
+       gchar *var_name;
 
        /* Bind ::= 'BIND' '(' Expression 'AS' Var ')'
         */
@@ -5337,9 +5338,18 @@ translate_Bind (TrackerSparql  *sparql,
        _expect (sparql, RULE_TYPE_LITERAL, LITERAL_AS);
        _call_rule (sparql, NAMED_RULE_Var, error);
 
+       /* "The variable introduced by the BIND clause must
+        * not have been used in the group graph pattern up
+        * to the point of use in BIND."
+        */
+       var_name = _dup_last_string (sparql);
+       already_defined = tracker_context_lookup_variable_by_name (sparql->current_state->context,
+                                                                  var_name);
+       g_free (var_name);
+
        variable = _last_node_variable (sparql);
 
-       if (tracker_variable_has_bindings (variable))
+       if (already_defined)
                _raise (PARSE, "Expected undefined variable in BIND", variable->name);
 
        _append_string_printf (sparql, "AS %s ",


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