[tracker/wip/carlosg/unrestricted-predicates: 3/6] libtracker-data: Use "tracker_triples" table in variable predicate queries
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/unrestricted-predicates: 3/6] libtracker-data: Use "tracker_triples" table in variable predicate queries
- Date: Mon, 14 Jan 2019 10:19:26 +0000 (UTC)
commit d46bdef70fe95867ad3ff0eae2b5de511877823a
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Jan 6 19:22:29 2019 +0100
libtracker-data: Use "tracker_triples" table in variable predicate queries
There were some special cases that were handled individually:
- select * { <s> ?p ?o } was handled through querying the rdf:types of <s>,
and performing an UNION of all related tables. This doesn't play along
with parameterized variables where the subject might be a variable assigned
later through the TrackerSparqlStatement.
- select * { ?s ?p <o> } used similar tricks (querying <o> this time). It had
all those drawbacks, plus it only worked for properties with rdfs:Resource
range.
- select * { ?s ?p ?o . ?p rdfs:domain <dom> } was handled specially.
- select * { ?s ?p ?o } is unsupported
- select * { <s> ?p <o> } was silently unhandled
All those combinations are transparently handled with the tracker_triples
virtual table now.
src/libtracker-data/tracker-sparql-types.c | 8 -
src/libtracker-data/tracker-sparql-types.h | 4 -
src/libtracker-data/tracker-sparql.c | 258 +++--------------------------
src/libtracker-data/tracker-vtab-triples.c | 1 +
4 files changed, 25 insertions(+), 246 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index c3c8eae3c..05b0600d7 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -71,19 +71,11 @@ tracker_predicate_variable_new (void)
static void
tracker_predicate_variable_free (TrackerPredicateVariable *pred_var)
{
- g_clear_object (&pred_var->domain);
g_free (pred_var->subject);
g_free (pred_var->object);
g_free (pred_var);
}
-void
-tracker_predicate_variable_set_domain (TrackerPredicateVariable *pred_var,
- TrackerClass *domain)
-{
- g_set_object (&pred_var->domain, domain);
-}
-
void
tracker_predicate_variable_set_triple_details (TrackerPredicateVariable *pred_var,
const gchar *subject,
diff --git a/src/libtracker-data/tracker-sparql-types.h b/src/libtracker-data/tracker-sparql-types.h
index bf3484475..bd3b063ba 100644
--- a/src/libtracker-data/tracker-sparql-types.h
+++ b/src/libtracker-data/tracker-sparql-types.h
@@ -143,8 +143,6 @@ struct _TrackerToken {
struct _TrackerPredicateVariable {
gchar *subject;
gchar *object;
- TrackerClass *domain;
-
guint return_graph : 1;
};
@@ -319,8 +317,6 @@ TrackerPathElement * tracker_token_get_path (TrackerToken *token);
/* Predicate variable */
TrackerPredicateVariable *tracker_predicate_variable_new (void);
-void tracker_predicate_variable_set_domain (TrackerPredicateVariable *pred_var,
- TrackerClass *domain);
void tracker_predicate_variable_set_triple_details (TrackerPredicateVariable *pred_var,
const gchar *subject,
const gchar *object,
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index d123c6330..80d41d4a5 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -1063,35 +1063,6 @@ _add_quad (TrackerSparql *sparql,
GPtrArray *binding_list;
variable = tracker_token_get_variable (subject);
-
- if (!tracker_token_get_variable (object) &&
- g_strcmp0 (tracker_token_get_literal (predicate), RDFS_NS "domain") == 0)
{
- TrackerPredicateVariable *pred_var;
- TrackerClass *domain;
-
- /* rdfs:domain */
- domain = tracker_ontologies_get_class_by_uri (ontologies,
-
tracker_token_get_literal (object));
- if (!domain) {
- g_set_error (error, TRACKER_SPARQL_ERROR,
- TRACKER_SPARQL_ERROR_UNKNOWN_CLASS,
- "Unknown class '%s'",
- tracker_token_get_literal (object));
- return FALSE;
- }
-
- pred_var = tracker_select_context_lookup_predicate_variable
(select_context,
-
variable);
- if (!pred_var) {
- pred_var = tracker_predicate_variable_new ();
- tracker_select_context_add_predicate_variable (select_context,
- variable,
- pred_var);
- }
-
- tracker_predicate_variable_set_domain (pred_var, domain);
- }
-
binding_list = tracker_triple_context_lookup_variable_binding_list
(triple_context,
variable);
/* Domain specific index might be a possibility, let's check */
@@ -1445,227 +1416,46 @@ convert_expression_to_string (TrackerSparql *sparql,
}
}
-static TrackerClass **
-lookup_resource_types (TrackerSparql *sparql,
- const gchar *resource,
- gint *n_types,
- GError **error)
-{
- TrackerOntologies *ontologies;
- TrackerDBInterface *iface;
- TrackerDBStatement *stmt;
- TrackerDBCursor *cursor = NULL;
- GError *inner_error = NULL;
- GPtrArray *types;
- gint resource_id;
-
- if (n_types)
- *n_types = 0;
-
- ontologies = tracker_data_manager_get_ontologies (sparql->data_manager);
- iface = tracker_data_manager_get_writable_db_interface (sparql->data_manager);
- resource_id = tracker_data_query_resource_id (sparql->data_manager,
- iface, resource);
-
- /* This is not an error condition, query might refer to an unknown resource */
- if (resource_id <= 0)
- return NULL;
-
- stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT,
&inner_error,
- "SELECT (SELECT Uri FROM Resource WHERE ID =
\"rdf:type\") "
- "FROM \"rdfs:Resource_rdf:type\" WHERE ID = ?");
- if (!stmt) {
- g_propagate_error (error, inner_error);
- return NULL;
- }
-
- tracker_db_statement_bind_int (stmt, 0, resource_id);
- cursor = tracker_db_statement_start_cursor (stmt, error);
- g_object_unref (stmt);
-
- if (!cursor) {
- g_propagate_error (error, inner_error);
- return NULL;
- }
-
- types = g_ptr_array_new ();
-
- while (tracker_db_cursor_iter_next (cursor, NULL, &inner_error)) {
- TrackerClass *type;
-
- type = tracker_ontologies_get_class_by_uri (ontologies,
- tracker_db_cursor_get_string (cursor, 0, NULL));
- g_ptr_array_add (types, type);
- }
-
- g_object_unref (cursor);
-
- if (inner_error) {
- g_propagate_error (error, inner_error);
- g_ptr_array_unref (types);
- return NULL;
- }
-
- if (n_types)
- *n_types = types->len;
-
- return (TrackerClass **) g_ptr_array_free (types, FALSE);
-}
-
static gboolean
append_predicate_variable_query (TrackerSparql *sparql,
TrackerPredicateVariable *pred_var,
GError **error)
{
- TrackerOntologies *ontologies;
- TrackerProperty **properties;
- TrackerStringBuilder *str, *old;
- TrackerClass **types;
- TrackerBinding *binding = NULL;
- gint n_properties, n_types, i, j;
- GError *inner_error = NULL;
- gboolean first = TRUE;
-
- ontologies = tracker_data_manager_get_ontologies (sparql->data_manager);
- properties = tracker_ontologies_get_properties (ontologies, &n_properties);
-
- if (pred_var->subject) {
- /* <s> ?p ?o */
- types = lookup_resource_types (sparql, pred_var->subject, &n_types, &inner_error);
- if (inner_error) {
- g_propagate_error (error, inner_error);
- return FALSE;
- }
-
- for (i = 0; i < n_types; i++) {
- for (j = 0; j < n_properties; j++) {
- if (types[i] != tracker_property_get_domain (properties[j]))
- continue;
-
- if (!first)
- _append_string (sparql, "UNION ALL ");
-
- first = FALSE;
- _append_string_printf (sparql,
- "SELECT ID, (SELECT ID FROM Resource WHERE Uri = '%s')
AS \"predicate\", ",
- tracker_property_get_uri (properties[j]));
-
- str = _append_placeholder (sparql);
- old = tracker_sparql_swap_builder (sparql, str);
- _append_string_printf (sparql, "\"%s\" ", tracker_property_get_name
(properties[j]));
- convert_expression_to_string (sparql, tracker_property_get_data_type
(properties[j]));
- tracker_sparql_swap_builder (sparql, old);
-
- _append_string (sparql, " AS \"object\" ");
-
- if (pred_var->return_graph) {
- _append_string_printf (sparql, ", \"%s:graph\" AS \"graph\" ",
- tracker_property_get_name (properties[j]));
- }
-
- _append_string_printf (sparql, "FROM \"%s\" WHERE ID = ",
- tracker_property_get_table_name (properties[j]));
-
- if (!binding) {
- binding = tracker_literal_binding_new (pred_var->subject, NULL);
- tracker_binding_set_data_type (binding,
TRACKER_PROPERTY_TYPE_RESOURCE);
- tracker_select_context_add_literal_binding (TRACKER_SELECT_CONTEXT
(sparql->context),
- TRACKER_LITERAL_BINDING
(binding));
- }
-
- _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
- }
- }
-
- if (first) {
- /* No match */
- _append_string (sparql,
- "SELECT NULL AS ID, NULL AS \"predicate\", NULL AS \"object\", NULL
AS \"graph\"");
- }
-
- g_free (types);
- } else if (pred_var->object) {
- /* ?s ?p <o> */
- types = lookup_resource_types (sparql, pred_var->object, &n_types, &inner_error);
- if (inner_error) {
- g_propagate_error (error, inner_error);
- return FALSE;
- }
+ TrackerBinding *binding;
- for (i = 0; i < n_types; i++) {
- for (j = 0; j < n_properties; j++) {
- if (types[i] != tracker_property_get_range (properties[j]))
- continue;
+ _append_string (sparql,
+ "SELECT subject AS ID, predicate, object ");
- if (!first)
- _append_string (sparql, "UNION ALL ");
+ if (pred_var->return_graph)
+ _append_string (sparql, ", graph ");
- first = FALSE;
- _append_string_printf (sparql,
- "SELECT ID, (SELECT ID FROM Resource WHERE Uri = '%s')
AS \"predicate\", ",
- tracker_property_get_uri (properties[j]));
-
- str = _append_placeholder (sparql);
- old = tracker_sparql_swap_builder (sparql, str);
- _append_string_printf (sparql, "\"%s\" ", tracker_property_get_name
(properties[j]));
- convert_expression_to_string (sparql, tracker_property_get_data_type
(properties[j]));
- tracker_sparql_swap_builder (sparql, old);
+ _append_string (sparql, "FROM tracker_triples ");
- _append_string (sparql, " AS \"object\" ");
+ if (pred_var->subject || pred_var->object) {
+ _append_string (sparql, "WHERE ");
- if (pred_var->return_graph) {
- _append_string_printf (sparql,
- ", \"%s:graph\" AS \"graph\" ",
- tracker_property_get_name (properties[j]));
- }
+ if (pred_var->subject) {
+ _append_string (sparql, "subject = ");
+ binding = tracker_literal_binding_new (pred_var->subject, NULL);
+ tracker_binding_set_data_type (binding, TRACKER_PROPERTY_TYPE_RESOURCE);
+ tracker_select_context_add_literal_binding (TRACKER_SELECT_CONTEXT (sparql->context),
+ TRACKER_LITERAL_BINDING (binding));
- _append_string_printf (sparql, " FROM \"%s\" ",
- tracker_property_get_table_name (properties[j]));
- }
- }
+ _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
- if (first) {
- /* No match */
- _append_string (sparql,
- "SELECT NULL AS ID, NULL AS \"predicate\", NULL AS \"object\", NULL
AS \"graph\" ");
+ if (pred_var->object)
+ _append_string (sparql, "AND ");
}
- g_free (types);
- } else if (pred_var->domain) {
- /* Any subject, predicates limited to a specific domain */
-
- for (j = 0; j < n_properties; j++) {
- if (pred_var->domain != tracker_property_get_domain (properties[j]))
- continue;
-
- if (!first)
- _append_string (sparql, "UNION ALL ");
-
- first = FALSE;
- _append_string_printf (sparql,
- "SELECT ID, (SELECT ID FROM Resource WHERE Uri = '%s') AS
\"predicate\", ",
- tracker_property_get_uri (properties[j]));
-
- str = _append_placeholder (sparql);
- old = tracker_sparql_swap_builder (sparql, str);
- _append_string_printf (sparql, "\"%s\" ", tracker_property_get_name (properties[j]));
- convert_expression_to_string (sparql, tracker_property_get_data_type (properties[j]));
- tracker_sparql_swap_builder (sparql, old);
-
- _append_string (sparql, " AS \"object\" ");
-
- if (pred_var->return_graph) {
- _append_string_printf (sparql,
- ", \"%s:graph\" AS \"graph\" ",
- tracker_property_get_name (properties[j]));
- }
+ if (pred_var->object) {
+ _append_string (sparql, "object = ");
+ binding = tracker_literal_binding_new (pred_var->object, NULL);
+ tracker_binding_set_data_type (binding, TRACKER_PROPERTY_TYPE_STRING);
+ tracker_select_context_add_literal_binding (TRACKER_SELECT_CONTEXT (sparql->context),
+ TRACKER_LITERAL_BINDING (binding));
- _append_string_printf (sparql, "FROM \"%s\" ",
- tracker_property_get_table_name (properties[j]));
+ _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
}
- } else {
- /* ?s ?p ?o */
- _unimplemented ("Unrestricted predicate variables are not supported");
}
return TRUE;
diff --git a/src/libtracker-data/tracker-vtab-triples.c b/src/libtracker-data/tracker-vtab-triples.c
index 37210a7be..9ff15b628 100644
--- a/src/libtracker-data/tracker-vtab-triples.c
+++ b/src/libtracker-data/tracker-vtab-triples.c
@@ -75,6 +75,7 @@ tracker_triples_module_free (gpointer data)
{
TrackerTriplesModule *module = data;
+ g_clear_object (&module->ontologies);
g_free (module);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]