diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2015-10-18 22:41:27 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2015-10-19 14:07:18 +0200 |
commit | ca5d939fed4715398a8f424e746626e9905e04b6 (patch) | |
tree | 5b0681158e47d596f47f23cb0763e06c36d5749d | |
parent | e825bf2275f16319032ba39aed4b10d0a75c518f (diff) | |
download | tracker-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.vala | 22 | ||||
-rw-r--r-- | src/libtracker-data/tracker-sparql-scanner.vala | 13 |
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'"; |