summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2018-09-23 11:55:25 +0200
committerCarlos Garnacho <carlosg@gnome.org>2018-11-13 11:17:31 +0100
commit39daf8e7b2729237be0045f122868e2a9e7835dc (patch)
treed99f1aaef045caad875afed195079813e6e111f1
parentc8c5c43cba77630548f212f0c4bde447f90a4807 (diff)
downloadtracker-39daf8e7b2729237be0045f122868e2a9e7835dc.tar.gz
libtracker-data: Fix handling of fn:string-join
In a quite unstandard way, this function takes the list of strings to join surrounded by parentheses, eg. fn:string-join(('a', 'b'), '|'). Handle this through allowing nesting of ArgList for this case, it will error out in every other case.
-rw-r--r--src/libtracker-data/tracker-sparql-grammar.h8
-rw-r--r--src/libtracker-data/tracker-sparql.c16
2 files changed, 23 insertions, 1 deletions
diff --git a/src/libtracker-data/tracker-sparql-grammar.h b/src/libtracker-data/tracker-sparql-grammar.h
index c74eb4401..d6baf45f9 100644
--- a/src/libtracker-data/tracker-sparql-grammar.h
+++ b/src/libtracker-data/tracker-sparql-grammar.h
@@ -1078,11 +1078,17 @@ static const TrackerGrammarRule helper_ExpressionList_or[] = { T(NIL), S(helper_
static const TrackerGrammarRule rule_ExpressionList[] = { OR(helper_ExpressionList_or), NIL };
/* ArgList ::= NIL | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
+ *
+ * TRACKER EXTENSION:
+ * First argument may be an ArgList in itself for fn:string-join, resulting in:
+ * ( ArgList | 'DISTINCT'? Expression )
*/
static const TrackerGrammarRule helper_ArgList_seq_1[] = { L(COMMA), R(Expression), NIL };
static const TrackerGrammarRule helper_ArgList_gte0[] = { S(helper_ArgList_seq_1), NIL };
static const TrackerGrammarRule helper_ArgList_opt[] = { L(DISTINCT), NIL };
-static const TrackerGrammarRule helper_ArgList_seq_2[] = { L(OPEN_PARENS), OPT(helper_ArgList_opt), R(Expression), GTE0(helper_ArgList_gte0), L(CLOSE_PARENS), NIL };
+static const TrackerGrammarRule helper_ArgList_seq_3[] = { OPT(helper_ArgList_opt), R(Expression), NIL };
+static const TrackerGrammarRule helper_ArgList_or_2[] = { S(helper_ArgList_seq_3), R(ArgList), NIL };
+static const TrackerGrammarRule helper_ArgList_seq_2[] = { L(OPEN_PARENS), OR(helper_ArgList_or_2), GTE0(helper_ArgList_gte0), L(CLOSE_PARENS), NIL };
static const TrackerGrammarRule helper_ArgList_or[] = { T(NIL), S(helper_ArgList_seq_2), NIL };
static const TrackerGrammarRule rule_ArgList[] = { OR(helper_ArgList_or), NIL };
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index da7dd8506..a962bb439 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -3553,6 +3553,9 @@ translate_ArgList (TrackerSparql *sparql,
*/
if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_NIL)) {
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS)) {
+ if (_check_in_rule (sparql, NAMED_RULE_ArgList))
+ _raise (PARSE, "Recursive ArgList is not allowed", "ArgList");
+
if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_DISTINCT)) {
_unimplemented ("DISTINCT in ArgList");
}
@@ -4870,7 +4873,20 @@ handle_xpath_function (TrackerSparql *sparql,
sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_STRING;
} else if (g_str_equal (function, FN_NS "string-join")) {
_append_string (sparql, "SparqlStringJoin (");
+ _step (sparql);
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+
+ if (!_check_in_rule (sparql, NAMED_RULE_ArgList))
+ _raise (PARSE, "List of strings to join must be surrounded by parentheses", "fn:string-join");
+
_call_rule (sparql, NAMED_RULE_ArgList, error);
+
+ while (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_COMMA)) {
+ _append_string (sparql, ", ");
+ _call_rule (sparql, NAMED_RULE_Expression, error);
+ }
+
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
_append_string (sparql, ") ");
sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_STRING;
} else if (g_str_equal (function, FN_NS "replace")) {