[tracker/wip/carlosg/sparql1.1: 6/56] libtracker-data: Use single column for times/dates



commit 9a875c6e5b18644038424da0e61a58af5ff7e03b
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sun Mar 3 21:44:18 2019 +0100

    libtracker-data: Use single column for times/dates
    
    Instead of having it split across 3 columns, use a single time column
    that can either store int64 timestamps (if conversion is lossless) or
    ISO8601 time strings.

 src/libtracker-data/tracker-data-manager.c        | 149 +++++++---------------
 src/libtracker-data/tracker-data-update.c         |  43 +++----
 src/libtracker-data/tracker-db-interface-sqlite.c |  14 +-
 src/libtracker-data/tracker-sparql.c              |  72 +++--------
 4 files changed, 86 insertions(+), 192 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index cce5e3610..a5ccb9196 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -218,6 +218,7 @@ set_index_for_single_value_property (TrackerDBInterface  *iface,
                                      const gchar         *service_name,
                                      const gchar         *field_name,
                                      gboolean             enabled,
+                                     gboolean             datetime,
                                      GError             **error)
 {
        GError *internal_error = NULL;
@@ -237,16 +238,24 @@ set_index_for_single_value_property (TrackerDBInterface  *iface,
        }
 
        if (enabled) {
+               gchar *expr;
+
+               if (datetime)
+                       expr = g_strdup_printf ("SparqlTimeSort(\"%s\")", field_name);
+               else
+                       expr = g_strdup_printf ("\"%s\"", field_name);
+
                g_debug ("Creating index (single-value property): "
-                        "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
-                        service_name, field_name, service_name, field_name);
+                        "CREATE INDEX \"%s_%s\" ON \"%s\" (%s)",
+                        service_name, field_name, service_name, expr);
 
                tracker_db_interface_execute_query (iface, &internal_error,
-                                                   "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
+                                                   "CREATE INDEX \"%s_%s\" ON \"%s\" (%s)",
                                                    service_name,
                                                    field_name,
                                                    service_name,
-                                                   field_name);
+                                                   expr);
+               g_free (expr);
 
                if (internal_error) {
                        g_propagate_error (error, internal_error);
@@ -260,9 +269,11 @@ set_index_for_multi_value_property (TrackerDBInterface  *iface,
                                     const gchar         *field_name,
                                     gboolean             enabled,
                                     gboolean             recreate,
+                                    gboolean             datetime,
                                     GError             **error)
 {
        GError *internal_error = NULL;
+       gchar *expr;
 
        g_debug ("Dropping index (multi-value property): "
                 "DROP INDEX IF EXISTS \"%s_%s_ID_ID\"",
@@ -299,6 +310,11 @@ set_index_for_multi_value_property (TrackerDBInterface  *iface,
                return;
        }
 
+       if (datetime)
+               expr = g_strdup_printf ("SparqlTimeSort(\"%s\")", field_name);
+       else
+               expr = g_strdup_printf ("\"%s\"", field_name);
+
        if (enabled) {
                g_debug ("Creating index (multi-value property): "
                         "CREATE INDEX \"%s_%s_ID\" ON \"%s_%s\" (ID)",
@@ -320,20 +336,20 @@ set_index_for_multi_value_property (TrackerDBInterface  *iface,
                }
 
                g_debug ("Creating index (multi-value property): "
-                        "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (\"%s\", ID)",
+                        "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (%s, ID)",
                         service_name,
                         field_name,
                         service_name,
                         field_name,
-                        field_name);
+                        expr);
 
                tracker_db_interface_execute_query (iface, &internal_error,
-                                                   "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" 
(\"%s\", ID)",
+                                                   "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (%s, 
ID)",
                                                    service_name,
                                                    field_name,
                                                    service_name,
                                                    field_name,
-                                                   field_name);
+                                                   expr);
 
                if (internal_error) {
                        g_propagate_error (error, internal_error);
@@ -341,25 +357,27 @@ set_index_for_multi_value_property (TrackerDBInterface  *iface,
                }
        } else {
                g_debug ("Creating index (multi-value property): "
-                        "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, \"%s\")",
+                        "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, %s)",
                         service_name,
                         field_name,
                         service_name,
                         field_name,
-                        field_name);
+                        expr);
 
                tracker_db_interface_execute_query (iface, &internal_error,
-                                                   "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, 
\"%s\")",
+                                                   "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, 
%s)",
                                                    service_name,
                                                    field_name,
                                                    service_name,
                                                    field_name,
-                                                   field_name);
+                                                   expr);
 
                if (internal_error) {
                        g_propagate_error (error, internal_error);
                }
        }
+
+       g_free (expr);
 }
 
 static gboolean
@@ -573,17 +591,20 @@ fix_indexed (TrackerDataManager  *manager,
        TrackerClass *class;
        const gchar *service_name;
        const gchar *field_name;
+       gboolean datetime;
 
        iface = tracker_db_manager_get_writable_db_interface (manager->db_manager);
 
        class = tracker_property_get_domain (property);
        field_name = tracker_property_get_name (property);
        service_name = tracker_class_get_name (class);
+       datetime = tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME;
 
        if (tracker_property_get_multiple_values (property)) {
                set_index_for_multi_value_property (iface, service_name, field_name,
                                                    tracker_property_get_indexed (property),
                                                    recreate,
+                                                   datetime,
                                                    &internal_error);
        } else {
                TrackerProperty *secondary_index;
@@ -593,6 +614,7 @@ fix_indexed (TrackerDataManager  *manager,
                if (secondary_index == NULL) {
                        set_index_for_single_value_property (iface, service_name, field_name,
                                                             recreate && tracker_property_get_indexed 
(property),
+                                                            datetime,
                                                             &internal_error);
                } else {
                        set_secondary_index_for_single_value_property (iface, service_name, field_name,
@@ -608,6 +630,7 @@ fix_indexed (TrackerDataManager  *manager,
                                                             tracker_class_get_name (*domain_index_classes),
                                                             field_name,
                                                             recreate,
+                                                            datetime,
                                                             &internal_error);
                        domain_index_classes++;
                }
@@ -2531,15 +2554,6 @@ range_change_for (TrackerProperty *property,
 
                g_string_append_printf (sel_col_sql, ", \"%s\", \"%s:graph\"",
                                        field_name, field_name);
-
-               g_string_append_printf (in_col_sql, ", \"%s:localDate\", \"%s:localTime\"",
-                                       tracker_property_get_name (property),
-                                       tracker_property_get_name (property));
-
-               g_string_append_printf (sel_col_sql, ", \"%s:localDate\", \"%s:localTime\"",
-                                       tracker_property_get_name (property),
-                                       tracker_property_get_name (property));
-
        } else if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_BOOLEAN) {
                g_string_append_printf (sel_col_sql, ", \"%s\" != 0, \"%s:graph\"",
                                        field_name, field_name);
@@ -2562,7 +2576,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
        GError *internal_error = NULL;
        const char *field_name;
        const char *sql_type;
-       gboolean    not_single;
+       gboolean    not_single, datetime;
 
        field_name = tracker_property_get_name (property);
 
@@ -2587,6 +2601,8 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                break;
        }
 
+       datetime = tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME;
+
        if (!in_update || (in_update && (tracker_property_get_is_new (property) ||
                                         tracker_property_get_is_new_domain_index (property, service) ||
                                         tracker_property_get_cardinality_changed (property) ||
@@ -2652,16 +2668,6 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                                range_change_for (property, in_col_sql, sel_col_sql, field_name);
                        }
 
-                       if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME) {
-                               /* xsd:dateTime is stored in three columns:
-                                * universal time, local date, local time of day */
-                               g_string_append_printf (sql,
-                                                       ", \"%s:localDate\" INTEGER NOT NULL"
-                                                       ", \"%s:localTime\" INTEGER NOT NULL",
-                                                       tracker_property_get_name (property),
-                                                       tracker_property_get_name (property));
-                       }
-
                        tracker_db_interface_execute_query (iface, &internal_error,
                                                            "%s)", sql->str);
 
@@ -2675,6 +2681,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                                /* use different UNIQUE index for properties whose
                                 * value should be indexed to minimize index size */
                                set_index_for_multi_value_property (iface, service_name, field_name, TRUE, 
TRUE,
+                                                                   datetime,
                                                                    &internal_error);
                                if (internal_error) {
                                        g_propagate_error (error, internal_error);
@@ -2682,6 +2689,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                                }
                        } else {
                                set_index_for_multi_value_property (iface, service_name, field_name, FALSE, 
TRUE,
+                                                                   datetime,
                                                                    &internal_error);
                                /* we still have to include the property value in
                                 * the unique index for proper constraints */
@@ -2723,6 +2731,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                                /* use different UNIQUE index for properties whose
                                 * value should be indexed to minimize index size */
                                set_index_for_multi_value_property (iface, service_name, field_name, TRUE, 
TRUE,
+                                                                   datetime,
                                                                    &internal_error);
                                if (internal_error) {
                                        g_propagate_error (error, internal_error);
@@ -2730,6 +2739,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                                }
                        } else {
                                set_index_for_multi_value_property (iface, service_name, field_name, FALSE, 
TRUE,
+                                                                   datetime,
                                                                    &internal_error);
                                if (internal_error) {
                                        g_propagate_error (error, internal_error);
@@ -3067,10 +3077,11 @@ create_decomposed_metadata_tables (TrackerDataManager  *manager,
        domain_indexes = tracker_class_get_domain_indexes (service);
 
        for (i = 0; i < n_props; i++) {
-               gboolean is_domain_index;
+               gboolean is_domain_index, datetime;
 
                property = properties[i];
                is_domain_index = is_a_domain_index (domain_indexes, property);
+               datetime = tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME;
 
                if (tracker_property_get_domain (property) == service || is_domain_index) {
                        gboolean put_change;
@@ -3143,21 +3154,6 @@ create_decomposed_metadata_tables (TrackerDataManager  *manager,
                                        if (is_domain_index && tracker_property_get_is_new_domain_index 
(property, service)) {
                                                schedule_copy (copy_schedule, property, field_name, ":graph");
                                        }
-
-                                       if (tracker_property_get_data_type (property) == 
TRACKER_PROPERTY_TYPE_DATETIME) {
-                                               /* xsd:dateTime is stored in three columns:
-                                                * universal time, local date, local time of day */
-                                               g_string_append_printf (create_sql, ", \"%s:localDate\" 
INTEGER, \"%s:localTime\" INTEGER",
-                                                                       tracker_property_get_name (property),
-                                                                       tracker_property_get_name (property));
-
-                                               if (is_domain_index && 
tracker_property_get_is_new_domain_index (property, service)) {
-                                                       schedule_copy (copy_schedule, property, field_name, 
":localTime");
-                                                       schedule_copy (copy_schedule, property, field_name, 
":localDate");
-                                               }
-
-                                       }
-
                                } else if ((!is_domain_index && tracker_property_get_is_new (property)) ||
                                           (is_domain_index && tracker_property_get_is_new_domain_index 
(property, service))) {
                                        GString *alter_sql = NULL;
@@ -3205,6 +3201,7 @@ create_decomposed_metadata_tables (TrackerDataManager  *manager,
                                                /* This is implicit for all domain-specific-indices */
                                                set_index_for_single_value_property (iface, service_name,
                                                                                     field_name, TRUE,
+                                                                                    datetime,
                                                                                     &internal_error);
                                                if (internal_error) {
                                                        g_string_free (alter_sql, TRUE);
@@ -3239,58 +3236,6 @@ create_decomposed_metadata_tables (TrackerDataManager  *manager,
                                        }
 
                                        g_string_free (alter_sql, TRUE);
-
-                                       if (tracker_property_get_data_type (property) == 
TRACKER_PROPERTY_TYPE_DATETIME) {
-                                               alter_sql = g_string_new ("ALTER TABLE ");
-                                               g_string_append_printf (alter_sql, "\"%s\" ADD COLUMN 
\"%s:localDate\" INTEGER",
-                                                                       service_name,
-                                                                       field_name);
-                                               g_debug ("Altering: '%s'", alter_sql->str);
-                                               tracker_db_interface_execute_query (iface, &internal_error,
-                                                                                   "%s", alter_sql->str);
-
-                                               if (internal_error) {
-                                                       g_string_free (alter_sql, TRUE);
-                                                       g_propagate_error (error, internal_error);
-                                                       goto error_out;
-                                               } else if (is_domain_index) {
-                                                       copy_from_domain_to_domain_index (iface, property,
-                                                                                         field_name, 
":localDate",
-                                                                                         service,
-                                                                                         &internal_error);
-                                                       if (internal_error) {
-                                                               g_string_free (alter_sql, TRUE);
-                                                               g_propagate_error (error, internal_error);
-                                                               goto error_out;
-                                                       }
-                                               }
-
-                                               g_string_free (alter_sql, TRUE);
-
-                                               alter_sql = g_string_new ("ALTER TABLE ");
-                                               g_string_append_printf (alter_sql, "\"%s\" ADD COLUMN 
\"%s:localTime\" INTEGER",
-                                                                       service_name,
-                                                                       field_name);
-                                               g_debug ("Altering: '%s'", alter_sql->str);
-                                               tracker_db_interface_execute_query (iface, &internal_error,
-                                                                                   "%s", alter_sql->str);
-                                               if (internal_error) {
-                                                       g_string_free (alter_sql, TRUE);
-                                                       g_propagate_error (error, internal_error);
-                                                       goto error_out;
-                                               } else if (is_domain_index) {
-                                                       copy_from_domain_to_domain_index (iface, property,
-                                                                                         field_name, 
":localTime",
-                                                                                         service,
-                                                                                         &internal_error);
-                                                       if (internal_error) {
-                                                               g_string_free (alter_sql, TRUE);
-                                                               g_propagate_error (error, internal_error);
-                                                               goto error_out;
-                                                       }
-                                               }
-                                               g_string_free (alter_sql, TRUE);
-                                       }
                                } else {
                                        put_change = TRUE;
                                }
@@ -3317,7 +3262,7 @@ create_decomposed_metadata_tables (TrackerDataManager  *manager,
        for (field_it = class_properties; field_it != NULL; field_it = field_it->next) {
                TrackerProperty *field, *secondary_index;
                const char *field_name;
-               gboolean is_domain_index;
+               gboolean is_domain_index, datetime;
 
                field = field_it->data;
 
@@ -3328,11 +3273,13 @@ create_decomposed_metadata_tables (TrackerDataManager  *manager,
                    && (tracker_property_get_indexed (field) || is_domain_index)) {
 
                        field_name = tracker_property_get_name (field);
+                       datetime = tracker_property_get_data_type (field) == TRACKER_PROPERTY_TYPE_DATETIME;
 
                        secondary_index = tracker_property_get_secondary_index (field);
                        if (secondary_index == NULL) {
                                set_index_for_single_value_property (iface, service_name,
                                                                     field_name, TRUE,
+                                                                    datetime,
                                                                     &internal_error);
                                if (internal_error) {
                                        g_propagate_error (error, internal_error);
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 60bdfe07b..1fcc29584 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -789,9 +789,21 @@ statement_bind_gvalue (TrackerDBStatement *stmt,
                break;
        default:
                if (type == TRACKER_TYPE_DATE_TIME) {
-                       tracker_db_statement_bind_double (stmt, (*idx)++, tracker_date_time_get_time (value));
-                       tracker_db_statement_bind_int (stmt, (*idx)++, tracker_date_time_get_local_date 
(value));
-                       tracker_db_statement_bind_int (stmt, (*idx)++, tracker_date_time_get_local_time 
(value));
+                       gdouble time = tracker_date_time_get_time (value);
+                       int offset = tracker_date_time_get_offset (value);
+
+                       /* If we have anything that prevents a unix timestamp to be
+                        * lossless, we use the ISO8601 string.
+                        */
+                       if (offset != 0 || floor (time) != time) {
+                               gchar *str;
+
+                               str = tracker_date_to_string (time, offset);
+                               tracker_db_statement_bind_text (stmt, (*idx)++, str);
+                               g_free (str);
+                       } else {
+                               tracker_db_statement_bind_int (stmt, (*idx)++, round (time));
+                       }
                } else {
                        g_warning ("Unknown type for binding: %s\n", G_VALUE_TYPE_NAME (value));
                }
@@ -845,14 +857,6 @@ tracker_data_resource_buffer_flush (TrackerData  *data,
                                                                                      "DELETE FROM \"%s\" 
WHERE ID = ? AND \"%s\" = ?",
                                                                                      table_name,
                                                                                      property->name);
-                               } else if (property->date_time) {
-                                       stmt = tracker_db_interface_create_statement (iface, 
TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error,
-                                                                                     "INSERT OR IGNORE INTO 
\"%s\" (ID, \"%s\", \"%s:localDate\", \"%s:localTime\", \"%s:graph\") VALUES (?, ?, ?, ?, ?)",
-                                                                                     table_name,
-                                                                                     property->name,
-                                                                                     property->name,
-                                                                                     property->name,
-                                                                                     property->name);
                                } else {
                                        stmt = tracker_db_interface_create_statement (iface, 
TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error,
                                                                                      "INSERT OR IGNORE INTO 
\"%s\" (ID, \"%s\", \"%s:graph\") VALUES (?, ?, ?)",
@@ -955,12 +959,6 @@ tracker_data_resource_buffer_flush (TrackerData  *data,
                                        g_string_append_printf (sql, ", \"%s\"", property->name);
                                        g_string_append (values_sql, ", ?");
 
-                                       if (property->date_time) {
-                                               g_string_append_printf (sql, ", \"%s:localDate\"", 
property->name);
-                                               g_string_append_printf (sql, ", \"%s:localTime\"", 
property->name);
-                                               g_string_append (values_sql, ", ?, ?");
-                                       }
-
                                        g_string_append_printf (sql, ", \"%s:graph\"", property->name);
                                        g_string_append (values_sql, ", ?");
                                } else {
@@ -968,12 +966,6 @@ tracker_data_resource_buffer_flush (TrackerData  *data,
                                                g_string_append (sql, ", ");
                                        }
                                        g_string_append_printf (sql, "\"%s\" = ?", property->name);
-
-                                       if (property->date_time) {
-                                               g_string_append_printf (sql, ", \"%s:localDate\" = ?", 
property->name);
-                                               g_string_append_printf (sql, ", \"%s:localTime\" = ?", 
property->name);
-                                       }
-
                                        g_string_append_printf (sql, ", \"%s:graph\" = ?", property->name);
                                }
                        }
@@ -1019,11 +1011,6 @@ tracker_data_resource_buffer_flush (TrackerData  *data,
                                if (table->delete_value) {
                                        /* just set value to NULL for single value properties */
                                        tracker_db_statement_bind_null (stmt, param++);
-                                       if (property->date_time) {
-                                               /* also set localDate and localTime to NULL */
-                                               tracker_db_statement_bind_null (stmt, param++);
-                                               tracker_db_statement_bind_null (stmt, param++);
-                                       }
                                } else {
                                        statement_bind_gvalue (stmt, &param, &property->value);
                                }
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c 
b/src/libtracker-data/tracker-db-interface-sqlite.c
index 8baddb26a..d253df52d 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -492,16 +492,12 @@ function_sparql_time_sort (sqlite3_context *context,
        if (sqlite3_value_type (argv[0]) == SQLITE_NULL) {
                sqlite3_result_null (context);
                return;
-       } else if (sqlite3_value_numeric_type (argv[0]) == SQLITE_INTEGER) {
-               gint64 value;
-
-               value = sqlite3_value_int64 (argv[0]);
-               sort_key = value * G_USEC_PER_SEC;
+       } else if (sqlite3_value_numeric_type (argv[0]) == SQLITE_INTEGER ||
+                  sqlite3_value_numeric_type (argv[0]) == SQLITE_FLOAT) {
+               gdouble value;
 
-               if (sort_key < value) {
-                       sqlite3_result_error (context, "Invalid integer argument value", -1);
-                       return;
-               }
+               value = sqlite3_value_double (argv[0]);
+               sort_key = (gint64) (value * G_USEC_PER_SEC);
        } else if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) {
                const gchar *value;
                gdouble time;
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index e36d2341e..347960e53 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -514,25 +514,8 @@ static void
 _append_variable_sql (TrackerSparql   *sparql,
                       TrackerVariable *variable)
 {
-       TrackerBinding *binding;
-
-       binding = TRACKER_BINDING (tracker_variable_get_sample_binding (variable));
-
-       if (binding &&
-           binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME) {
-               TrackerVariable *local_time;
-               gchar *name;
-
-               name = g_strdup_printf ("%s:local", variable->name);
-               local_time = _ensure_variable (sparql, name);
-               g_free (name);
-
-               _append_string_printf (sparql, "%s ",
-                                      tracker_variable_get_sql_expression (local_time));
-       } else {
-               _append_string_printf (sparql, "%s ",
-                                      tracker_variable_get_sql_expression (variable));
-       }
+       _append_string_printf (sparql, "%s ",
+                              tracker_variable_get_sql_expression (variable));
 }
 
 static void
@@ -1200,31 +1183,6 @@ _add_quad (TrackerSparql  *sparql,
                                 */
                                tracker_variable_binding_set_nullable (TRACKER_VARIABLE_BINDING (binding), 
TRUE);
                        }
-
-                       if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME) {
-                               gchar *date_var, *sql_expression, *local_date, *local_time;
-                               TrackerBinding *local_time_binding;
-
-                               /* Merge localDate/localTime into $var:local */
-                               date_var = g_strdup_printf ("%s:local", variable->name);
-                               variable = _ensure_variable (sparql, date_var);
-
-                               local_date = tracker_binding_get_extra_sql_expression (binding, "localDate");
-                               local_time = tracker_binding_get_extra_sql_expression (binding, "localTime");
-                               sql_expression = g_strdup_printf ("((%s * 24 * 3600) + %s)",
-                                                                 local_date, local_time);
-
-                               local_time_binding = tracker_variable_binding_new (variable, NULL, NULL);
-                               tracker_binding_set_sql_expression (local_time_binding,
-                                                                   sql_expression);
-                               _add_binding (sparql, local_time_binding);
-                               g_object_unref (local_time_binding);
-
-                               g_free (sql_expression);
-                               g_free (local_date);
-                               g_free (local_time);
-                               g_free (date_var);
-                       }
                }
 
                _add_binding (sparql, binding);
@@ -1386,8 +1344,8 @@ convert_expression_to_string (TrackerSparql       *sparql,
                break;
        case TRACKER_PROPERTY_TYPE_DATE:
                /* ISO 8601 format */
-               _prepend_string (sparql, "strftime (\"%Y-%m-%d\", ");
-               _append_string (sparql, ", \"unixepoch\") ");
+               _prepend_string (sparql, "strftime (\"%Y-%m-%d\", SparqlTimestamp (");
+               _append_string (sparql, "), \"unixepoch\") ");
                break;
        case TRACKER_PROPERTY_TYPE_DATETIME:
                /* ISO 8601 format */
@@ -1562,8 +1520,14 @@ _end_triples_block (TrackerSparql  *sparql,
 
                first = FALSE;
                binding = g_ptr_array_index (triple_context->literal_bindings, i);
-               _append_string_printf (sparql, "%s = ", tracker_binding_get_sql_expression (binding));
-               _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+               if (binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME) {
+                       _append_string_printf (sparql, "SparqlTimeSort (%s) = SparqlTimeSort (", 
tracker_binding_get_sql_expression (binding));
+                       _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+                       _append_string (sparql, ") ");
+               } else {
+                       _append_string_printf (sparql, "%s = ", tracker_binding_get_sql_expression (binding));
+                       _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+               }
        }
 
        /* If we had any where clauses, prepend the 'WHERE' literal */
@@ -5380,12 +5344,12 @@ helper_translate_date (TrackerSparql  *sparql,
                        GError        **error)
 {
        _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
-       _append_string_printf (sparql, "strftime (\"%s\", ", format);
+       _append_string_printf (sparql, "strftime (\"%s\", SparqlTimestamp (", format);
 
        _call_rule (sparql, NAMED_RULE_Expression, error);
 
        _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
-       _append_string (sparql, ", \"unixepoch\") ");
+       _append_string (sparql, "), \"unixepoch\") ");
 
        return TRUE;
 }
@@ -5395,20 +5359,20 @@ helper_translate_time (TrackerSparql  *sparql,
                        guint           format,
                        GError        **error)
 {
+       _append_string (sparql, "CAST (SparqlTimestamp (");
        _expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
        _call_rule (sparql, NAMED_RULE_Expression, error);
-
        _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
 
        switch (format) {
        case TIME_FORMAT_SECONDS:
-               _append_string (sparql, " % 60 ");
+               _append_string (sparql, ") AS INTEGER) % 60 ");
                break;
        case TIME_FORMAT_MINUTES:
-               _append_string (sparql, " / 60 % 60 ");
+               _append_string (sparql, ") AS INTEGER) / 60 % 60 ");
                break;
        case TIME_FORMAT_HOURS:
-               _append_string (sparql, " / 3600 % 24 ");
+               _append_string (sparql, ") AS INTEGER) / 3600 % 24 ");
                break;
        default:
                g_assert_not_reached ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]