[tracker/wip/carlosg/sparql1.1: 114/201] libtracker-data: Implement VALUES
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/sparql1.1: 114/201] libtracker-data: Implement VALUES
- Date: Mon, 9 Sep 2019 22:28:23 +0000 (UTC)
commit 2485acf0d1494440275e399f3ddce6dc57655540
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Jun 13 11:34:18 2019 +0200
libtracker-data: Implement VALUES
Both as InlineData (inside the pattern graph) and ValuesClause
(outside the pattern graph).
src/libtracker-data/tracker-sparql.c | 134 +++++++++++++++++++++++++++++++++--
1 file changed, 127 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 316391c51..d04e25bd6 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -158,6 +158,7 @@ struct _TrackerSparql
TrackerPropertyType expression_type;
guint type;
guint graph_op;
+ gint values_idx;
gboolean convert_to_string;
} current_state;
@@ -2551,7 +2552,10 @@ translate_ValuesClause (TrackerSparql *sparql,
/* ValuesClause ::= ( 'VALUES' DataBlock )?
*/
if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_VALUES)) {
- _unimplemented ("VALUES");
+ _prepend_string (sparql, "SELECT * FROM (");
+ _append_string (sparql, ") NATURAL INNER JOIN (");
+ _call_rule (sparql, NAMED_RULE_DataBlock, error);
+ _append_string (sparql, ") ");
}
return TRUE;
@@ -3944,9 +3948,24 @@ static gboolean
translate_InlineData (TrackerSparql *sparql,
GError **error)
{
+ gboolean do_join;
+
/* InlineData ::= 'VALUES' DataBlock
*/
- _unimplemented ("VALUES");
+ do_join = !tracker_string_builder_is_empty (sparql->current_state.sql);
+
+ if (do_join) {
+ _prepend_string (sparql, "SELECT * FROM (");
+ _append_string (sparql, ") NATURAL INNER JOIN (");
+ }
+
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_VALUES);
+ _call_rule (sparql, NAMED_RULE_DataBlock, error);
+
+ if (do_join)
+ _append_string (sparql, ")");
+
+ return TRUE;
}
static gboolean
@@ -3954,9 +3973,20 @@ translate_DataBlock (TrackerSparql *sparql,
GError **error)
{
TrackerGrammarNamedRule rule;
+ TrackerStringBuilder *old;
/* DataBlock ::= InlineDataOneVar | InlineDataFull
*/
+ old = tracker_sparql_swap_builder (sparql, sparql->current_state.with_clauses);
+
+ if (tracker_string_builder_is_empty (sparql->current_state.with_clauses))
+ _append_string (sparql, "WITH ");
+ else
+ _append_string (sparql, ", ");
+
+ sparql->current_state.values_idx++;
+ _append_string_printf (sparql, "\"dataBlock%d\"",
+ sparql->current_state.values_idx);
rule = _current_rule (sparql);
switch (rule) {
@@ -3968,6 +3998,11 @@ translate_DataBlock (TrackerSparql *sparql,
g_assert_not_reached ();
}
+ tracker_sparql_swap_builder (sparql, old);
+
+ _append_string_printf (sparql, "SELECT * FROM \"dataBlock%d\"",
+ sparql->current_state.values_idx);
+
return TRUE;
}
@@ -3975,17 +4010,41 @@ static gboolean
translate_InlineDataOneVar (TrackerSparql *sparql,
GError **error)
{
+ TrackerVariable *var;
+ TrackerBinding *binding;
+ gint n_values = 0;
+
/* InlineDataOneVar ::= Var '{' DataBlockValue* '}'
*/
_call_rule (sparql, NAMED_RULE_Var, error);
+ var = _last_node_variable (sparql);
+ binding = tracker_variable_binding_new (var, NULL, NULL);
+ tracker_variable_set_sample_binding (var, TRACKER_VARIABLE_BINDING (binding));
+
+ _append_string (sparql, "(");
+ _append_variable_sql (sparql, var);
+ _append_string (sparql, ") AS ( ");
+
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_BRACE);
while (_check_in_rule (sparql, NAMED_RULE_DataBlockValue)) {
+ if (n_values == 0)
+ _append_string (sparql, "VALUES ");
+ else
+ _append_string (sparql, ", ");
+
+ _append_string (sparql, "(");
_call_rule (sparql, NAMED_RULE_DataBlockValue, error);
+ _append_string (sparql, ") ");
+ n_values++;
}
+ if (n_values == 0)
+ _append_string (sparql, "SELECT NULL WHERE FALSE");
+
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_BRACE);
+ _append_string (sparql, ") ");
return TRUE;
}
@@ -3994,13 +4053,30 @@ static gboolean
translate_InlineDataFull (TrackerSparql *sparql,
GError **error)
{
+ TrackerVariable *var;
+ TrackerBinding *binding;
+ gint n_params, n_args = 0, n_values = 0;
+
/* InlineDataFull ::= ( NIL | '(' Var* ')' ) '{' ( '(' DataBlockValue* ')' | NIL )* '}'
*/
- if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_NIL)) {
+ _append_string (sparql, "(");
+ if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_NIL)) {
+ _append_string (sparql, "NONE");
+ n_args = 0;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS)) {
while (_check_in_rule (sparql, NAMED_RULE_Var)) {
+ if (n_args != 0)
+ _append_string (sparql, ", ");
+
_call_rule (sparql, NAMED_RULE_Var, error);
+
+ var = _last_node_variable (sparql);
+ binding = tracker_variable_binding_new (var, NULL, NULL);
+ tracker_variable_set_sample_binding (var, TRACKER_VARIABLE_BINDING (binding));
+ n_args++;
+
+ _append_variable_sql (sparql, var);
}
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
@@ -4008,21 +4084,58 @@ translate_InlineDataFull (TrackerSparql *sparql,
g_assert_not_reached ();
}
+ _append_string (sparql, ") AS ( ");
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_BRACE);
do {
- if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_NIL)) {
- } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS)) {
+ gboolean is_nil = FALSE;
+
+ if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_NIL))
+ is_nil = TRUE;
+ else if (!_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS))
+ break;
+
+ if (n_values == 0)
+ _append_string (sparql, "VALUES ");
+ else
+ _append_string (sparql, ", ");
+
+ if (is_nil) {
+ _append_string (sparql, "(NULL)");
+ n_params = 0;
+ } else {
+ n_params = 0;
+
+ _append_string (sparql, "(");
+
while (_check_in_rule (sparql, NAMED_RULE_DataBlockValue)) {
+ if (n_params != 0)
+ _append_string (sparql, ", ");
+
_call_rule (sparql, NAMED_RULE_DataBlockValue, error);
+ n_params++;
}
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
- } else {
- break;
+ _append_string (sparql, ") ");
+ }
+
+ if (n_params != n_args) {
+ g_set_error (error, TRACKER_SPARQL_ERROR,
+ TRACKER_SPARQL_ERROR_PARSE,
+ "VALUES defined %d arguments but set has %d parameters",
+ n_args, n_params);
+ return FALSE;
}
+
+ n_values++;
} while (TRUE);
+ if (n_values == 0)
+ _append_string (sparql, "SELECT NULL WHERE FALSE");
+
+ _append_string (sparql, ") ");
+
return TRUE;
}
@@ -4031,10 +4144,12 @@ translate_DataBlockValue (TrackerSparql *sparql,
GError **error)
{
TrackerGrammarNamedRule rule;
+ TrackerBinding *binding;
/* DataBlockValue ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
*/
if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_UNDEF)) {
+ _append_string (sparql, "NULL ");
return TRUE;
}
@@ -4046,6 +4161,11 @@ translate_DataBlockValue (TrackerSparql *sparql,
case NAMED_RULE_NumericLiteral:
case NAMED_RULE_BooleanLiteral:
_call_rule (sparql, rule, error);
+ binding = _convert_terminal (sparql);
+ tracker_select_context_add_literal_binding (TRACKER_SELECT_CONTEXT
(sparql->current_state.select_context),
+ TRACKER_LITERAL_BINDING (binding));
+ _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+ g_object_unref (binding);
break;
default:
g_assert_not_reached ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]