[tracker/wip/carlosg/sparql1.1: 110/145] 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: 110/145] libtracker-data: Implement isNumeric/isLiteral/datatype
- Date: Thu, 18 Jul 2019 22:33:17 +0000 (UTC)
commit 9a6a61194c08babb2c1bd61251da7568bc96468a
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 16d131b86..b53fdbf9e 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -1099,6 +1099,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,
@@ -6577,10 +6593,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;
@@ -6612,7 +6673,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;
@@ -6757,32 +6827,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]