[tracker/parser] SPARQL: Support aggregate functions and more cleanup
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/parser] SPARQL: Support aggregate functions and more cleanup
- Date: Tue, 11 Aug 2009 16:12:21 +0000 (UTC)
commit 26bf27ab551361fdd79e1edcb15394181b7fad77
Author: Jürg Billeter <j bitron ch>
Date: Tue Aug 11 18:10:44 2009 +0200
SPARQL: Support aggregate functions and more cleanup
src/libtracker-data/tracker-sparql-query.vala | 205 +++--------------------
src/libtracker-data/tracker-sparql-scanner.vala | 56 ++++++-
2 files changed, 74 insertions(+), 187 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 1241add..587fb7c 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -291,34 +291,6 @@ public class Tracker.SparqlQuery : Object {
this.update_extensions = true;
}
-#if 0
- string get_sql_for_literal (Rasqal.Literal literal) {
- assert (literal.type == Rasqal.Literal.Type.VARIABLE);
-
- string variable_name = literal.as_variable ().name;
- return "\"%s_u\"".printf (variable_name);
- }
-
- string get_sql_for_expression (Rasqal.Expression expr) {
- if (expr.op == Rasqal.Op.COUNT) {
- return "COUNT(%s)".printf (get_sql_for_expression (expr.arg1));
- } else if (expr.op == Rasqal.Op.SUM) {
- return "SUM(%s)".printf (get_sql_for_expression (expr.arg1));
- } else if (expr.op == Rasqal.Op.AVG) {
- return "AVG(%s)".printf (get_sql_for_expression (expr.arg1));
- } else if (expr.op == Rasqal.Op.MIN) {
- return "MIN(%s)".printf (get_sql_for_expression (expr.arg1));
- } else if (expr.op == Rasqal.Op.MAX) {
- return "MAX(%s)".printf (get_sql_for_expression (expr.arg1));
- } else if (expr.op == Rasqal.Op.VARSTAR) {
- return "*";
- } else if (expr.op == Rasqal.Op.LITERAL) {
- return get_sql_for_literal (expr.literal);
- }
- return "NULL";
- }
-#endif
-
string generate_bnodeid (string? user_bnodeid) {
// user_bnodeid is NULL for anonymous nodes
if (user_bnodeid == null) {
@@ -338,15 +310,6 @@ public class Tracker.SparqlQuery : Object {
}
}
-#if 0
- void error_handler (Raptor.Locator? locator, string message) {
- if (error_message == null) {
- // return first, not last, error message
- error_message = message;
- }
- }
-#endif
-
inline bool next () {
index = (index + 1) % BUFFER_SIZE;
size--;
@@ -532,6 +495,32 @@ public class Tracker.SparqlQuery : Object {
}
}
+ void translate_select_expression (StringBuilder sql) {
+ if (accept (SparqlTokenType.COUNT)) {
+ sql.append ("COUNT(");
+ translate_bracketted_expression_as_string (sql);
+ sql.append (")");
+ } else if (accept (SparqlTokenType.SUM)) {
+ sql.append ("SUM(");
+ translate_bracketted_expression_as_string (sql);
+ sql.append (")");
+ } else if (accept (SparqlTokenType.AVG)) {
+ sql.append ("AVG(");
+ translate_bracketted_expression_as_string (sql);
+ sql.append (")");
+ } else if (accept (SparqlTokenType.MIN)) {
+ sql.append ("MIN(");
+ translate_bracketted_expression_as_string (sql);
+ sql.append (")");
+ } else if (accept (SparqlTokenType.MAX)) {
+ sql.append ("MAX(");
+ translate_bracketted_expression_as_string (sql);
+ sql.append (")");
+ } else {
+ translate_primary_expression_as_string (sql);
+ }
+ }
+
DBResultSet? execute_select () throws Error {
// SELECT query
@@ -1672,47 +1661,8 @@ public class Tracker.SparqlQuery : Object {
sql.append (") NATURAL LEFT JOIN (SELECT * FROM (");
translate_group_graph_pattern (sql);
sql.append ("))");
-#if 0
- if (graph_pattern.get_operator () == Rasqal.GraphPattern.Operator.BASIC) {
- } else if (graph_pattern.get_operator () == Rasqal.GraphPattern.Operator.GROUP
- || graph_pattern.get_operator () == Rasqal.GraphPattern.Operator.OPTIONAL) {
- } else if (graph_pattern.get_operator () == Rasqal.GraphPattern.Operator.UNION) {
- for (int pattern_idx = 0; true; pattern_idx++) {
- weak Rasqal.GraphPattern sub_graph_pattern = graph_pattern.get_sub_graph_pattern (pattern_idx);
- if (sub_graph_pattern == null) {
- break;
- }
-
- if (sub_graph_pattern.get_operator () == Rasqal.GraphPattern.Operator.FILTER) {
- // ignore filters, processed later
- continue;
- }
-
- if (pattern_idx > 0) {
- pattern_sql.append (" UNION ALL ");
- }
- visit_graph_pattern (sub_graph_pattern);
- }
- }
-#endif
}
-#if 0
- string get_string_from_literal (Rasqal.Literal lit, bool is_subject = false) {
- if (lit.type == Rasqal.Literal.Type.BLANK) {
- if (!is_subject && lit.as_string ().has_prefix (":")) {
- // anonymous blank node, libtracker-data will
- // generate appropriate uri
- return lit.as_string ();
- } else {
- return generate_bnodeid (lit.as_string ());
- }
- } else {
- return lit.as_string ();
- }
- }
-#endif
-
void parse_object (StringBuilder sql) throws SparqlError {
bool object_is_var;
string object = parse_var_or_term (sql, out object_is_var);
@@ -1951,109 +1901,6 @@ public class Tracker.SparqlQuery : Object {
return table;
}
-#if 0
- bool is_datetime_variable (Rasqal.Expression expr) {
- if (expr.op == Rasqal.Op.LITERAL) {
- if (expr.literal.type == Rasqal.Literal.Type.VARIABLE) {
- string variable_name = expr.literal.as_variable ().name;
- var binding = var_map.lookup (variable_name);
- if (binding != null && binding.is_datetime) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- void visit_filter (Rasqal.Expression expr, bool is_datetime = false) throws SparqlError {
- switch (expr.op) {
- case Rasqal.Op.UMINUS:
- pattern_sql.append ("-(");
- visit_filter (expr.arg1);
- pattern_sql.append (")");
- break;
- case Rasqal.Op.ISBLANK:
- /* We don't store blank nodes as blank nodes atm, so we always
- * return false. */
- pattern_sql.append ("(0)");
- break;
- case Rasqal.Op.STR:
- if (expr.arg1.literal.type == Rasqal.Literal.Type.VARIABLE) {
- string variable_name = expr.arg1.literal.as_variable ().name;
- var binding = var_map.lookup (variable_name);
-
- if (binding.is_uri) {
- pattern_sql.append_printf ("(SELECT \"%s\".\"Uri\" as \"STR\" FROM \"%s\" WHERE \"%s\".\"ID\" = \"%s_u\")",
- binding.table.sql_db_tablename,
- binding.table.sql_db_tablename,
- binding.table.sql_db_tablename,
- variable_name);
- } else {
- visit_filter (expr.arg1);
- }
- } else if (expr.arg1.literal.type == Rasqal.Literal.Type.URI) {
- // Rasqal already takes care of this, but I added it here
- // for the reader of this code to understand what goes on
- // Note that rasqal will have converted a str(<urn:something>)
- // to a literal string 'urn:something'
- pattern_sql.append_printf ("'%s'", expr.arg1.literal.as_string ());
- } else {
- visit_filter (expr.arg1);
- }
- break;
- case Rasqal.Op.ISURI:
- if (expr.arg1.literal.type == Rasqal.Literal.Type.VARIABLE) {
- string variable_name = expr.arg1.literal.as_variable ().name;
- var binding = var_map.lookup (variable_name);
-
- if (!binding.is_uri) {
- pattern_sql.append ("(0)");
- } else {
- pattern_sql.append ("(1)");
- }
- } else if (expr.arg1.literal.type != Rasqal.Literal.Type.URI) {
- pattern_sql.append ("(0)");
- } else {
- pattern_sql.append ("(1)");
- }
- break;
- case Rasqal.Op.DATATYPE:
- if (expr.arg1.literal.type == Rasqal.Literal.Type.VARIABLE) {
- string variable_name = expr.arg1.literal.as_variable ().name;
- var binding = var_map.lookup (variable_name);
-
- if (binding.is_uri || binding.type == null) {
- throw new SparqlError.PARSE ("Invalid FILTER");
- }
-
- pattern_sql.append_printf ("(SELECT ID FROM \"rdfs:Resource\" WHERE Uri = '%s')", binding.type);
- } else {
- throw new SparqlError.PARSE ("Invalid FILTER");
- }
- break;
- case Rasqal.Op.LITERAL:
- if (expr.literal.type == Rasqal.Literal.Type.VARIABLE) {
- string variable_name = expr.literal.as_variable ().name;
- pattern_sql.append_printf ("\"%s_u\"", variable_name);
- } else {
- if (expr.literal.type == Rasqal.Literal.Type.URI) {
- pattern_sql.append ("(SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?)");
- } else {
- pattern_sql.append ("?");
- }
-
- var binding = new LiteralBinding ();
- binding.literal = expr.literal.as_string ();
- binding.literal_type = expr.literal.type;
- binding.is_datetime = is_datetime;
- bindings.append (binding);
- }
- break;
- }
- }
-#endif
-
static string? get_string_for_value (Value value)
{
if (value.type () == typeof (int)) {
diff --git a/src/libtracker-data/tracker-sparql-scanner.vala b/src/libtracker-data/tracker-sparql-scanner.vala
index bf14afa..ef22546 100644
--- a/src/libtracker-data/tracker-sparql-scanner.vala
+++ b/src/libtracker-data/tracker-sparql-scanner.vala
@@ -65,20 +65,51 @@ public class Tracker.SparqlScanner : Object {
switch (begin[0]) {
case 'A':
case 'a':
- switch (begin[2]) {
- case 'C':
- case 'c':
- if (matches (begin, "ASC")) return SparqlTokenType.ASC;
+ switch (begin[1]) {
+ case 'S':
+ case 's':
+ switch (begin[2]) {
+ case 'C':
+ case 'c':
+ if (matches (begin, "ASC")) return SparqlTokenType.ASC;
+ break;
+ case 'K':
+ case 'k':
+ if (matches (begin, "ASK")) return SparqlTokenType.ASK;
+ break;
+ }
+ break;
+ case 'V':
+ case 'v':
+ if (matches (begin, "AVG")) return SparqlTokenType.AVG;
+ break;
+ }
+ break;
+ case 'M':
+ case 'm':
+ switch (begin[1]) {
+ case 'A':
+ case 'a':
+ if (matches (begin, "MAX")) return SparqlTokenType.MAX;
break;
- case 'K':
- case 'k':
- if (matches (begin, "ASK")) return SparqlTokenType.ASK;
+ case 'I':
+ case 'i':
+ if (matches (begin, "MIN")) return SparqlTokenType.MIN;
break;
}
break;
case 'S':
case 's':
- if (matches (begin, "STR")) return SparqlTokenType.STR;
+ switch (begin[1]) {
+ case 'T':
+ case 't':
+ if (matches (begin, "STR")) return SparqlTokenType.STR;
+ break;
+ case 'U':
+ case 'u':
+ if (matches (begin, "SUM")) return SparqlTokenType.SUM;
+ break;
+ }
break;
}
break;
@@ -88,6 +119,10 @@ public class Tracker.SparqlScanner : Object {
case 'b':
if (matches (begin, "BASE")) return SparqlTokenType.BASE;
break;
+ case 'C':
+ case 'c':
+ if (matches (begin, "COUNT")) return SparqlTokenType.COUNT;
+ break;
case 'D':
case 'd':
switch (begin[1]) {
@@ -710,6 +745,7 @@ public enum Tracker.SparqlTokenType {
AS,
ASC,
ASK,
+ AVG,
BASE,
BOUND,
BY,
@@ -719,6 +755,7 @@ public enum Tracker.SparqlTokenType {
COLON,
COMMA,
CONSTRUCT,
+ COUNT,
DATATYPE,
DECIMAL,
DELETE,
@@ -745,6 +782,8 @@ public enum Tracker.SparqlTokenType {
LANG,
LANGMATCHES,
LIMIT,
+ MAX,
+ MIN,
MINUS,
NAMED,
OFFSET,
@@ -776,6 +815,7 @@ public enum Tracker.SparqlTokenType {
STRING_LITERAL2,
STRING_LITERAL_LONG1,
STRING_LITERAL_LONG2,
+ SUM,
TRUE,
UNION,
VAR,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]