[tracker/wip/carlosg/portal: 270/298] libtracker-data: Add support for CONSTRAINT query prologues
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/portal: 270/298] libtracker-data: Add support for CONSTRAINT query prologues
- Date: Fri, 22 May 2020 20:48:09 +0000 (UTC)
commit 4a0f42777e1c7ee38b08e50a0c589342b18857b9
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Jan 23 15:49:59 2020 +0100
libtracker-data: Add support for CONSTRAINT query prologues
This prologue declaration is a Tracker extension, in order to
constraint access to graphs and services within the query.
Successive CONSTRAINT calls will intersect with previous ones,
meaning that the dataset can only be shrunk and no clause will
be violated.
We allow 2 types of CONSTRAINT clauses, for graphs (CONSTRAINT
GRAPH) and services (CONSTRAINT SERVICE). These take a list of
comma-separated IRIREFs. An empty list is also accepted, resulting
in the most restrictive (empty) set. No clauses will mean access
to graphs and services is undeterred.
src/libtracker-data/tracker-sparql-grammar.h | 20 ++++++-
src/libtracker-data/tracker-sparql.c | 81 +++++++++++++++++++++++++++-
2 files changed, 97 insertions(+), 4 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-grammar.h b/src/libtracker-data/tracker-sparql-grammar.h
index f8cc8a1bf..bce189109 100644
--- a/src/libtracker-data/tracker-sparql-grammar.h
+++ b/src/libtracker-data/tracker-sparql-grammar.h
@@ -31,6 +31,7 @@ typedef enum {
NAMED_RULE_Prologue,
NAMED_RULE_BaseDecl,
NAMED_RULE_PrefixDecl,
+ NAMED_RULE_ConstraintDecl,
NAMED_RULE_SelectQuery,
NAMED_RULE_SubSelect,
NAMED_RULE_ConstructQuery,
@@ -191,6 +192,7 @@ typedef enum {
LITERAL_COLON,
LITERAL_CONCAT,
LITERAL_CONTAINS,
+ LITERAL_CONSTRAINT,
LITERAL_COMMA,
LITERAL_CONSTRUCT,
LITERAL_COPY,
@@ -341,6 +343,7 @@ static const gchar literals[][N_LITERALS] = {
":", /* LITERAL_COLON */
"concat", /* LITERAL_CONCAT */
"contains", /* LITERAL_CONTAINS */
+ "constraint", /* LITERAL_CONSTRAINT */
",", /* LITERAL_COMMA */
"construct", /* LITERAL_CONSTRUCT */
"copy", /* LITERAL_COPY */
@@ -1498,14 +1501,26 @@ static const TrackerGrammarRule rule_SelectQuery[] = { R(SelectClause), GTE0(hel
*/
static const TrackerGrammarRule rule_PrefixDecl[] = { L(PREFIX), T(PNAME_NS), T(IRIREF), NIL };
+/* ConstraintDecl ::= 'CONSTRAINT' ( 'GRAPH' | 'SERVICE' ) ( IRIREF (',' IRIREF)* )?
+ *
+ * TRACKER EXTENSION
+ */
+static const TrackerGrammarRule helper_ConstraintDecl_or_1[] = { L(GRAPH), L(SERVICE), NIL };
+static const TrackerGrammarRule helper_ConstraintDecl_seq_1[] = { L(COMMA), T(IRIREF), NIL };
+static const TrackerGrammarRule helper_ConstraintDecl_gte0_1[] = { S(helper_ConstraintDecl_seq_1), NIL };
+static const TrackerGrammarRule helper_ConstraintDecl_opt_1[] = { T(IRIREF),
GTE0(helper_ConstraintDecl_gte0_1), NIL };
+static const TrackerGrammarRule rule_ConstraintDecl[] = { L(CONSTRAINT), OR(helper_ConstraintDecl_or_1),
OPT(helper_ConstraintDecl_opt_1), NIL };
/* BaseDecl ::= 'BASE' IRIREF
*/
static const TrackerGrammarRule rule_BaseDecl[] = { L(BASE), T(IRIREF), NIL };
-/* Prologue ::= ( BaseDecl | PrefixDecl )*
+/* Prologue ::= ( BaseDecl | PrefixDecl | ConstraintDecl )*
+ *
+ * TRACKER EXTENSION:
+ * ConstraintDecl entirely.
*/
-static const TrackerGrammarRule helper_Prologue_or[] = { R(BaseDecl), R(PrefixDecl), NIL };
+static const TrackerGrammarRule helper_Prologue_or[] = { R(BaseDecl), R(PrefixDecl), R(ConstraintDecl), NIL
};
static const TrackerGrammarRule helper_Prologue_gte0[] = { OR(helper_Prologue_or), NIL };
static const TrackerGrammarRule rule_Prologue[] = { GTE0 (helper_Prologue_gte0), NIL };
@@ -2144,6 +2159,7 @@ static const TrackerGrammarRule *named_rules[N_NAMED_RULES] = {
rule_Prologue,
rule_BaseDecl,
rule_PrefixDecl,
+ rule_ConstraintDecl,
rule_SelectQuery,
rule_SubSelect,
rule_ConstructQuery,
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index ee49ac204..5f678ab51 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -2591,11 +2591,16 @@ translate_Prologue (TrackerSparql *sparql,
{
TrackerGrammarNamedRule rule;
- /* Prologue ::= ( BaseDecl | PrefixDecl )*
+ /* Prologue ::= ( BaseDecl | PrefixDecl | ConstraintDecl )*
+ *
+ * TRACKER EXTENSION:
+ * ConstraintDecl entirely.
*/
rule = _current_rule (sparql);
- while (rule == NAMED_RULE_BaseDecl || rule == NAMED_RULE_PrefixDecl) {
+ while (rule == NAMED_RULE_BaseDecl ||
+ rule == NAMED_RULE_PrefixDecl ||
+ rule == NAMED_RULE_ConstraintDecl) {
_call_rule (sparql, rule, error);
rule = _current_rule (sparql);
}
@@ -2643,6 +2648,77 @@ translate_PrefixDecl (TrackerSparql *sparql,
return TRUE;
}
+static void
+intersect_set (GPtrArray *array,
+ GPtrArray *set)
+{
+ const gchar *set_graph, *graph;
+ gint i = 0, j;
+ gboolean found;
+
+ while (i < array->len) {
+ graph = g_ptr_array_index (array, i);
+ found = FALSE;
+
+ for (j = 0; j < set->len; j++) {
+ set_graph = g_ptr_array_index (set, j);
+
+ if (g_strcmp0 (set_graph, graph) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found) {
+ i++;
+ } else {
+ g_ptr_array_remove_index_fast (array, i);
+ }
+ }
+}
+
+static gboolean
+translate_ConstraintDecl (TrackerSparql *sparql,
+ GError **error)
+{
+ GPtrArray **previous_set, *set;
+
+ /* ConstraintDecl ::= 'CONSTRAINT' ( 'GRAPH' | 'SERVICE' ) ( IRIREF (',' IRIREF)* )?
+ *
+ * TRACKER EXTENSION
+ */
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CONSTRAINT);
+
+ if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_GRAPH)) {
+ previous_set = &sparql->policy.graphs;
+ } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_SERVICE)) {
+ previous_set = &sparql->policy.services;
+ } else {
+ g_assert_not_reached ();
+ }
+
+ set = g_ptr_array_new_with_free_func (g_free);
+
+ while (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_IRIREF)) {
+ gchar *elem;
+
+ elem = _dup_last_string (sparql);
+ g_ptr_array_add (set, elem);
+
+ if (!_accept (sparql, RULE_TYPE_LITERAL, LITERAL_COMMA))
+ break;
+ }
+
+ if (*previous_set) {
+ intersect_set (*previous_set, set);
+ g_ptr_array_unref (set);
+ } else {
+ *previous_set = set;
+ }
+
+ return TRUE;
+}
+
static gboolean
_check_undefined_variables (TrackerSparql *sparql,
TrackerSelectContext *context,
@@ -8637,6 +8713,7 @@ const RuleTranslationFunc rule_translation_funcs[N_NAMED_RULES] = {
translate_Prologue,
translate_BaseDecl,
translate_PrefixDecl,
+ translate_ConstraintDecl,
translate_SelectQuery,
translate_SubSelect,
translate_ConstructQuery,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]