diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2021-06-08 20:24:28 +0000 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2021-06-08 20:24:28 +0000 |
commit | d765b0707c03fe08efd5885edaec4ddcf5d5f390 (patch) | |
tree | 4c86d7bf52c711dc1163a67929bb5c27a284da57 | |
parent | 04e5c7a2f404815495aa8790457b1c32ab6b87a7 (diff) | |
parent | 6c80a634ae7681cc9d34945f8dfdd6fa94a8197e (diff) | |
download | tracker-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.c | 66 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-1.out | 1 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-1.rq | 9 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-2.out | 1 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-2.rq | 8 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-3.out | 2 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-3.rq | 9 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-4.out | 1 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-4.rq | 9 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-5.out | 2 | ||||
-rw-r--r-- | tests/libtracker-data/datetime/filter-5.rq | 9 | ||||
-rw-r--r-- | tests/libtracker-data/tracker-sparql-test.c | 5 | ||||
-rw-r--r-- | tests/libtracker-sparql/statement/cast.out | 1 | ||||
-rw-r--r-- | tests/libtracker-sparql/statement/cast.rq | 6 | ||||
-rw-r--r-- | tests/libtracker-sparql/tracker-statement-test.c | 1 |
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 { |