[libgda] Generalized usage of gda_sql_identifier_quote()



commit 01abd214235544a1a46a5e39e5f45a469ac4dfc7
Author: Vivien Malerba <malerba gnome-db org>
Date:   Fri Jul 10 20:55:53 2009 +0200

    Generalized usage of gda_sql_identifier_quote()
    
    * improved doc. related to SQL identifiers
    * use gda_sql_identifier_quote() whenever possible
    * fixed test data which used SQL reserved keywords

 doc/C/Makefile.am                                |    3 +-
 doc/C/SqlIdentifiers.dia                         |  Bin 0 -> 2964 bytes
 doc/C/SqlIdentifiers.png                         |  Bin 0 -> 54538 bytes
 doc/C/libgda-4.0-docs.sgml                       |   88 ++++++++++-----
 doc/C/libgda-4.0-sections.txt                    |    1 +
 libgda/gda-data-proxy.c                          |   23 ++--
 libgda/gda-data-select.c                         |    2 +-
 libgda/gda-easy.c                                |   39 ++-----
 libgda/gda-meta-struct-io.c                      |   32 ++----
 libgda/gda-statement.c                           |   62 +++++++++--
 libgda/gda-util.c                                |   80 ++++++++++---
 libgda/libgda.symbols                            |    1 +
 libgda/sql-parser/gda-statement-struct-util.c    |   11 ++-
 libgda/sqlite/gda-sqlite-provider.c              |   13 +--
 libgda/sqlite/virtual/gda-vprovider-data-model.c |    4 +-
 po/POTFILES.in                                   |    1 -
 providers/mysql/gda-mysql-provider.c             |  130 +---------------------
 tests/gda-ddl-creator.c                          |   24 ++--
 tests/parser/testdata.xml                        |   78 +++++++-------
 tools/gda-sql.c                                  |   20 +---
 tools/web-server.c                               |   14 +--
 21 files changed, 285 insertions(+), 341 deletions(-)
---
diff --git a/doc/C/Makefile.am b/doc/C/Makefile.am
index f1947a9..7c084e9 100644
--- a/doc/C/Makefile.am
+++ b/doc/C/Makefile.am
@@ -55,7 +55,8 @@ HTML_IMAGES = DataModels.png \
 	data_proxy1.png data_proxy2.png data_proxy3.png data_proxy4.png data_proxy5.png \
 	gda-sql-graph.png howto-exec.png \
 	parser_gen.png parser_prov.png \
-	tree-overview.png tree-overview2.png
+	tree-overview.png tree-overview2.png \
+	SqlIdentifiers.png
 
 # Extra options to supply to gtkdoc-fixref
 FIXXREF_OPTIONS=
diff --git a/doc/C/SqlIdentifiers.dia b/doc/C/SqlIdentifiers.dia
new file mode 100644
index 0000000..e8f105e
Binary files /dev/null and b/doc/C/SqlIdentifiers.dia differ
diff --git a/doc/C/SqlIdentifiers.png b/doc/C/SqlIdentifiers.png
new file mode 100644
index 0000000..d4a16da
Binary files /dev/null and b/doc/C/SqlIdentifiers.png differ
diff --git a/doc/C/libgda-4.0-docs.sgml b/doc/C/libgda-4.0-docs.sgml
index fb3cd48..b03967e 100644
--- a/doc/C/libgda-4.0-docs.sgml
+++ b/doc/C/libgda-4.0-docs.sgml
@@ -438,6 +438,62 @@
     <para>
       The following sections describe the API available for &GDA; applications.
     </para>
+    <chapter>
+      <title>Foreword about abstraction</title>
+      <para>
+	&LIBGDA; aims both at making it easier to use databases and, for applications written using it, 
+	at making it easier to switch to a different database or to to be able to use different types of databases
+	with a minimum or no code modifications. To achieve the 2nd goal, &LIBGDA; proposes an abstraction of
+	most of database's engine features, which has to be understood to write portable code.
+      </para>
+
+      <sect1 id="gen:sql_identifiers">
+	<title>SQL identifiers</title>
+	<para>
+	  The SQL standard has never defined if SQL identifiers (database object's names) have to be case sensitive
+	  or not, leaving that
+	  subject to each database engine implementation. All of them accept two syntaxes for SQL identifiers:
+	  <itemizedlist>
+	    <listitem><para>the first is if the SQL identifier is surrounded by double quotes (sometimes backquotes
+		or other characters), making the SQL identifier case sensitive (and also making
+		it possible to use reserved SQL keywords as identifiers).</para></listitem>
+	    <listitem><para>the second is if it's not enquoted, meaning that the SQL identifier is not
+		case sensitive.</para></listitem>
+	  </itemizedlist>
+	  <note>
+	    <para>
+	      Many people consider that using the quoted syntax should be avoided if possible because:
+	      <itemizedlist>
+		<listitem><para>once an SQL identifier has been defined using the quoted syntax, it must
+		    <emphasis>always</emphasis> be used quoted, which is error prone especially if external
+		    tools are used on the database</para></listitem>
+		<listitem><para>the SQL code is less readable (there are quoted strings everywhere)</para></listitem>
+		<listitem><para>the SQL code is less portable as each database engine sets up different techniques to
+		    avoid confusing the SQL identifiers' quoting with SQL literals which are quoted when writing
+		    complex statements</para></listitem>
+		<listitem><para>writing SQL requires a more in-depth knowledge of the database engine being used and as
+		    a consequence it's far easier to make errors when writing SQL</para></listitem>
+	      </itemizedlist>
+	      For some more example, see
+	      <ulink url="http://www.alberton.info/dbms_identifiers_and_case_sensitivity.html";>Database identifiers, quoting and case sensitivity</ulink> from  Lorenzo Alberton.
+	    </para>
+	  </note>
+	</para>
+
+	<para>
+	  The following diagram illustrates how &LIBGDA; handles SQL identifiers' representations depending where
+	  they are used:
+	  <mediaobject>
+	    <imageobject role="html">
+	      <imagedata fileref="SqlIdentifiers.png" format="PNG"/>
+	    </imageobject>
+	    <textobject>
+	      <phrase>Diagram illustrating how &LIBGDA; handles SQL identifiers' representations</phrase>
+	    </textobject>
+	  </mediaobject>
+	</para>
+      </sect1>
+    </chapter>
 
     &howto;
     <chapter>
@@ -1070,35 +1126,9 @@ g_object_unref (store);
 	<sect2 id="information_schema:sql_identifiers">
 	  <title>SQL identifiers</title>
 	  <para>
-	    The SQL standard has never defined if SQL identifiers (database object's names) have to be case sensitive
-	    or not, leaving that
-	    subject to each database engine implementation. All of them accept two syntaxes for SQL identifiers:
-	    <itemizedlist>
-	      <listitem><para>the first is if the SQL identifier is surrounded by double quotes (sometimes simple
-		  quotes are also accepted), making the SQL identifier case sensitive (and also making
-		  it possible to use reserved SQL keywords as identifiers).</para></listitem>
-	      <listitem><para>the second is if it's not enquoted, meaning that the SQL identifier is not
-		  case sensitive.</para></listitem>
-	    </itemizedlist>
-	    <note>
-	      <para>
-		Many people consider that using the quoted syntax should be avoided if possible because:
-		<itemizedlist>
-		  <listitem><para>once an SQL identifier has been defined using the quoted syntax, it must
-		      <emphasis>always</emphasis> be used quoted, which is error prone especially if external
-		      tools are used on the database</para></listitem>
-		  <listitem><para>the SQL code is less readable (there are quoted strings everywhere)</para></listitem>
-		  <listitem><para>the SQL code is less portable as each database engine sets up different techniques to
-		      avoid confusing the SQL identifiers' quoting with SQL literals which are quoted when writing
-		      complex statements</para></listitem>
-		  <listitem><para>writing SQL requires a more in-depth knowledge of the database engine being used and as
-		      a consequence it's far easier to make errors when writing SQL</para></listitem>
-		</itemizedlist>
-		For some more example, see
-		<ulink url="http://www.alberton.info/dbms_identifiers_and_case_sensitivity.html";>Database identifiers, quoting and case sensitivity</ulink> from  Lorenzo Alberton.
-	      </para>
-	    </note>
-	  </para>
+	    Please refer to the <link linkend="gen:sql_identifiers">SQL identifiers and abstraction</link> section
+	    for an overview of how SQL identifiers are handled thoughout &LIBGDA;
+	  </para> 
 	  <para>
 	    Considering that each database has its own
 	    internal way of representing case insensitive SQL identifiers (for instance PostgreSQL
diff --git a/doc/C/libgda-4.0-sections.txt b/doc/C/libgda-4.0-sections.txt
index 4fc8928..92a43fa 100644
--- a/doc/C/libgda-4.0-sections.txt
+++ b/doc/C/libgda-4.0-sections.txt
@@ -1466,6 +1466,7 @@ gda_meta_store_set_reserved_keywords_func
 gda_compute_dml_statements
 gda_compute_select_statement_from_update
 gda_compute_unique_table_row_condition
+gda_compute_unique_table_row_condition_with_cnc
 <SUBSECTION>
 gda_sql_any_part_check_structure
 </SECTION>
diff --git a/libgda/gda-data-proxy.c b/libgda/gda-data-proxy.c
index 7d5a946..4594739 100644
--- a/libgda/gda-data-proxy.c
+++ b/libgda/gda-data-proxy.c
@@ -2824,7 +2824,7 @@ gda_data_proxy_cancel_all_changes (GdaDataProxy *proxy)
 }
 
 static gboolean
-sql_where_foreach (GdaSqlAnyPart *part, GdaDataModel *model, GError **error)
+sql_where_foreach (GdaSqlAnyPart *part, GdaDataProxy *proxy, GError **error)
 {
 	if (part->type == GDA_SQL_ANY_EXPR) {
 		GdaSqlExpr *expr = (GdaSqlExpr*) part;
@@ -2840,14 +2840,15 @@ sql_where_foreach (GdaSqlAnyPart *part, GdaDataModel *model, GError **error)
 					gint colnum;
 					colnum = atoi (cstr+1) - 1;
 					if (colnum >= 0) {
-						GdaColumn *col = gda_data_model_describe_column (model, colnum);
+						GdaColumn *col = gda_data_model_describe_column ((GdaDataModel*) proxy,
+												 colnum);
 						const gchar *cname = gda_column_get_name (col);
 						if (cname && *cname) {
-							if (gda_sql_identifier_needs_quotes (cname))
-								g_value_take_string (expr->value, 
-										     g_strdup_printf ("\"%s\"", cname));
-							else
-								g_value_set_string (expr->value, cname);
+							g_value_take_string (expr->value,
+									     gda_sql_identifier_quote (cname,
+												       proxy->priv->filter_vcnc,
+												       NULL,
+												       FALSE, FALSE));
 						}
 					}
 				}
@@ -3110,12 +3111,8 @@ gda_data_proxy_set_ordering_column (GdaDataProxy *proxy, gint col, GError **erro
 		gchar *colname;
 
 		cname = gda_column_get_name (gda_data_model_describe_column ((GdaDataModel*) proxy, col));
-		if (cname && *cname) {
-			if (gda_sql_identifier_needs_quotes (cname))
-				colname = g_strdup_printf ("\"%s\"", cname);
-			else
-				colname = g_strdup (cname);
-		}
+		if (cname && *cname)
+			colname = gda_sql_identifier_quote (cname, proxy->priv->filter_vcnc, NULL, FALSE, FALSE);
 		else
 			colname = g_strdup_printf ("_%d", col + 1);
 
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index ed7fb7c..5b16f2c 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -3103,7 +3103,7 @@ compute_insert_select_params_mapping (GdaSet *sel_params, GdaSet *ins_values, Gd
 			goto onerror;
 		}
 		g_assert (cdata.colid);
-		if (*(cdata.colid) == '"')
+		if ((*(cdata.colid) == '"') || (*(cdata.colid) == '`'))
 			gda_sql_identifier_remove_quotes ((gchar*) cdata.colid);
 		/*g_print ("SEL param '%s' <=> column named '%s'\n", cdata.hid, cdata.colid);*/
 		
diff --git a/libgda/gda-easy.c b/libgda/gda-easy.c
index 73cf1ee..c942ba4 100644
--- a/libgda/gda-easy.c
+++ b/libgda/gda-easy.c
@@ -25,6 +25,7 @@
 #include <sql-parser/gda-sql-parser.h>
 #include <sql-parser/gda-sql-statement.h>
 #include <libgda/gda-holder.h>
+#include <libgda/gda-util.h>
 
 static GStaticMutex parser_mutex = G_STATIC_MUTEX_INIT;
 static GdaSqlParser *internal_parser = NULL;
@@ -646,10 +647,7 @@ gda_insert_row_into_table_v (GdaConnection *cnc, const gchar *table,
 	g_assert (GDA_SQL_ANY_PART (ssi)->type == GDA_SQL_ANY_STMT_INSERT);
 
 	ssi->table = gda_sql_table_new (GDA_SQL_ANY_PART (ssi));
-	if (gda_sql_identifier_needs_quotes (table))
-		ssi->table->table_name = gda_sql_identifier_add_quotes (table);
-	else
-		ssi->table->table_name = g_strdup (table);
+	ssi->table->table_name = gda_sql_identifier_quote (table, cnc, NULL, FALSE, FALSE);
 
 	i = 0;
 	for (l1 = col_names, l2 = values;
@@ -662,10 +660,7 @@ gda_insert_row_into_table_v (GdaConnection *cnc, const gchar *table,
 		
 		/* field */
 		field = gda_sql_field_new (GDA_SQL_ANY_PART (ssi));
-		if (gda_sql_identifier_needs_quotes (col_name))
-			field->field_name = gda_sql_identifier_add_quotes (col_name);
-		else
-			field->field_name = g_strdup (col_name);
+		field->field_name = gda_sql_identifier_quote (col_name, cnc, NULL, FALSE, FALSE);
 		fields = g_slist_prepend (fields, field);
 
 		/* value */
@@ -822,10 +817,7 @@ gda_update_row_in_table_v (GdaConnection *cnc, const gchar *table,
 	g_assert (GDA_SQL_ANY_PART (ssu)->type == GDA_SQL_ANY_STMT_UPDATE);
 
 	ssu->table = gda_sql_table_new (GDA_SQL_ANY_PART (ssu));
-	if (gda_sql_identifier_needs_quotes (table))
-		ssu->table->table_name = gda_sql_identifier_add_quotes (table);
-	else
-		ssu->table->table_name = g_strdup (table);
+	ssu->table->table_name = gda_sql_identifier_quote (table, cnc, NULL, FALSE, FALSE);
 
 	if (condition_column_name) {
 		GdaSqlExpr *where, *op;
@@ -838,10 +830,8 @@ gda_update_row_in_table_v (GdaConnection *cnc, const gchar *table,
 		op = gda_sql_expr_new (GDA_SQL_ANY_PART (where->cond));
 		where->cond->operands = g_slist_prepend (NULL, op);
 		op->value = gda_value_new (G_TYPE_STRING);
-		if (gda_sql_identifier_needs_quotes (condition_column_name))
-			g_value_take_string (op->value, gda_sql_identifier_add_quotes (condition_column_name));
-		else
-			g_value_set_string (op->value, condition_column_name);
+		g_value_take_string (op->value, gda_sql_identifier_quote (condition_column_name, cnc, NULL,
+									  FALSE, FALSE));
 
 		op = gda_sql_expr_new (GDA_SQL_ANY_PART (where->cond));
 		where->cond->operands = g_slist_append (where->cond->operands, op);
@@ -875,10 +865,7 @@ gda_update_row_in_table_v (GdaConnection *cnc, const gchar *table,
 		
 		/* field */
 		field = gda_sql_field_new (GDA_SQL_ANY_PART (ssu));
-		if (gda_sql_identifier_needs_quotes (col_name))
-			field->field_name = gda_sql_identifier_add_quotes (col_name);
-		else
-			field->field_name = g_strdup (col_name);
+		field->field_name = gda_sql_identifier_quote (col_name, cnc, NULL, FALSE, FALSE);
 		fields = g_slist_prepend (fields, field);
 
 		/* value */
@@ -951,7 +938,6 @@ gda_delete_row_from_table (GdaConnection *cnc, const gchar *table,
 			   GValue *condition_value, GError **error)
 {
 	gboolean retval;
-	gchar *col_name;
 	GdaSqlStatement *sql_stm;
 	GdaSqlStatementDelete *ssd;
 	GdaStatement *delete;
@@ -967,10 +953,7 @@ gda_delete_row_from_table (GdaConnection *cnc, const gchar *table,
 	g_assert (GDA_SQL_ANY_PART (ssd)->type == GDA_SQL_ANY_STMT_DELETE);
 
 	ssd->table = gda_sql_table_new (GDA_SQL_ANY_PART (ssd));
-	if (gda_sql_identifier_needs_quotes (table))
-		ssd->table->table_name = gda_sql_identifier_add_quotes (table);
-	else
-		ssd->table->table_name = g_strdup (table);
+	ssd->table->table_name = gda_sql_identifier_quote (table, cnc, NULL, FALSE, FALSE);
 
 	if (condition_column_name) {
 		GdaSqlExpr *where, *op;
@@ -983,10 +966,8 @@ gda_delete_row_from_table (GdaConnection *cnc, const gchar *table,
 		op = gda_sql_expr_new (GDA_SQL_ANY_PART (where->cond));
 		where->cond->operands = g_slist_prepend (NULL, op);
 		op->value = gda_value_new (G_TYPE_STRING);
-		if (gda_sql_identifier_needs_quotes (condition_column_name))
-			g_value_take_string (op->value, gda_sql_identifier_add_quotes (condition_column_name));
-		else
-			g_value_set_string (op->value, condition_column_name);
+		g_value_take_string (op->value, gda_sql_identifier_quote (condition_column_name, cnc, NULL,
+									  FALSE, FALSE));
 
 		op = gda_sql_expr_new (GDA_SQL_ANY_PART (where->cond));
 		where->cond->operands = g_slist_append (where->cond->operands, op);
diff --git a/libgda/gda-meta-struct-io.c b/libgda/gda-meta-struct-io.c
index c6e4d83..400067b 100644
--- a/libgda/gda-meta-struct-io.c
+++ b/libgda/gda-meta-struct-io.c
@@ -62,17 +62,11 @@ gda_meta_struct_load_from_xml_file (GdaMetaStruct *mstruct, const gchar *catalog
 
 	if (catalog) {
 		g_value_set_string ((catalog_value = gda_value_new (G_TYPE_STRING)), catalog);
-		if (gda_sql_identifier_needs_quotes (catalog)) 
-			quoted_catalog = gda_sql_identifier_add_quotes (catalog);
-		else
-			quoted_catalog = g_strdup (catalog);
+		quoted_catalog = gda_sql_identifier_quote (catalog, NULL, NULL, FALSE, FALSE);
 	}
 	if (schema) {
 		g_value_set_string ((schema_value = gda_value_new (G_TYPE_STRING)), schema);
-		if (gda_sql_identifier_needs_quotes (schema)) 
-			quoted_schema = gda_sql_identifier_add_quotes (schema);
-		else
-			quoted_schema = g_strdup (schema);
+		quoted_schema = gda_sql_identifier_quote (schema, NULL, NULL, FALSE, FALSE);
 	}
 
 	/* load information schema's structure XML file */
@@ -168,6 +162,7 @@ create_table_object (GdaMetaStruct *mstruct, const GValue *catalog, const gchar
 	xmlChar *table_name, *table_schema;
 	GString *full_table_name;
 	GValue *v1 = NULL, *v2 = NULL, *v3 = NULL;
+	gchar *tmp;
 
 	table_name = xmlGetProp (node, BAD_CAST "name");
 	if (!table_name) {
@@ -186,13 +181,9 @@ create_table_object (GdaMetaStruct *mstruct, const GValue *catalog, const gchar
 	}
 	if (table_schema) {
 		g_value_set_string ((v2 = gda_value_new (G_TYPE_STRING)), (gchar *) table_schema);
-		if (gda_sql_identifier_needs_quotes ((gchar *) table_schema)) {
-			gchar *tmp = gda_sql_identifier_add_quotes ((gchar *) table_schema);
-			g_string_append (full_table_name, tmp);
-			g_free (tmp);
-		}
-		else
-			g_string_append (full_table_name, (gchar*) table_schema);
+		tmp = gda_sql_identifier_quote ((gchar *) table_schema, NULL, NULL, FALSE, FALSE);
+		g_string_append (full_table_name, tmp);
+		g_free (tmp);
 		g_string_append_c (full_table_name, '.');
 	}
 	else if (quoted_schema) {
@@ -201,13 +192,10 @@ create_table_object (GdaMetaStruct *mstruct, const GValue *catalog, const gchar
 		g_string_append_c (full_table_name, '.');
 	}
 	g_value_set_string ((v3 = gda_value_new (G_TYPE_STRING)), (gchar *) table_name);
-	if (gda_sql_identifier_needs_quotes ((gchar *) table_name)) {
-		gchar *tmp = gda_sql_identifier_add_quotes ((gchar *) table_name);
-		g_string_append (full_table_name, tmp);
-		g_free (tmp);
-	}
-	else
-		g_string_append (full_table_name, (gchar *) table_name);
+	
+	tmp = gda_sql_identifier_quote ((gchar *) table_name, NULL, NULL, FALSE, FALSE);
+	g_string_append (full_table_name, tmp);
+	g_free (tmp);
 
 	/* a new GdaMetaDbObject structure */
 	dbobj = g_new0 (GdaMetaDbObject, 1);
diff --git a/libgda/gda-statement.c b/libgda/gda-statement.c
index 5a35480..2f4db6b 100644
--- a/libgda/gda-statement.c
+++ b/libgda/gda-statement.c
@@ -1395,7 +1395,29 @@ default_render_table (GdaSqlTable *table, GdaSqlRenderingContext *context, GErro
 	/* can't have: table->table_name not a valid SQL identifier */
 	if (!gda_sql_any_part_check_structure (GDA_SQL_ANY_PART (table), error)) return NULL;
 
-	return g_strdup (table->table_name);
+	gchar **ids_array;
+	ids_array = gda_sql_identifier_split (table->table_name);
+	if (!ids_array) {
+		g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
+			     "%s", _("Malformed table name"));
+		return NULL;
+	}
+	
+	gint i;
+	GString *string;
+	string = g_string_new ("");
+	for (i = 0; ids_array [i]; i++) {
+		gchar *tmp;
+		tmp = gda_sql_identifier_quote (ids_array [i], context->cnc, context->provider,
+						FALSE, FALSE);
+		g_free (ids_array [i]);
+		ids_array [i] = tmp;
+		if (i != 0)
+			g_string_append_c (string, '.');
+		g_string_append (string, ids_array [i]);
+	}
+	g_strfreev (ids_array);
+	return g_string_free (string, FALSE);
 }
 
 static gchar *
@@ -1736,11 +1758,35 @@ default_render_select_target (GdaSqlSelectTarget *target, GdaSqlRenderingContext
 	/* can't have: target->expr == NULL */
 	if (!gda_sql_any_part_check_structure (GDA_SQL_ANY_PART (target), error)) return NULL;
 
-	string = g_string_new ("");
-	str = context->render_expr (target->expr, context, NULL, NULL, error);
-	if (!str) goto err;
-	g_string_append (string, str);
-	g_free (str);
+	if (! target->expr->value || (G_VALUE_TYPE (target->expr->value) != G_TYPE_STRING)) {
+		str = context->render_expr (target->expr, context, NULL, NULL, error);
+		if (!str)
+			return NULL;
+		string = g_string_new (str);
+	}
+	else {
+		gchar **ids_array;
+		ids_array = gda_sql_identifier_split (g_value_get_string (target->expr->value));
+		if (!ids_array) {
+			g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
+				     "%s", _("Malformed expression in select target"));
+			return NULL;
+		}
+
+		gint i;
+		string = g_string_new ("");
+		for (i = 0; ids_array [i]; i++) {
+			gchar *tmp;
+			tmp = gda_sql_identifier_quote (ids_array [i], context->cnc, context->provider,
+							FALSE, FALSE);
+			g_free (ids_array [i]);
+			ids_array [i] = tmp;
+			if (i != 0)
+				g_string_append_c (string, '.');
+			g_string_append (string, ids_array [i]);
+		}
+		g_strfreev (ids_array);
+	}
 
 	if (target->as)
 		g_string_append_printf (string, " AS %s", target->as);
@@ -1748,10 +1794,6 @@ default_render_select_target (GdaSqlSelectTarget *target, GdaSqlRenderingContext
 	str = string->str;
 	g_string_free (string, FALSE);
 	return str;
-
- err:
-	g_string_free (string, TRUE);
-	return NULL;
 }
 
 static gchar *
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index 3152174..66df7a2 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -779,7 +779,8 @@ dml_statements_check_select_structure (GdaConnection *cnc, GdaSqlStatement *sel_
 }
 
 /**
- * gda_compute_unique_table_row_condition
+ * gda_compute_unique_table_row_condition_with_cnc
+ * @cnc: a #GdaConnection, or %NULL
  * @stsel: a #GdaSqlSelectStatement
  * @mtable: a #GdaMetaTable
  * @require_pk: set to TRUE if a primary key ir required
@@ -789,14 +790,19 @@ dml_statements_check_select_structure (GdaConnection *cnc, GdaSqlStatement *sel_
  * or DELETE statement when a row from the result of the @stsel statement has to be modified.
  *
  * Returns: a new #GdaSqlExpr, or %NULL if an error occurred.
+ *
+ * Since: 4.0.3
  */
 GdaSqlExpr*
-gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTable *mtable, gboolean require_pk, GError **error)
+gda_compute_unique_table_row_condition_with_cnc (GdaConnection *cnc, GdaSqlStatementSelect *stsel,
+						 GdaMetaTable *mtable, gboolean require_pk, GError **error)
 {
 	gint i;
 	GdaSqlExpr *expr;
 	GdaSqlOperation *and_cond = NULL;
 
+	g_return_val_if_fail (!cnc || GDA_IS_CONNECTION (cnc), NULL);
+
 	if (mtable->pk_cols_nb == 0) {
 		g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
 			     "%s", _("Table does not have any primary key"));
@@ -854,8 +860,11 @@ gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTab
 				}
 				op->operator_type = GDA_SQL_OPERATOR_TYPE_EQ;
 				/* left operand */
+				gchar *str;
 				opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
-				g_value_set_string (opexpr->value = gda_value_new (G_TYPE_STRING), tcol->column_name);
+				str = gda_sql_identifier_quote (tcol->column_name, cnc, NULL, TRUE, FALSE);
+				g_value_take_string (opexpr->value = gda_value_new (G_TYPE_STRING), str);
+
 				op->operands = g_slist_append (op->operands, opexpr);
 
 				/* right operand */
@@ -882,6 +891,24 @@ gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTab
 }
 
 /**
+ * gda_compute_unique_table_row_condition
+ * @stsel: a #GdaSqlSelectStatement
+ * @mtable: a #GdaMetaTable
+ * @require_pk: set to TRUE if a primary key ir required
+ * @error: a place to store errors, or %NULL
+ * 
+ * Computes a #GdaSqlExpr expression which can be used in the WHERE clause of an UPDATE
+ * or DELETE statement when a row from the result of the @stsel statement has to be modified.
+ *
+ * Returns: a new #GdaSqlExpr, or %NULL if an error occurred.
+ */
+GdaSqlExpr*
+gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTable *mtable, gboolean require_pk, GError **error)
+{
+	return gda_compute_unique_table_row_condition_with_cnc (NULL, stsel, mtable, require_pk, error);
+}
+
+/**
  * gda_compute_dml_statements
  * @cnc: a #GdaConnection
  * @select_stmt: a SELECT #GdaStatement (compound statements not handled)
@@ -941,7 +968,9 @@ gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gbool
 	stsel = (GdaSqlStatementSelect*) sel_struct->contents;
 	target = (GdaSqlSelectTarget*) stsel->from->targets->data;
 	
-	/* actual statement structure's computation */        
+	/* actual statement structure's computation */
+	gchar *tmp;
+	tmp = gda_sql_identifier_quote (target->table_name, cnc, NULL, TRUE, FALSE);
 	if (insert_stmt) {
 		sql_ist = gda_sql_statement_new (GDA_SQL_STATEMENT_INSERT);
 		ist = (GdaSqlStatementInsert*) sql_ist->contents;
@@ -957,10 +986,10 @@ gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gbool
 		g_assert (GDA_SQL_ANY_PART (ust)->type == GDA_SQL_ANY_STMT_UPDATE);
 
 		ust->table = gda_sql_table_new (GDA_SQL_ANY_PART (ust));
-		ust->table->table_name = g_strdup ((gchar *) target->table_name);
-		ust->cond = gda_compute_unique_table_row_condition (stsel, 
-								    GDA_META_TABLE (target->validity_meta_object),
-								    require_pk, error);
+		ust->table->table_name = g_strdup (tmp);
+		ust->cond = gda_compute_unique_table_row_condition_with_cnc (cnc, stsel, 
+									     GDA_META_TABLE (target->validity_meta_object),
+									     require_pk, error);
 		if (!ust->cond) {
 			retval = FALSE;
 			goto cleanup;
@@ -974,16 +1003,17 @@ gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gbool
 		g_assert (GDA_SQL_ANY_PART (dst)->type == GDA_SQL_ANY_STMT_DELETE);
 
 		dst->table = gda_sql_table_new (GDA_SQL_ANY_PART (dst));
-		dst->table->table_name = g_strdup ((gchar *) target->table_name);
-		dst->cond = gda_compute_unique_table_row_condition (stsel, 
-								    GDA_META_TABLE (target->validity_meta_object),
-								    require_pk, error);
+		dst->table->table_name = g_strdup (tmp);
+		dst->cond = gda_compute_unique_table_row_condition_with_cnc (cnc, stsel, 
+									     GDA_META_TABLE (target->validity_meta_object),
+									     require_pk, error);
 		if (!dst->cond) {
 			retval = FALSE;
 			goto cleanup;
 		}
 		GDA_SQL_ANY_PART (dst->cond)->parent = GDA_SQL_ANY_PART (dst);
 	}
+	g_free (tmp);
 
 	GSList *expr_list;
 	gint colindex;
@@ -1002,6 +1032,9 @@ gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gbool
 		if (g_hash_table_lookup (fields_hash, selfield->field_name))
 			continue;
 		g_hash_table_insert (fields_hash, selfield->field_name, GINT_TO_POINTER (1));
+
+		gchar *str;
+		str = gda_sql_identifier_quote (selfield->field_name, cnc, NULL, TRUE, FALSE);
 		if (insert_stmt) {
 			GdaSqlField *field;
 			field = gda_sql_field_new (GDA_SQL_ANY_PART (ist));
@@ -1560,7 +1593,8 @@ static gboolean _sql_identifier_needs_quotes (const gchar *str);
  * If @id already has quotes, then this function returns a copy of @id, except that the quotes may be
  * replaced by database specific characters (such as the backquote for MySQL).
  *
- * If @id has no quotes, and if none are requited, then this function returns a copy if @id. The criteria to
+ * If @id has no quotes, if none are requited, and if @force_quotes if %FALSE, 
+ * then this function returns a copy if @id. The criteria to
  * determine if @id needs quotes depends on the database provider associated to @cnc, and if @cnc is %NULL, then
  * in all the following cases quotes are required:
  * <itemizedlist>
@@ -1571,7 +1605,14 @@ static gboolean _sql_identifier_needs_quotes (const gchar *str);
  *
  * If @force_quotes is %TRUE, then the this function always returns a quoted SQL identifier.
  *
- * Returns: the possibly quoted representation of @id as a new string, or %NULL if @id is in a wrong format
+ * Note that @id must not be a composed SQL identifier (such as "mytable.mycolumn" which should be
+ * treated as the "mytable" and "mycolumn" SQL identifiers). If unsure, use gda_sql_identifier_split().
+ *
+ * For more information, see the <link linkend="gen:sql_identifiers">SQL identifiers and abstraction</link> and
+ * <link linkend="information_schema:sql_identifiers">SQL identifiers in meta data</link> sections.
+ *
+ * Returns: the representation of @id ready to be used in SQL statement, as a new string,
+ *          or %NULL if @id is in a wrong format
  *
  * Since: 4.0.3
  */
@@ -1580,12 +1621,15 @@ gda_sql_identifier_quote (const gchar *id, GdaConnection *cnc, GdaServerProvider
 			  gboolean meta_store_convention, gboolean force_quotes)
 {
 	g_return_val_if_fail (id && *id, NULL);
-	if (cnc)
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	if (prov)
 		g_return_val_if_fail (GDA_IS_SERVER_PROVIDER (prov), NULL);
-	if (cnc && prov)
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == prov, NULL);
+	if (cnc) {
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		if (prov)
+			g_return_val_if_fail (gda_connection_get_provider (cnc) == prov, NULL);
+		else
+			prov = gda_connection_get_provider (cnc);
+	}
 
 	if (prov && PROV_CLASS (prov)->identifier_quote) {
 		return PROV_CLASS (prov)->identifier_quote (prov, cnc, id,
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 08d004a..0f90787 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -66,6 +66,7 @@
 	gda_compute_dml_statements
 	gda_compute_select_statement_from_update
 	gda_compute_unique_table_row_condition
+	gda_compute_unique_table_row_condition_with_cnc
 	gda_config_can_modify_system_config
 	gda_config_define_dsn
 	gda_config_dsn_needs_authentication
diff --git a/libgda/sql-parser/gda-statement-struct-util.c b/libgda/sql-parser/gda-statement-struct-util.c
index 4592a89..9aa363d 100644
--- a/libgda/sql-parser/gda-statement-struct-util.c
+++ b/libgda/sql-parser/gda-statement-struct-util.c
@@ -268,12 +268,17 @@ _string_is_identifier (const gchar *str)
 
 	if (!str || !(*str)) 
 		return FALSE;
-	for (ptr = *str == '"' ? str + 1 : str; 
-	     IdChar(*ptr) || (*ptr == '*') || (*ptr == '.') || ((*ptr == '"') && ptr[1] == 0); 
+	if ((*str == '"') || (*str == '`'))
+		ptr = str + 1;
+	else
+		ptr = str;
+	for (; 
+	     IdChar(*ptr) || (*ptr == '*') || (*ptr == '.') || (((*ptr == '"') || (*ptr == '`')) && ptr[1] == 0); 
 	     ptr++);
 	if (*ptr) 
 		return FALSE;
-	if ((*str == '"') && (ptr[-1] == '"'))
+	if (((*str == '"') && (ptr[-1] == '"')) ||
+	    ((*str == '`') && (ptr[-1] == '`')))
 		return TRUE;
 
 	/* @str is composed only of character that can be used in an identifier */
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index e46240d..c716b77 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -1661,21 +1661,16 @@ add_oid_columns (GdaStatement *stmt, GHashTable **out_hash, gint *out_nb_cols_ad
 		
 		field->expr = gda_sql_expr_new (GDA_SQL_ANY_PART (field));
 		
-		gchar *str;
+		gchar *str, *tmp;
 		const gchar *name;
 		if (target->as)
 			name = target->as;
 		else
 			name = target->table_name;
 		
-		if ((*name != '"') && gda_sql_identifier_needs_quotes (name)) {
-			gchar *tmp;
-			tmp = gda_sql_identifier_add_quotes (target->table_name);
-			str = g_strdup_printf ("%s.rowid", tmp);
-			g_free (tmp);
-		}
-		else
-			str = g_strdup_printf ("%s.rowid", name);
+		tmp = gda_sql_identifier_quote (target->table_name, NULL, NULL, FALSE, FALSE);
+		str = g_strdup_printf ("%s.rowid", tmp);
+		g_free (tmp);
 		g_value_take_string ((field->expr->value = gda_value_new (G_TYPE_STRING)), str);
 		
 		/* add to hash table */
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index 0b2539e..a9fb3a6 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -430,10 +430,8 @@ virtualCreate (sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlit
 		name = gda_column_get_name (column);
 		if (!name || !(*name))
 			newcolname = g_strdup_printf ("_%d", i + 1);
-		else if (gda_sql_identifier_needs_quotes (name))
-			newcolname = g_strdup_printf ("\"%s\"", name);
 		else
-			newcolname = g_strdup (name);
+			newcolname = gda_sql_identifier_quote (name, GDA_CONNECTION (cnc), NULL, FALSE, FALSE);
 
 		gtype = gda_column_get_g_type (column);
 		type = g_type_name (gtype);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index afeeb5d..804a88d 100755
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -212,7 +212,6 @@ tools/browser/schema-browser/favorite-selector.c
 tools/browser/schema-browser/mgr-columns.c
 tools/browser/schema-browser/objects-index.c
 tools/browser/schema-browser/perspective-main.c
-tools/browser/schema-browser/relations-diagram.c
 tools/browser/schema-browser/schema-browser-perspective.c
 tools/browser/schema-browser/table-columns.c
 tools/browser/schema-browser/table-info.c
diff --git a/providers/mysql/gda-mysql-provider.c b/providers/mysql/gda-mysql-provider.c
index 416ef5f..2f9cbe5 100644
--- a/providers/mysql/gda-mysql-provider.c
+++ b/providers/mysql/gda-mysql-provider.c
@@ -1189,132 +1189,10 @@ gda_mysql_provider_create_parser (GdaServerProvider  *provider,
 					      NULL);
 }
 
-static gchar *
-mysql_render_select_target (GdaSqlSelectTarget *target, GdaSqlRenderingContext *context, GError **error)
-{
-	GString *string;
-	gchar *str;
-
-	g_return_val_if_fail (target, NULL);
-	g_return_val_if_fail (GDA_SQL_ANY_PART (target)->type == GDA_SQL_ANY_SQL_SELECT_TARGET, NULL);
-
-	/* can't have: target->expr == NULL */
-	if (!gda_sql_any_part_check_structure (GDA_SQL_ANY_PART (target), error)) return NULL;
-
-	if (!target->expr->value || (G_VALUE_TYPE (target->expr->value) != G_TYPE_STRING)) {
-		str = context->render_expr (target->expr, context, NULL, NULL, error);
-		if (!str)
-			return NULL;
-		string = g_string_new (str);
-	}
-	else {
-		gchar **ids_array;
-		ids_array = gda_sql_identifier_split (g_value_get_string (target->expr->value));
-		if (!ids_array) {
-			g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
-				     "%s", _("Malformed expression in select target"));
-			return NULL;
-		}
-
-		gint i;
-		string = g_string_new ("");
-		for (i = 0; ids_array [i]; i++) {
-			if (*(ids_array [i]) == '"')
-				gda_sql_identifier_remove_quotes (ids_array [i]);
-			if (i != 0)
-				g_string_append_c (string, '.');
-			g_string_append (string, ids_array [i]);
-		}
-		g_strfreev (ids_array);
-	}
-
-	if (target->as)
-		g_string_append_printf (string, " AS %s", target->as);
-
-	str = string->str;
-	g_string_free (string, FALSE);
-	return str;
-}
-
-static gchar *
-mysql_render_table (GdaSqlTable *table, GdaSqlRenderingContext *context, GError **error)
-{
-	g_return_val_if_fail (table, NULL);
-	g_return_val_if_fail (GDA_SQL_ANY_PART (table)->type == GDA_SQL_ANY_SQL_TABLE, NULL);
-
-	/* can't have: table->table_name not a valid SQL identifier */
-	if (!gda_sql_any_part_check_structure (GDA_SQL_ANY_PART (table), error)) return NULL;
-
-	gchar **ids_array;
-	ids_array = gda_sql_identifier_split (table->table_name);
-	if (!ids_array) {
-		g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
-			     "%s", _("Malformed table name"));
-		return NULL;
-	}
-	
-	gint i;
-	GString *string;
-	string = g_string_new ("");
-	for (i = 0; ids_array [i]; i++) {
-		if (*(ids_array [i]) == '"') {
-			gchar *ptr;
-			for (ptr = ids_array [i]; *ptr; ptr++) {
-				if (*ptr == '"')
-					*ptr = '`';
-			}
-		}
-		if (i != 0)
-			g_string_append_c (string, '.');
-		g_string_append (string, ids_array [i]);
-	}
-	g_strfreev (ids_array);
-	return g_string_free (string, FALSE);
-}
-
-static gchar *
-mysql_render_field (GdaSqlField *field, GdaSqlRenderingContext *context, GError **error)
-{
-	g_return_val_if_fail (field, NULL);
-        g_return_val_if_fail (GDA_SQL_ANY_PART (field)->type == GDA_SQL_ANY_SQL_FIELD, NULL);
-
-        /* can't have: field->field_name not a valid SQL identifier */
-        if (!gda_sql_any_part_check_structure (GDA_SQL_ANY_PART (field), error)) return NULL;
-
-	gchar **ids_array;
-	ids_array = gda_sql_identifier_split (field->field_name);
-	if (!ids_array) {
-		g_set_error (error, GDA_SQL_ERROR, GDA_SQL_STRUCTURE_CONTENTS_ERROR,
-			     "%s", _("Malformed field name"));
-		return NULL;
-	}
-	
-	gint i;
-	GString *string;
-	string = g_string_new ("");
-	for (i = 0; ids_array [i]; i++) {
-		if (*(ids_array [i]) == '"') {
-			gchar *ptr;
-			for (ptr = ids_array [i]; *ptr; ptr++) {
-				if (*ptr == '"')
-					*ptr = '`';
-			}
-		}
-		if (i != 0)
-			g_string_append_c (string, '.');
-		g_string_append (string, ids_array [i]);
-	}
-	g_strfreev (ids_array);
-	g_print ("%s ==> %s\n", field->field_name, string->str);
-	return g_string_free (string, FALSE);
-}
-
 /*
  * GdaStatement to SQL request
  * 
  * This method renders a #GdaStatement into its SQL representation.
- *
- * It is specialized to remove the double quotes around table names.
  */
 static gchar *
 gda_mysql_provider_statement_to_sql (GdaServerProvider    *provider,
@@ -1337,9 +1215,10 @@ gda_mysql_provider_statement_to_sql (GdaServerProvider    *provider,
         memset (&context, 0, sizeof (context));
         context.params = params;
         context.flags = flags;
-	/* replace double quotes around table name with backquotes */
-	context.render_select_target = (GdaSqlRenderingFunc) mysql_render_select_target; 
-	context.render_table = (GdaSqlRenderingFunc) mysql_render_table; 
+	if (cnc) {
+		context.cnc = cnc;
+		context.provider = gda_connection_get_provider (cnc);
+	}
 
         str = gda_statement_to_sql_real (stmt, &context, error);
 
@@ -1392,7 +1271,6 @@ real_prepare (GdaServerProvider *provider, GdaConnection *cnc, GdaStatement *stm
 		return FALSE;
 	}
 
-	g_print ("PREPARE: %s\n", sql);
 	if (mysql_stmt_prepare (mysql_stmt, sql, strlen (sql))) {
 		_gda_mysql_make_error (cdata->cnc, NULL, mysql_stmt, error);
 		mysql_stmt_close (mysql_stmt);
diff --git a/tests/gda-ddl-creator.c b/tests/gda-ddl-creator.c
index cb25a3c..b48a75a 100644
--- a/tests/gda-ddl-creator.c
+++ b/tests/gda-ddl-creator.c
@@ -264,9 +264,9 @@ gda_ddl_creator_finalize (GObject *object)
 
 static void
 gda_ddl_creator_set_property (GObject *object,
-			     guint param_id,
-			     const GValue *value,
-			     GParamSpec *pspec) 
+			      guint param_id,
+			      const GValue *value,
+			      GParamSpec *pspec) 
 {
 	GdaDDLCreator *creator;
 	
@@ -289,10 +289,11 @@ gda_ddl_creator_set_property (GObject *object,
 			creator->priv->quoted_catalog = NULL;
 			if (g_value_get_string (value) && *g_value_get_string (value)) {
 				creator->priv->catalog = gda_value_copy (value);
-				if (gda_sql_identifier_needs_quotes (g_value_get_string (value))) 
-					creator->priv->quoted_catalog = gda_sql_identifier_add_quotes (g_value_get_string (value));
-				else
-					creator->priv->quoted_catalog = g_value_dup_string (value);
+				if (!creator->priv->cnc)
+					g_warning ("The \"catalog\" property should be set after the \"cnc\" one");
+				creator->priv->quoted_catalog =
+					gda_sql_identifier_quote (g_value_get_string (value), creator->priv->cnc, NULL,
+								  FALSE, FALSE);
 			}
 			break;
 		case PROP_SCHEMA:
@@ -303,10 +304,11 @@ gda_ddl_creator_set_property (GObject *object,
 			creator->priv->quoted_schema = NULL;
 			if (g_value_get_string (value) && *g_value_get_string (value)) {
 				creator->priv->schema = gda_value_copy (value);
-				if (gda_sql_identifier_needs_quotes (g_value_get_string (value))) 
-					creator->priv->quoted_schema = gda_sql_identifier_add_quotes (g_value_get_string (value));
-				else
-					creator->priv->quoted_schema = g_value_dup_string (value);
+				if (!creator->priv->cnc)
+					g_warning ("The \"schema\" property should be set after the \"cnc\" one");
+				creator->priv->quoted_schema =
+					gda_sql_identifier_quote (g_value_get_string (value), creator->priv->cnc, NULL,
+								  FALSE, FALSE);
 			}
 			break;
 		}
diff --git a/tests/parser/testdata.xml b/tests/parser/testdata.xml
index 32e24d3..4c6806b 100644
--- a/tests/parser/testdata.xml
+++ b/tests/parser/testdata.xml
@@ -244,8 +244,8 @@
 
   <!-- Misc SQL -->
   <test id="42">
-    <sql>SELECT * from table as t;</sql>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"SELECT * from table as t;","stmt_type":"UNKNOWN","contents":[{"value":"SELECT"},{"value":" "},{"value":"*"},{"value":" "},{"value":"from"},{"value":" "},{"value":"table"},{"value":" "},{"value":"as"},{"value":" "},{"value":"t"}]}}]}</expected>
+    <sql>SELECT * from mytable as t;</sql>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"SELECT * from mytable as t;","stmt_type":"UNKNOWN","contents":[{"value":"SELECT"},{"value":" "},{"value":"*"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable"},{"value":" "},{"value":"as"},{"value":" "},{"value":"t"}]}}]}</expected>
   </test>
 
   <!-- MySQL DELIMITER command -->
@@ -551,33 +551,33 @@
   </test>
 
   <test id="2002">
-    <sql>insert into cat.schema.mytable (a, b) values (null, 1);</sql>
-    <expected>{"statements":[{"statement":{"sql":"insert into cat.schema.mytable (a, b) values (null, 1);","stmt_type":"INSERT","contents":{"table":"cat.schema.mytable","fields":["a","b"],"values":[[{"value":null},{"value":"1"}]]}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into cat.schema.mytable (a, b) values (null, 1);","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"cat.schema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"1"},{"value":")"}]}}]}</expected>
+    <sql>insert into cat.myschema.mytable (a, b) values (null, 1);</sql>
+    <expected>{"statements":[{"statement":{"sql":"insert into cat.myschema.mytable (a, b) values (null, 1);","stmt_type":"INSERT","contents":{"table":"cat.myschema.mytable","fields":["a","b"],"values":[[{"value":null},{"value":"1"}]]}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into cat.myschema.mytable (a, b) values (null, 1);","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"cat.myschema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"1"},{"value":")"}]}}]}</expected>
   </test>
 
   <test id="2003">
-    <sql>insert or replace into schema.mytable (a, b) values (null, 1);</sql>
-    <expected>{"statements":[{"statement":{"sql":"insert or replace into schema.mytable (a, b) values (null, 1);","stmt_type":"INSERT","contents":{"table":"schema.mytable","fields":["a","b"],"values":[[{"value":null},{"value":"1"}]],"on_conflict":"replace"}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"insert or replace into schema.mytable (a, b) values (null, 1);","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"or"},{"value":" "},{"value":"replace"},{"value":" "},{"value":"into"},{"value":" "},{"value":"schema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"1"},{"value":")"}]}}]}</expected>
+    <sql>insert or replace into myschema.mytable (a, b) values (null, 1);</sql>
+    <expected>{"statements":[{"statement":{"sql":"insert or replace into myschema.mytable (a, b) values (null, 1);","stmt_type":"INSERT","contents":{"table":"myschema.mytable","fields":["a","b"],"values":[[{"value":null},{"value":"1"}]],"on_conflict":"replace"}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"insert or replace into myschema.mytable (a, b) values (null, 1);","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"or"},{"value":" "},{"value":"replace"},{"value":" "},{"value":"into"},{"value":" "},{"value":"myschema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"1"},{"value":")"}]}}]}</expected>
   </test>
 
   <test id="2004">
-    <sql>insert into schema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, 'a string');</sql>
-    <expected>{"statements":[{"statement":{"sql":"insert into schema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, 'a string');","stmt_type":"INSERT","contents":{"table":"schema.mytable","fields":["a","b","c","d","e"],"values":[[{"value":null},{"value":"DEFAULT"},{"value":"12"},{"value":"1.23"},{"value":"'a string'"}]]}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into schema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, 'a string');","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"schema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b,"},{"value":" "},{"value":"c,"},{"value":" "},{"value":"d,"},{"value":" "},{"value":"e)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"DEFAULT,"},{"value":" "},{"value":"12"},{"value":","},{"value":" "},{"value":"1.23"},{"value":","},{"value":" "},{"value":"'a string'"},{"value":")"}]}}]}</expected>
+    <sql>insert into myschema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, 'a string');</sql>
+    <expected>{"statements":[{"statement":{"sql":"insert into myschema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, 'a string');","stmt_type":"INSERT","contents":{"table":"myschema.mytable","fields":["a","b","c","d","e"],"values":[[{"value":null},{"value":"DEFAULT"},{"value":"12"},{"value":"1.23"},{"value":"'a string'"}]]}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into myschema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, 'a string');","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"myschema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b,"},{"value":" "},{"value":"c,"},{"value":" "},{"value":"d,"},{"value":" "},{"value":"e)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"DEFAULT,"},{"value":" "},{"value":"12"},{"value":","},{"value":" "},{"value":"1.23"},{"value":","},{"value":" "},{"value":"'a string'"},{"value":")"}]}}]}</expected>
   </test>
 
   <test id="2005">
-    <sql>insert into schema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, f('a string'));</sql>
-    <expected>{"statements":[{"statement":{"sql":"insert into schema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, f('a string'));","stmt_type":"INSERT","contents":{"table":"schema.mytable","fields":["a","b","c","d","e"],"values":[[{"value":null},{"value":"DEFAULT"},{"value":"12"},{"value":"1.23"},{"func":{"function_name":"f","function_args":[{"value":"'a string'"}]}}]]}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into schema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, f('a string'));","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"schema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b,"},{"value":" "},{"value":"c,"},{"value":" "},{"value":"d,"},{"value":" "},{"value":"e)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"DEFAULT,"},{"value":" "},{"value":"12"},{"value":","},{"value":" "},{"value":"1.23"},{"value":","},{"value":" "},{"value":"f("},{"value":"'a string'"},{"value":")"},{"value":")"}]}}]}</expected>
+    <sql>insert into myschema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, f('a string'));</sql>
+    <expected>{"statements":[{"statement":{"sql":"insert into myschema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, f('a string'));","stmt_type":"INSERT","contents":{"table":"myschema.mytable","fields":["a","b","c","d","e"],"values":[[{"value":null},{"value":"DEFAULT"},{"value":"12"},{"value":"1.23"},{"func":{"function_name":"f","function_args":[{"value":"'a string'"}]}}]]}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into myschema.mytable (a, b, c, d, e) values (null, DEFAULT, 12, 1.23, f('a string'));","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"myschema.mytable"},{"value":" "},{"value":"("},{"value":"a,"},{"value":" "},{"value":"b,"},{"value":" "},{"value":"c,"},{"value":" "},{"value":"d,"},{"value":" "},{"value":"e)"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"null"},{"value":","},{"value":" "},{"value":"DEFAULT,"},{"value":" "},{"value":"12"},{"value":","},{"value":" "},{"value":"1.23"},{"value":","},{"value":" "},{"value":"f("},{"value":"'a string'"},{"value":")"},{"value":")"}]}}]}</expected>
   </test>
 
   <test id="2006">
-    <sql>insert into schema.mytable values (f1('a string'), f2(aa.bb, dd));</sql>
-    <expected>{"statements":[{"statement":{"sql":"insert into schema.mytable values (f1('a string'), f2(aa.bb, dd));","stmt_type":"INSERT","contents":{"table":"schema.mytable","fields":null,"values":[[{"func":{"function_name":"f1","function_args":[{"value":"'a string'"}]}},{"func":{"function_name":"f2","function_args":[{"value":"aa.bb"},{"value":"dd"}]}}]]}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into schema.mytable values (f1('a string'), f2(aa.bb, dd));","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"schema.mytable"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"f1("},{"value":"'a string'"},{"value":")"},{"value":","},{"value":" "},{"value":"f2(aa.bb,"},{"value":" "},{"value":"dd))"}]}}]}</expected>
+    <sql>insert into myschema.mytable values (f1('a string'), f2(aa.bb, dd));</sql>
+    <expected>{"statements":[{"statement":{"sql":"insert into myschema.mytable values (f1('a string'), f2(aa.bb, dd));","stmt_type":"INSERT","contents":{"table":"myschema.mytable","fields":null,"values":[[{"func":{"function_name":"f1","function_args":[{"value":"'a string'"}]}},{"func":{"function_name":"f2","function_args":[{"value":"aa.bb"},{"value":"dd"}]}}]]}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"insert into myschema.mytable values (f1('a string'), f2(aa.bb, dd));","stmt_type":"UNKNOWN","contents":[{"value":"insert"},{"value":" "},{"value":"into"},{"value":" "},{"value":"myschema.mytable"},{"value":" "},{"value":"values"},{"value":" "},{"value":"("},{"value":"f1("},{"value":"'a string'"},{"value":")"},{"value":","},{"value":" "},{"value":"f2(aa.bb,"},{"value":" "},{"value":"dd))"}]}}]}</expected>
   </test>
 
   <test id="2006.1">
@@ -756,15 +756,15 @@
   </test>
 
   <test id="2210">
-    <sql>select a, (select afield as fname from mytable) as src from table</sql>
-    <expected>{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from table","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"a"},"field_name":"a"},{"expr":{"select":{"contents":{"distinct":"false","fields":[{"expr":{"value":"afield"},"field_name":"afield","as":"fname"}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]}}}},"as":"src"}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]}}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from table","stmt_type":"UNKNOWN","contents":[{"value":"select"},{"value":" "},{"value":"a,"},{"value":" "},{"value":"("},{"value":"select"},{"value":" "},{"value":"afield"},{"value":" "},{"value":"as"},{"value":" "},{"value":"fname"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable)"},{"value":" "},{"value":"as"},{"value":" "},{"value":"src"},{"value":" "},{"value":"from"},{"value":" "},{"value":"table"}]}}]}</expected>
+    <sql>select a, (select afield as fname from mytable) as src from mytable</sql>
+    <expected>{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from mytable","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"a"},"field_name":"a"},{"expr":{"select":{"contents":{"distinct":"false","fields":[{"expr":{"value":"afield"},"field_name":"afield","as":"fname"}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]}}}},"as":"src"}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]}}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from mytable","stmt_type":"UNKNOWN","contents":[{"value":"select"},{"value":" "},{"value":"a,"},{"value":" "},{"value":"("},{"value":"select"},{"value":" "},{"value":"afield"},{"value":" "},{"value":"as"},{"value":" "},{"value":"fname"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable)"},{"value":" "},{"value":"as"},{"value":" "},{"value":"src"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable"}]}}]}</expected>
   </test>
 
   <test id="2211">
-    <sql>select a, (select afield as fname from mytable) as src from table</sql>
-    <expected>{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from table","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"a"},"field_name":"a"},{"expr":{"select":{"contents":{"distinct":"false","fields":[{"expr":{"value":"afield"},"field_name":"afield","as":"fname"}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]}}}},"as":"src"}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]}}}}]}</expected>
-    <expected mode="delim">{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from table","stmt_type":"UNKNOWN","contents":[{"value":"select"},{"value":" "},{"value":"a,"},{"value":" "},{"value":"("},{"value":"select"},{"value":" "},{"value":"afield"},{"value":" "},{"value":"as"},{"value":" "},{"value":"fname"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable)"},{"value":" "},{"value":"as"},{"value":" "},{"value":"src"},{"value":" "},{"value":"from"},{"value":" "},{"value":"table"}]}}]}</expected>
+    <sql>select a, (select afield as fname from mytable) as src from mytable</sql>
+    <expected>{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from mytable","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"a"},"field_name":"a"},{"expr":{"select":{"contents":{"distinct":"false","fields":[{"expr":{"value":"afield"},"field_name":"afield","as":"fname"}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]}}}},"as":"src"}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]}}}}]}</expected>
+    <expected mode="delim">{"statements":[{"statement":{"sql":"select a, (select afield as fname from mytable) as src from mytable","stmt_type":"UNKNOWN","contents":[{"value":"select"},{"value":" "},{"value":"a,"},{"value":" "},{"value":"("},{"value":"select"},{"value":" "},{"value":"afield"},{"value":" "},{"value":"as"},{"value":" "},{"value":"fname"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable)"},{"value":" "},{"value":"as"},{"value":" "},{"value":"src"},{"value":" "},{"value":"from"},{"value":" "},{"value":"mytable"}]}}]}</expected>
   </test>
 
   <test id="2212">
@@ -824,43 +824,43 @@
   </test>
 
   <test id="2222">
-    <sql>select * from table where a=b or c is null</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table where a=b or c is null","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"where":{"operation":{"operator":"OR","operand0":{"operation":{"operator":"=","operand0":{"value":"a"},"operand1":{"value":"b"}}},"operand1":{"operation":{"operator":"IS NULL","operand0":{"value":"c"}}}}}}}}]}</expected>
+    <sql>select * from mytable where a=b or c is null</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable where a=b or c is null","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"where":{"operation":{"operator":"OR","operand0":{"operation":{"operator":"=","operand0":{"value":"a"},"operand1":{"value":"b"}}},"operand1":{"operation":{"operator":"IS NULL","operand0":{"value":"c"}}}}}}}}]}</expected>
   </test>
 
   <test id="2223">
-    <sql>select * from table where a=(select c from tab2)</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table where a=(select c from tab2)","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"where":{"operation":{"operator":"=","operand0":{"value":"a"},"operand1":{"select":{"contents":{"distinct":"false","fields":[{"expr":{"value":"c"},"field_name":"c"}],"from":{"targets":[{"expr":{"value":"tab2"},"table_name":"tab2"}]}}}}}}}}}]}</expected>
+    <sql>select * from mytable where a=(select c from tab2)</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable where a=(select c from tab2)","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"where":{"operation":{"operator":"=","operand0":{"value":"a"},"operand1":{"select":{"contents":{"distinct":"false","fields":[{"expr":{"value":"c"},"field_name":"c"}],"from":{"targets":[{"expr":{"value":"tab2"},"table_name":"tab2"}]}}}}}}}}}]}</expected>
   </test>
 
   <test id="2224">
-    <sql>select * from table group by z, u</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table group by z, u","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"group_by":[{"value":"z"},{"value":"u"}]}}}]}</expected>
+    <sql>select * from mytable group by z, u</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable group by z, u","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"group_by":[{"value":"z"},{"value":"u"}]}}}]}</expected>
   </test>
 
   <test id="2225">
-    <sql>select * from table where id&lt;100 group by z, u having c(id)&gt;=0</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table where id&lt;100 group by z, u having c(id)&gt;=0","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"where":{"operation":{"operator":"&lt;","operand0":{"value":"id"},"operand1":{"value":"100"}}},"group_by":[{"value":"z"},{"value":"u"}],"having":{"operation":{"operator":"&gt;=","operand0":{"func":{"function_name":"c","function_args":[{"value":"id"}]}},"operand1":{"value":"0"}}}}}}]}</expected>
+    <sql>select * from mytable where id&lt;100 group by z, u having c(id)&gt;=0</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable where id&lt;100 group by z, u having c(id)&gt;=0","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"where":{"operation":{"operator":"&lt;","operand0":{"value":"id"},"operand1":{"value":"100"}}},"group_by":[{"value":"z"},{"value":"u"}],"having":{"operation":{"operator":"&gt;=","operand0":{"func":{"function_name":"c","function_args":[{"value":"id"}]}},"operand1":{"value":"0"}}}}}}]}</expected>
   </test>
 
   <test id="2226">
-    <sql>select * from table order by col1 ASC, col2 DESC, col3;</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table order by col1 ASC, col2 DESC, col3;","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"order_by":[{"expr":{"value":"col1"},"sort":"ASC"},{"expr":{"value":"col2"},"sort":"DESC"},{"expr":{"value":"col3"},"sort":"ASC"}]}}}]}</expected>
+    <sql>select * from mytable order by col1 ASC, col2 DESC, col3;</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable order by col1 ASC, col2 DESC, col3;","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"order_by":[{"expr":{"value":"col1"},"sort":"ASC"},{"expr":{"value":"col2"},"sort":"DESC"},{"expr":{"value":"col3"},"sort":"ASC"}]}}}]}</expected>
   </test>
 
   <test id="2227">
-    <sql>select * from table limit 4 offset 5</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table limit 4 offset 5","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"limit":{"value":"4"},"offset":{"value":"5"}}}}]}</expected>
+    <sql>select * from mytable limit 4 offset 5</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable limit 4 offset 5","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"limit":{"value":"4"},"offset":{"value":"5"}}}}]}</expected>
   </test>
 
   <test id="2228">
-    <sql>select * from table limit 4,5;</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table limit 4,5;","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"limit":{"value":"4"},"offset":{"value":"5"}}}}]}</expected>
+    <sql>select * from mytable limit 4,5;</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable limit 4,5;","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"limit":{"value":"4"},"offset":{"value":"5"}}}}]}</expected>
   </test>
 
   <test id="2229">
-    <sql>select * from table limit ##limval::gint</sql>
-    <expected>{"statements":[{"statement":{"sql":"select * from table limit ##limval::gint","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"table"},"table_name":"table"}]},"limit":{"value":null,"param_spec":{"name":"limval","descr":null,"type":"int","is_param":true,"nullok":false}}}}}]}</expected>
+    <sql>select * from mytable limit ##limval::gint</sql>
+    <expected>{"statements":[{"statement":{"sql":"select * from mytable limit ##limval::gint","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"mytable"},"table_name":"mytable"}]},"limit":{"value":null,"param_spec":{"name":"limval","descr":null,"type":"int","is_param":true,"nullok":false}}}}}]}</expected>
   </test>
 
   <test id="2230">
diff --git a/tools/gda-sql.c b/tools/gda-sql.c
index a946b54..1e0218c 100644
--- a/tools/gda-sql.c
+++ b/tools/gda-sql.c
@@ -3913,14 +3913,8 @@ get_table_value_at_cell (GdaConnection *cnc, GError **error, MainData *data,
 	gchar *sql;
 	gchar *rtable, *rcolumn;
 	
-	if (gda_sql_identifier_needs_quotes (table))
-		rtable = gda_sql_identifier_add_quotes (table);
-	else
-		rtable = g_strdup (table);
-	if (gda_sql_identifier_needs_quotes (column))
-		rcolumn = gda_sql_identifier_add_quotes (column);
-	else
-		rcolumn = g_strdup (column);
+	rtable = gda_sql_identifier_quote (table, cnc, NULL, FALSE, FALSE);
+	rcolumn = gda_sql_identifier_quote (column, cnc, NULL, FALSE, FALSE);
 	sql = g_strdup_printf ("SELECT %s FROM %s WHERE %s", rcolumn, rtable, row_cond);
 	g_free (rtable);
 	g_free (rcolumn);
@@ -4442,14 +4436,8 @@ extra_command_lo_update (SqlConsole *console, GdaConnection *cnc, const gchar **
 	gchar *sql;
 	gchar *rtable, *rblob_col;
 	
-	if (gda_sql_identifier_needs_quotes (table))
-		rtable = gda_sql_identifier_add_quotes (table);
-	else
-		rtable = g_strdup (table);
-	if (gda_sql_identifier_needs_quotes (blob_col))
-		rblob_col = gda_sql_identifier_add_quotes (blob_col);
-	else
-		rblob_col = g_strdup (blob_col);
+	rtable = gda_sql_identifier_quote (table, cnc, NULL, FALSE, FALSE);
+	rblob_col = gda_sql_identifier_quote (blob_col, cnc, NULL, FALSE, FALSE);
 	sql = g_strdup_printf ("UPDATE %s SET %s = ##blob::GdaBlob WHERE %s", rtable, rblob_col, row_cond);
 	g_free (rtable);
 	g_free (rblob_col);
diff --git a/tools/web-server.c b/tools/web-server.c
index 06db914..9b51244 100644
--- a/tools/web-server.c
+++ b/tools/web-server.c
@@ -1390,16 +1390,10 @@ compute_object_content (HtmlDoc *hdoc, WebServer *webserver, const ConnectionSet
 	GValue *v0, *v1;
 	gboolean retval;
 
-	if (gda_sql_identifier_needs_quotes (schema))
-		g_value_take_string ((v0 = gda_value_new (G_TYPE_STRING)),
-				     gda_sql_identifier_add_quotes (schema));
-	else
-		g_value_set_string ((v0 = gda_value_new (G_TYPE_STRING)), schema);
-	if (gda_sql_identifier_needs_quotes (name))
-		g_value_take_string ((v1 = gda_value_new (G_TYPE_STRING)),
-				     gda_sql_identifier_add_quotes (name));
-	else
-		g_value_set_string ((v1 = gda_value_new (G_TYPE_STRING)), name);
+	g_value_take_string ((v0 = gda_value_new (G_TYPE_STRING)),
+			     gda_sql_identifier_quote (schema, cs->cnc, NULL, FALSE, FALSE));
+	g_value_take_string ((v1 = gda_value_new (G_TYPE_STRING)),
+			     gda_sql_identifier_quote (name, cs->cnc, NULL, FALSE, FALSE));
 
 	mstruct = gda_meta_struct_new (gda_connection_get_meta_store (cs->cnc),
 				       GDA_META_STRUCT_FEATURE_ALL);



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