diff options
author | Sam Thursfield <sam@afuera.me.uk> | 2020-08-28 11:33:42 +0000 |
---|---|---|
committer | Sam Thursfield <sam@afuera.me.uk> | 2020-08-28 11:33:42 +0000 |
commit | 351b108fc23fbbb26f7b6b9c8b9ead55c086c684 (patch) | |
tree | a375187f029124952566b60399d16d17dbb34147 | |
parent | eef3ec23c77f6b3d181ea9ef76278b8b6da381f7 (diff) | |
parent | dce9bc257098d554502d41a5f4f90451d821e86b (diff) | |
download | tracker-351b108fc23fbbb26f7b6b9c8b9ead55c086c684.tar.gz |
Merge branch 'wip/carlosg/sparql-fixes' into 'master'
Several SPARQL query fixes
Closes #248
See merge request GNOME/tracker!303
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 }, |