[libgda] make gda_sql_builder_select_add_target_id() return an already existing ID
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] make gda_sql_builder_select_add_target_id() return an already existing ID
- Date: Mon, 24 May 2010 16:24:09 +0000 (UTC)
commit 4797dc40c3452e4debd6ae3d989955a138b0830d
Author: Vivien Malerba <malerba gnome-db org>
Date: Mon May 24 17:14:16 2010 +0200
make gda_sql_builder_select_add_target_id() return an already existing ID
in case a target with the same characteristics as the one to add is
already present
libgda/gda-sql-builder.c | 38 +++++++++++++++++++++++++++++--
tests/test-sql-builder.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 3 deletions(-)
---
diff --git a/libgda/gda-sql-builder.c b/libgda/gda-sql-builder.c
index d44345c..6e21885 100644
--- a/libgda/gda-sql-builder.c
+++ b/libgda/gda-sql-builder.c
@@ -1035,9 +1035,11 @@ typedef struct {
* @table_id: the ID of the expression holding a table reference (not %0)
* @alias: the alias to give to the target, or %NULL
*
- * Adds a new target to a SELECT statement
+ * Adds a new target to a SELECT statement. If there already exists a target representing
+ * the same table and the same alias (or with the same absence of alias) then the same target
+ * ID is returned instead of the ID of a new target.
*
- * Returns: the ID of the new target, or 0 if there was an error
+ * Returns: the ID of the new (or existing) target, or 0 if there was an error
*
* Since: 4.2
*/
@@ -1057,9 +1059,39 @@ gda_sql_builder_select_add_target_id (GdaSqlBuilder *builder, guint table_id, co
if (!p)
return 0;
+ /* check for an already existing target with the same characteristics */
+ GdaSqlStatementSelect *sel = (GdaSqlStatementSelect*) builder->priv->main_stmt->contents;
+ if (sel->from) {
+ gchar *ser;
+ GSList *list;
+
+ g_assert (p->part->type == GDA_SQL_ANY_EXPR);
+ ser = gda_sql_expr_serialize ((GdaSqlExpr*) p->part);
+ for (list = sel->from->targets; list; list = list->next) {
+ BuildTarget *bt = (BuildTarget*) list->data;
+ GdaSqlSelectTarget *t = (GdaSqlSelectTarget*) list->data;
+ gboolean idalias = FALSE;
+ if (alias && t->as && !strcmp (t->as, alias))
+ idalias = TRUE;
+ else if (!alias && ! t->as)
+ idalias = TRUE;
+
+ gchar *tmp;
+ tmp = gda_sql_expr_serialize (t->expr);
+ if (! strcmp (ser, tmp)) {
+ if (idalias) {
+ g_free (tmp);
+ g_free (ser);
+ return bt->part_id;
+ }
+ }
+ g_free (tmp);
+ }
+ g_free (ser);
+ }
+
BuildTarget *btarget;
GdaSqlSelectTarget *target;
- GdaSqlStatementSelect *sel = (GdaSqlStatementSelect*) builder->priv->main_stmt->contents;
btarget = g_new0 (BuildTarget, 1);
GDA_SQL_ANY_PART (btarget)->type = GDA_SQL_ANY_SQL_SELECT_TARGET;
GDA_SQL_ANY_PART (btarget)->parent = GDA_SQL_ANY_PART (sel->from);
diff --git a/tests/test-sql-builder.c b/tests/test-sql-builder.c
index 163c0fd..3c849e3 100644
--- a/tests/test-sql-builder.c
+++ b/tests/test-sql-builder.c
@@ -44,6 +44,8 @@ static GdaSqlStatement *build10 (void);
static GdaSqlStatement *build11 (void);
static GdaSqlStatement *build12 (void);
+static gboolean builder_test_target_id (void);
+
ATest tests[] = {
{"build0", build0, "{\"sql\":null,\"stmt_type\":\"SELECT\",\"contents\":{\"distinct\":\"false\",\"fields\":[{\"expr\":{\"value\":\"*\",\"sqlident\":\"TRUE\"}}],\"from\":{\"targets\":[{\"expr\":{\"value\":\"mytable\",\"sqlident\":\"TRUE\"},\"table_name\":\"mytable\"}]}}}"},
{"build1", build1, "{\"sql\":null,\"stmt_type\":\"SELECT\",\"contents\":{\"distinct\":\"false\",\"fields\":[{\"expr\":{\"value\":\"contents\",\"sqlident\":\"TRUE\"}},{\"expr\":{\"value\":\"descr\",\"sqlident\":\"TRUE\"}},{\"expr\":{\"value\":\"rank\",\"sqlident\":\"TRUE\"}},{\"expr\":{\"value\":\"name\",\"sqlident\":\"TRUE\"}}],\"from\":{\"targets\":[{\"expr\":{\"value\":\"mytable\",\"sqlident\":\"TRUE\"},\"table_name\":\"mytable\"}]},\"where\":{\"operation\":{\"operator\":\"AND\",\"operand0\":{\"operation\":{\"operator\":\"=\",\"operand0\":{\"value\":\"session\",\"sqlident\":\"TRUE\"},\"operand1\":{\"value\":null,\"param_spec\":{\"name\":\"session\",\"descr\":null,\"type\":\"string\",\"is_param\":true,\"nullok\":false}}}},\"operand1\":{\"operation\":{\"operator\":\"AND\",\"operand0\":{\"operation\":{\"operator\":\"=\",\"operand0\":{\"value\":\"type\",\"sqlident\":\"TRUE\"},\"operand1\":{\"value\":\"'TABLE'\"}}},\"operand1\":{\"operation\":{\"operator\":\"=\",\"operand0\":{
\"value\":\"name\",\"sqlident\":\"TRUE\"},\"operand1\":{\"value\":\"'alf'\"}}}}}}}}}"},
@@ -116,6 +118,9 @@ main (int argc, char** argv)
nfailed++;
}
+ if (! builder_test_target_id ())
+ nfailed++;
+
g_print ("%d tests executed, ", i);
if (nfailed > 0)
g_print ("%d failed\n", nfailed);
@@ -546,3 +551,52 @@ build12 (void)
g_object_unref (b);
return stmt;
}
+
+/*
+ *
+ */
+static gboolean
+builder_test_target_id (void)
+{
+ GdaSqlBuilder *builder;
+ guint id1, id2;
+ gboolean allok = TRUE;
+
+ builder = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
+ gda_sql_builder_add_field_id (builder,
+ gda_sql_builder_add_id (builder, "*"), 0);
+ /* same target with aliases */
+ id1 = gda_sql_builder_select_add_target_id (builder,
+ gda_sql_builder_add_id (builder, "mytable"), "alias");
+ id2 = gda_sql_builder_select_add_target_id (builder,
+ gda_sql_builder_add_id (builder, "mytable"), "alias");
+ if (id1 != id2) {
+ g_print ("identical targets with an alias not recognized as same target.\n");
+ allok = FALSE;
+ }
+
+ id2 = gda_sql_builder_select_add_target_id (builder,
+ gda_sql_builder_add_id (builder, "mytable"), "alias2");
+ if (id1 == id2) {
+ g_print ("identical tables with different alias recognized as same target.\n");
+ allok = FALSE;
+ }
+
+ id2 = gda_sql_builder_select_add_target_id (builder,
+ gda_sql_builder_add_id (builder, "mytable"), NULL);
+ if (id1 == id2) {
+ g_print ("identical tables with no alias recognized as same target.\n");
+ allok = FALSE;
+ }
+
+ id1 = gda_sql_builder_select_add_target_id (builder,
+ gda_sql_builder_add_id (builder, "mytable"), NULL);
+ if (id1 != id2) {
+ g_print ("identical tables with different alias not recognized as same target.\n");
+ allok = FALSE;
+ }
+
+ g_object_unref (builder);
+
+ return allok;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]