diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2018-11-03 13:16:59 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2018-11-13 11:17:31 +0100 |
commit | 204ff72f6a9b1411fdf52d55700f8f74d07c9406 (patch) | |
tree | 10f196ad32eebe5a9ed8b78d9cc3cda2c205cfd9 | |
parent | d58a15bea1b2ad2b1a9a5f5f4f208f066f8959ba (diff) | |
download | tracker-204ff72f6a9b1411fdf52d55700f8f74d07c9406.tar.gz |
libtracker-data: Support sequence property path
"?a :foo/:bar ?b" is equivalent to "?a :foo ?gen . ?gen :bar ?b",
make the parser make up those generated variables before processing
the current predicate property.
-rw-r--r-- | src/libtracker-data/tracker-sparql.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c index 1961e6dad..9a2732a80 100644 --- a/src/libtracker-data/tracker-sparql.c +++ b/src/libtracker-data/tracker-sparql.c @@ -4078,14 +4078,35 @@ static gboolean translate_PathSequence (TrackerSparql *sparql, GError **error) { + TrackerToken old_object, old_subject; + TrackerVariable *var; + TrackerParserNode *rule; + /* PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )* */ - _call_rule (sparql, NAMED_RULE_PathEltOrInverse, error); + old_object = sparql->current_state.object; + old_subject = sparql->current_state.subject; - if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_PATH_SEQUENCE)) { - _unimplemented ("Property paths"); + rule = _skip_rule (sparql, NAMED_RULE_PathEltOrInverse); + + while (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_PATH_SEQUENCE)) { + var = tracker_select_context_add_generated_variable (TRACKER_SELECT_CONTEXT (sparql->context)); + tracker_token_variable_init (&sparql->current_state.object, var); + + if (!_postprocess_rule (sparql, rule, NULL, error)) + return FALSE; + + rule = _skip_rule (sparql, NAMED_RULE_PathEltOrInverse); + sparql->current_state.subject = sparql->current_state.object; + tracker_token_unset (&sparql->current_state.object); } + if (!_postprocess_rule (sparql, rule, NULL, error)) + return FALSE; + + sparql->current_state.subject = old_subject; + sparql->current_state.object = old_object; + return TRUE; } |