[tracker/collation: 7/9] sparql: New 'COLLATE' keyword supported in 'ORDER BY'
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/collation: 7/9] sparql: New 'COLLATE' keyword supported in 'ORDER BY'
- Date: Wed, 18 Aug 2010 08:55:06 +0000 (UTC)
commit 4327a630aeffc17fc68e57fc0d913e416dc62df1
Author: Aleksander Morgado <aleksander lanedo com>
Date: Tue Aug 17 13:47:20 2010 +0200
sparql: New 'COLLATE' keyword supported in 'ORDER BY'
src/libtracker-data/tracker-collation.c | 48 +++++++++++++++++--
src/libtracker-data/tracker-sparql-expression.vala | 7 ++-
src/libtracker-data/tracker-sparql-pattern.vala | 12 ++++-
src/libtracker-data/tracker-sparql-scanner.vala | 6 +++
4 files changed, 62 insertions(+), 11 deletions(-)
---
diff --git a/src/libtracker-data/tracker-collation.c b/src/libtracker-data/tracker-collation.c
index e12007e..af04315 100644
--- a/src/libtracker-data/tracker-collation.c
+++ b/src/libtracker-data/tracker-collation.c
@@ -19,14 +19,15 @@
#include "config.h"
#include <glib.h>
+#include <string.h>
#include "tracker-collation.h"
/* If defined, will dump some additional logs as prints,
* instead of debugs*/
-#define G_INSTEADOF_LOG 1
+#define PRINT_INSTEADOF_LOG 0
-#ifdef G_INSTEADOF_LOG
+#ifdef PRINT_INSTEADOF_LOG
#undef g_debug
#define g_debug(message, ...) \
g_print ("(debug) %s:%d: " message "\n", \
@@ -39,7 +40,7 @@
#define g_critical(message, ...) \
g_print ("(critical) %s:%d: " message "\n", \
__FILE__, __LINE__, ##__VA_ARGS__)
-#endif /* G_INSTEADOF_LOG */
+#endif /* PRINT_INSTEADOF_LOG */
#ifdef HAVE_LIBUNISTRING
/* libunistring versions prior to 9.1.2 need this hack */
@@ -50,6 +51,9 @@
#include <unicode/ucol.h>
#endif
+/* If string lenth less than this value, allocating from the stack */
+#define MAX_STACK_STR_SIZE 512
+
#ifdef HAVE_LIBUNISTRING /* ---- GNU libunistring based collation ---- */
gpointer
@@ -73,7 +77,24 @@ tracker_collation_utf8 (gpointer collator,
gint len2,
gconstpointer str2)
{
- return u8_strcoll (str1, str2);
+ gint result;
+ gchar *aux1;
+ gchar *aux2;
+
+ /* Note: str1 and str2 are NOT NUL-terminated */
+ aux1 = (len1 < MAX_STACK_STR_SIZE) ? g_alloca (len1+1) : g_malloc (len1+1);
+ aux2 = (len2 < MAX_STACK_STR_SIZE) ? g_alloca (len2+1) : g_malloc (len2+1);
+
+ memcpy (aux1, str1, len1); aux1[len1] = '\0';
+ memcpy (aux2, str2, len2); aux2[len2] = '\0';
+
+ result = u8_strcoll (aux1, aux2);
+
+ if (len1 >= MAX_STACK_STR_SIZE)
+ g_free (aux1);
+ if (len2 >= MAX_STACK_STR_SIZE)
+ g_free (aux2);
+ return result;
}
#elif HAVE_LIBICU /* ---- ICU based collation (UTF-16) ----*/
@@ -164,7 +185,24 @@ tracker_collation_utf8 (gpointer collator,
gint len2,
gconstpointer str2)
{
- return g_utf8_collate (str1, str2);
+ gint result;
+ gchar *aux1;
+ gchar *aux2;
+
+ /* Note: str1 and str2 are NOT NUL-terminated */
+ aux1 = (len1 < MAX_STACK_STR_SIZE) ? g_alloca (len1+1) : g_malloc (len1+1);
+ aux2 = (len2 < MAX_STACK_STR_SIZE) ? g_alloca (len2+1) : g_malloc (len2+1);
+
+ memcpy (aux1, str1, len1); aux1[len1] = '\0';
+ memcpy (aux2, str2, len2); aux2[len2] = '\0';
+
+ result = g_utf8_collate (aux1, aux2);
+
+ if (len1 >= MAX_STACK_STR_SIZE)
+ g_free (aux1);
+ if (len2 >= MAX_STACK_STR_SIZE)
+ g_free (aux2);
+ return result;
}
#endif
diff --git a/src/libtracker-data/tracker-sparql-expression.vala b/src/libtracker-data/tracker-sparql-expression.vala
index 064217b..d8760b1 100644
--- a/src/libtracker-data/tracker-sparql-expression.vala
+++ b/src/libtracker-data/tracker-sparql-expression.vala
@@ -180,15 +180,16 @@ class Tracker.Sparql.Expression : Object {
}
}
- internal void translate_order_condition (StringBuilder sql) throws Sparql.Error {
+ internal string translate_order_condition (StringBuilder sql) throws Sparql.Error {
if (accept (SparqlTokenType.ASC)) {
translate_expression_as_order_condition (sql);
- sql.append (" ASC");
+ return (" ASC");
} else if (accept (SparqlTokenType.DESC)) {
translate_expression_as_order_condition (sql);
- sql.append (" DESC");
+ return (" DESC");
} else {
translate_expression_as_order_condition (sql);
+ return ("");
}
}
diff --git a/src/libtracker-data/tracker-sparql-pattern.vala b/src/libtracker-data/tracker-sparql-pattern.vala
index e030fa3..477eae2 100644
--- a/src/libtracker-data/tracker-sparql-pattern.vala
+++ b/src/libtracker-data/tracker-sparql-pattern.vala
@@ -358,10 +358,16 @@ class Tracker.Sparql.Pattern : Object {
if (first_order) {
first_order = false;
} else {
- sql.append (" COLLATE TRACKER, ");
+ sql.append (", ");
+ }
+ string order = expression.translate_order_condition (sql);
+
+ if (accept (SparqlTokenType.COLLATE)) {
+ sql.append (" COLLATE TRACKER ");
}
- expression.translate_order_condition (sql);
- } while (current () != SparqlTokenType.LIMIT && current () != SparqlTokenType.OFFSET && current () != SparqlTokenType.CLOSE_BRACE && current () != SparqlTokenType.CLOSE_PARENS && current () != SparqlTokenType.EOF);
+
+ sql.append (order);
+ } while (current () != SparqlTokenType.LIMIT && current () != SparqlTokenType.OFFSET && current () != SparqlTokenType.COLLATE && current () != SparqlTokenType.CLOSE_BRACE && current () != SparqlTokenType.CLOSE_PARENS && current () != SparqlTokenType.EOF);
}
int limit = -1;
diff --git a/src/libtracker-data/tracker-sparql-scanner.vala b/src/libtracker-data/tracker-sparql-scanner.vala
index d216ac0..6bf020b 100644
--- a/src/libtracker-data/tracker-sparql-scanner.vala
+++ b/src/libtracker-data/tracker-sparql-scanner.vala
@@ -281,6 +281,10 @@ public class Tracker.SparqlScanner : Object {
break;
case 7:
switch (begin[0]) {
+ case 'c':
+ case 'C':
+ if (matches (begin, "COLLATE")) return SparqlTokenType.COLLATE;
+ break;
case 'R':
case 'r':
if (matches (begin, "REDUCED")) return SparqlTokenType.REDUCED;
@@ -826,6 +830,7 @@ public enum Tracker.SparqlTokenType {
CLOSE_BRACE,
CLOSE_BRACKET,
CLOSE_PARENS,
+ COLLATE,
COLON,
COMMA,
CONSTRUCT,
@@ -919,6 +924,7 @@ public enum Tracker.SparqlTokenType {
case CLOSE_BRACE: return "`}'";
case CLOSE_BRACKET: return "`]'";
case CLOSE_PARENS: return "`)'";
+ case COLLATE: return "`COLLATE'";
case COLON: return "`:'";
case COMMA: return "`,'";
case CONSTRUCT: return "`CONSTRUCT'";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]