summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam@afuera.me.uk>2022-03-27 22:43:17 +0000
committerSam Thursfield <sam@afuera.me.uk>2022-03-27 22:43:17 +0000
commit282f55f349f1310b21d81d782f6bdb923697152e (patch)
tree927cde051e0d3bef3a04f21355c29aa21e4fb246
parent60046b2bcd21ec4e4866d73d9167cc0633efedb6 (diff)
parent7ab14938c335aab539e67ef8768316b377e7a1d2 (diff)
downloadtracker-282f55f349f1310b21d81d782f6bdb923697152e.tar.gz
Merge branch 'wip/carlosg/more-sparql-fixes' into 'master'
Sparql compliance fixes See merge request GNOME/tracker!503
-rw-r--r--src/libtracker-data/tracker-sparql-grammar.h2
-rw-r--r--src/libtracker-data/tracker-sparql-types.c6
-rw-r--r--src/libtracker-data/tracker-sparql-types.h1
-rw-r--r--src/libtracker-data/tracker-sparql.c128
-rw-r--r--src/libtracker-data/tracker-vtab-triples.c11
-rw-r--r--tests/libtracker-data/basic/long-strings.out1
-rw-r--r--tests/libtracker-data/basic/long-strings.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-1.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-1.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-10.out2
-rw-r--r--tests/libtracker-data/property-paths/negated-path-10.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-11.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-11.rq2
-rw-r--r--tests/libtracker-data/property-paths/negated-path-2.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-2.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-3.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-3.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-4.out0
-rw-r--r--tests/libtracker-data/property-paths/negated-path-4.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-5.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-5.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-6.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-6.rq2
-rw-r--r--tests/libtracker-data/property-paths/negated-path-7.out0
-rw-r--r--tests/libtracker-data/property-paths/negated-path-7.rq2
-rw-r--r--tests/libtracker-data/property-paths/negated-path-8.out1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-8.rq1
-rw-r--r--tests/libtracker-data/property-paths/negated-path-9.out2
-rw-r--r--tests/libtracker-data/property-paths/negated-path-9.rq1
-rw-r--r--tests/libtracker-data/tracker-sparql-test.c12
30 files changed, 139 insertions, 48 deletions
diff --git a/src/libtracker-data/tracker-sparql-grammar.h b/src/libtracker-data/tracker-sparql-grammar.h
index 8835539ad..673c39721 100644
--- a/src/libtracker-data/tracker-sparql-grammar.h
+++ b/src/libtracker-data/tracker-sparql-grammar.h
@@ -556,7 +556,7 @@ static const TrackerGrammarRule rule_iri[] = { OR(helper_iri_or), NIL };
* TRACKER EXTENSION:
* The terminal PARAMETERIZED_VAR is additionally accepted
*/
-static const TrackerGrammarRule helper_String_or[] = { T(STRING_LITERAL1), T(STRING_LITERAL2), T(STRING_LITERAL_LONG1), T(STRING_LITERAL_LONG2), T(PARAMETERIZED_VAR), NIL };
+static const TrackerGrammarRule helper_String_or[] = { T(STRING_LITERAL_LONG1), T(STRING_LITERAL_LONG2), T(STRING_LITERAL1), T(STRING_LITERAL2), T(PARAMETERIZED_VAR), NIL };
static const TrackerGrammarRule rule_String[] = { OR(helper_String_or), NIL };
/* BooleanLiteral ::= 'true' | 'false'
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index 9211ddbf2..50ad62c05 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -560,7 +560,8 @@ tracker_path_element_property_new (TrackerPathOperator op,
g_return_val_if_fail (TRACKER_IS_PROPERTY (prop), NULL);
g_return_val_if_fail (op == TRACKER_PATH_OPERATOR_NONE ||
- op == TRACKER_PATH_OPERATOR_NEGATED, NULL);
+ op == TRACKER_PATH_OPERATOR_NEGATED ||
+ op == TRACKER_PATH_OPERATOR_NEGATED_INVERSE, NULL);
elem = g_new0 (TrackerPathElement, 1);
elem->op = op;
@@ -631,6 +632,9 @@ tracker_path_element_set_unique_name (TrackerPathElement *elem,
case TRACKER_PATH_OPERATOR_INTERSECTION:
name = "intersect";
break;
+ case TRACKER_PATH_OPERATOR_NEGATED_INVERSE:
+ name = "neg_inv";
+ break;
default:
g_assert_not_reached ();
}
diff --git a/src/libtracker-data/tracker-sparql-types.h b/src/libtracker-data/tracker-sparql-types.h
index 3829fd1d6..23bb06ea0 100644
--- a/src/libtracker-data/tracker-sparql-types.h
+++ b/src/libtracker-data/tracker-sparql-types.h
@@ -160,6 +160,7 @@ typedef enum {
TRACKER_PATH_OPERATOR_ZEROORMORE, /* * */
TRACKER_PATH_OPERATOR_NEGATED, /* ! */
TRACKER_PATH_OPERATOR_INTERSECTION, /* Used for negated paths */
+ TRACKER_PATH_OPERATOR_NEGATED_INVERSE, /* !^, used for negated paths */
} TrackerPathOperator;
struct _TrackerPathElement {
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index d32005212..98cd0711e 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -1093,12 +1093,22 @@ _prepend_path_element (TrackerSparql *sparql,
path_elem->data.composite.child1->name);
break;
case TRACKER_PATH_OPERATOR_NEGATED:
- _append_string_printf (sparql,
- "\"%s\" (ID, value, graph, ID_type, value_type) AS "
- "(SELECT subject AS ID, object AS value, graph, %d, object_type "
- "FROM \"tracker_triples\" ",
- path_elem->name,
- TRACKER_PROPERTY_TYPE_RESOURCE);
+ case TRACKER_PATH_OPERATOR_NEGATED_INVERSE:
+ if (path_elem->op == TRACKER_PATH_OPERATOR_NEGATED) {
+ _append_string_printf (sparql,
+ "\"%s\" (ID, value, graph, ID_type, value_type) AS "
+ "(SELECT subject AS ID, object_raw AS value, graph, %d, object_type "
+ "FROM \"tracker_triples\" ",
+ path_elem->name,
+ TRACKER_PROPERTY_TYPE_RESOURCE);
+ } else {
+ _append_string_printf (sparql,
+ "\"%s\" (ID, value, graph, ID_type, value_type) AS "
+ "(SELECT object_raw AS ID, subject AS value, graph, object_type, %d "
+ "FROM \"tracker_triples\" ",
+ path_elem->name,
+ TRACKER_PROPERTY_TYPE_RESOURCE);
+ }
if (!tracker_token_is_empty (&sparql->current_state->graph) &&
tracker_sparql_find_graph (sparql, tracker_token_get_idstring (&sparql->current_state->graph))) {
@@ -6928,6 +6938,45 @@ translate_PathPrimary (TrackerSparql *sparql,
return TRUE;
}
+static TrackerPathElement *
+intersect_path_elements (TrackerSparql *sparql,
+ GPtrArray *path_elems)
+{
+ TrackerPathElement *elem;
+
+ if (path_elems->len == 0)
+ return NULL;
+
+ if (path_elems->len == 1)
+ return g_ptr_array_index (path_elems, 0);
+
+ if (path_elems->len > 1) {
+ guint i;
+
+ 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),
+ elem);
+ _prepend_path_element (sparql, elem);
+
+ for (i = 2; i < path_elems->len; i++) {
+ TrackerPathElement *child;
+
+ child = g_ptr_array_index (path_elems, i);
+ elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INTERSECTION,
+ tracker_token_get_idstring (&sparql->current_state->graph),
+ child, elem);
+ tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
+ elem);
+ _prepend_path_element (sparql, elem);
+ }
+ }
+
+ return elem;
+}
+
static gboolean
translate_PathNegatedPropertySet (TrackerSparql *sparql,
GError **error)
@@ -6939,45 +6988,47 @@ translate_PathNegatedPropertySet (TrackerSparql *sparql,
if (_check_in_rule (sparql, NAMED_RULE_PathOneInPropertySet))
_call_rule (sparql, NAMED_RULE_PathOneInPropertySet, error);
else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS)) {
- GPtrArray *path_elems;
+ TrackerPathElement *negated, *negated_inverse;
+ GPtrArray *negated_elems, *negated_inverse_elems;
- path_elems = g_ptr_array_new ();
+ negated_elems = g_ptr_array_new ();
+ negated_inverse_elems = g_ptr_array_new ();
- _call_rule (sparql, NAMED_RULE_PathEltOrInverse, error);
- g_ptr_array_add (path_elems, sparql->current_state->path);
+ _call_rule (sparql, NAMED_RULE_PathOneInPropertySet, error);
+ g_ptr_array_add (sparql->current_state->path->op == TRACKER_PATH_OPERATOR_NEGATED ?
+ negated_elems : negated_inverse_elems,
+ sparql->current_state->path);
- while (_check_in_rule (sparql, NAMED_RULE_PathOneInPropertySet)) {
+ while (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_PATH_ALTERNATIVE)) {
_call_rule (sparql, NAMED_RULE_PathOneInPropertySet, error);
- g_ptr_array_add (path_elems, sparql->current_state->path);
+ g_ptr_array_add (sparql->current_state->path->op == TRACKER_PATH_OPERATOR_NEGATED ?
+ negated_elems : negated_inverse_elems,
+ sparql->current_state->path);
}
- if (path_elems->len > 1) {
- guint i;
+ negated = intersect_path_elements (sparql, negated_elems);
+ negated_inverse = intersect_path_elements (sparql, negated_inverse_elems);
- path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_INTERSECTION,
+ if (negated && negated_inverse) {
+ 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));
+ negated, negated_inverse);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
path_elem);
_prepend_path_element (sparql, path_elem);
-
- for (i = 2; i < path_elems->len; i++) {
- TrackerPathElement *child;
-
- 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);
- _prepend_path_element (sparql, path_elem);
- }
-
- sparql->current_state->path = path_elem;
+ } else if (negated) {
+ path_elem = negated;
+ } else if (negated_inverse) {
+ path_elem = negated_inverse;
+ } else {
+ g_assert_not_reached ();
}
+ sparql->current_state->path = path_elem;
+
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+ g_ptr_array_unref (negated_elems);
+ g_ptr_array_unref (negated_inverse_elems);
} else {
g_assert_not_reached ();
}
@@ -7024,7 +7075,9 @@ translate_PathOneInPropertySet (TrackerSparql *sparql,
prop);
if (!path_elem) {
- path_elem = tracker_path_element_property_new (TRACKER_PATH_OPERATOR_NEGATED,
+ path_elem = tracker_path_element_property_new (inverse ?
+ TRACKER_PATH_OPERATOR_NEGATED_INVERSE :
+ TRACKER_PATH_OPERATOR_NEGATED,
tracker_token_get_idstring (&sparql->current_state->graph),
prop);
tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
@@ -7038,17 +7091,6 @@ translate_PathOneInPropertySet (TrackerSparql *sparql,
g_assert_not_reached ();
}
- 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),
- path_elem);
- _prepend_path_element (sparql, path_elem);
- sparql->current_state->path = path_elem;
- }
-
return TRUE;
}
diff --git a/src/libtracker-data/tracker-vtab-triples.c b/src/libtracker-data/tracker-vtab-triples.c
index 469a6f02e..6879da38b 100644
--- a/src/libtracker-data/tracker-vtab-triples.c
+++ b/src/libtracker-data/tracker-vtab-triples.c
@@ -44,6 +44,7 @@ enum {
COL_PREDICATE,
COL_OBJECT,
COL_OBJECT_TYPE,
+ COL_OBJECT_RAW,
N_COLS
};
@@ -158,7 +159,8 @@ triples_connect (sqlite3 *db,
" subject INTEGER, "
" predicate INTEGER, "
" object INTEGER, "
- " object_type INTEGER"
+ " object_type INTEGER, "
+ " object_raw INTEGER"
")");
if (rc == SQLITE_OK) {
@@ -200,7 +202,8 @@ triples_best_index (sqlite3_vtab *vtab,
* translation to strings can be done.
*/
if (info->aConstraint[i].iColumn == COL_OBJECT ||
- info->aConstraint[i].iColumn == COL_OBJECT_TYPE)
+ info->aConstraint[i].iColumn == COL_OBJECT_TYPE ||
+ info->aConstraint[i].iColumn == COL_OBJECT_RAW)
continue;
if (info->aConstraint[i].iColumn == COL_ROWID) {
@@ -478,13 +481,15 @@ init_stmt (TrackerTriplesCursor *cursor)
"SELECT %" G_GINT64_FORMAT ", t.ID, "
" (SELECT ID From Resource WHERE Uri = \"%s\"), "
" %s, "
- " %d "
+ " %d, "
+ " t.\"%s\" "
"FROM \"%s\".\"%s\" AS t "
"WHERE 1 ",
graph_id,
tracker_property_get_uri (property),
string_expr,
tracker_property_get_data_type (property),
+ tracker_property_get_name (property),
graph,
tracker_property_get_table_name (property));
diff --git a/tests/libtracker-data/basic/long-strings.out b/tests/libtracker-data/basic/long-strings.out
new file mode 100644
index 000000000..28c6e7be9
--- /dev/null
+++ b/tests/libtracker-data/basic/long-strings.out
@@ -0,0 +1 @@
+"hello" "This is a "quoted" string" "hello" "This is a 'quoted' string"
diff --git a/tests/libtracker-data/basic/long-strings.rq b/tests/libtracker-data/basic/long-strings.rq
new file mode 100644
index 000000000..9b7abccf9
--- /dev/null
+++ b/tests/libtracker-data/basic/long-strings.rq
@@ -0,0 +1 @@
+SELECT ("""hello""" AS ?a) ("""This is a "quoted" string""" AS ?b) ('''hello''' AS ?b) ('''This is a 'quoted' string''' AS ?d) {}
diff --git a/tests/libtracker-data/property-paths/negated-path-1.out b/tests/libtracker-data/property-paths/negated-path-1.out
new file mode 100644
index 000000000..ef0350743
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-1.out
@@ -0,0 +1 @@
+"Alice"
diff --git a/tests/libtracker-data/property-paths/negated-path-1.rq b/tests/libtracker-data/property-paths/negated-path-1.rq
new file mode 100644
index 000000000..6c03cb750
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-1.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !foaf:member ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-10.out b/tests/libtracker-data/property-paths/negated-path-10.out
new file mode 100644
index 000000000..d76316a4c
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-10.out
@@ -0,0 +1,2 @@
+"Alice"
+"Foo"
diff --git a/tests/libtracker-data/property-paths/negated-path-10.rq b/tests/libtracker-data/property-paths/negated-path-10.rq
new file mode 100644
index 000000000..4c8db4ab4
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-10.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !(foaf:knows|^foaf:member|foaf:mbox) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-11.out b/tests/libtracker-data/property-paths/negated-path-11.out
new file mode 100644
index 000000000..09b6f23e7
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-11.out
@@ -0,0 +1 @@
+"Bob"
diff --git a/tests/libtracker-data/property-paths/negated-path-11.rq b/tests/libtracker-data/property-paths/negated-path-11.rq
new file mode 100644
index 000000000..fca43d101
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-11.rq
@@ -0,0 +1,2 @@
+# Only foaf:name is left
+select ?a { [ foaf:name "Bob" ] !(nrl:modified|nrl:added|foaf:knows|foaf:member|foaf:mbox|a) ?a } order by ?a
diff --git a/tests/libtracker-data/property-paths/negated-path-2.out b/tests/libtracker-data/property-paths/negated-path-2.out
new file mode 100644
index 000000000..ef0350743
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-2.out
@@ -0,0 +1 @@
+"Alice"
diff --git a/tests/libtracker-data/property-paths/negated-path-2.rq b/tests/libtracker-data/property-paths/negated-path-2.rq
new file mode 100644
index 000000000..4cca76cf5
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-2.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !(foaf:member) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-3.out b/tests/libtracker-data/property-paths/negated-path-3.out
new file mode 100644
index 000000000..ef0350743
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-3.out
@@ -0,0 +1 @@
+"Alice"
diff --git a/tests/libtracker-data/property-paths/negated-path-3.rq b/tests/libtracker-data/property-paths/negated-path-3.rq
new file mode 100644
index 000000000..284b86b7b
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-3.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !(foaf:member|foaf:mbox) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-4.out b/tests/libtracker-data/property-paths/negated-path-4.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-4.out
diff --git a/tests/libtracker-data/property-paths/negated-path-4.rq b/tests/libtracker-data/property-paths/negated-path-4.rq
new file mode 100644
index 000000000..6186ff4b4
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-4.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !(foaf:member|foaf:knows) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-5.out b/tests/libtracker-data/property-paths/negated-path-5.out
new file mode 100644
index 000000000..ef0350743
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-5.out
@@ -0,0 +1 @@
+"Alice"
diff --git a/tests/libtracker-data/property-paths/negated-path-5.rq b/tests/libtracker-data/property-paths/negated-path-5.rq
new file mode 100644
index 000000000..985b2a1f4
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-5.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !^foaf:member ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-6.out b/tests/libtracker-data/property-paths/negated-path-6.out
new file mode 100644
index 000000000..ef0350743
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-6.out
@@ -0,0 +1 @@
+"Alice"
diff --git a/tests/libtracker-data/property-paths/negated-path-6.rq b/tests/libtracker-data/property-paths/negated-path-6.rq
new file mode 100644
index 000000000..e6c4b611b
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-6.rq
@@ -0,0 +1,2 @@
+# The existing inverse relation is '_:alice foaf:knows _:bob'
+select foaf:name(?a) { [ foaf:name "Bob" ] !(^foaf:member) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-7.out b/tests/libtracker-data/property-paths/negated-path-7.out
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-7.out
diff --git a/tests/libtracker-data/property-paths/negated-path-7.rq b/tests/libtracker-data/property-paths/negated-path-7.rq
new file mode 100644
index 000000000..19a1859f5
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-7.rq
@@ -0,0 +1,2 @@
+# The existing inverse relation is '_:alice foaf:knows _:bob'
+select foaf:name(?a) { [ foaf:name "Bob" ] !(^foaf:knows) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-8.out b/tests/libtracker-data/property-paths/negated-path-8.out
new file mode 100644
index 000000000..ef0350743
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-8.out
@@ -0,0 +1 @@
+"Alice"
diff --git a/tests/libtracker-data/property-paths/negated-path-8.rq b/tests/libtracker-data/property-paths/negated-path-8.rq
new file mode 100644
index 000000000..0419f90af
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-8.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { ?a a foaf:Agent; !(^foaf:mbox|^foaf:member) [ foaf:name "Bob"] } order by foaf:name(?a)
diff --git a/tests/libtracker-data/property-paths/negated-path-9.out b/tests/libtracker-data/property-paths/negated-path-9.out
new file mode 100644
index 000000000..d76316a4c
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-9.out
@@ -0,0 +1,2 @@
+"Alice"
+"Foo"
diff --git a/tests/libtracker-data/property-paths/negated-path-9.rq b/tests/libtracker-data/property-paths/negated-path-9.rq
new file mode 100644
index 000000000..9c406c07e
--- /dev/null
+++ b/tests/libtracker-data/property-paths/negated-path-9.rq
@@ -0,0 +1 @@
+select foaf:name(?a) { [ foaf:name "Bob" ] !(foaf:knows|^foaf:member) ?a . ?a a foaf:Agent } order by foaf:name(?a)
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index 8dddd6a74..59bc73ccc 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -88,6 +88,7 @@ const TestInfo tests[] = {
{ "basic/predicate-variable-4", "basic/data-1", FALSE },
{ "basic/urn-in-as", "basic/data-1", FALSE },
{ "basic/codepoint-escaping", "basic/data-1", FALSE },
+ { "basic/long-strings", "basic/data-1", FALSE },
{ "bnode/query-1", "bnode/data", FALSE },
{ "bnode/query-2", "bnode/data", FALSE },
{ "bnode/query-3", "bnode/data", FALSE },
@@ -312,6 +313,17 @@ const TestInfo tests[] = {
{ "property-paths/alternative-path-1", "property-paths/data", FALSE },
{ "property-paths/alternative-path-2", "property-paths/data", FALSE },
{ "property-paths/alternative-path-3", "property-paths/data", FALSE },
+ { "property-paths/negated-path-1", "property-paths/data", FALSE },
+ { "property-paths/negated-path-2", "property-paths/data", FALSE },
+ { "property-paths/negated-path-3", "property-paths/data", FALSE },
+ { "property-paths/negated-path-4", "property-paths/data", FALSE },
+ { "property-paths/negated-path-5", "property-paths/data", FALSE },
+ { "property-paths/negated-path-6", "property-paths/data", FALSE },
+ { "property-paths/negated-path-7", "property-paths/data", FALSE },
+ { "property-paths/negated-path-8", "property-paths/data", FALSE },
+ { "property-paths/negated-path-9", "property-paths/data", FALSE },
+ { "property-paths/negated-path-10", "property-paths/data", FALSE },
+ { "property-paths/negated-path-11", "property-paths/data", FALSE },
{ "property-paths/mixed-inverse-and-sequence-1", "property-paths/data", FALSE },
{ "property-paths/mixed-inverse-and-sequence-2", "property-paths/data", FALSE },
{ "property-paths/mixed-inverse-and-sequence-3", "property-paths/data", FALSE },