summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2021-06-08 20:24:28 +0000
committerCarlos Garnacho <carlosg@gnome.org>2021-06-08 20:24:28 +0000
commitd765b0707c03fe08efd5885edaec4ddcf5d5f390 (patch)
tree4c86d7bf52c711dc1163a67929bb5c27a284da57
parent04e5c7a2f404815495aa8790457b1c32ab6b87a7 (diff)
parent6c80a634ae7681cc9d34945f8dfdd6fa94a8197e (diff)
downloadtracker-d765b0707c03fe08efd5885edaec4ddcf5d5f390.tar.gz
Merge branch 'wip/carlosg/datetime-comparisons' into 'master'
Fixes to xsd:dateTime relational expressions See merge request GNOME/tracker!402
-rw-r--r--src/libtracker-data/tracker-sparql.c66
-rw-r--r--tests/libtracker-data/datetime/filter-1.out1
-rw-r--r--tests/libtracker-data/datetime/filter-1.rq9
-rw-r--r--tests/libtracker-data/datetime/filter-2.out1
-rw-r--r--tests/libtracker-data/datetime/filter-2.rq8
-rw-r--r--tests/libtracker-data/datetime/filter-3.out2
-rw-r--r--tests/libtracker-data/datetime/filter-3.rq9
-rw-r--r--tests/libtracker-data/datetime/filter-4.out1
-rw-r--r--tests/libtracker-data/datetime/filter-4.rq9
-rw-r--r--tests/libtracker-data/datetime/filter-5.out2
-rw-r--r--tests/libtracker-data/datetime/filter-5.rq9
-rw-r--r--tests/libtracker-data/tracker-sparql-test.c5
-rw-r--r--tests/libtracker-sparql/statement/cast.out1
-rw-r--r--tests/libtracker-sparql/statement/cast.rq6
-rw-r--r--tests/libtracker-sparql/tracker-statement-test.c1
15 files changed, 119 insertions, 11 deletions
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 332b295cb..7b11fa44e 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -153,6 +153,7 @@ typedef struct
gboolean convert_to_string;
gboolean in_property_function;
+ gboolean in_relational_expression;
} TrackerSparqlState;
struct _TrackerSparql
@@ -2474,7 +2475,8 @@ _end_triples_block (TrackerSparql *sparql,
first = FALSE;
binding = g_ptr_array_index (triple_context->literal_bindings, i);
- if (binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME) {
+ if (binding->data_type == TRACKER_PROPERTY_TYPE_DATE ||
+ binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME) {
_append_string_printf (sparql, "SparqlTimeSort (%s) = SparqlTimeSort (", tracker_binding_get_sql_expression (binding));
_append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
_append_string (sparql, ") ");
@@ -7413,51 +7415,69 @@ static gboolean
translate_RelationalExpression (TrackerSparql *sparql,
GError **error)
{
+ TrackerStringBuilder *str, *old;
const gchar *old_sep;
+ gboolean in_relational_expression, bool_op = TRUE;
/* RelationalExpression ::= NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
*/
+ str = _append_placeholder (sparql);
+ old = tracker_sparql_swap_builder (sparql, str);
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
+ tracker_sparql_swap_builder (sparql, old);
+
+ in_relational_expression = sparql->current_state->in_relational_expression;
+ sparql->current_state->in_relational_expression = TRUE;
if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_IN)) {
_append_string (sparql, "IN ");
old_sep = tracker_sparql_swap_current_expression_list_separator (sparql, ", ");
_call_rule (sparql, NAMED_RULE_ExpressionList, error);
tracker_sparql_swap_current_expression_list_separator (sparql, old_sep);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_NOT)) {
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OP_IN);
_append_string (sparql, "NOT IN ");
old_sep = tracker_sparql_swap_current_expression_list_separator (sparql, ", ");
_call_rule (sparql, NAMED_RULE_ExpressionList, error);
tracker_sparql_swap_current_expression_list_separator (sparql, old_sep);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_EQ)) {
_append_string (sparql, " = ");
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_NE)) {
_append_string (sparql, " != ");
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_LT)) {
_append_string (sparql, " < ");
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_GT)) {
_append_string (sparql, " > ");
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_LE)) {
_append_string (sparql, " <= ");
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_OP_GE)) {
_append_string (sparql, " >= ");
_call_rule (sparql, NAMED_RULE_NumericExpression, error);
- sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
+ } else {
+ /* This is an unary expression */
+ sparql->current_state->in_relational_expression = FALSE;
+ bool_op = FALSE;
+ }
+
+ if (sparql->current_state->in_relational_expression &&
+ (sparql->current_state->expression_type == TRACKER_PROPERTY_TYPE_DATE ||
+ sparql->current_state->expression_type == TRACKER_PROPERTY_TYPE_DATETIME)) {
+ old = tracker_sparql_swap_builder (sparql, str);
+ _prepend_string (sparql, "SparqlTimeSort(");
+ _append_string (sparql, ") ");
+ tracker_sparql_swap_builder (sparql, old);
}
+ if (bool_op)
+ sparql->current_state->expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
+
+ sparql->current_state->in_relational_expression = in_relational_expression;
+
return TRUE;
}
@@ -7597,6 +7617,8 @@ translate_PrimaryExpression (TrackerSparql *sparql,
TrackerGrammarNamedRule rule;
TrackerBinding *binding;
TrackerVariable *variable;
+ TrackerStringBuilder *str, *old;
+ gboolean is_datetime_comparison = FALSE;
gchar *name;
/* PrimaryExpression ::= BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var
@@ -7604,6 +7626,9 @@ translate_PrimaryExpression (TrackerSparql *sparql,
rule = _current_rule (sparql);
select_context = TRACKER_SELECT_CONTEXT (sparql->context);
+ str = _append_placeholder (sparql);
+ old = tracker_sparql_swap_builder (sparql, str);
+
switch (rule) {
case NAMED_RULE_NumericLiteral:
case NAMED_RULE_BooleanLiteral:
@@ -7618,6 +7643,11 @@ translate_PrimaryExpression (TrackerSparql *sparql,
_call_rule (sparql, rule, error);
name = _dup_last_string (sparql);
+ is_datetime_comparison =
+ (sparql->current_state->in_relational_expression &&
+ (sparql->current_state->expression_type == TRACKER_PROPERTY_TYPE_DATE ||
+ sparql->current_state->expression_type == TRACKER_PROPERTY_TYPE_DATETIME));
+
if (tracker_context_lookup_variable_by_name (sparql->current_state->context,
name)) {
variable = _last_node_variable (sparql);
@@ -7638,6 +7668,13 @@ translate_PrimaryExpression (TrackerSparql *sparql,
_call_rule (sparql, rule, error);
binding = g_ptr_array_index (select_context->literal_bindings,
select_context->literal_bindings->len - 1);
+ sparql->current_state->expression_type = binding->data_type;
+
+ is_datetime_comparison =
+ (sparql->current_state->in_relational_expression &&
+ (binding->data_type == TRACKER_PROPERTY_TYPE_DATE ||
+ binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME));
+
_append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
break;
case NAMED_RULE_BrackettedExpression:
@@ -7649,6 +7686,13 @@ translate_PrimaryExpression (TrackerSparql *sparql,
g_assert_not_reached ();
}
+ if (is_datetime_comparison) {
+ _prepend_string (sparql, "SparqlTimeSort(");
+ _append_string (sparql, ") ");
+ }
+
+ tracker_sparql_swap_builder (sparql, old);
+
return TRUE;
}
@@ -8951,11 +8995,11 @@ translate_RDFLiteral (TrackerSparql *sparql,
cast = _dup_last_string (sparql);
}
- if (is_parameter && (langtag || cast)) {
+ if (is_parameter && langtag) {
g_free (str);
g_free (langtag);
g_free (cast);
- _raise (PARSE, "Parameter cannot have LANGTAG/^^ modifiers", "RDFLiteral");
+ _raise (PARSE, "Parameter cannot have LANGTAG modifier", "RDFLiteral");
}
if (is_parameter) {
diff --git a/tests/libtracker-data/datetime/filter-1.out b/tests/libtracker-data/datetime/filter-1.out
new file mode 100644
index 000000000..4f6581e08
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-1.out
@@ -0,0 +1 @@
+"2010-02-16T11:00:00Z"
diff --git a/tests/libtracker-data/datetime/filter-1.rq b/tests/libtracker-data/datetime/filter-1.rq
new file mode 100644
index 000000000..e0ab2aeb9
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-1.rq
@@ -0,0 +1,9 @@
+SELECT ?d {
+ VALUES ?d {
+ '2010-02-16T11:00:00Z'^^xsd:dateTime
+ '2011-02-16T11:00:00.123Z'^^xsd:dateTime
+ '2012-02-16T11:00:00Z'^^xsd:dateTime
+ }
+ FILTER (?d = '2010-02-16T11:00:00Z'^^xsd:dateTime)
+}
+ORDER BY ?d
diff --git a/tests/libtracker-data/datetime/filter-2.out b/tests/libtracker-data/datetime/filter-2.out
new file mode 100644
index 000000000..edb57a0aa
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-2.out
@@ -0,0 +1 @@
+"2011-02-16T11:00:00.123Z"
diff --git a/tests/libtracker-data/datetime/filter-2.rq b/tests/libtracker-data/datetime/filter-2.rq
new file mode 100644
index 000000000..bcb5ac340
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-2.rq
@@ -0,0 +1,8 @@
+SELECT ?d {
+ VALUES ?d {
+ '2010-02-16T11:00:00Z'^^xsd:dateTime
+ '2011-02-16T11:00:00.123Z'^^xsd:dateTime
+ '2012-02-16T11:00:00Z'^^xsd:dateTime
+ }
+ FILTER (?d = '2011-02-16T11:00:00.123Z'^^xsd:dateTime)
+}
diff --git a/tests/libtracker-data/datetime/filter-3.out b/tests/libtracker-data/datetime/filter-3.out
new file mode 100644
index 000000000..4907aa6a6
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-3.out
@@ -0,0 +1,2 @@
+"2012-02-16T11:00:00Z"
+"2011-02-16T11:00:00.123Z"
diff --git a/tests/libtracker-data/datetime/filter-3.rq b/tests/libtracker-data/datetime/filter-3.rq
new file mode 100644
index 000000000..38257e3c2
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-3.rq
@@ -0,0 +1,9 @@
+SELECT ?d {
+ VALUES ?d {
+ '2010-02-16T11:00:00Z'^^xsd:dateTime
+ '2011-02-16T11:00:00.123Z'^^xsd:dateTime
+ '2012-02-16T11:00:00Z'^^xsd:dateTime
+ }
+ FILTER (?d >= '2011-02-16T11:00:00.123Z'^^xsd:dateTime)
+}
+ORDER BY ?d
diff --git a/tests/libtracker-data/datetime/filter-4.out b/tests/libtracker-data/datetime/filter-4.out
new file mode 100644
index 000000000..edb57a0aa
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-4.out
@@ -0,0 +1 @@
+"2011-02-16T11:00:00.123Z"
diff --git a/tests/libtracker-data/datetime/filter-4.rq b/tests/libtracker-data/datetime/filter-4.rq
new file mode 100644
index 000000000..9e9070c19
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-4.rq
@@ -0,0 +1,9 @@
+SELECT ?d {
+ VALUES ?d {
+ '2010-02-16T11:00:00Z'^^xsd:dateTime
+ '2011-02-16T11:00:00.123Z'^^xsd:dateTime
+ '2012-02-16T11:00:00Z'^^xsd:dateTime
+ }
+ FILTER ('2011-02-16T11:00:00.123Z'^^xsd:dateTime = ?d)
+}
+ORDER BY ?d
diff --git a/tests/libtracker-data/datetime/filter-5.out b/tests/libtracker-data/datetime/filter-5.out
new file mode 100644
index 000000000..4907aa6a6
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-5.out
@@ -0,0 +1,2 @@
+"2012-02-16T11:00:00Z"
+"2011-02-16T11:00:00.123Z"
diff --git a/tests/libtracker-data/datetime/filter-5.rq b/tests/libtracker-data/datetime/filter-5.rq
new file mode 100644
index 000000000..0b2b6dc0b
--- /dev/null
+++ b/tests/libtracker-data/datetime/filter-5.rq
@@ -0,0 +1,9 @@
+SELECT ?d {
+ VALUES ?d {
+ '2010-02-16T11:00:00Z'^^xsd:dateTime
+ '2011-02-16T11:00:00.123Z'^^xsd:dateTime
+ '2012-02-16T11:00:00Z'^^xsd:dateTime
+ }
+ FILTER (?d IN ('2011-02-16T11:00:00.123Z'^^xsd:dateTime, '2012-02-16T11:00:00Z'^^xsd:dateTime, '2013-02-16T11:00:00Z'^^xsd:dateTime))
+}
+ORDER BY ?d
diff --git a/tests/libtracker-data/tracker-sparql-test.c b/tests/libtracker-data/tracker-sparql-test.c
index dc4cdd2c4..aa53bbf41 100644
--- a/tests/libtracker-data/tracker-sparql-test.c
+++ b/tests/libtracker-data/tracker-sparql-test.c
@@ -104,6 +104,11 @@ const TestInfo tests[] = {
{ "datetime/functions-timezone-2", "datetime/data-2", FALSE },
{ "datetime/functions-timezone-3", "datetime/data-2", FALSE },
{ "datetime/functions-tz-1", "datetime/data-2", FALSE },
+ { "datetime/filter-1", "datetime/data-1", FALSE },
+ { "datetime/filter-2", "datetime/data-1", FALSE },
+ { "datetime/filter-3", "datetime/data-1", FALSE },
+ { "datetime/filter-4", "datetime/data-1", FALSE },
+ { "datetime/filter-5", "datetime/data-1", FALSE },
{ "describe/describe-single", "describe/data", FALSE },
{ "describe/describe-non-existent", "describe/data", FALSE },
{ "describe/describe-pattern", "describe/data", FALSE },
diff --git a/tests/libtracker-sparql/statement/cast.out b/tests/libtracker-sparql/statement/cast.out
new file mode 100644
index 000000000..5a02e8885
--- /dev/null
+++ b/tests/libtracker-sparql/statement/cast.out
@@ -0,0 +1 @@
+"http://www.w3.org/2001/XMLSchema#"
diff --git a/tests/libtracker-sparql/statement/cast.rq b/tests/libtracker-sparql/statement/cast.rq
new file mode 100644
index 000000000..ee32af1f4
--- /dev/null
+++ b/tests/libtracker-sparql/statement/cast.rq
@@ -0,0 +1,6 @@
+SELECT ?s {
+ ?s nrl:lastModified ?d
+ FILTER ( ?d <= ~arg1^^xsd:dateTime )
+}
+ORDER BY ASC ?d
+LIMIT 1
diff --git a/tests/libtracker-sparql/tracker-statement-test.c b/tests/libtracker-sparql/tracker-statement-test.c
index 9b26ac410..df9276489 100644
--- a/tests/libtracker-sparql/tracker-statement-test.c
+++ b/tests/libtracker-sparql/tracker-statement-test.c
@@ -50,6 +50,7 @@ TestInfo tests[] = {
{ "offset", "statement/offset.rq", "statement/offset.out", "0" },
{ "offset-2", "statement/offset.rq", "statement/offset-2.out", "1" },
{ "datetime", "statement/datetime.rq", "statement/datetime.out", NULL, NULL, "2020-12-04T04:10:03Z" },
+ { "cast", "statement/cast.rq", "statement/cast.out", "2021-02-24T22:01:02Z" },
};
typedef struct {