[tracker/wip/sam/meson] libtracker-data: Fix INSERT/DELETE DATA and DELETE WHERE syntax



commit 616204b2dba77504de7c3e061848e09b2737f98b
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Jun 26 18:02:02 2016 +0200

    libtracker-data: Fix INSERT/DELETE DATA and DELETE WHERE syntax
    
    This was broken with the introduction of DELETE{}INSERT{}WHERE{}.
    Unbreak it, and check harder for invalid syntax situations, which
    we should warn about.

 src/libtracker-data/tracker-sparql-query.vala |   49 +++++++++++++++++++++----
 1 files changed, 42 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 1ff4483..d6a4489 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -644,19 +644,20 @@ public class Tracker.Sparql.Query : Object {
                                // INSERT/DELETE DATA are simpler variants
                                // that don't support variables
                                data = true;
-                       } else if (current() == SparqlTokenType.WHERE) {
+                       } else if (accept (SparqlTokenType.WHERE)) {
                                // DELETE WHERE is a short form where the pattern
                                // is also used as the template for deletion
                                delete_where = true;
                        }
 
+                       delete_location = get_location ();
+
                        if (!data && !delete_where) {
-                               delete_location = get_location ();
                                skip_braces ();
                        }
                }
 
-               if (!data && accept (SparqlTokenType.INSERT)) {
+               if (!data && !delete_where && accept (SparqlTokenType.INSERT)) {
                        if (accept (SparqlTokenType.OR)) {
                                expect (SparqlTokenType.REPLACE);
                                insert_is_update = true;
@@ -677,8 +678,13 @@ public class Tracker.Sparql.Query : Object {
                                data = true;
                        }
 
-                       if (!data && current () == SparqlTokenType.OPEN_BRACE) {
-                               insert_location = get_location ();
+                       if (current () != SparqlTokenType.OPEN_BRACE) {
+                               throw get_error ("Expected '{' beginning a quad data/pattern block");
+                       }
+
+                       insert_location = get_location ();
+
+                       if (!data) {
                                skip_braces ();
                        }
                }
@@ -688,7 +694,7 @@ public class Tracker.Sparql.Query : Object {
                var sql = new StringBuilder ();
 
                if (!data) {
-                       if (accept (SparqlTokenType.WHERE)) {
+                       if (delete_where || accept (SparqlTokenType.WHERE)) {
                                pattern.current_graph = current_graph;
                                context = pattern.translate_group_graph_pattern (pattern_sql);
                                pattern.current_graph = null;
@@ -698,7 +704,11 @@ public class Tracker.Sparql.Query : Object {
                                pattern_sql.append ("SELECT 1");
                        }
                } else {
-                       // WHERE pattern not supported for INSERT/DELETE DATA
+                       // WHERE pattern not supported for INSERT/DELETE DATA,
+                       // nor unbound values in the quad data.
+                       if (quad_data_unbound_var_count () > 0) {
+                               throw get_error ("INSERT/DELETE DATA do not allow unbound values");
+                       }
 
                        context = new Context (this);
 
@@ -807,6 +817,31 @@ public class Tracker.Sparql.Query : Object {
                return ns + local_name;
        }
 
+       int quad_data_unbound_var_count () throws Sparql.Error {
+               SourceLocation current_pos = get_location ();
+               int n_braces = 1;
+               int n_unbound = 0;
+
+               expect (SparqlTokenType.OPEN_BRACE);
+               while (n_braces > 0) {
+                       if (accept (SparqlTokenType.OPEN_BRACE)) {
+                               n_braces++;
+                       } else if (accept (SparqlTokenType.CLOSE_BRACE)) {
+                               n_braces--;
+                       } else if (current () == SparqlTokenType.EOF) {
+                               throw get_error ("unexpected end of query, expected }");
+                       } else {
+                               if (current () == SparqlTokenType.VAR)
+                                       n_unbound++;
+                               // ignore everything else
+                               next ();
+                       }
+               }
+
+               set_location (current_pos);
+               return n_unbound;
+       }
+
        void skip_braces () throws Sparql.Error {
                expect (SparqlTokenType.OPEN_BRACE);
                int n_braces = 1;


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