[tracker/wip/carlosg/vars-in-service: 1/2] libtracker-data: Handle variables for SERVICE clauses correctly
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/vars-in-service: 1/2] libtracker-data: Handle variables for SERVICE clauses correctly
- Date: Tue, 26 Jan 2021 09:44:14 +0000 (UTC)
commit fbc67cbdf277dfccb0e30342771a7078e347e9a6
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Jan 26 10:07:32 2021 +0100
libtracker-data: Handle variables for SERVICE clauses correctly
The sparql1.1 spec allows the use of variables in SERVICE clauses,
e.g.:
... SERVICE ?s { ... } ...
Where ?s is a variable resolved in other parts of the graph pattern.
https://www.w3.org/TR/2013/REC-sparql11-federated-query-20130321/#variableService
precisely advocates that query execution order should resolve the
possible values for the queried services before attempting to access
those.
Let Tracker do this sommersault, if the service is a variable instead
of a literal propagate it up as a variable in the subselect so it is
matched together with all other variables when JOINed with the other
bits of the graph pattern, and let the services virtual table enforce
the execution order that resolves the service variable by returning
SQLITE_CONSTRAINT if the service column is missing. This makes SQLite
try the alternative execution orders, and eventually find one that
resolves the service variable when executing the remote service(s).
This allows delegating service queries to a variable, which may be
useful if e.g. we want to propagate a same query to multiple services:
SELECT ?u {
SERVICE ?s {
?u a nfo:Document
}
}
VALUES ?s { 'dbus:...', 'dbus:...' }
src/libtracker-data/tracker-sparql.c | 17 +++++++++++++++--
src/libtracker-data/tracker-vtab-service.c | 7 +++++++
2 files changed, 22 insertions(+), 2 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 2a3e8c17b..9b0f5701f 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -5214,6 +5214,15 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
i++;
}
+ if (tracker_token_get_variable (&service)) {
+ if (variable_rules != NULL)
+ _append_string (sparql, ", ");
+
+ _append_string_printf (sparql, "service AS %s ",
+ tracker_token_get_idstring (&service));
+ join_vars = g_list_prepend (join_vars, tracker_token_get_variable (&service));
+ }
+
tracker_parser_node_get_extents (pattern, &pattern_start, &pattern_end);
pattern_str = g_strndup (&sparql->sparql[pattern_start], pattern_end - pattern_start);
escaped_str = _escape_sql_string (pattern_str, '"');
@@ -5222,11 +5231,15 @@ translate_ServiceGraphPattern (TrackerSparql *sparql,
g_free (pattern_str);
g_free (escaped_str);
- _append_string_printf (sparql, "FROM tracker_service WHERE service=\"%s\" AND query=\"%s\" AND
silent=%d ",
- tracker_token_get_idstring (&service),
+ _append_string_printf (sparql, "FROM tracker_service WHERE query=\"%s\" AND silent=%d ",
service_sparql->str,
silent);
+ if (!tracker_token_get_variable (&service)) {
+ _append_string_printf (sparql, "AND service=\"%s\" ",
+ tracker_token_get_idstring (&service));
+ }
+
i = 0;
/* Proxy parameters to the virtual table */
diff --git a/src/libtracker-data/tracker-vtab-service.c b/src/libtracker-data/tracker-vtab-service.c
index a14d50509..628ecada1 100644
--- a/src/libtracker-data/tracker-vtab-service.c
+++ b/src/libtracker-data/tracker-vtab-service.c
@@ -158,6 +158,7 @@ service_best_index (sqlite3_vtab *vtab,
{
int i, argv_idx = 1;
ConstraintData *data;
+ gboolean has_service = FALSE;
data = sqlite3_malloc (sizeof (ConstraintData) * info->nConstraint);
bzero (data, sizeof (ConstraintData) * info->nConstraint);
@@ -174,6 +175,9 @@ service_best_index (sqlite3_vtab *vtab,
if (info->aConstraint[i].op != SQLITE_INDEX_CONSTRAINT_EQ)
goto error;
+ if (info->aConstraint[i].iColumn == COL_SERVICE)
+ has_service = TRUE;
+
data[i].column = info->aConstraint[i].iColumn;
data[i].op = info->aConstraint[i].op;
@@ -186,6 +190,9 @@ service_best_index (sqlite3_vtab *vtab,
info->idxStr = (char *) data;
info->needToFreeIdxStr = TRUE;
+ if (!has_service)
+ return SQLITE_CONSTRAINT;
+
return SQLITE_OK;
error:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]