]> saetta.ns0.it Git - libgdaex/commitdiff
Implemented groups (parenthesis) in GdaExQueryEditor.
authorAndrea Zagli <azagli@libero.it>
Mon, 28 Nov 2011 16:10:44 +0000 (17:10 +0100)
committerAndrea Zagli <azagli@libero.it>
Mon, 28 Nov 2011 16:12:22 +0000 (17:12 +0100)
There's a bug when the group is negated.

.anjuta/session/anjuta.session
.anjuta/session/dock-layout.xml
.anjuta_sym_db.db
po/it.po
src/queryeditor.c

index 5319aca3a3578931c3f28ca3894babb4ca5158be..1282bd7e2c779613477b0817d75a012abbb3db08 100644 (file)
@@ -5,10 +5,10 @@ Geometry=1366x745+0+1
 
 [Project Manager]
 Shortcut=libgdaex//libgdaex//src//libgdaex.la%%%libgdaex//libgdaex//tests//fill_liststore%%%libgdaex//libgdaex//tests//grid%%%libgdaex//libgdaex//tests//query_editor%%%libgdaex//libgdaex//tests//select%%%libgdaex//libgdaex//tests//test_prefix
-Expand=libgdaex.la
+Expand=libgdaex.la%%%libgdaex
 
 [File Loader]
-Files=file:///home/andreaz/files/c/libgdaex/src/gdaex.c#2780
+Files=file:///home/andreaz/files/c/libgdaex/src/queryeditor.c#1710
 
 [Document Manager]
 bookmarks=<?xml version="1.0" encoding="UTF-8"?>\n<bookmarks/>\n
index 44849a94bd0361bfebb48fea09e003c4337e64c2..c70c788925ab45542730f93d1de557b4544a6db1 100644 (file)
@@ -1,2 +1,2 @@
 <?xml version="1.0"?>
-<dock-layout><layout name="__default__"><dock name="__dock_1" floating="no" width="-1" height="-1" floatx="0" floaty="0"><paned orientation="horizontal" locked="no" position="1019"><notebook orientation="vertical" locked="no" page="0"><item name="AnjutaDocumentManager" orientation="vertical" locked="no"/><item name="AnjutaDevhelpDisplay" orientation="vertical" locked="yes"/><item name="AnjutaTerminal" orientation="vertical" locked="yes"/></notebook><paned orientation="vertical" locked="no" position="289"><notebook orientation="vertical" locked="no" page="0"><item name="AnjutaFileManager" orientation="vertical" locked="no"/><item name="AnjutaProjectManager" orientation="vertical" locked="no"/></notebook><notebook orientation="vertical" locked="no" page="0"><item name="AnjutaSymbolDB" orientation="vertical" locked="no"/><item name="AnjutaDevhelpIndex" orientation="vertical" locked="no"/></notebook></paned></paned></dock></layout></dock-layout>
+<dock-layout><layout name="__default__"><dock name="__dock_1" floating="no" width="-1" height="-1" floatx="0" floaty="0"><paned orientation="horizontal" locked="no" position="1019"><notebook orientation="vertical" locked="no" page="0"><item name="AnjutaDocumentManager" orientation="vertical" locked="no"/><item name="AnjutaDevhelpDisplay" orientation="vertical" locked="yes"/><item name="AnjutaTerminal" orientation="vertical" locked="yes"/></notebook><paned orientation="vertical" locked="no" position="289"><notebook orientation="vertical" locked="no" page="1"><item name="AnjutaFileManager" orientation="vertical" locked="no"/><item name="AnjutaProjectManager" orientation="vertical" locked="no"/></notebook><notebook orientation="vertical" locked="no" page="0"><item name="AnjutaSymbolDB" orientation="vertical" locked="no"/><item name="AnjutaDevhelpIndex" orientation="vertical" locked="no"/></notebook></paned></paned></dock></layout></dock-layout>
index a7eb1adf8b41cd049f9f0fbe88291098134277a5..b8cbbc5185e421d170b25f77ff19b2fbe861c866 100644 (file)
Binary files a/.anjuta_sym_db.db and b/.anjuta_sym_db.db differ
index 71feb3bb1341f042fa97870c353fc61791f88047..585742b3ff6c0fa66f0dcfdc0b1c2b4cbe4376f6 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: libgdaex 0.4.0\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-11-27 11:27+0100\n"
+"POT-Creation-Date: 2011-11-27 15:25+0100\n"
 "PO-Revision-Date: 2011-10-24 17:44+0200\n"
 "Last-Translator: Andrea Zagli <azagli@libero.it>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
@@ -39,8 +39,8 @@ msgstr "Errore nella creazione della connessione al database: %s"
 #: ../src/gdaex.c:2308 ../src/gdaex.c:2418 ../src/gdaex.c:2465
 #: ../src/gdaex.c:2483 ../src/gdaex.c:2536 ../src/gdaex.c:2595
 #: ../src/gdaex.c:2648 ../src/gdaex.c:2951 ../src/gdaex.c:2969
-#: ../src/queryeditor.c:366 ../src/queryeditor.c:1350
-#: ../src/queryeditor.c:1362
+#: ../src/queryeditor.c:371 ../src/queryeditor.c:1392
+#: ../src/queryeditor.c:1404
 msgid "no details"
 msgstr "nessun dettaglio"
 
@@ -226,171 +226,171 @@ msgstr "Errore nella creazione dell'espressione regolare: %s"
 msgid "Error on regex replacing: %s"
 msgstr "Errore nell'espressione regolare di sostituzione: %s"
 
-#: ../src/queryeditor.c:365
+#: ../src/queryeditor.c:370
 #, c-format
 msgid "Error on gui initialization: %s."
 msgstr "Errore nell'inizializzazione dell'interfaccia grafica: %s."
 
-#: ../src/queryeditor.c:601 ../src/queryeditor.c:763 ../src/queryeditor.c:771
+#: ../src/queryeditor.c:606 ../src/queryeditor.c:768 ../src/queryeditor.c:776
 #, c-format
 msgid "Table «%s» doesn't exists."
 msgstr "La tabella «%s» non esiste."
 
-#: ../src/queryeditor.c:610 ../src/queryeditor.c:618
+#: ../src/queryeditor.c:615 ../src/queryeditor.c:623
 msgid "No field added: the field must have a name."
 msgstr "Nessun campo aggiunto: il campo deve avere un nome."
 
-#: ../src/queryeditor.c:807
+#: ../src/queryeditor.c:812
 msgid "Relation not created: no field added to the relation."
 msgstr "Relazione non creata: nesuun campo aggiunto alla relazione."
 
-#: ../src/queryeditor.c:1272 ../src/queryeditor.c:1665
+#: ../src/queryeditor.c:1222 ../src/queryeditor.c:1665
 #, c-format
 msgid "Where type «%d» not valid."
 msgstr "Tipo where «%d» non valido."
 
-#: ../src/queryeditor.c:1349
+#: ../src/queryeditor.c:1391
 #, c-format
 msgid "Unable to create GdaStatement: %s."
 msgstr "Impossibile creare l'oggetto GdaStatement: %s."
 
-#: ../src/queryeditor.c:1361
+#: ../src/queryeditor.c:1403
 #, c-format
 msgid "Unable to create sql: %s."
 msgstr "Impossibile creare l'sql: %s."
 
-#: ../src/queryeditor.c:1600
+#: ../src/queryeditor.c:1598
 #, c-format
 msgid "Link type «%d» not valid."
 msgstr "Tipo collegamento «%d» non valido."
 
-#: ../src/queryeditor.c:1760
+#: ../src/queryeditor.c:1846
 #, c-format
 msgid "Table «%s» not found."
 msgstr "Tabella «%s» non trovata."
 
-#: ../src/queryeditor.c:1768
+#: ../src/queryeditor.c:1854
 #, c-format
 msgid "Field «%s» not found in table «%s»."
 msgstr "Campo «%s» non trovato nella tabella «%s»."
 
-#: ../src/queryeditor.c:1955 ../src/queryeditor.c:2815
+#: ../src/queryeditor.c:2041 ../src/queryeditor.c:2914
 msgid "ASC"
 msgstr "ASC"
 
-#: ../src/queryeditor.c:1956 ../src/queryeditor.c:2819
+#: ../src/queryeditor.c:2042 ../src/queryeditor.c:2918
 msgid "DESC"
 msgstr "DISC"
 
-#: ../src/queryeditor.c:2207
+#: ../src/queryeditor.c:2293
 msgid "Are you sure you want to remove the selected field?"
 msgstr "Eliminare il campo selezionato?"
 
-#: ../src/queryeditor.c:2228 ../src/queryeditor.c:2324
-#: ../src/queryeditor.c:2893 ../src/queryeditor.c:3095
-#: ../src/queryeditor.c:3606
+#: ../src/queryeditor.c:2314 ../src/queryeditor.c:2410
+#: ../src/queryeditor.c:2992 ../src/queryeditor.c:3194
+#: ../src/queryeditor.c:3766
 msgid "You must select a field before."
 msgstr "Occorre prima selezione un campo."
 
-#: ../src/queryeditor.c:2386
+#: ../src/queryeditor.c:2470
 msgid "Equal"
 msgstr "uguale a"
 
-#: ../src/queryeditor.c:2390
+#: ../src/queryeditor.c:2474
 msgid "Starts with"
 msgstr "inizia per"
 
-#: ../src/queryeditor.c:2394
+#: ../src/queryeditor.c:2478
 msgid "Contains"
 msgstr "contiene"
 
-#: ../src/queryeditor.c:2398
+#: ../src/queryeditor.c:2482
 msgid "Ends with"
 msgstr "finisce con"
 
-#: ../src/queryeditor.c:2402
+#: ../src/queryeditor.c:2486
 msgid "Case-insensitive starts with"
 msgstr "inizia per (no maiuscole/minuscole)"
 
-#: ../src/queryeditor.c:2406
+#: ../src/queryeditor.c:2490
 msgid "Case-insensitive contains"
 msgstr "contiene (no maiuscole/minuscole)"
 
-#: ../src/queryeditor.c:2410
+#: ../src/queryeditor.c:2494
 msgid "Case-insensitive ends with"
 msgstr "finisce con (no maiuscole/minuscole)"
 
-#: ../src/queryeditor.c:2414
+#: ../src/queryeditor.c:2498
 msgid "Greater"
 msgstr "maggiore di"
 
-#: ../src/queryeditor.c:2418
+#: ../src/queryeditor.c:2502
 msgid "Greater or equal"
 msgstr "maggiore di o uguale a"
 
-#: ../src/queryeditor.c:2422
+#: ../src/queryeditor.c:2506
 msgid "Lesser"
 msgstr "minore di"
 
-#: ../src/queryeditor.c:2426
+#: ../src/queryeditor.c:2510
 msgid "Lesser or equal"
 msgstr "minore di o uguale a"
 
-#: ../src/queryeditor.c:2430
+#: ../src/queryeditor.c:2514
 msgid "Between"
 msgstr "compreso tra"
 
-#: ../src/queryeditor.c:2434
+#: ../src/queryeditor.c:2518
 msgid "Is NULL"
 msgstr "è NULL"
 
-#: ../src/queryeditor.c:2451
+#: ../src/queryeditor.c:2539
 msgid "And"
 msgstr "e"
 
-#: ../src/queryeditor.c:2455
+#: ../src/queryeditor.c:2543
 msgid "Or"
 msgstr "o"
 
-#: ../src/queryeditor.c:2721
+#: ../src/queryeditor.c:2809
 msgid "You must select a link's type before."
 msgstr "Occorre selezionare prima un tipo di collegamento."
 
-#: ../src/queryeditor.c:2743
+#: ../src/queryeditor.c:2833
 msgid "You must select a condition's type before."
 msgstr "Occorre selezionare prima un tipo di condizione."
 
 #. if it is the first condition, "link" isn't visibile
-#: ../src/queryeditor.c:3269 ../data/libgdaex/gui/libgdaex.ui.h:7
+#: ../src/queryeditor.c:3391 ../data/libgdaex/gui/libgdaex.ui.h:7
 msgid "Link"
 msgstr "Collegamento"
 
-#: ../src/queryeditor.c:3273 ../data/libgdaex/gui/libgdaex.ui.h:8
+#: ../src/queryeditor.c:3395 ../data/libgdaex/gui/libgdaex.ui.h:8
 msgid "Not"
 msgstr "Non"
 
-#: ../src/queryeditor.c:3276 ../data/libgdaex/gui/libgdaex.ui.h:3
+#: ../src/queryeditor.c:3398 ../data/libgdaex/gui/libgdaex.ui.h:3
 msgid "Condition"
 msgstr "Condizione"
 
-#: ../src/queryeditor.c:3279
+#: ../src/queryeditor.c:3401
 msgid "Value"
 msgstr "Valore"
 
-#: ../src/queryeditor.c:3323
+#: ../src/queryeditor.c:3445
 msgid "and"
 msgstr "e"
 
-#: ../src/queryeditor.c:3485
+#: ../src/queryeditor.c:3621
 #, c-format
 msgid "Field's type «%d» not valid."
 msgstr "Il tipo campo «%d» non è valido."
 
-#: ../src/queryeditor.c:3698
+#: ../src/queryeditor.c:3858
 msgid "Ascending"
 msgstr "ascendente"
 
-#: ../src/queryeditor.c:3701
+#: ../src/queryeditor.c:3861
 msgid "Descending"
 msgstr "discendente"
 
@@ -412,7 +412,7 @@ msgstr "Campi"
 
 #: ../data/libgdaex/gui/libgdaex.ui.h:6
 msgid "From"
-msgstr "da"
+msgstr "Da"
 
 #: ../data/libgdaex/gui/libgdaex.ui.h:9
 msgid "Order"
@@ -424,7 +424,7 @@ msgstr "Mostra"
 
 #: ../data/libgdaex/gui/libgdaex.ui.h:11
 msgid "To"
-msgstr "a"
+msgstr "A"
 
 #: ../data/libgdaex/gui/libgdaex.ui.h:12
 msgid "Where"
index bd6a94125bd51014d99ec652a4eccd98aae3da8b..1a47945b7900709c8620ec995cd77d099c7dd4e3 100644 (file)
@@ -979,120 +979,78 @@ gdaex_query_editor_add_table_relation_to_gdasqlbuilder (GdaExQueryEditor *qe,
                }
 }
 
-GdaSqlBuilder
-*gdaex_query_editor_get_sql_as_gdasqlbuilder (GdaExQueryEditor *qe)
+static guint
+gdaex_query_editor_sql_where (GdaExQueryEditor *qe,
+                              GdaSqlBuilder *sqlbuilder,
+                              GtkTreeIter *iter,
+                              GtkTreeIter *iter_parent,
+                              guint id_cond_parent)
 {
        GdaExQueryEditorPrivate *priv;
 
-       GdaSqlBuilder *sqlbuilder;
-
-       GtkTreeIter iter;
+       guint id_ret;
 
        gchar *table_name;
        gchar *field_name;
-       gchar *alias;
-       gchar *asc_desc;
+       gchar *field_name_with_table;
 
        GdaExQueryEditorTable *table;
        GdaExQueryEditorField *field;
 
-       g_return_val_if_fail (GDAEX_IS_QUERY_EDITOR (qe), NULL);
-
-       priv = GDAEX_QUERY_EDITOR_GET_PRIVATE (qe);
+       guint link_type;
+       GdaSqlOperatorType link_op;
+       gboolean not;
+       guint where_type;
+       GdaSqlOperatorType where_op;
+       gchar *from_str;
+       gchar *to_str;
+       GDate *from_date;
+       GDateTime *from_datetime;
 
-       sqlbuilder = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
+       guint id_field;
+       guint id_value1;
+       guint id_value2;
+       guint id_cond_iter;
 
-       /* SHOW */
-       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->lstore_show), &iter))
-               {
-                       guint id_target1;
-                       guint id_target2;
-                       guint id_join1;
-                       guint id_join2;
-                       guint join_cond;
+       gboolean case_insensitive;
 
-                       do
-                               {
-                                       gtk_tree_model_get (GTK_TREE_MODEL (priv->lstore_show), &iter,
-                                                           COL_SHOW_TABLE_NAME, &table_name,
-                                                           COL_SHOW_NAME, &field_name,
-                                                           COL_SHOW_ALIAS, &alias,
-                                                           -1);
+       gboolean is_group;
 
-                                       table = g_hash_table_lookup (priv->tables, table_name);
-                                       field = g_hash_table_lookup (table->fields, field_name);
+       GtkTreeIter children;
 
-                                       gdaex_query_editor_add_table_relation_to_gdasqlbuilder (qe, sqlbuilder, table_name);
+       priv = GDAEX_QUERY_EDITOR_GET_PRIVATE (qe);
 
-                                       if (field->decode_table2 != NULL)
-                                               {
-                                                       id_target1 = gda_sql_builder_select_add_target_id (sqlbuilder,
-                                                                                                          gda_sql_builder_add_id (sqlbuilder, table->name),
-                                                                                                          NULL);
-                                                       id_target2 = gda_sql_builder_select_add_target_id (sqlbuilder,
-                                                                                                          gda_sql_builder_add_id (sqlbuilder, field->decode_table2),
-                                                                                                          NULL);
+       id_ret = 0;
 
-                                                       id_join1 = gda_sql_builder_add_id (sqlbuilder, g_strconcat (field->table_name, ".", field->name, NULL));
-                                                       id_join2 = gda_sql_builder_add_id (sqlbuilder, g_strconcat (field->decode_table2, ".", field->decode_field2, NULL));
+       do
+               {
+                       id_value2 = 0;
 
-                                                       join_cond = gda_sql_builder_add_cond (sqlbuilder, GDA_SQL_OPERATOR_TYPE_EQ,
-                                                                                             id_join1, id_join2, 0);
+                       gtk_tree_model_get (GTK_TREE_MODEL (priv->tstore_where), iter,
+                                           COL_WHERE_LINK_TYPE, &link_type,
+                                           COL_WHERE_TABLE_NAME, &table_name,
+                                           COL_WHERE_NAME, &field_name,
+                                           COL_WHERE_CONDITION_NOT, &not,
+                                           COL_WHERE_CONDITION_TYPE, &where_type,
+                                           COL_WHERE_CONDITION_FROM_SQL, &from_str,
+                                           COL_WHERE_CONDITION_TO_SQL, &to_str,
+                                           -1);
 
-                                                       gda_sql_builder_select_join_targets (sqlbuilder, id_target1, id_target2,
-                                                                                            field->decode_join_type == GDAEX_QE_JOIN_TYPE_LEFT ? GDA_SQL_SELECT_JOIN_LEFT : GDA_SQL_SELECT_JOIN_INNER,
-                                                                                            join_cond);
-                                                       gda_sql_builder_select_add_field (sqlbuilder, field->decode_field_to_show,
-                                                                                         field->decode_table2,
-                                                                                         alias != NULL && g_strcmp0 (alias, "") != 0 ? alias : field->decode_field_alias);
-                                               }
-                                       else
-                                               {
-                                                       gda_sql_builder_select_add_field (sqlbuilder, field->name, table->name,
-                                                                                         alias != NULL && g_strcmp0 (alias, "") != 0 ? alias : field->alias);
-                                                       gda_sql_builder_select_add_target_id (sqlbuilder,
-                                                                                             gda_sql_builder_add_id (sqlbuilder, table->name),
-                                                                                             NULL);
-                                               }
-                               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->lstore_show), &iter));
-               }
+                       is_group = (g_strcmp0 (table_name, GROUP) == 0);
 
-       /* WHERE */
-       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->tstore_where), &iter))
-               {
-                       guint link_type;
-                       GdaSqlOperatorType link_op;
-                       gboolean not;
-                       guint where_type;
-                       GdaSqlOperatorType where_op;
-                       gchar *from_str;
-                       gchar *to_str;
-                       GDate *from_date;
-                       GDateTime *from_datetime;
-
-                       guint id_field;
-                       guint id_value1;
-                       guint id_value2;
-                       guint id_cond;
-                       guint id_cond_iter;
+                       switch (link_type)
+                               {
+                                       case GDAEX_QE_LINK_TYPE_AND:
+                                               link_op = GDA_SQL_OPERATOR_TYPE_AND;
+                                               break;
 
-                       gboolean case_insensitive;
+                                       case GDAEX_QE_LINK_TYPE_OR:
+                                               link_op = GDA_SQL_OPERATOR_TYPE_OR;
+                                               break;
+                               }
 
-                       id_cond = 0;
-                       do
+                       if (!is_group)
                                {
-                                       id_value2 = 0;
-
-                                       gtk_tree_model_get (GTK_TREE_MODEL (priv->tstore_where), &iter,
-                                                           COL_WHERE_LINK_TYPE, &link_type,
-                                                           COL_WHERE_TABLE_NAME, &table_name,
-                                                           COL_WHERE_NAME, &field_name,
-                                                           COL_WHERE_CONDITION_NOT, &not,
-                                                           COL_WHERE_CONDITION_TYPE, &where_type,
-                                                           COL_WHERE_CONDITION_FROM_SQL, &from_str,
-                                                           COL_WHERE_CONDITION_TO_SQL, &to_str,
-                                                           -1);
-
                                        case_insensitive = (where_type == GDAEX_QE_WHERE_TYPE_ISTARTS
                                                            || where_type == GDAEX_QE_WHERE_TYPE_ICONTAINS
                                                            || where_type == GDAEX_QE_WHERE_TYPE_IENDS);
@@ -1155,22 +1113,12 @@ GdaSqlBuilder
 
                                        gdaex_query_editor_add_table_relation_to_gdasqlbuilder (qe, sqlbuilder, table_name);
 
-                                       id_field = gda_sql_builder_add_id (sqlbuilder,
-                                                                          g_strconcat (case_insensitive ? "LOWER(" : "",
-                                                                                       table->name, ".", field->name,
-                                                                                       case_insensitive ? ")" : "",
-                                                                                       NULL));
-
-                                       switch (link_type)
-                                               {
-                                                       case GDAEX_QE_LINK_TYPE_AND:
-                                                               link_op = GDA_SQL_OPERATOR_TYPE_AND;
-                                                               break;
-
-                                                       case GDAEX_QE_LINK_TYPE_OR:
-                                                               link_op = GDA_SQL_OPERATOR_TYPE_OR;
-                                                               break;
-                                               }
+                                       field_name_with_table = g_strconcat (case_insensitive ? "LOWER(" : "",
+                                                                            table->name, ".", field->name,
+                                                                            case_insensitive ? ")" : "",
+                                                                            NULL);
+                                       id_field = gda_sql_builder_add_id (sqlbuilder, field_name_with_table);
+                                       g_free (field_name_with_table);
 
                                        if (where_type == GDAEX_QE_WHERE_TYPE_IS_NULL)
                                                {
@@ -1283,15 +1231,126 @@ GdaSqlBuilder
                                                {
                                                        id_cond_iter = gda_sql_builder_add_cond (sqlbuilder, GDA_SQL_OPERATOR_TYPE_NOT, id_cond_iter, 0, 0);
                                                }
-                                       if (id_cond == 0)
+                                       if (id_ret == 0)
                                                {
-                                                       id_cond = id_cond_iter;
+                                                       id_ret = id_cond_iter;
                                                }
                                        else
                                                {
-                                                       id_cond = gda_sql_builder_add_cond (sqlbuilder, link_op, id_cond, id_cond_iter, 0);
+                                                       id_ret = gda_sql_builder_add_cond (sqlbuilder, link_op, id_ret, id_cond_iter, 0);
                                                }
-                               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->tstore_where), &iter));
+                               }
+                       else
+                               {
+                                       if (gtk_tree_model_iter_children (GTK_TREE_MODEL (priv->tstore_where), &children, iter))
+                                               {
+                                                       id_cond_iter = gdaex_query_editor_sql_where (qe, sqlbuilder, &children, iter, 0);
+                                                       if (id_cond_iter != 0)
+                                                               {
+                                                                       if (not)
+                                                                               {
+                                                                                       id_cond_iter = gda_sql_builder_add_cond (sqlbuilder, GDA_SQL_OPERATOR_TYPE_NOT, id_cond_iter, 0, 0);
+                                                                               }
+                                                                       if (id_ret == 0)
+                                                                               {
+                                                                                       id_ret = id_cond_iter;
+                                                                               }
+                                                                       else
+                                                                               {
+                                                                                       id_ret = gda_sql_builder_add_cond (sqlbuilder, link_op, id_ret, id_cond_iter, 0);
+                                                                               }
+                                                               }
+                                               }
+                               }
+               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->tstore_where), iter));
+
+       return id_ret;
+}
+
+GdaSqlBuilder
+*gdaex_query_editor_get_sql_as_gdasqlbuilder (GdaExQueryEditor *qe)
+{
+       GdaExQueryEditorPrivate *priv;
+
+       GdaSqlBuilder *sqlbuilder;
+
+       GtkTreeIter iter;
+
+       gchar *table_name;
+       gchar *field_name;
+       gchar *alias;
+       gchar *asc_desc;
+
+       GdaExQueryEditorTable *table;
+       GdaExQueryEditorField *field;
+
+       g_return_val_if_fail (GDAEX_IS_QUERY_EDITOR (qe), NULL);
+
+       priv = GDAEX_QUERY_EDITOR_GET_PRIVATE (qe);
+
+       sqlbuilder = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
+
+       /* SHOW */
+       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->lstore_show), &iter))
+               {
+                       guint id_target1;
+                       guint id_target2;
+                       guint id_join1;
+                       guint id_join2;
+                       guint join_cond;
+
+                       do
+                               {
+                                       gtk_tree_model_get (GTK_TREE_MODEL (priv->lstore_show), &iter,
+                                                           COL_SHOW_TABLE_NAME, &table_name,
+                                                           COL_SHOW_NAME, &field_name,
+                                                           COL_SHOW_ALIAS, &alias,
+                                                           -1);
+
+                                       table = g_hash_table_lookup (priv->tables, table_name);
+                                       field = g_hash_table_lookup (table->fields, field_name);
+
+                                       gdaex_query_editor_add_table_relation_to_gdasqlbuilder (qe, sqlbuilder, table_name);
+
+                                       if (field->decode_table2 != NULL)
+                                               {
+                                                       id_target1 = gda_sql_builder_select_add_target_id (sqlbuilder,
+                                                                                                          gda_sql_builder_add_id (sqlbuilder, table->name),
+                                                                                                          NULL);
+                                                       id_target2 = gda_sql_builder_select_add_target_id (sqlbuilder,
+                                                                                                          gda_sql_builder_add_id (sqlbuilder, field->decode_table2),
+                                                                                                          NULL);
+
+                                                       id_join1 = gda_sql_builder_add_id (sqlbuilder, g_strconcat (field->table_name, ".", field->name, NULL));
+                                                       id_join2 = gda_sql_builder_add_id (sqlbuilder, g_strconcat (field->decode_table2, ".", field->decode_field2, NULL));
+
+                                                       join_cond = gda_sql_builder_add_cond (sqlbuilder, GDA_SQL_OPERATOR_TYPE_EQ,
+                                                                                             id_join1, id_join2, 0);
+
+                                                       gda_sql_builder_select_join_targets (sqlbuilder, id_target1, id_target2,
+                                                                                            field->decode_join_type == GDAEX_QE_JOIN_TYPE_LEFT ? GDA_SQL_SELECT_JOIN_LEFT : GDA_SQL_SELECT_JOIN_INNER,
+                                                                                            join_cond);
+                                                       gda_sql_builder_select_add_field (sqlbuilder, field->decode_field_to_show,
+                                                                                         field->decode_table2,
+                                                                                         alias != NULL && g_strcmp0 (alias, "") != 0 ? alias : field->decode_field_alias);
+                                               }
+                                       else
+                                               {
+                                                       gda_sql_builder_select_add_field (sqlbuilder, field->name, table->name,
+                                                                                         alias != NULL && g_strcmp0 (alias, "") != 0 ? alias : field->alias);
+                                                       gda_sql_builder_select_add_target_id (sqlbuilder,
+                                                                                             gda_sql_builder_add_id (sqlbuilder, table->name),
+                                                                                             NULL);
+                                               }
+                               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->lstore_show), &iter));
+               }
+
+       /* WHERE */
+       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->tstore_where), &iter))
+               {
+                       guint id_cond;
+
+                       id_cond = gdaex_query_editor_sql_where (qe, sqlbuilder, &iter, NULL, 0);
 
                        if (id_cond != 0)
                                {
@@ -1497,121 +1556,79 @@ const gchar
        return ret;
 }
 
-
-xmlNode
-*gdaex_query_editor_get_sql_as_xml (GdaExQueryEditor *qe)
+static void
+gdaex_query_editor_xml_where (GdaExQueryEditor *qe,
+                              GtkTreeIter *iter,
+                              GtkTreeIter *iter_parent,
+                              xmlNode *xnode_parent)
 {
        GdaExQueryEditorPrivate *priv;
 
-       xmlNode *ret;
-
-       GtkTreeIter iter;
-
        gchar *table_name;
        gchar *field_name;
 
        GdaExQueryEditorTable *table;
        GdaExQueryEditorField *field;
 
-       xmlNode *node;
-
-       ret = NULL;
-
-       g_return_val_if_fail (GDAEX_IS_QUERY_EDITOR (qe), NULL);
-
-       priv = GDAEX_QUERY_EDITOR_GET_PRIVATE (qe);
-
-       ret = xmlNewNode (NULL, "gdaex_query_editor_choices");
-
-       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->lstore_show), &iter))
-               {
-                       gchar *alias;
-                       xmlNode *node_show;
+       GtkTreePath *path;
+       gint *indices;
 
-                       node_show = xmlNewNode (NULL, "show");
-                       xmlAddChild (ret, node_show);
+       gboolean is_group;
 
-                       do
-                               {
-                                       gtk_tree_model_get (GTK_TREE_MODEL (priv->lstore_show), &iter,
-                                                           COL_SHOW_TABLE_NAME, &table_name,
-                                                           COL_SHOW_NAME, &field_name,
-                                                           COL_SHOW_ALIAS, &alias,
-                                                           -1);
+       gboolean not;
+       guint link_type;
+       guint where_type;
+       gchar *from_str;
+       gchar *to_str;
+       gchar *str_link;
+       gchar *str_op;
 
-                                       table = g_hash_table_lookup (priv->tables, table_name);
-                                       field = g_hash_table_lookup (table->fields, field_name);
+       xmlNode *xnode;
+       GtkTreeIter children;
 
-                                       node = xmlNewNode (NULL, "field");
-                                       xmlAddChild (node_show, node);
-                                       xmlNewProp (node, "table", table_name);
-                                       xmlNewProp (node, "field", field_name);
-                                       if (alias != NULL && g_strcmp0 (alias, "") != 0)
-                                               {
-                                                       xmlNewProp (node, "alias", alias);
-                                               }
-                                       else
-                                               {
-                                                       xmlNewProp (node, "alias", field->alias);
-                                               }
-                               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->lstore_show), &iter));
-               }
+       priv = GDAEX_QUERY_EDITOR_GET_PRIVATE (qe);
 
-       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->tstore_where), &iter))
+       do
                {
-                       xmlNode *node_where;
-
-                       GtkTreePath *path;
-                       gint *indices;
-
-                       gboolean not;
-                       guint link_type;
-                       guint where_type;
-                       gchar *from_str;
-                       gchar *to_str;
-                       gchar *str_link;
-                       gchar *str_op;
+                       gtk_tree_model_get (GTK_TREE_MODEL (priv->tstore_where), iter,
+                                           COL_WHERE_LINK_TYPE, &link_type,
+                                           COL_WHERE_TABLE_NAME, &table_name,
+                                           COL_WHERE_NAME, &field_name,
+                                           COL_WHERE_CONDITION_NOT, &not,
+                                           COL_WHERE_CONDITION_TYPE, &where_type,
+                                           COL_WHERE_CONDITION_FROM_SQL, &from_str,
+                                           COL_WHERE_CONDITION_TO_SQL, &to_str,
+                                           -1);
 
-                       node_where = xmlNewNode (NULL, "where");
-                       xmlAddChild (ret, node_where);
+                       is_group = (g_strcmp0 (table_name, GROUP) == 0);
 
-                       do
+                       switch (link_type)
                                {
-                                       gtk_tree_model_get (GTK_TREE_MODEL (priv->tstore_where), &iter,
-                                                           COL_WHERE_LINK_TYPE, &link_type,
-                                                           COL_WHERE_TABLE_NAME, &table_name,
-                                                           COL_WHERE_NAME, &field_name,
-                                                           COL_WHERE_CONDITION_NOT, &not,
-                                                           COL_WHERE_CONDITION_TYPE, &where_type,
-                                                           COL_WHERE_CONDITION_FROM_SQL, &from_str,
-                                                           COL_WHERE_CONDITION_TO_SQL, &to_str,
-                                                           -1);
-
-                                       switch (link_type)
-                                               {
-                                                       case GDAEX_QE_LINK_TYPE_AND:
-                                                               str_link = g_strdup ("AND");
-                                                               break;
-
-                                                       case GDAEX_QE_LINK_TYPE_OR:
-                                                               str_link = g_strdup ("OR");
+                                       case GDAEX_QE_LINK_TYPE_AND:
+                                               str_link = g_strdup ("AND");
+                                               break;
+
+                                       case GDAEX_QE_LINK_TYPE_OR:
+                                               str_link = g_strdup ("OR");
+                                               break;
+
+                                       default:
+                                               path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->tstore_where), iter);
+                                               indices = gtk_tree_path_get_indices (path);
+                                               if (indices[gtk_tree_path_get_depth (path) - 1] != 0)
+                                                       {
+                                                               g_warning (_("Link type «%d» not valid."), link_type);
+                                                               continue;
+                                                       }
+                                               else
+                                                       {
+                                                               str_link = g_strdup ("");
                                                                break;
+                                                       }
+                               }
 
-                                                       default:
-                                                               path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->tstore_where), &iter);
-                                                               indices = gtk_tree_path_get_indices (path);
-                                                               if (indices[0] != 0)
-                                                                       {
-                                                                               g_warning (_("Link type «%d» not valid."), link_type);
-                                                                               continue;
-                                                                       }
-                                                               else
-                                                                       {
-                                                                               str_link = g_strdup ("");
-                                                                               break;
-                                                                       }
-                                               }
-
+                       if (!is_group)
+                               {
                                        switch (where_type)
                                                {
                                                        case GDAEX_QE_WHERE_TYPE_EQUAL:
@@ -1671,23 +1688,110 @@ xmlNode
                                                                continue;
                                                }
 
-                                       node = xmlNewNode (NULL, "field");
+                                       xnode = xmlNewNode (NULL, "field");
+
+                                       xmlAddChild (xnode_parent, xnode);
+
+                                       xmlNewProp (xnode, "table", table_name);
+                                       xmlNewProp (xnode, "field", field_name);
+                                       xmlNewProp (xnode, "link_type", str_link);
+                                       xmlNewProp (xnode, "not", (not ? "y" : "n"));
+                                       xmlNewProp (xnode, "where_type", str_op);
+                                       xmlNewProp (xnode, "from", from_str);
+                                       xmlNewProp (xnode, "to", to_str);
+
+                                       g_free (str_op);
+                               }
+                       else
+                               {
+                                       if (gtk_tree_model_iter_children (GTK_TREE_MODEL (priv->tstore_where), &children, iter))
+                                               {
+                                                       xnode = xmlNewNode (NULL, "group");
+
+                                                       xmlAddChild (xnode_parent, xnode);
+
+                                                       xmlNewProp (xnode, "not", (not ? "y" : "n"));
+
+                                                       gdaex_query_editor_xml_where (qe, &children, iter, xnode);
+                                               }
+                               }
+
+                       g_free (str_link);
+               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->tstore_where), iter));
+}
+
+xmlNode
+*gdaex_query_editor_get_sql_as_xml (GdaExQueryEditor *qe)
+{
+       GdaExQueryEditorPrivate *priv;
+
+       xmlNode *ret;
+
+       GtkTreeIter iter;
+
+       gchar *table_name;
+       gchar *field_name;
+
+       GdaExQueryEditorTable *table;
+       GdaExQueryEditorField *field;
+
+       xmlNode *node;
+
+       ret = NULL;
+
+       g_return_val_if_fail (GDAEX_IS_QUERY_EDITOR (qe), NULL);
 
-                                       xmlAddChild (node_where, node);
+       priv = GDAEX_QUERY_EDITOR_GET_PRIVATE (qe);
+
+       ret = xmlNewNode (NULL, "gdaex_query_editor_choices");
+
+       /* SHOW */
+       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->lstore_show), &iter))
+               {
+                       gchar *alias;
+                       xmlNode *node_show;
+
+                       node_show = xmlNewNode (NULL, "show");
+                       xmlAddChild (ret, node_show);
+
+                       do
+                               {
+                                       gtk_tree_model_get (GTK_TREE_MODEL (priv->lstore_show), &iter,
+                                                           COL_SHOW_TABLE_NAME, &table_name,
+                                                           COL_SHOW_NAME, &field_name,
+                                                           COL_SHOW_ALIAS, &alias,
+                                                           -1);
+
+                                       table = g_hash_table_lookup (priv->tables, table_name);
+                                       field = g_hash_table_lookup (table->fields, field_name);
 
+                                       node = xmlNewNode (NULL, "field");
+                                       xmlAddChild (node_show, node);
                                        xmlNewProp (node, "table", table_name);
                                        xmlNewProp (node, "field", field_name);
-                                       xmlNewProp (node, "link_type", str_link);
-                                       xmlNewProp (node, "not", (not ? "y" : "n"));
-                                       xmlNewProp (node, "where_type", str_op);
-                                       xmlNewProp (node, "from", from_str);
-                                       xmlNewProp (node, "to", to_str);
+                                       if (alias != NULL && g_strcmp0 (alias, "") != 0)
+                                               {
+                                                       xmlNewProp (node, "alias", alias);
+                                               }
+                                       else
+                                               {
+                                                       xmlNewProp (node, "alias", field->alias);
+                                               }
+                               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->lstore_show), &iter));
+               }
 
-                                       g_free (str_op);
-                                       g_free (str_link);
-                               } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->tstore_where), &iter));
+       /* WHERE */
+       if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->tstore_where), &iter))
+               {
+                       xmlNode *node_where;
+
+                       node_where = xmlNewNode (NULL, "where");
+                       xmlAddChild (ret, node_where);
+
+                       gdaex_query_editor_xml_where (qe, &iter, NULL, node_where);
                }
 
+       /* ORDER */
        if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->lstore_order), &iter))
                {
                        gchar *asc_desc;
@@ -2716,7 +2820,7 @@ gdaex_query_editor_on_btn_save_clicked (GtkButton *button,
                                                /* if it is the first condition, "link" doesn't is visibile */
                                                GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->tstore_where), &iter);
                                                gint *indices = gtk_tree_path_get_indices (path);
-                                               if (indices[0] != 0)
+                                               if (indices[gtk_tree_path_get_depth (path) - 1] != 0)
                                                        {
                                                                model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->cb_link_type));
                                                                if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->cb_link_type), &iter_val))
@@ -3159,7 +3263,7 @@ gdaex_query_editor_on_btn_where_add_group_clicked (GtkButton *button,
        gtk_tree_store_set (priv->tstore_where, &iter,
                            COL_WHERE_TABLE_NAME, GROUP,
                            COL_WHERE_NAME, GROUP,
-                           COL_WHERE_VISIBLE_NAME, "( )",
+                           COL_WHERE_VISIBLE_NAME, "(...)",
                            -1);
        gtk_tree_view_expand_to_path (GTK_TREE_VIEW (priv->trv_where),
                                      gtk_tree_model_get_path (GTK_TREE_MODEL (priv->tstore_where), &iter));
@@ -3376,7 +3480,7 @@ gdaex_query_editor_on_sel_where_changed (GtkTreeSelection *treeselection,
                                }
 
                        /* if it is the first condition, "link" isn't visibile */
-                       if (indices[0] != 0)
+                       if (indices[gtk_tree_path_get_depth (path) - 1] != 0)
                                {
                                        if (link_type != 0
                                            && gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->lstore_link_type), &iter_cb))