summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2015-10-18 22:41:27 +0200
committerCarlos Garnacho <carlosg@gnome.org>2015-10-19 14:07:18 +0200
commitca5d939fed4715398a8f424e746626e9905e04b6 (patch)
tree5b0681158e47d596f47f23cb0763e06c36d5749d
parente825bf2275f16319032ba39aed4b10d0a75c518f (diff)
downloadtracker-ca5d939fed4715398a8f424e746626e9905e04b6.tar.gz
libtracker-data: Add support for BIND
The BIND form allows a value to be assigned to a variable from a graph pattern: SELECT ?u ?hour { ?u a rdfs:Resource . nfo:fileLastModified ?modified BIND (HOUR (?modified) AS ?hour) } It will be specially useful on places where we use the result of a calculation on more than one places, eg. on SELECT and FILTER(). It will also be useful combined with DELETE...INSERT...WHERE to perform complex mass-updates in a single query. http://www.w3.org/TR/sparql11-query/#bind
-rw-r--r--src/libtracker-data/tracker-sparql-pattern.vala22
-rw-r--r--src/libtracker-data/tracker-sparql-scanner.vala13
2 files changed, 34 insertions, 1 deletions
diff --git a/src/libtracker-data/tracker-sparql-pattern.vala b/src/libtracker-data/tracker-sparql-pattern.vala
index 7dfbcd44a..ec9d5471e 100644
--- a/src/libtracker-data/tracker-sparql-pattern.vala
+++ b/src/libtracker-data/tracker-sparql-pattern.vala
@@ -1102,6 +1102,28 @@ class Tracker.Sparql.Pattern : Object {
current_graph = old_graph;
current_graph_is_var = old_graph_is_var;
+ } else if (accept (SparqlTokenType.BIND)) {
+ var binding = new VariableBinding ();
+ var bind_sql = new StringBuilder ();
+
+ expect (SparqlTokenType.OPEN_PARENS);
+
+ expression.translate_expression (bind_sql);
+ binding.sql_expression = bind_sql.str;
+
+ expect (SparqlTokenType.AS);
+ expect (SparqlTokenType.VAR);
+
+ var as_var = context.get_variable (get_last_string ().substring (1));
+
+ if (as_var.binding != null) {
+ throw query.get_internal_error ("Expected undefined variable in BIND alias");
+ }
+
+ binding.variable = as_var;
+ add_variable_binding (sql, binding, VariableState.BOUND);
+
+ expect (SparqlTokenType.CLOSE_PARENS);
} else if (current () == SparqlTokenType.OPEN_BRACE) {
if (!in_triples_block && !in_group_graph_pattern) {
in_group_graph_pattern = true;
diff --git a/src/libtracker-data/tracker-sparql-scanner.vala b/src/libtracker-data/tracker-sparql-scanner.vala
index f23ba0ad2..e3705609b 100644
--- a/src/libtracker-data/tracker-sparql-scanner.vala
+++ b/src/libtracker-data/tracker-sparql-scanner.vala
@@ -159,7 +159,16 @@ public class Tracker.SparqlScanner : Object {
switch (begin[0]) {
case 'B':
case 'b':
- if (matches (begin, "BASE")) return SparqlTokenType.BASE;
+ switch (begin[1]) {
+ case 'A':
+ case 'a':
+ if (matches (begin, "BASE")) return SparqlTokenType.BASE;
+ break;
+ case 'I':
+ case 'i':
+ if (matches (begin, "BIND")) return SparqlTokenType.BIND;
+ break;
+ }
break;
case 'C':
case 'c':
@@ -1021,6 +1030,7 @@ public enum Tracker.SparqlTokenType {
AVG,
BASE,
BLANK_NODE,
+ BIND,
BOUND,
BY,
CEIL,
@@ -1148,6 +1158,7 @@ public enum Tracker.SparqlTokenType {
case AVG: return "`AVG'";
case BASE: return "`BASE'";
case BLANK_NODE: return "blank node";
+ case BIND: return "`BIND'";
case BOUND: return "`BOUND'";
case BY: return "`BY'";
case CEIL: return "`CEIL'";