[tracker/parser] SPARQL: Fix group graph pattern handling
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/parser] SPARQL: Fix group graph pattern handling
- Date: Thu, 13 Aug 2009 14:40:58 +0000 (UTC)
commit 8dc1075f5688133592987c6e7d9e69b8d4d86862
Author: Jürg Billeter <j bitron ch>
Date: Thu Aug 13 16:07:35 2009 +0200
SPARQL: Fix group graph pattern handling
src/libtracker-data/tracker-sparql-query.vala | 165 +++++++++++++++---------
1 files changed, 103 insertions(+), 62 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index a2641d9..1f0c279 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -705,15 +705,24 @@ public class Tracker.SparqlQuery : Object {
return exec_sql (sql.str);
}
+ void translate_expression_as_order_condition (StringBuilder sql) throws SparqlError {
+ long begin = sql.len;
+ if (translate_expression (sql) == DataType.RESOURCE) {
+ // ID => Uri
+ sql.insert (begin, "(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = ");
+ sql.append (")");
+ }
+ }
+
void translate_order_condition (StringBuilder sql) throws SparqlError {
if (accept (SparqlTokenType.ASC)) {
- translate_expression_as_string (sql);
+ translate_expression_as_order_condition (sql);
sql.append (" ASC");
} else if (accept (SparqlTokenType.DESC)) {
- translate_expression_as_string (sql);
+ translate_expression_as_order_condition (sql);
sql.append (" DESC");
} else {
- translate_expression_as_string (sql);
+ translate_expression_as_order_condition (sql);
}
}
@@ -939,17 +948,6 @@ public class Tracker.SparqlQuery : Object {
}
}
-
- void translate_graph_pattern_not_triples (StringBuilder sql, int group_graph_pattern_start) throws SparqlError {
- if (current () == SparqlTokenType.OPTIONAL) {
- translate_optional_graph_pattern (sql, group_graph_pattern_start);
- } else if (current () == SparqlTokenType.OPEN_BRACE) {
- translate_group_or_union_graph_pattern (sql, group_graph_pattern_start);
- } else if (current () == SparqlTokenType.GRAPH) {
- // translate_graph_graph_pattern ();
- }
- }
-
void translate_bound_call (StringBuilder sql) throws SparqlError {
expect (SparqlTokenType.BOUND);
expect (SparqlTokenType.OPEN_PARENS);
@@ -1013,7 +1011,7 @@ public class Tracker.SparqlQuery : Object {
default:
// let sqlite convert the expression to string
sql.insert (begin, "CAST (");
- sql.append ("AS TEXT)");
+ sql.append (" AS TEXT)");
break;
}
break;
@@ -1681,7 +1679,7 @@ public class Tracker.SparqlQuery : Object {
}
}
- void translate_triples_block (StringBuilder sql, ref bool first_where) throws SparqlError {
+ void start_triples_block (StringBuilder sql) throws SparqlError {
tables = new List<DataTable> ();
table_map = new HashTable<string,DataTable>.full (str_hash, str_equal, g_free, g_object_unref);
@@ -1691,24 +1689,9 @@ public class Tracker.SparqlQuery : Object {
pattern_bindings = new List<LiteralBinding> ();
sql.append ("SELECT ");
+ }
- while (true) {
- current_subject = parse_var_or_term (sql, out current_subject_is_var);
- parse_property_list_not_empty (sql);
-
- if (accept (SparqlTokenType.DOT)) {
- if (current () == SparqlTokenType.VAR ||
- current () == SparqlTokenType.IRI_REF ||
- current () == SparqlTokenType.PN_PREFIX ||
- current () == SparqlTokenType.COLON ||
- current () == SparqlTokenType.OPEN_BRACKET) {
- // optional TriplesBlock
- continue;
- }
- }
- break;
- }
-
+ void end_triples_block (StringBuilder sql, ref bool first_where, bool in_group_graph_pattern) throws SparqlError {
// remove last comma and space
sql.truncate (sql.len - 2);
@@ -1789,6 +1772,10 @@ public class Tracker.SparqlQuery : Object {
}
}
+ if (in_group_graph_pattern) {
+ sql.append (")");
+ }
+
tables = null;
table_map = null;
pattern_variables = null;
@@ -1796,34 +1783,91 @@ public class Tracker.SparqlQuery : Object {
pattern_bindings = null;
}
+ void parse_triples (StringBuilder sql, long group_graph_pattern_start, ref bool in_triples_block, ref bool first_where, bool in_group_graph_pattern) throws SparqlError {
+ while (true) {
+ if (current () != SparqlTokenType.VAR &&
+ current () != SparqlTokenType.IRI_REF &&
+ current () != SparqlTokenType.PN_PREFIX &&
+ current () != SparqlTokenType.COLON &&
+ current () != SparqlTokenType.OPEN_BRACKET) {
+ break;
+ }
+ if (!in_triples_block) {
+ if (in_group_graph_pattern) {
+ sql.insert (group_graph_pattern_start, "(");
+ sql.append (" NATURAL INNER JOIN ");
+ translate_group_or_union_graph_pattern (sql);
+ sql.append (")");
+ }
+ in_triples_block = true;
+ first_where = true;
+ start_triples_block (sql);
+ }
+
+ current_subject = parse_var_or_term (sql, out current_subject_is_var);
+ parse_property_list_not_empty (sql);
+
+ if (!accept (SparqlTokenType.DOT)) {
+ break;
+ }
+ }
+ }
+
void translate_group_graph_pattern (StringBuilder sql) throws SparqlError {
expect (SparqlTokenType.OPEN_BRACE);
SourceLocation[] filters = { };
+ bool in_triples_block = false;
+ bool in_group_graph_pattern = false;
bool first_where = true;
- int group_graph_pattern_start = (int) sql.len;
+ long group_graph_pattern_start = sql.len;
// optional TriplesBlock
- if (current () == SparqlTokenType.VAR ||
- current () == SparqlTokenType.IRI_REF ||
- current () == SparqlTokenType.PN_PREFIX ||
- current () == SparqlTokenType.COLON ||
- current () == SparqlTokenType.OPEN_BRACKET) {
- translate_triples_block (sql, ref first_where);
- }
+ parse_triples (sql, group_graph_pattern_start, ref in_triples_block, ref first_where, in_group_graph_pattern);
while (true) {
// check whether we have GraphPatternNotTriples | Filter
- if (current () == SparqlTokenType.OPTIONAL) {
- if (group_graph_pattern_start == (int) sql.len) {
+ if (accept (SparqlTokenType.OPTIONAL)) {
+ if (!in_triples_block && !in_group_graph_pattern) {
+ // expand { OPTIONAL { ... } } into { { } OPTIONAL { ... } }
// empty graph pattern => return one result without bound variables
sql.append ("SELECT 1");
+ } else if (in_triples_block) {
+ end_triples_block (sql, ref first_where, in_group_graph_pattern);
+ in_triples_block = false;
+ }
+ if (!in_group_graph_pattern) {
+ sql.insert (group_graph_pattern_start, "SELECT * FROM (");
+ group_graph_pattern_start += "SELECT * FROM (".len ();
+ in_group_graph_pattern = true;
+ }
+ sql.insert (group_graph_pattern_start, "(");
+ sql.append (") NATURAL LEFT JOIN (");
+ translate_group_graph_pattern (sql);
+ sql.append (")");
+ } else if (current () == SparqlTokenType.OPEN_BRACE) {
+ if (!in_triples_block && !in_group_graph_pattern) {
+ sql.append ("SELECT * FROM (");
+ group_graph_pattern_start = sql.len;
+ in_group_graph_pattern = true;
+ translate_group_or_union_graph_pattern (sql);
+ } else {
+ if (in_triples_block) {
+ end_triples_block (sql, ref first_where, in_group_graph_pattern);
+ in_triples_block = false;
+ }
+ if (!in_group_graph_pattern) {
+ sql.insert (group_graph_pattern_start, "SELECT * FROM (");
+ group_graph_pattern_start += "SELECT * FROM (".len ();
+ in_group_graph_pattern = true;
+ }
+
+ sql.insert (group_graph_pattern_start, "(");
+ sql.append (") NATURAL INNER JOIN (");
+ translate_group_or_union_graph_pattern (sql);
+ sql.append (")");
}
- translate_graph_pattern_not_triples (sql, group_graph_pattern_start);
- } else if (current () == SparqlTokenType.OPEN_BRACE ||
- current () == SparqlTokenType.GRAPH) {
- translate_graph_pattern_not_triples (sql, group_graph_pattern_start);
} else if (current () == SparqlTokenType.FILTER) {
filters += get_location ();
skip_filter ();
@@ -1834,18 +1878,23 @@ public class Tracker.SparqlQuery : Object {
accept (SparqlTokenType.DOT);
// optional TriplesBlock
- if (current () == SparqlTokenType.VAR ||
- current () == SparqlTokenType.IRI_REF ||
- current () == SparqlTokenType.OPEN_BRACKET) {
- translate_triples_block (sql, ref first_where);
- }
+ parse_triples (sql, group_graph_pattern_start, ref in_triples_block, ref first_where, in_group_graph_pattern);
}
expect (SparqlTokenType.CLOSE_BRACE);
- if (group_graph_pattern_start == (int) sql.len) {
+ if (!in_triples_block && !in_group_graph_pattern) {
// empty graph pattern => return one result without bound variables
sql.append ("SELECT 1");
+ } else if (in_triples_block) {
+ end_triples_block (sql, ref first_where, in_group_graph_pattern);
+ in_triples_block = false;
+ }
+
+ if (in_group_graph_pattern) {
+ // close SELECT * FROM (...
+ sql.append (")");
+ first_where = true;
}
// handle filters last, they apply to the pattern as a whole
@@ -1868,7 +1917,7 @@ public class Tracker.SparqlQuery : Object {
}
}
- void translate_group_or_union_graph_pattern (StringBuilder sql, int group_graph_pattern_start) throws SparqlError {
+ void translate_group_or_union_graph_pattern (StringBuilder sql) throws SparqlError {
translate_group_graph_pattern (sql);
while (accept (SparqlTokenType.UNION)) {
sql.append (" UNION ALL ");
@@ -1876,14 +1925,6 @@ public class Tracker.SparqlQuery : Object {
}
}
- void translate_optional_graph_pattern (StringBuilder sql, int group_graph_pattern_start) throws SparqlError {
- expect (SparqlTokenType.OPTIONAL);
- sql.insert (group_graph_pattern_start, "SELECT * FROM (");
- sql.append (") NATURAL LEFT JOIN (SELECT * FROM (");
- translate_group_graph_pattern (sql);
- sql.append ("))");
- }
-
void parse_object (StringBuilder sql) throws SparqlError {
bool object_is_var;
string object = parse_var_or_term (sql, out object_is_var);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]