[tracker/wip/carlosg/sparql1.1: 141/201] libtracker-data: Implement isNumeric/isLiteral/datatype
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/sparql1.1: 141/201] libtracker-data: Implement isNumeric/isLiteral/datatype
- Date: Mon, 9 Sep 2019 22:30:40 +0000 (UTC)
commit df87b58d25296360895ca68a58d85f0b44942f47
Author: Carlos Garnacho <carlosg gnome org>
Date: Sat Jul 6 13:22:54 2019 +0200
libtracker-data: Implement isNumeric/isLiteral/datatype
It's all implemented on top of the SparqlDataType sqlite function, and
property types derived from either the parser context or the query
itself.
isIRI/isURI were reimplemented on top of this too, as they could only
handle types inferred from the parser context and were thus
incomplete.
src/libtracker-data/tracker-sparql.c | 113 +++++++++++++++++++++++++++++------
1 file changed, 94 insertions(+), 19 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 3bb25f5b4..d3c50a449 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -1117,6 +1117,22 @@ reserve_subvariable (TrackerSparql *sparql,
return subvar;
}
+static TrackerVariable *
+lookup_subvariable (TrackerSparql *sparql,
+ TrackerVariable *var,
+ const gchar *suffix)
+{
+ TrackerVariable *subvar;
+ gchar *name;
+
+ name = g_strdup_printf ("%s:%s", var->name, suffix);
+ subvar = tracker_select_context_lookup_variable (TRACKER_SELECT_CONTEXT (sparql->context),
+ name);
+ g_free (name);
+
+ return subvar;
+}
+
static gboolean
_add_quad (TrackerSparql *sparql,
TrackerToken *graph,
@@ -6752,10 +6768,55 @@ helper_translate_time (TrackerSparql *sparql,
return TRUE;
}
+static gboolean
+helper_datatype (TrackerSparql *sparql,
+ TrackerParserNode *node,
+ GError **error)
+{
+ TrackerStringBuilder *dummy;
+ gboolean retval;
+
+ _append_string (sparql, "SparqlDataType (");
+
+ if (g_node_n_nodes ((GNode *) node, G_TRAVERSE_LEAVES) == 1) {
+ TrackerVariable *var, *type_var;
+ TrackerParserNode *arg;
+
+ arg = tracker_sparql_parser_tree_find_next (node, TRUE);
+ var = _extract_node_variable (arg, sparql);
+
+ if (var) {
+ /* This is a simple is*(?u) statement, check if the variable type is known */
+ type_var = lookup_subvariable (sparql, var, "type");
+
+ if (type_var && tracker_variable_has_bindings (type_var)) {
+ /* Exists and is known, use it */
+ _append_variable_sql (sparql, type_var);
+ _append_string (sparql, ") ");
+
+ return TRUE;
+ }
+ }
+ }
+
+ /* Redirect output to a dummy string, we just care of the parsed expression type */
+ dummy = tracker_string_builder_new ();
+ retval = _postprocess_rule (sparql, node, dummy, error);
+ tracker_string_builder_free (dummy);
+
+ if (!retval)
+ return retval;
+
+ _append_string_printf (sparql, "%d) ", sparql->current_state.expression_type);
+
+ return TRUE;
+}
+
static gboolean
translate_BuiltInCall (TrackerSparql *sparql,
GError **error)
{
+ TrackerParserNode *node;
gboolean convert_to_string;
const gchar *old_sep;
@@ -6787,7 +6848,16 @@ translate_BuiltInCall (TrackerSparql *sparql,
sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_STRING;
tracker_sparql_swap_builder (sparql, old);
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_DATATYPE)) {
- _unimplemented ("DATATYPE");
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+ node = _skip_rule (sparql, NAMED_RULE_Expression);
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+
+ _append_string (sparql, "NULLIF (");
+ if (!helper_datatype (sparql, node, error))
+ return FALSE;
+
+ _append_string (sparql, ", \"" RDFS_NS "Resource\") ");
+ sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_STRING;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_URI) ||
_accept (sparql, RULE_TYPE_LITERAL, LITERAL_IRI)) {
sparql->current_state.convert_to_string = TRUE;
@@ -6932,32 +7002,37 @@ translate_BuiltInCall (TrackerSparql *sparql,
sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_STRING;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_ISIRI) ||
_accept (sparql, RULE_TYPE_LITERAL, LITERAL_ISURI)) {
- TrackerBinding *binding;
- const gchar *str;
- GBytes *bytes;
-
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+ node = _skip_rule (sparql, NAMED_RULE_Expression);
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
- _call_rule (sparql, NAMED_RULE_Expression, error);
-
- str = (sparql->current_state.expression_type == TRACKER_PROPERTY_TYPE_RESOURCE) ? "1" : "0";
-
- bytes = g_bytes_new (str, strlen (str) + 1);
- binding = tracker_literal_binding_new (bytes, NULL);
- g_bytes_unref (bytes);
-
- tracker_select_context_add_literal_binding (TRACKER_SELECT_CONTEXT (sparql->context),
- TRACKER_LITERAL_BINDING (binding));
- _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+ if (!helper_datatype (sparql, node, error))
+ return FALSE;
- _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+ _append_string (sparql, "== \"" RDFS_NS "Resource\" ");
sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_ISBLANK)) {
_unimplemented ("ISBLANK");
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_ISLITERAL)) {
- _unimplemented ("ISLITERAL");
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+ node = _skip_rule (sparql, NAMED_RULE_Expression);
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+
+ if (!helper_datatype (sparql, node, error))
+ return FALSE;
+
+ _append_string (sparql, "!= \"" RDFS_NS "Resource\" ");
+ sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_ISNUMERIC)) {
- _unimplemented ("ISNUMERIC");
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
+ node = _skip_rule (sparql, NAMED_RULE_Expression);
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
+
+ if (!helper_datatype (sparql, node, error))
+ return FALSE;
+
+ _append_string (sparql, "IN (\"" XSD_NS "integer\", \"" XSD_NS "double\")");
+ sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
} else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_LANGMATCHES)) {
_append_string (sparql, "SparqlLangMatches (");
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]