summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam@afuera.me.uk>2020-08-28 11:33:42 +0000
committerSam Thursfield <sam@afuera.me.uk>2020-08-28 11:33:42 +0000
commit351b108fc23fbbb26f7b6b9c8b9ead55c086c684 (patch)
treea375187f029124952566b60399d16d17dbb34147
parenteef3ec23c77f6b3d181ea9ef76278b8b6da381f7 (diff)
parentdce9bc257098d554502d41a5f4f90451d821e86b (diff)
downloadtracker-351b108fc23fbbb26f7b6b9c8b9ead55c086c684.tar.gz
Merge branch 'wip/carlosg/sparql-fixes' into 'master'
Several SPARQL query fixes Closes #248 See merge request GNOME/tracker!303
-rw-r--r--src/libtracker-data/tracker-sparql-types.c8
-rw-r--r--src/libtracker-data/tracker-sparql-types.h4
-rw-r--r--src/libtracker-data/tracker-sparql.c39
-rw-r--r--tests/libtracker-data/property-paths/data-3.rq15
-rw-r--r--tests/libtracker-data/property-paths/mixed-graphs.out1
-rw-r--r--tests/libtracker-data/property-paths/mixed-graphs.rq9
-rw-r--r--tests/libtracker-data/service/service-union-with-local-2.out2
-rw-r--r--tests/libtracker-data/service/service-union-with-local-2.rq22
-rw-r--r--tests/libtracker-data/subqueries/subqueries-union-4.out2
-rw-r--r--tests/libtracker-data/subqueries/subqueries-union-4.rq1
-rw-r--r--tests/libtracker-data/tracker-service-test.c1
-rw-r--r--tests/libtracker-data/tracker-sparql-test.c2
12 files changed, 98 insertions, 8 deletions
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index 254523238..a029a275e 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -530,11 +530,13 @@ static void
tracker_path_element_free (TrackerPathElement *elem)
{
g_free (elem->name);
+ g_free (elem->graph);
g_free (elem);
}
TrackerPathElement *
tracker_path_element_property_new (TrackerPathOperator op,
+ const gchar *graph,
TrackerProperty *prop)
{
TrackerPathElement *elem;
@@ -545,6 +547,7 @@ tracker_path_element_property_new (TrackerPathOperator op,
elem = g_new0 (TrackerPathElement, 1);
elem->op = op;
+ elem->graph = g_strdup (graph);
elem->type = tracker_property_get_data_type (prop);
elem->data.property = prop;
@@ -553,6 +556,7 @@ tracker_path_element_property_new (TrackerPathOperator op,
TrackerPathElement *
tracker_path_element_operator_new (TrackerPathOperator op,
+ const gchar *graph,
TrackerPathElement *child1,
TrackerPathElement *child2)
{
@@ -568,6 +572,7 @@ tracker_path_element_operator_new (TrackerPathOperator op,
elem = g_new0 (TrackerPathElement, 1);
elem->op = op;
+ elem->graph = g_strdup (graph);
elem->data.composite.child1 = child1;
elem->data.composite.child2 = child2;
elem->type = child2 ? child2->type : child1->type;
@@ -614,6 +619,7 @@ tracker_path_element_set_unique_name (TrackerPathElement *elem,
}
elem->name = g_strdup_printf ("p%d_%s", id, name);
+
}
/* Context */
@@ -844,6 +850,7 @@ tracker_select_context_add_path_element (TrackerSelectContext *context,
TrackerPathElement *
tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *context,
+ const gchar *graph,
TrackerProperty *property)
{
guint i;
@@ -857,6 +864,7 @@ tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *c
path_elem = g_ptr_array_index (context->path_elements, i);
if (path_elem->op == TRACKER_PATH_OPERATOR_NONE &&
+ g_strcmp0 (path_elem->graph, graph) == 0 &&
path_elem->data.property == property)
return path_elem;
}
diff --git a/src/libtracker-data/tracker-sparql-types.h b/src/libtracker-data/tracker-sparql-types.h
index 1a660cfd7..fc79798b7 100644
--- a/src/libtracker-data/tracker-sparql-types.h
+++ b/src/libtracker-data/tracker-sparql-types.h
@@ -164,6 +164,7 @@ typedef enum {
struct _TrackerPathElement {
TrackerPathOperator op;
TrackerPropertyType type;
+ gchar *graph;
gchar *name;
union {
@@ -326,8 +327,10 @@ GHashTable * tracker_solution_get_bindings (TrackerSolution *solution);
/* Property path element */
TrackerPathElement * tracker_path_element_property_new (TrackerPathOperator op,
+ const gchar *graph,
TrackerProperty *prop);
TrackerPathElement * tracker_path_element_operator_new (TrackerPathOperator op,
+ const gchar *graph,
TrackerPathElement *child1,
TrackerPathElement *child2);
@@ -361,6 +364,7 @@ void tracker_select_context_add_path_element (TrackerSelectContext *context,
TrackerPathElement *path_elem);
TrackerPathElement *
tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *context,
+ const gchar *graph,
TrackerProperty *property);
/* Triple context */
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 5cff49755..5a2795af9 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -5047,7 +5047,7 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
gssize pattern_start, pattern_end;
TrackerParserNode *pattern;
gchar *pattern_str, *escaped_str, *var_str;
- TrackerContext *context;
+ TrackerContext *context, *parent;
GList *variables = NULL;
GList *variable_rules = NULL, *l;
GList *join_vars = NULL;
@@ -5066,6 +5066,7 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
}
context = tracker_triple_context_new ();
+ parent = sparql->current_state.context;
tracker_sparql_push_context (sparql, context);
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_SERVICE);
@@ -5105,6 +5106,7 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
const TrackerGrammarRule *rule;
TrackerBinding *binding;
TrackerVariable *var;
+ gboolean referenced = FALSE;
rule = tracker_parser_node_get_rule (node);
@@ -5113,7 +5115,9 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
continue;
var_str = _extract_node_string (node, sparql);
- var = _extract_node_variable (node, sparql);
+ var = tracker_select_context_ensure_variable (TRACKER_SELECT_CONTEXT (sparql->context),
+ var_str);
+ referenced = tracker_context_lookup_variable_ref (parent, var);
if (g_list_find (variables, var))
continue;
@@ -5122,12 +5126,13 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
_append_string (sparql, ", ");
/* Variable was used before in the graph pattern, preserve
- * for later so we join on it properly.
- */
- if (do_join && tracker_variable_get_sample_binding (var))
+ * for later so we join on it properly.
+ */
+ if (do_join && referenced)
join_vars = g_list_prepend (join_vars, var);
variables = g_list_prepend (variables, var);
+ tracker_context_add_variable_ref (sparql->current_state.context, var);
binding = tracker_variable_binding_new (var, NULL, NULL);
tracker_binding_set_data_type (binding, TRACKER_PROPERTY_TYPE_STRING);
_add_binding (sparql, binding);
@@ -5889,6 +5894,8 @@ translate_GroupGraphPattern (TrackerSparql *sparql,
_append_string (sparql, ") ");
} else if (rule == NAMED_RULE_GroupGraphPatternSub) {
_call_rule (sparql, rule, error);
+ } else {
+ _append_string (sparql, "SELECT NULL");
}
tracker_sparql_pop_context (sparql, TRUE);
@@ -6177,6 +6184,7 @@ translate_PathAlternative (TrackerSparql *sparql,
gint i;
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_ALTERNATIVE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
g_ptr_array_index (path_elems, 0),
g_ptr_array_index (path_elems, 1));
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6188,6 +6196,7 @@ translate_PathAlternative (TrackerSparql *sparql,
child = g_ptr_array_index (path_elems, i);
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_ALTERNATIVE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
child, path_elem);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
@@ -6228,6 +6237,7 @@ translate_PathSequence (TrackerSparql *sparql,
* the path element created in the previous step.
*/
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_SEQUENCE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
g_ptr_array_index (path_elems, path_elems->len - 2),
g_ptr_array_index (path_elems, path_elems->len - 1));
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6239,6 +6249,7 @@ translate_PathSequence (TrackerSparql *sparql,
child = g_ptr_array_index (path_elems, i);
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_SEQUENCE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
child, path_elem);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
@@ -6270,6 +6281,7 @@ translate_PathEltOrInverse (TrackerSparql *sparql,
TrackerPathElement *path_elem;
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INVERSE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
sparql->current_state.path,
NULL);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6315,7 +6327,9 @@ translate_PathMod (TrackerSparql *sparql,
return TRUE;
}
- path_elem = tracker_path_element_operator_new (op, sparql->current_state.path, NULL);
+ path_elem = tracker_path_element_operator_new (op,
+ tracker_token_get_idstring (&sparql->current_state.graph),
+ sparql->current_state.path, NULL);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
_prepend_path_element (sparql, path_elem);
@@ -6359,10 +6373,13 @@ translate_PathPrimary (TrackerSparql *sparql,
path_elem =
tracker_select_context_lookup_path_element_for_property (TRACKER_SELECT_CONTEXT (sparql->context),
+ tracker_token_get_idstring (&sparql->current_state.graph),
prop);
if (!path_elem) {
- path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NONE, prop);
+ path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NONE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
+ prop);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
_prepend_path_element (sparql, path_elem);
@@ -6404,6 +6421,7 @@ translate_PathNegatedPropertySet (TrackerSparql *sparql,
gint i;
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INTERSECTION,
+ tracker_token_get_idstring (&sparql->current_state.graph),
g_ptr_array_index (path_elems, 0),
g_ptr_array_index (path_elems, 1));
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -6415,6 +6433,7 @@ translate_PathNegatedPropertySet (TrackerSparql *sparql,
child = g_ptr_array_index (path_elems, i);
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INTERSECTION,
+ tracker_token_get_idstring (&sparql->current_state.graph),
child, path_elem);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
@@ -6467,10 +6486,13 @@ translate_PathOneInPropertySet (TrackerSparql *sparql,
path_elem =
tracker_select_context_lookup_path_element_for_property (TRACKER_SELECT_CONTEXT (sparql->context),
+ tracker_token_get_idstring (&sparql->current_state.graph),
prop);
if (!path_elem) {
- path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NEGATED, prop);
+ path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NEGATED,
+ tracker_token_get_idstring (&sparql->current_state.graph),
+ prop);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
_prepend_path_element (sparql, path_elem);
@@ -6484,6 +6506,7 @@ translate_PathOneInPropertySet (TrackerSparql *sparql,
if (inverse) {
path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INVERSE,
+ tracker_token_get_idstring (&sparql->current_state.graph),
sparql->current_state.path,
NULL);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
diff --git a/tests/libtracker-data/property-paths/data-3.rq b/tests/libtracker-data/property-paths/data-3.rq
new file mode 100644
index 000000000..87da24ec1
--- /dev/null
+++ b/tests/libtracker-data/property-paths/data-3.rq
@@ -0,0 +1,15 @@
+INSERT {
+ GRAPH <A> {
+ _:a a foaf:Person ;
+ foaf:name "a" ;
+ foaf:knows _:b .
+ _:b a foaf:Person ;
+ foaf:name "A_b" .
+ }
+ GRAPH <B> {
+ _:a a foaf:Person;
+ foaf:knows _:c .
+ _:c a foaf:Person ;
+ foaf:name "B_c" .
+ }
+}
diff --git a/tests/libtracker-data/property-paths/mixed-graphs.out b/tests/libtracker-data/property-paths/mixed-graphs.out
new file mode 100644
index 000000000..ec7394e44
--- /dev/null
+++ b/tests/libtracker-data/property-paths/mixed-graphs.out
@@ -0,0 +1 @@
+"a" "A_b" "B_c"
diff --git a/tests/libtracker-data/property-paths/mixed-graphs.rq b/tests/libtracker-data/property-paths/mixed-graphs.rq
new file mode 100644
index 000000000..4c7bb155e
--- /dev/null
+++ b/tests/libtracker-data/property-paths/mixed-graphs.rq
@@ -0,0 +1,9 @@
+SELECT ?a ?n1 ?n2 {
+ GRAPH <A> {
+ ?u foaf:name ?a ;
+ foaf:knows/foaf:name ?n1
+ }
+ GRAPH <B> {
+ ?u foaf:knows/foaf:name ?n2
+ }
+}
diff --git a/tests/libtracker-data/service/service-union-with-local-2.out b/tests/libtracker-data/service/service-union-with-local-2.out
new file mode 100644
index 000000000..6eed860fd
--- /dev/null
+++ b/tests/libtracker-data/service/service-union-with-local-2.out
@@ -0,0 +1,2 @@
+"http://purl.org/dc/elements/1.1/" "a"
+"http://tracker.api.gnome.org/ontology/v3/nao#hasTag" "b"
diff --git a/tests/libtracker-data/service/service-union-with-local-2.rq b/tests/libtracker-data/service/service-union-with-local-2.rq
new file mode 100644
index 000000000..0566ec42e
--- /dev/null
+++ b/tests/libtracker-data/service/service-union-with-local-2.rq
@@ -0,0 +1,22 @@
+SELECT ?u ?s {
+ {
+ SELECT ?u ('a' AS ?s) {
+ ?u a rdfs:Resource
+ }
+ ORDER BY STR(?u)
+ LIMIT 1
+ }
+ UNION
+ {
+ SELECT ?u ?s {
+ ?u a rdfs:Resource .
+ SERVICE <dbus:%s> {
+ SELECT ?u ('b' AS ?s) {
+ ?u nrl:indexed true
+ }
+ ORDER BY STR(?u)
+ LIMIT 1
+ }
+ }
+ }
+}
diff --git a/tests/libtracker-data/subqueries/subqueries-union-4.out b/tests/libtracker-data/subqueries/subqueries-union-4.out
new file mode 100644
index 000000000..9aac76e5b
--- /dev/null
+++ b/tests/libtracker-data/subqueries/subqueries-union-4.out
@@ -0,0 +1,2 @@
+"1"
+"1"
diff --git a/tests/libtracker-data/subqueries/subqueries-union-4.rq b/tests/libtracker-data/subqueries/subqueries-union-4.rq
new file mode 100644
index 000000000..6d656adf3
--- /dev/null
+++ b/tests/libtracker-data/subqueries/subqueries-union-4.rq
@@ -0,0 +1 @@
+SELECT (1 AS ?a) { { } UNION { } }
diff --git a/tests/libtracker-data/tracker-service-test.c b/tests/libtracker-data/tracker-service-test.c
index 788c6c1ef..5dfeb63f5 100644
--- a/tests/libtracker-data/tracker-service-test.c
+++ b/tests/libtracker-data/tracker-service-test.c
@@ -40,6 +40,7 @@ const TestInfo tests[] = {
{ "service/service-before-triples-1", FALSE },
{ "service/service-local-filter-1", FALSE },
{ "service/service-union-with-local-1", FALSE },
+ { "service/service-union-with-local-2", FALSE },
};
static GDBusConnection *dbus_conn = NULL;
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index ca2fd3dea..ff20def91 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -196,6 +196,7 @@ const TestInfo tests[] = {
{ "subqueries/subqueries-union-1", "subqueries/data-1", FALSE },
{ "subqueries/subqueries-union-2", "subqueries/data-1", FALSE },
{ "subqueries/subqueries-union-3", "subqueries/data-1", FALSE },
+ { "subqueries/subqueries-union-4", "subqueries/data-1", FALSE },
{ "subqueries/subqueries-minus-1", "subqueries/data-1", FALSE },
{ "subqueries/subqueries-minus-2", "subqueries/data-1", FALSE },
{ "subqueries/subqueries-minus-3", "subqueries/data-1", FALSE },
@@ -246,6 +247,7 @@ const TestInfo tests[] = {
{ "property-paths/mixed-recursive-and-inverse-3", "property-paths/data", FALSE },
{ "property-paths/mixed-optional-and-sequence-1", "property-paths/data-2", FALSE },
{ "property-paths/mixed-optional-and-sequence-2", "property-paths/data-2", FALSE },
+ { "property-paths/mixed-graphs", "property-paths/data-3", FALSE },
/* Update tests */
{ "update/insert-data-query-1", "update/insert-data-1", FALSE, FALSE },
{ "update/insert-data-query-2", "update/insert-data-2", FALSE, TRUE },