[tracker/fts4: 12/26] libtracker-data: Perform FTS matching in subquery
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/fts4: 12/26] libtracker-data: Perform FTS matching in subquery
- Date: Tue, 5 Feb 2013 16:55:05 +0000 (UTC)
commit 3a3f780108836ae7a7f9c3e854c5fa995e17e352
Author: Carlos Garnacho <carlos lanedo com>
Date: Thu Dec 1 13:47:21 2011 +0100
libtracker-data: Perform FTS matching in subquery
The outer query will call the functions that require a full row
scan only with the elements returned by the inner query, so
it would perform better with OFFSET and LIMIT
src/libtracker-data/tracker-sparql-expression.vala | 3 +-
src/libtracker-data/tracker-sparql-pattern.vala | 46 +++++++++++++++----
2 files changed, 38 insertions(+), 11 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-expression.vala b/src/libtracker-data/tracker-sparql-expression.vala
index 668f03d..2dfa532 100644
--- a/src/libtracker-data/tracker-sparql-expression.vala
+++ b/src/libtracker-data/tracker-sparql-expression.vala
@@ -647,7 +647,8 @@ class Tracker.Sparql.Expression : Object {
} else if (uri == FTS_NS + "offsets") {
bool is_var;
string v = pattern.parse_var_or_term (null, out is_var);
- sql.append_printf ("\"%s_u_offsets\"", v);
+
+ sql.append ("tracker_offsets(offsets(\"fts\"),fts_property_names())");
return PropertyType.STRING;
} else if (uri == TRACKER_NS + "id") {
diff --git a/src/libtracker-data/tracker-sparql-pattern.vala b/src/libtracker-data/tracker-sparql-pattern.vala
index 76dcce0..93dc166 100644
--- a/src/libtracker-data/tracker-sparql-pattern.vala
+++ b/src/libtracker-data/tracker-sparql-pattern.vala
@@ -170,6 +170,8 @@ class Tracker.Sparql.Pattern : Object {
string current_predicate;
bool current_predicate_is_var;
+ internal StringBuilder? match_str;
+
public Pattern (Query query) {
this.query = query;
this.expression = query.expression;
@@ -239,6 +241,8 @@ class Tracker.Sparql.Pattern : Object {
internal SelectContext translate_select (StringBuilder sql, bool subquery = false, bool scalar_subquery = false) throws Sparql.Error {
SelectContext result;
+ bool has_fts_match = false;
+
if (scalar_subquery) {
result = new SelectContext.subquery (query, context);
} else {
@@ -250,6 +254,8 @@ class Tracker.Sparql.Pattern : Object {
var pattern_sql = new StringBuilder ();
var old_bindings = (owned) query.bindings;
+ match_str = new StringBuilder ();
+
sql.append ("SELECT ");
expect (SparqlTokenType.SELECT);
@@ -283,6 +289,8 @@ class Tracker.Sparql.Pattern : Object {
foreach (var variable in context.var_set.get_keys ()) {
if (variable.binding == null) {
throw get_error ("use of undefined variable `%s'".printf (variable.name));
+ } else if (variable.binding.table.sql_db_tablename == "fts") {
+ has_fts_match = true;
}
}
@@ -345,9 +353,20 @@ class Tracker.Sparql.Pattern : Object {
}
// select from results of WHERE clause
- sql.append (" FROM (");
- sql.append (pattern_sql.str);
- sql.append (")");
+
+ if (has_fts_match) {
+ sql.append (" FROM fts JOIN (");
+ sql.append (pattern_sql.str);
+
+ /* Leave parenthesis opened,
+ * "group/limit/offset goes in
+ * the inner query
+ */
+ } else {
+ sql.append (" FROM (");
+ sql.append (pattern_sql.str);
+ sql.append (")");
+ }
set_location (after_where);
@@ -429,9 +448,14 @@ class Tracker.Sparql.Pattern : Object {
query.bindings.append (binding);
}
+ if (has_fts_match) {
+ sql.append (") AS ranks USING (docid)");
+ sql.append_printf (" WHERE fts %s", match_str.str);
+ }
context = context.parent_context;
result.type = type;
+ match_str = null;
return result;
}
@@ -730,6 +754,10 @@ class Tracker.Sparql.Pattern : Object {
// parameters do not work with fts MATCH
string escaped_literal = string.joinv ("''", binding.literal.split ("'"));
sql.append_printf (" MATCH '%s'", escaped_literal);
+
+ if (match_str != null) {
+ match_str.append_printf (" MATCH '%s'", escaped_literal);
+ }
} else {
sql.append (" = ");
if (binding.data_type == PropertyType.RESOURCE) {
@@ -1470,14 +1498,12 @@ class Tracker.Sparql.Pattern : Object {
binding.sql_db_column_name = "fts";
triple_context.bindings.append (binding);
+ sql.append_printf ("\"%s\".\"docid\", ",
+ binding.table.sql_query_tablename);
sql.append_printf ("tracker_rank(matchinfo(\"%s\".\"fts\", 'cl'),fts_column_weights()) " +
- "AS \"%s_u_rank\", ",
- binding.table.sql_query_tablename,
- context.get_variable (current_subject).name);
- sql.append_printf ("tracker_offsets(offsets(\"%s\".\"fts\"),fts_property_names()) " +
- "AS \"%s_u_offsets\", ",
- binding.table.sql_query_tablename,
- context.get_variable (current_subject).name);
+ "AS \"%s_u_rank\", ",
+ binding.table.sql_query_tablename,
+ context.get_variable (current_subject).name);
} else {
var binding = new LiteralBinding ();
binding.literal = object;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]