[tracker/wip/carlosg/unrestricted-predicates: 17/18] 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: 17/18] libtracker-data: Use "tracker_triples" table in variable predicate queries
- Date: Tue, 5 Feb 2019 23:18:38 +0000 (UTC)
commit 5d186707cc42ab4ffa38fe8d3b9365473b9bcae5
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 | 66 +------
src/libtracker-data/tracker-sparql-types.h | 33 +---
src/libtracker-data/tracker-sparql.c | 290 +----------------------------
src/libtracker-data/tracker-vtab-triples.c | 1 +
4 files changed, 11 insertions(+), 379 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index c3c8eae3c..38765cb44 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -56,45 +56,10 @@ tracker_data_table_free (TrackerDataTable *table)
}
void
-tracker_data_table_set_predicate_variable (TrackerDataTable *table,
- TrackerPredicateVariable *variable)
+tracker_data_table_set_predicate_variable (TrackerDataTable *table,
+ gboolean is_variable)
{
- table->predicate_variable = variable;
-}
-
-TrackerPredicateVariable *
-tracker_predicate_variable_new (void)
-{
- return g_new0 (TrackerPredicateVariable, 1);
-}
-
-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,
- const gchar *object,
- gboolean return_graph)
-{
- g_free (pred_var->subject);
- pred_var->subject = g_strdup (subject);
- g_free (pred_var->object);
- pred_var->object = g_strdup (object);
- pred_var->return_graph = !!return_graph;
+ table->predicate_variable = is_variable;
}
static TrackerVariable *
@@ -723,7 +688,6 @@ tracker_select_context_finalize (GObject *object)
TrackerSelectContext *context = TRACKER_SELECT_CONTEXT (object);
g_clear_pointer (&context->variables, g_hash_table_unref);
- g_clear_pointer (&context->predicate_variables, g_hash_table_unref);
g_clear_pointer (&context->generated_variables, g_ptr_array_unref);
g_clear_pointer (&context->literal_bindings, g_ptr_array_unref);
g_clear_pointer (&context->path_elements, g_ptr_array_unref);
@@ -807,30 +771,6 @@ tracker_select_context_add_generated_variable (TrackerSelectContext *context)
return variable;
}
-TrackerPredicateVariable *
-tracker_select_context_lookup_predicate_variable (TrackerSelectContext *context,
- TrackerVariable *variable)
-{
- if (!context->predicate_variables)
- return NULL;
- return g_hash_table_lookup (context->predicate_variables, variable);
-}
-
-void
-tracker_select_context_add_predicate_variable (TrackerSelectContext *context,
- TrackerVariable *variable,
- TrackerPredicateVariable *pred_var)
-{
- if (!context->predicate_variables) {
- context->predicate_variables =
- g_hash_table_new_full (tracker_variable_hash,
- tracker_variable_equal, NULL,
- (GDestroyNotify) tracker_predicate_variable_free);
- }
-
- g_hash_table_insert (context->predicate_variables, variable, pred_var);
-}
-
void
tracker_select_context_add_literal_binding (TrackerSelectContext *context,
TrackerLiteralBinding *binding)
diff --git a/src/libtracker-data/tracker-sparql-types.h b/src/libtracker-data/tracker-sparql-types.h
index bf3484475..a474f5142 100644
--- a/src/libtracker-data/tracker-sparql-types.h
+++ b/src/libtracker-data/tracker-sparql-types.h
@@ -71,13 +71,12 @@ typedef struct _TrackerVariable TrackerVariable;
typedef struct _TrackerToken TrackerToken;
typedef struct _TrackerSolution TrackerSolution;
typedef struct _TrackerPathElement TrackerPathElement;
-typedef struct _TrackerPredicateVariable TrackerPredicateVariable;
struct _TrackerDataTable {
gchar *subject; /* Subject this table is pulled from */
gchar *sql_db_tablename; /* as in db schema */
gchar *sql_query_tablename; /* temp. name, generated */
- TrackerPredicateVariable *predicate_variable;
+ gboolean predicate_variable;
};
struct _TrackerBinding {
@@ -140,14 +139,6 @@ struct _TrackerToken {
} content;
};
-struct _TrackerPredicateVariable {
- gchar *subject;
- gchar *object;
- TrackerClass *domain;
-
- guint return_graph : 1;
-};
-
struct _TrackerSolution {
GPtrArray *columns;
GPtrArray *values;
@@ -197,9 +188,6 @@ struct _TrackerContextClass {
struct _TrackerSelectContext {
TrackerContext parent_instance;
- /* Variables used as predicates */
- GHashTable *predicate_variables; /* TrackerVariable -> TrackerPredicateVariable */
-
/* All variables declared from this context. All these TrackerVariables
* are shared with children contexts. Only the root context has contents
* here.
@@ -246,8 +234,8 @@ struct _TrackerTripleContextClass {
};
/* Data table */
-void tracker_data_table_set_predicate_variable (TrackerDataTable *table,
- TrackerPredicateVariable *variable);
+void tracker_data_table_set_predicate_variable (TrackerDataTable *table,
+ gboolean is_variable);
/* Binding */
GType tracker_binding_get_type (void) G_GNUC_CONST;
@@ -316,16 +304,6 @@ const gchar * tracker_token_get_idstring (TrackerToken *token);
const gchar * tracker_token_get_parameter (TrackerToken *token);
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,
- gboolean return_graph);
-
/* Solution */
TrackerSolution * tracker_solution_new (guint n_cols);
void tracker_solution_free (TrackerSolution *solution);
@@ -366,11 +344,6 @@ TrackerVariable * tracker_select_context_ensure_variable (TrackerSelectContext *
const gchar *name);
TrackerVariable * tracker_select_context_add_generated_variable (TrackerSelectContext *context);
-TrackerPredicateVariable * tracker_select_context_lookup_predicate_variable (TrackerSelectContext *context,
- TrackerVariable *variable);
-void tracker_select_context_add_predicate_variable (TrackerSelectContext *context,
- TrackerVariable *variable,
- TrackerPredicateVariable *pred_var);
void tracker_select_context_add_literal_binding (TrackerSelectContext *context,
TrackerLiteralBinding *binding);
guint tracker_select_context_get_literal_binding_index (TrackerSelectContext *context,
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index d123c6330..5d47c7fb1 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -1015,7 +1015,6 @@ _add_quad (TrackerSparql *sparql,
TrackerToken *object,
GError **error)
{
- TrackerSelectContext *select_context;
TrackerTripleContext *triple_context;
TrackerOntologies *ontologies;
TrackerDataTable *table = NULL;
@@ -1025,7 +1024,6 @@ _add_quad (TrackerSparql *sparql,
TrackerClass *subject_type = NULL;
gboolean new_table = FALSE, is_fts = FALSE, is_rdf_type = FALSE;
- select_context = TRACKER_SELECT_CONTEXT (sparql->current_state.select_context);
triple_context = TRACKER_TRIPLE_CONTEXT (sparql->current_state.context);
ontologies = tracker_data_manager_get_ontologies (sparql->data_manager);
@@ -1063,35 +1061,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 */
@@ -1149,39 +1118,19 @@ _add_quad (TrackerSparql *sparql,
new_table = TRUE;
}
} else if (tracker_token_get_variable (predicate)) {
- TrackerPredicateVariable *pred_var;
-
/* Variable in predicate */
variable = tracker_token_get_variable (predicate);
table = tracker_triple_context_add_table (triple_context,
variable->name, variable->name);
+ tracker_data_table_set_predicate_variable (table, TRUE);
new_table = TRUE;
- pred_var = tracker_select_context_lookup_predicate_variable (select_context,
- variable);
- if (!pred_var) {
- pred_var = tracker_predicate_variable_new ();
- tracker_predicate_variable_set_triple_details (pred_var,
- tracker_token_get_literal (subject),
- tracker_token_get_literal (object),
- !tracker_token_is_empty (graph));
-
- tracker_select_context_add_predicate_variable (select_context,
- variable,
- pred_var);
- }
-
- tracker_data_table_set_predicate_variable (table, pred_var);
-
/* Add to binding list */
binding = tracker_variable_binding_new (variable, NULL, table);
tracker_binding_set_data_type (binding, TRACKER_PROPERTY_TYPE_RESOURCE);
tracker_binding_set_db_column_name (binding, "predicate");
_add_binding (sparql, binding);
g_object_unref (binding);
-
- if (!tracker_token_is_empty (graph))
- pred_var->return_graph = TRUE;
} else if (tracker_token_get_path (predicate)) {
table = tracker_triple_context_add_table (triple_context,
"value",
@@ -1445,232 +1394,6 @@ 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;
- }
-
- for (i = 0; i < n_types; i++) {
- for (j = 0; j < n_properties; j++) {
- if (types[i] != tracker_property_get_range (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\" ",
- tracker_property_get_table_name (properties[j]));
- }
- }
-
- 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->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]));
- }
-
- _append_string_printf (sparql, "FROM \"%s\" ",
- tracker_property_get_table_name (properties[j]));
- }
- } else {
- /* ?s ?p ?o */
- _unimplemented ("Unrestricted predicate variables are not supported");
- }
-
- return TRUE;
-}
-
static TrackerContext *
_begin_triples_block (TrackerSparql *sparql)
{
@@ -1741,14 +1464,9 @@ _end_triples_block (TrackerSparql *sparql,
_append_string (sparql, ", ");
if (table->predicate_variable) {
- _append_string (sparql, "(");
-
- if (!append_predicate_variable_query (sparql,
- table->predicate_variable,
- error))
- return FALSE;
-
- _append_string (sparql, ") ");
+ _append_string (sparql,
+ "(SELECT subject AS ID, predicate, "
+ "object, graph FROM tracker_triples) ");
} else {
_append_string_printf (sparql, "\"%s\" ", table->sql_db_tablename);
}
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]