[libgda/LIBGDA_4.0] SQL identifiers case sensitiveness specified in the connection



commit ce88eb845d5e642ea02a973718e11561e1f5088d
Author: Vivien Malerba <malerba gnome-db org>
Date:   Thu Jul 23 20:57:41 2009 +0200

    SQL identifiers case sensitiveness specified in the connection
    
    * added the GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE flag
      when opening a connection
    * added gda_connection_quote_sql_identifier()
    * added gda_meta_store_sql_identifier_quote()
    * added gda_server_operation_get_sql_identifier_at(), to be used by database provider's
      implementations when getting a value which is an SQL identifier from a GdaServerOperation
    * modified the providers' DDL implemntations to use gda_server_operation_get_sql_identifier_at()

 doc/C/libgda-4.0-sections.txt                     |    3 +
 doc/C/tmpl/gda-connection.sgml                    |   11 +
 doc/C/tmpl/gda-meta-store.sgml                    |   10 +
 doc/C/tmpl/gda-server-operation.sgml              |   13 +
 libgda/gda-connection.c                           |   45 ++++-
 libgda/gda-connection.h                           |   30 +++-
 libgda/gda-meta-store.c                           |   31 +++-
 libgda/gda-meta-store.h                           |    1 +
 libgda/gda-server-operation.c                     |  101 +++++++--
 libgda/gda-server-operation.h                     |    3 +
 libgda/libgda.symbols                             |    3 +
 libgda/sqlite/gda-sqlite-ddl.c                    |  117 +++++-----
 providers/jdbc/gda-jdbc-ddl.c                     |   33 ++-
 providers/mysql/gda-mysql-ddl.c                   |  205 +++++++++--------
 providers/oracle/gda-oracle-ddl.c                 |  191 ++++++++-------
 providers/postgres/gda-postgres-ddl.c             |  262 +++++++++++----------
 providers/skel-implementation/capi/gda-capi-ddl.c |   39 ++--
 17 files changed, 680 insertions(+), 418 deletions(-)
---
diff --git a/doc/C/libgda-4.0-sections.txt b/doc/C/libgda-4.0-sections.txt
index 3ebbf75..c580af7 100644
--- a/doc/C/libgda-4.0-sections.txt
+++ b/doc/C/libgda-4.0-sections.txt
@@ -116,6 +116,7 @@ gda_connection_is_opened
 <SUBSECTION>
 gda_connection_create_parser
 gda_connection_value_to_sql_string
+gda_connection_quote_sql_identifier
 gda_connection_statement_to_sql
 gda_connection_statement_prepare
 gda_connection_statement_execute
@@ -434,6 +435,7 @@ gda_server_operation_get_op_type
 gda_server_operation_op_type_to_string
 <SUBSECTION>
 gda_server_operation_get_value_at
+gda_server_operation_get_sql_identifier_at
 gda_server_operation_set_value_at
 gda_server_operation_save_data_to_xml
 gda_server_operation_load_data_from_xml
@@ -1294,6 +1296,7 @@ GdaMetaContext
 gda_meta_store_new
 gda_meta_store_new_with_file
 gda_meta_store_get_version
+gda_meta_store_sql_identifier_quote
 gda_meta_store_extract
 gda_meta_store_schema_get_structure
 gda_meta_store_get_attribute_value
diff --git a/doc/C/tmpl/gda-connection.sgml b/doc/C/tmpl/gda-connection.sgml
index cd1f78d..4b4ea69 100644
--- a/doc/C/tmpl/gda-connection.sgml
+++ b/doc/C/tmpl/gda-connection.sgml
@@ -117,6 +117,7 @@ Management of connections to data sources
 
 @GDA_CONNECTION_OPTIONS_NONE: 
 @GDA_CONNECTION_OPTIONS_READ_ONLY: 
+ GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE: 
 
 <!-- ##### ENUM GdaConnectionError ##### -->
 <para>
@@ -217,6 +218,16 @@ Management of connections to data sources
 @Returns: 
 
 
+<!-- ##### FUNCTION gda_connection_quote_sql_identifier ##### -->
+<para>
+
+</para>
+
+ cnc: 
+ id: 
+ Returns: 
+
+
 <!-- ##### FUNCTION gda_connection_statement_to_sql ##### -->
 <para>
 
diff --git a/doc/C/tmpl/gda-meta-store.sgml b/doc/C/tmpl/gda-meta-store.sgml
index 2088760..ec4ab6e 100644
--- a/doc/C/tmpl/gda-meta-store.sgml
+++ b/doc/C/tmpl/gda-meta-store.sgml
@@ -152,6 +152,16 @@ Dictionary object
 @Returns: 
 
 
+<!-- ##### FUNCTION gda_meta_store_sql_identifier_quote ##### -->
+<para>
+
+</para>
+
+ Param1: 
+ cnc: 
+ Returns: 
+
+
 <!-- ##### FUNCTION gda_meta_store_extract ##### -->
 <para>
 
diff --git a/doc/C/tmpl/gda-server-operation.sgml b/doc/C/tmpl/gda-server-operation.sgml
index bf338d8..f18ef19 100644
--- a/doc/C/tmpl/gda-server-operation.sgml
+++ b/doc/C/tmpl/gda-server-operation.sgml
@@ -130,6 +130,19 @@ Handles any DDL query in an abstract way
 @Returns: 
 
 
+<!-- ##### FUNCTION gda_server_operation_get_sql_identifier_at ##### -->
+<para>
+
+</para>
+
+ op: 
+ cnc: 
+ prov: 
+ path_format: 
+ Varargs: 
+ Returns: 
+
+
 <!-- ##### FUNCTION gda_server_operation_set_value_at ##### -->
 <para>
 
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index cfde721..60acb32 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -1490,6 +1490,41 @@ gda_connection_batch_execute (GdaConnection *cnc, GdaBatch *batch, GdaSet *param
 
 
 /**
+ * gda_connection_quote_sql_identifier
+ * @cnc: a #GdaConnection object
+ * @id: an SQL identifier
+ *
+ * Use this method to get a correctly quoted (if necessary) SQL identifier which can be used
+ * in SQL statements, from @id. If @id is already correctly quoted for @cnc, then a copy of @id
+ * may be returned.
+ *
+ * This method may add double quotes (or other characters) around @id:
+ * <itemizedlist>
+ *  <listitem><para>if @id is a reserved SQL keyword (such as SELECT, INSERT, ...)</para></listitem>
+ *  <listitem><para>if @id contains non allowed characters such as spaces, or if it starts with a digit</para></listitem>
+ *  <listitem><para>in any other event as necessary for @cnc, depending on the the options passed when opening the @cnc
+ *            connection, and specifically the <link linkend="GDA-CONNECTION-OPTIONS-SQL-IDENTIFIERS-CASE-SENSITIVE:CAPS">
+ *            GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE</link> option.</para></listitem>
+ * </itemizedlist>
+ *
+ * One can safely pass an already quoted @id to this method, either with quoting characters allowed by @cnc or using the
+ * double quote (") character.
+ *
+ * Returns: a new string, to free with g_free() once not needed anymore
+ *
+ * Since: 4.0.3
+ */
+gchar *
+gda_connection_quote_sql_identifier (GdaConnection *cnc, const gchar *id)
+{
+	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+	g_return_val_if_fail (id, NULL);
+
+	return gda_sql_identifier_quote (id, cnc, NULL, FALSE,
+					 cnc->priv->options & GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE);
+}
+
+/**
  * gda_connection_statement_to_sql
  * @cnc: a #GdaConnection object
  * @stmt: a #GdaStatement object
@@ -3037,7 +3072,9 @@ suggest_update_cb_downstream (GdaMetaStore *store, GdaMetaContext *suggest, Down
  *
  * When @context is not %NULL, and contains specified SQL identifiers (for example the "table_name" of the "_tables"
  * table), then each SQL identifier has to match the convention the #GdaMetaStore has adopted regarding
- * case sensitivity. see the <link linkend="information_schema:sql_identifiers">
+ * case sensitivity, using gda_meta_store_sql_identifier_quote().
+ *
+ * see the <link linkend="information_schema:sql_identifiers">
  * meta data section about SQL identifiers</link> for more information, and the documentation about the
  * gda_sql_identifier_quote() function which will be most usefull.
  *
@@ -3406,7 +3443,7 @@ prepare_meta_statements_hash (void)
  * @cnc: a #GdaConnection object.
  * @meta_type: describes which data to get.
  * @error: a place to store errors, or %NULL
- * @nb_filters: the number of filters in the ... argument
+ * @nb_filters: the number of filters in the @... argument
  * @...: a list of (filter name (gchar *), filter value (GValue*)) pairs specifying
  * the filter to apply to the returned data model's contents (there must be @nb_filters pairs)
  *
@@ -3422,7 +3459,9 @@ prepare_meta_statements_hash (void)
  * see <link linkend="GdaConnectionMetaTypeHead">this description</link>.
  *
  * Also, when using filters involving data which are SQL identifiers, make sure each SQL identifier
- * is represented using the #GdaMetaStore convention; see the <link linkend="information_schema:sql_identifiers">
+ * is represented using the #GdaMetaStore convention, using gda_meta_store_sql_identifier_quote().
+ *
+ * See the <link linkend="information_schema:sql_identifiers">
  * meta data section about SQL identifiers</link> for more information, and the documentation about the
  * gda_sql_identifier_quote() function which will be most usefull.
  * 
diff --git a/libgda/gda-connection.h b/libgda/gda-connection.h
index fe52993..7272e31 100644
--- a/libgda/gda-connection.h
+++ b/libgda/gda-connection.h
@@ -80,9 +80,36 @@ struct _GdaConnectionClass {
 	void (*_gda_reserved4) (void);
 };
 
+/**
+ * GdaConnectionOptions:
+ * @GDA_CONNECTION_OPTIONS_NONE: no specific aspect
+ * @GDA_CONNECTION_OPTIONS_READ_ONLY: this flag specifies that the connection to open should be in a read-only mode
+ *                                    (this policy is not correctly enforced at the moment)
+ * @GDA_CONNECTION_OPTIONS_THREAD_SAFE: this flag specifies that the connection to open will be used 
+ *                                     by several threads at once so it has to be thread safe
+ * @GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE: this flag specifies that SQL identifiers submitted as input
+ *                                    to Libgda have to keep their case sensitivity. 
+ *                                    
+ *
+ * Specifies some aspects of a connection when opening it.
+ *
+ * Additionnal information about the GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE flag:
+ * <itemizedlist>
+ *   <listitem><para>For example without this flag, if the table
+ *       name specified in a #GdaServerOperation to create a table is
+ *       <emphasis>MyTable</emphasis>, then usually the database will create a table named
+ *       <emphasis>mytable</emphasis>, whereas with this flag, the table will be created
+ *       as <emphasis>MyTable</emphasis> (note that in the end the database may still decide
+ *       to name the table <emphasis>mytable</emphasis> or differently if it can't do
+ *       otherwise).</para></listitem>
+ *   <listitem><para>Libgda will not apply this rule when parsing SQL code, the SQL code being parsed
+ *       has to be conform to the database it will be used with</para></listitem>
+ * </itemizedlist>
+ */
 typedef enum {
         GDA_CONNECTION_OPTIONS_NONE = 0,
-	GDA_CONNECTION_OPTIONS_READ_ONLY = 1 << 0
+	GDA_CONNECTION_OPTIONS_READ_ONLY = 1 << 0,
+	GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE = 1 << 1
 } GdaConnectionOptions;
 
 typedef enum {
@@ -165,6 +192,7 @@ GSList              *gda_connection_batch_execute        (GdaConnection *cnc,
 							  GdaBatch *batch, GdaSet *params,
 							  GdaStatementModelUsage model_usage, GError **error);
 
+gchar               *gda_connection_quote_sql_identifier (GdaConnection *cnc, const gchar *id);
 gchar               *gda_connection_statement_to_sql     (GdaConnection *cnc,
 							  GdaStatement *stmt, GdaSet *params, GdaStatementSqlFlag flags,
 							  GSList **params_used, GError **error);
diff --git a/libgda/gda-meta-store.c b/libgda/gda-meta-store.c
index 7ca8208..52886c1 100644
--- a/libgda/gda-meta-store.c
+++ b/libgda/gda-meta-store.c
@@ -2034,6 +2034,33 @@ gda_meta_store_get_internal_connection (GdaMetaStore *store) {
 }
 
 /**
+ * gda_meta_store_sql_identifier_quote
+ * @id: an SQL identifier
+ * @cnc: a #GdaConnection
+ *
+ * Use this method to get a correctly quoted (if necessary) SQL identifier which can be used
+ * to retreive or filter information in a #GdaMetaStore which stores meta data about @cnc.
+ *
+ * The returned SQL identifier can be used in conjunction with gda_connection_update_meta_store(),
+ * gda_connection_get_meta_store_data(), gda_connection_get_meta_store_data_v() and
+ * gda_meta_store_extract().
+ *
+ * Returns: a new string, to free with g_free() once not needed anymore
+ *
+ * Since: 4.0.3
+ */
+gchar *
+gda_meta_store_sql_identifier_quote (const char *id, GdaConnection *cnc)
+{
+	GdaConnectionOptions cncoptions;
+	g_return_val_if_fail (!cnc || GDA_IS_CONNECTION (cnc), NULL);
+	
+	g_object_get (G_OBJECT (cnc), "options", &cncoptions, NULL);
+	return gda_sql_identifier_quote (id, cnc, NULL, TRUE,
+					 cncoptions & GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE);
+}
+
+/**
  * gda_meta_store_extract
  * @store: a #GdaMetaStore object
  * @select_sql: a SELECT statement
@@ -2041,7 +2068,9 @@ gda_meta_store_get_internal_connection (GdaMetaStore *store) {
  * @...: a list of (variable name (gchar *), GValue *value) terminated with NULL, representing values for all the
  * variables mentionned in @select_sql. If there is no variable then this part can be omitted.
  *
- * Extracts some data stored in @store using a custom SELECT query.
+ * Extracts some data stored in @store using a custom SELECT query. If the @select_sql filter involves
+ * SQL identifiers (such as table or column names), then the values should have been adapted using
+ * gda_meta_store_sql_identifier_quote().
  *
  * For more information about
  * SQL identifiers are represented in @store, see the
diff --git a/libgda/gda-meta-store.h b/libgda/gda-meta-store.h
index 740f024..57317dc 100644
--- a/libgda/gda-meta-store.h
+++ b/libgda/gda-meta-store.h
@@ -108,6 +108,7 @@ GdaMetaStore     *gda_meta_store_new                      (const gchar *cnc_stri
 gint              gda_meta_store_get_version              (GdaMetaStore *store);
 
 GdaConnection    *gda_meta_store_get_internal_connection  (GdaMetaStore *store);
+gchar            *gda_meta_store_sql_identifier_quote     (const char*, GdaConnection *cnc);
 GdaDataModel     *gda_meta_store_extract                  (GdaMetaStore *store, const gchar *select_sql, GError **error, ...);
 gboolean          gda_meta_store_modify                   (GdaMetaStore *store, const gchar *table_name, 
 							   GdaDataModel *new_data, const gchar *condition, GError **error, ...);
diff --git a/libgda/gda-server-operation.c b/libgda/gda-server-operation.c
index 70d013c..fae1541 100644
--- a/libgda/gda-server-operation.c
+++ b/libgda/gda-server-operation.c
@@ -1889,33 +1889,25 @@ gda_server_operation_del_item_from_sequence (GdaServerOperation *op, const gchar
 	return FALSE;
 }
 
-/**
- * gda_server_operation_get_value_at
+/*
+ * real_gda_server_operation_get_value_at
  * @op: a #GdaServerOperation object
- * @path_format: a complete path to a node (starting with "/")
- * @...: arguments to use with @path_format to make a complete path
+ * @path: a complete path to a node (starting with "/")
  *
- * Get the value for the node at the path formed using @path_format and ... (the rules are the same as
- * for g_strdup_printf())
+ * Get the value for the node at the @path path
  *
  * Returns: a constant #GValue if a value has been defined, or %NULL if the value is undefined or
  * if the @path is not defined or @path does not hold any value.
  */
-const GValue *
-gda_server_operation_get_value_at (GdaServerOperation *op, const gchar *path_format, ...)
+static const GValue *
+real_gda_server_operation_get_value_at (GdaServerOperation *op, const gchar *path)
 {
 	const GValue *value = NULL;
 	GdaServerOperationNode *node_info;
-	gchar *path;
-	va_list args;
 
 	g_return_val_if_fail (GDA_IS_SERVER_OPERATION (op), NULL);
 	g_return_val_if_fail (op->priv, NULL);
-
-	/* build path */
-	va_start (args, path_format);
-	path = g_strdup_vprintf (path_format, args);
-	va_end (args);
+	g_return_val_if_fail (path && *path, NULL);
 
 	/* use path */
 	node_info = gda_server_operation_get_node_info (op, path);
@@ -1958,11 +1950,90 @@ gda_server_operation_get_value_at (GdaServerOperation *op, const gchar *path_for
 		}		
 	}
 
+	return value;
+}
+
+/**
+ * gda_server_operation_get_value_at
+ * @op: a #GdaServerOperation object
+ * @path_format: a complete path to a node (starting with "/")
+ * @...: arguments to use with @path_format to make a complete path
+ *
+ * Get the value for the node at the path formed using @path_format and ... (the rules are the same as
+ * for g_strdup_printf())
+ *
+ * Returns: a constant #GValue if a value has been defined, or %NULL if the value is undefined or
+ * if the @path is not defined or @path does not hold any value.
+ */
+const GValue *
+gda_server_operation_get_value_at (GdaServerOperation *op, const gchar *path_format, ...)
+{
+	const GValue *value = NULL;
+	gchar *path;
+	va_list args;
+
+	g_return_val_if_fail (GDA_IS_SERVER_OPERATION (op), NULL);
+	g_return_val_if_fail (op->priv, NULL);
+
+	/* build path */
+	va_start (args, path_format);
+	path = g_strdup_vprintf (path_format, args);
+	va_end (args);
+
+	value = real_gda_server_operation_get_value_at (op, path);
 	g_free (path);
+
 	return value;
 }
 
 /**
+ * gda_server_operation_get_sql_identifier_at
+ * @op: a #GdaServerOperation object
+ * @cnc: a #GdaConnection, or %NULL
+ * @prov: a #GdaServerProvider, or %NULL
+ * @path_format: a complete path to a node (starting with "/")
+ * @...: arguments to use with @path_format to make a complete path
+ *
+ * This method is similar to gda_server_operation_get_value_at(), but for SQL identifiers: a new string
+ * is returned instead of a #GValue. Also the returned string is assumed to represents an SQL identifier
+ * and will correctly be quoted to be used with @cnc, or @prov if @cnc is %NULL (a generic quoting rule
+ * will be applied if both are %NULL).
+ *
+ * Returns: a new string, or %NULL if the value is undefined or
+ * if the @path is not defined or @path does not hold any value, or if the value held is not a string
+ * (in that last case a warning is shown).
+ *
+ * Since: 4.0.3
+ */
+gchar *
+gda_server_operation_get_sql_identifier_at (GdaServerOperation *op, GdaConnection *cnc, GdaServerProvider *prov,
+					    const gchar *path_format, ...)
+{
+	const GValue *value = NULL;
+	gchar *path;
+	va_list args;
+	GdaConnectionOptions cncoptions;
+
+	g_return_val_if_fail (GDA_IS_SERVER_OPERATION (op), NULL);
+
+	/* build path */
+	va_start (args, path_format);
+	path = g_strdup_vprintf (path_format, args);
+	va_end (args);
+
+	value = real_gda_server_operation_get_value_at (op, path);
+	g_free (path);
+
+	if (!value || (G_VALUE_TYPE (value) == GDA_TYPE_NULL))
+		return NULL;
+	g_return_val_if_fail (G_VALUE_TYPE (value) == G_TYPE_STRING, NULL);
+
+	g_object_get (G_OBJECT (cnc), "options", &cncoptions, NULL);
+	return gda_sql_identifier_quote (g_value_get_string (value), cnc, prov, FALSE,
+					 cncoptions & GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE);
+}
+
+/**
  * gda_server_operation_set_value_at
  * @op: a #GdaServerOperation object
  * @value: a string
diff --git a/libgda/gda-server-operation.h b/libgda/gda-server-operation.h
index df7ebe0..958cc44 100644
--- a/libgda/gda-server-operation.h
+++ b/libgda/gda-server-operation.h
@@ -113,6 +113,9 @@ const gchar               *gda_server_operation_op_type_to_string       (GdaServ
 GdaServerOperationNode    *gda_server_operation_get_node_info           (GdaServerOperation *op, const gchar *path_format, ...);
 
 const GValue              *gda_server_operation_get_value_at            (GdaServerOperation *op, const gchar *path_format, ...);
+gchar                     *gda_server_operation_get_sql_identifier_at   (GdaServerOperation *op,
+									 GdaConnection *cnc, GdaServerProvider *prov,
+									 const gchar *path_format, ...);
 gboolean                   gda_server_operation_set_value_at            (GdaServerOperation *op, const gchar *value, 
 									 GError **error, const gchar *path_format, ...);
 
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 84b1df2..1a47a74 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -146,6 +146,7 @@
 	gda_connection_open_from_string
 	gda_connection_options_get_type
 	gda_connection_perform_operation
+	gda_connection_quote_sql_identifier
 	gda_connection_rollback_savepoint
 	gda_connection_rollback_transaction
 	gda_connection_schema_get_type
@@ -410,6 +411,7 @@
 	gda_meta_store_schema_get_structure
 	gda_meta_store_schema_remove_custom_object
 	gda_meta_store_set_attribute_value
+	gda_meta_store_sql_identifier_quote
 	gda_meta_struct_add_db_object
 	gda_meta_struct_complement
 	gda_meta_struct_complement_all
@@ -488,6 +490,7 @@
 	gda_server_operation_get_sequence_size
 	gda_server_operation_get_type
 	gda_server_operation_get_value_at
+	gda_server_operation_get_sql_identifier_at
 	gda_server_operation_is_valid
 	gda_server_operation_load_data_from_xml
 	gda_server_operation_new
diff --git a/libgda/sqlite/gda-sqlite-ddl.c b/libgda/sqlite/gda-sqlite-ddl.c
index 2005fe6..7369ef5 100644
--- a/libgda/sqlite/gda-sqlite-ddl.c
+++ b/libgda/sqlite/gda-sqlite-ddl.c
@@ -28,7 +28,7 @@
 
 gchar *
 _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc, 
-			       GdaServerOperation *op, GError **error)
+				 GdaServerOperation *op, GError **error)
 {
 	GString *string;
 	const GValue *value;
@@ -41,6 +41,7 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 	gint nbpkfields = 0;
 	gchar *sql = NULL;
 	gchar *conflict_algo = NULL;
+	gchar *tmp;
 
 	/* CREATE TABLE */
 	string = g_string_new ("CREATE ");
@@ -53,9 +54,9 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "IF NOT EXISTS ");
 		
-	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	g_string_append (string, " (");
 		
 	/* FIELDS */
@@ -69,11 +70,13 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 		nrows = gda_data_model_get_n_rows (node->model);
 		for (i = 0; i < nrows; i++) {
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
-				pkfields = g_slist_append (pkfields,
-							   (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+										  "/FIELDS_A/@COLUMN_NAME/%d", i);
+				pkfields = g_slist_append (pkfields, tmp);
+				nbpkfields++;
+			}
 		}
-		nbpkfields = g_slist_length (pkfields);
 
 		/* manually defined fields */
 		first = TRUE;
@@ -85,8 +88,9 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 			else
 				g_string_append (string, ", ");
 				
-			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-			g_string_append (string, g_value_get_string (value));
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/FIELDS_A/@COLUMN_NAME/%d", i);
+			g_string_append (string, tmp);
+			g_free (tmp);
 			g_string_append_c (string, ' ');
 				
 			if (nbpkfields == 1) {
@@ -191,14 +195,13 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 
 	/* composed primary key */
 	if (nbpkfields > 1) {
-		GSList *list = pkfields;
+		GSList *list;
 
 		g_string_append (string, ", PRIMARY KEY (");
-		while (list) {
+		for (list = pkfields; list; list = list->next) {
 			if (list != pkfields)
 				g_string_append (string, ", ");
-			g_string_append (string, g_value_get_string ((GValue*) list->data));
-			list = list->next;
+			g_string_append (string, (gchar *) list->data);
 		}
 		g_string_append_c (string, ')');
 		
@@ -207,6 +210,8 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 			g_string_append (string, conflict_algo);
 		}
 	}
+	g_slist_foreach (pkfields, (GFunc) g_free, NULL);
+	g_slist_free (pkfields);
 
 	g_free (conflict_algo);
 	g_string_append (string, ")");
@@ -215,8 +220,6 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 		allok = FALSE;
 		g_set_error (error, 0, 0, "%s", _("Table to create must have at least one row"));
 	}
-	g_slist_free (pkfields);
-
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -226,11 +229,12 @@ _gda_sqlite_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc
 
 gchar *
 _gda_sqlite_render_DROP_TABLE (GdaServerProvider *provider, GdaConnection *cnc, 
-			     GdaServerOperation *op, GError **error)
+			       GdaServerOperation *op, GError **error)
 {
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	/* DROP TABLE */
 	string = g_string_new ("DROP TABLE");
@@ -239,10 +243,10 @@ _gda_sqlite_render_DROP_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, " IF EXISTS");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NAME");
 	g_string_append_c (string, ' ');
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -252,23 +256,23 @@ _gda_sqlite_render_DROP_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 
 gchar *
 _gda_sqlite_render_RENAME_TABLE (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
+				 GdaServerOperation *op, GError **error)
 {
 	GString *string;
-	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	/* DROP TABLE */
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NEW_NAME");
 	g_string_append (string, " RENAME TO ");
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -283,19 +287,20 @@ _gda_sqlite_render_ADD_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	/* DROP TABLE */
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	g_string_append (string, " ADD COLUMN ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DEF_P/COLUMN_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_TYPE");
 	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
@@ -353,6 +358,7 @@ _gda_sqlite_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc
 	gchar *sql = NULL;
 	GdaServerOperationNode *node;
 	gint nrows, i;
+	gchar *tmp;
 
 	/* CREATE INDEX */
 	string = g_string_new ("CREATE ");
@@ -371,16 +377,15 @@ _gda_sqlite_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc
 		g_string_append (string, " IF NOT EXISTS ");
 	
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DEF_P/INDEX_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	g_string_append (string, " ON ");
 	
-	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_ON_TABLE");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
-
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DEF_P/INDEX_ON_TABLE");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	/* fields or expressions the index is on */
 	g_string_append (string, " (");
@@ -388,11 +393,13 @@ _gda_sqlite_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc
 	g_assert (node);
 	nrows = gda_server_operation_get_sequence_size (op, "/INDEX_FIELDS_S");
 	for (i = 0; i < nrows; i++) {
-		value = gda_server_operation_get_value_at (op, "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
-		if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+		tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+								  "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
+		if (tmp) {
 			if (i != 0)
 				g_string_append (string, ", ");
-			g_string_append (string, g_value_get_string (value));
+			g_string_append (string, tmp);
+			g_free (tmp);
 			
 			value = gda_server_operation_get_value_at (op, "/INDEX_FIELDS_S/%d/INDEX_COLLATE", i);
 			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
@@ -430,6 +437,7 @@ _gda_sqlite_render_DROP_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	/* DROP INDEX */
 	string = g_string_new ("DROP INDEX ");
@@ -438,9 +446,9 @@ _gda_sqlite_render_DROP_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "IF EXISTS ");
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DESC_P/INDEX_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -456,6 +464,7 @@ _gda_sqlite_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	const GValue *value;
 	gboolean allok = TRUE;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 	value = gda_server_operation_get_value_at (op, "/VIEW_DEF_P/VIEW_TEMP");
@@ -468,10 +477,9 @@ _gda_sqlite_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "IF NOT EXISTS ");
 
-		
-	value = gda_server_operation_get_value_at (op, "/VIEW_DEF_P/VIEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/VIEW_DEF_P/VIEW_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	
 	if (allok) {
 		value = gda_server_operation_get_value_at (op, "/VIEW_DEF_P/VIEW_DEF");
@@ -499,6 +507,7 @@ _gda_sqlite_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP VIEW");
 
@@ -506,10 +515,10 @@ _gda_sqlite_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, " IF EXISTS");
 
-	value = gda_server_operation_get_value_at (op, "/VIEW_DESC_P/VIEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/VIEW_DESC_P/VIEW_NAME");
 	g_string_append_c (string, ' ');
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
diff --git a/providers/jdbc/gda-jdbc-ddl.c b/providers/jdbc/gda-jdbc-ddl.c
index b48bd6e..6631c28 100644
--- a/providers/jdbc/gda-jdbc-ddl.c
+++ b/providers/jdbc/gda-jdbc-ddl.c
@@ -38,13 +38,14 @@ gda_jdbc_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	GSList *pkfields = NULL; /* list of GValue* composing the pkey */
 	gint nbpkfields = 0;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	/* CREATE TABLE */
 	string = g_string_new ("CREATE TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	g_string_append (string, " (");
 		
 	/* FIELDS */
@@ -58,11 +59,13 @@ gda_jdbc_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		nrows = gda_data_model_get_n_rows (node->model);
 		for (i = 0; i < nrows; i++) {
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
-				pkfields = g_slist_append (pkfields,
-							   (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+										  "/FIELDS_A/@COLUMN_NAME/%d", i);
+				pkfields = g_slist_append (pkfields, tmp);
+				nbpkfields++;
+			}
 		}
-		nbpkfields = g_slist_length (pkfields);
 
 		/* manually defined fields */
 		first = TRUE;
@@ -73,8 +76,10 @@ gda_jdbc_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 			else
 				g_string_append (string, ", ");
 				
-			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-			g_string_append (string, g_value_get_string (value));
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/FIELDS_A/@COLUMN_NAME/%d", i);
+			g_string_append (string, tmp);
+			g_free (tmp);
 			g_string_append_c (string, ' ');
 				
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
@@ -117,17 +122,18 @@ gda_jdbc_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 
 	/* composed primary key */
 	if (nbpkfields > 1) {
-		GSList *list = pkfields;
+		GSList *list;
 
 		g_string_append (string, ", PRIMARY KEY (");
-		while (list) {
+		for (list = pkfields; list; list = list->next) {
 			if (list != pkfields)
 				g_string_append (string, ", ");
-			g_string_append (string, g_value_get_string ((GValue*) list->data));
-			list = list->next;
+			g_string_append (string, (gchar*) list->data);
 		}
 		g_string_append_c (string, ')');
 	}
+	g_slist_foreach (pkfields, (GFunc) g_free, NULL);
+	g_slist_free (pkfields);
 
 	g_string_append (string, ")");
 
@@ -135,7 +141,6 @@ gda_jdbc_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		allok = FALSE;
 		g_set_error (error, 0, 0, "%s", _("Table to create must have at least one row"));
 	}
-	g_slist_free (pkfields);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
diff --git a/providers/mysql/gda-mysql-ddl.c b/providers/mysql/gda-mysql-ddl.c
index 4c0647b..526b1b4 100644
--- a/providers/mysql/gda-mysql-ddl.c
+++ b/providers/mysql/gda-mysql-ddl.c
@@ -24,6 +24,7 @@
 #include "gda-mysql-ddl.h"
 #include <glib/gi18n-lib.h>
 #include <libgda/gda-data-handler.h>
+#include <libgda/sql-parser/gda-sql-parser.h>
 
 gchar *
 gda_mysql_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc, 
@@ -33,6 +34,7 @@ gda_mysql_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc,
 	const GValue *value;
 	gchar *sql = NULL;
 	gboolean first = TRUE;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE DATABASE ");
 
@@ -40,9 +42,9 @@ gda_mysql_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "IF NOT EXISTS ");
 
-	value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/DB_DEF_P/DB_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_CSET");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
@@ -51,14 +53,15 @@ gda_mysql_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc,
 		first = FALSE;
 	}
 
-	value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_COLLATION");
-	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/DB_DEF_P/DB_COLLATION");
+	if (tmp) {
 		if (first)
 			first = FALSE;
 		else
 			g_string_append (string, ", ");
 		g_string_append (string, " COLLATION ");
-		g_string_append (string, g_value_get_string (value));
+		g_string_append (string, tmp);
+		g_free (tmp);
 	}
 
 	sql = string->str;
@@ -74,6 +77,7 @@ gda_mysql_render_DROP_DB (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP DATABASE ");
 
@@ -81,9 +85,9 @@ gda_mysql_render_DROP_DB (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "IF EXISTS ");
 
-	value = gda_server_operation_get_value_at (op, "/DB_DESC_P/DB_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/DB_DESC_P/DB_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -106,6 +110,7 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	GSList *pkfields = NULL; /* list of GValue* composing the pkey */
 	gint nbpkfields = 0;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_TEMP");
@@ -117,9 +122,9 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "IF NOT EXISTS ");
 		
-	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	g_string_append (string, " (");
 		
 	/* FIELDS */
@@ -133,11 +138,13 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		nrows = gda_data_model_get_n_rows (node->model);
 		for (i = 0; i < nrows; i++) {
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
-				pkfields = g_slist_append (pkfields,
-							   (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, 
+										  "/FIELDS_A/@COLUMN_NAME/%d", i);
+				pkfields = g_slist_append (pkfields, tmp);
+				nbpkfields ++;
+			}
 		}
-		nbpkfields = g_slist_length (pkfields);
 
 		/* manually defined fields */
 		first = TRUE;
@@ -148,8 +155,10 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 			else
 				g_string_append (string, ", ");
 				
-			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-			g_string_append (string, g_value_get_string (value));
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/FIELDS_A/@COLUMN_NAME/%d", i);
+			g_string_append (string, tmp);
+			g_free (tmp);
 			g_string_append_c (string, ' ');
 				
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
@@ -226,14 +235,15 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		GSList *list = pkfields;
 
 		g_string_append (string, ", PRIMARY KEY (");
-		while (list) {
+		for (list = pkfields; list; list = list->next) {
 			if (list != pkfields)
 				g_string_append (string, ", ");
-			g_string_append (string, g_value_get_string ((GValue*) list->data));
-			list = list->next;
+			g_string_append (string, (gchar *) tmp);
 		}
 		g_string_append_c (string, ')');
 	}
+	g_slist_foreach (pkfields, (GFunc) g_free, NULL);
+	g_slist_free (pkfields);
 
 	/* foreign keys */
 	if (allok) {
@@ -256,10 +266,12 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 					for (j = 0; j < nbfields; j++) {
 						if (j != 0)
 							g_string_append (string, ", ");
-						value = gda_server_operation_get_value_at (op, 
-											   "/FKEY_S/%d/FKEY_FIELDS_A/@FK_FIELD/%d", i, j);
-						if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
-							g_string_append (string, g_value_get_string (value));
+						tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+												  "/FKEY_S/%d/FKEY_FIELDS_A/@FK_FIELD/%d", i, j);
+						if (tmp) {
+							g_string_append (string, tmp);
+							g_free (tmp);
+						}
 						else {
 							allok = FALSE;
 							g_set_error (error, 0, 0, "%s",  
@@ -268,11 +280,9 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 					}
 				}
 				g_string_append (string, ") REFERENCES ");
-				value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_REF_TABLE", i);
-				if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
-					gchar *tmp;
-					tmp = gda_sql_identifier_quote (g_value_get_string (value), cnc, NULL,
-									FALSE, FALSE);
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+										  "/FKEY_S/%d/FKEY_REF_TABLE", i);
+				if (tmp) {
 					g_string_append (string, tmp);
 					g_free (tmp);
 				}
@@ -285,10 +295,12 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 				for (j = 0; j < nbfields; j++) {
 					if (j != 0)
 						g_string_append (string, ", ");
-					value = gda_server_operation_get_value_at (op, 
-										   "/FKEY_S/%d/FKEY_FIELDS_A/@FK_REF_PK_FIELD/%d", i, j);
-					if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
-						g_string_append (string, g_value_get_string (value));
+					tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+											  "/FKEY_S/%d/FKEY_FIELDS_A/@FK_REF_PK_FIELD/%d", i, j);
+					if (tmp) {
+						g_string_append (string, tmp);
+						g_free (tmp);
+					}
 					else {
 						allok = FALSE;
 						g_set_error (error, 0, 0, "%s",  
@@ -322,7 +334,7 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && 
 		    g_value_get_string (value) && *g_value_get_string (value))
 			g_string_append (string, " ENGINE = ");
-			g_string_append (string, g_value_get_string (value));
+		g_string_append (string, g_value_get_string (value));
 		
 		value = gda_server_operation_get_value_at (op, "/TABLE_OPTIONS_P/TABLE_AUTOINC_VALUE");
 		if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) 
@@ -339,11 +351,12 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 			g_string_append (string, " CHARACTER SET ");
 			g_string_append (string, g_value_get_string (value));
 
-			value = gda_server_operation_get_value_at (op, "/TABLE_OPTIONS_P/TABLE_COLLATION");
-			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && 
-			    g_value_get_string (value) && *g_value_get_string (value)) {
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/TABLE_OPTIONS_P/TABLE_COLLATION");
+			if (tmp) {
 				g_string_append (string, " COLLATE ");
-				g_string_append (string, g_value_get_string (value));
+				g_string_append (string, tmp);
+				g_free (tmp);
 			}
 		}
 		
@@ -356,7 +369,7 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		    g_value_get_string (value) && *g_value_get_string (value)) {
 			GdaDataHandler *dh;
 			gchar *str;
-
+			
 			dh = gda_server_provider_get_data_handler_g_type (provider, cnc, G_TYPE_STRING);
 			str = gda_data_handler_get_sql_from_value (dh, value);
 			if (str) {
@@ -365,15 +378,15 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 				g_free (str);
 			}
 		}
-
+		
 		value = gda_server_operation_get_value_at (op, "/TABLE_OPTIONS_P/TABLE_MAX_ROWS");
 		if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) 
 			g_string_append_printf (string, " MAX_ROWS = %d", g_value_get_int (value));
-
+		
 		value = gda_server_operation_get_value_at (op, "/TABLE_OPTIONS_P/TABLE_MIN_ROWS");
 		if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) 
 			g_string_append_printf (string, " MIN_ROWS = %d", g_value_get_int (value));
-
+		
 		value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_PACK_KEYS");
 		if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && 
 		    g_value_get_string (value) && *g_value_get_string (value)) {
@@ -452,12 +465,9 @@ gda_mysql_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		}
 	}
 
-	g_slist_free (pkfields);
-
-
 	sql = string->str;
 	g_string_free (string, FALSE);
-
+	
 	return sql;
 }
 
@@ -468,6 +478,7 @@ gda_mysql_render_DROP_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP");
 
@@ -481,10 +492,10 @@ gda_mysql_render_DROP_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, " IF EXISTS");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NAME");
 	g_string_append_c (string, ' ');
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/REFERENCED_ACTION");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
@@ -503,19 +514,19 @@ gda_mysql_render_RENAME_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 			       GdaServerOperation *op, GError **error)
 {
 	GString *string;
-	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NEW_NAME");
 	g_string_append (string, " RENAME TO ");
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -530,18 +541,19 @@ gda_mysql_render_ADD_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	g_string_append (string, " ADD COLUMN ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DEF_P/COLUMN_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_TYPE");
 	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
@@ -635,19 +647,19 @@ gda_mysql_render_DROP_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
 			      GdaServerOperation *op, GError **error)
 {
 	GString *string;
-	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DESC_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/COLUMN_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DESC_P/COLUMN_NAME");
 	g_string_append (string, " DROP COLUMN ");
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -665,6 +677,7 @@ gda_mysql_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
 	gchar *sql = NULL;
 	GdaServerOperationNode *node;
 	gint nrows, i;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 
@@ -677,9 +690,9 @@ gda_mysql_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
 
 	g_string_append (string, "INDEX ");
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DEF_P/INDEX_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_METHOD");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
@@ -689,10 +702,9 @@ gda_mysql_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
 
 	g_string_append (string, " ON ");
 	
-	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_ON_TABLE");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
-
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DEF_P/INDEX_ON_TABLE");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	/* fields or expressions the index is on */
 	g_string_append (string, " (");
@@ -731,19 +743,19 @@ gda_mysql_render_DROP_INDEX (GdaServerProvider *provider, GdaConnection *cnc,
 			     GdaServerOperation *op, GError **error)
 {
 	GString *string;
-	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP INDEX ");
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DESC_P/INDEX_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/INDEX_ON_TABLE");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DESC_P/INDEX_ON_TABLE");
 	g_string_append (string, " ON ");
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -760,6 +772,7 @@ gda_mysql_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	gboolean allok = TRUE;
 	gchar *sql = NULL;
 	GdaServerOperationNode *node;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 
@@ -768,10 +781,10 @@ gda_mysql_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 		g_string_append (string, "OR REPLACE ");
 
 	g_string_append (string, "VIEW ");
-		
-	value = gda_server_operation_get_value_at (op, "/VIEW_DEF_P/VIEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/VIEW_DEF_P/VIEW_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	node = gda_server_operation_get_node_info (op, "/FIELDS_A");
 	if (node) {
@@ -782,13 +795,16 @@ gda_mysql_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 		for (i = 0; (i < nrows) && allok; i++) {
 			if (i == 0)
 				g_string_append (string, " (");
-			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/FIELDS_A/@COLUMN_NAME/%d", i);
+			if (tmp) {
 				if (i != 0) 
 					g_string_append (string, ", ");
 				
-				g_string_append (string, g_value_get_string (value));
+				g_string_append (string, tmp);
 				g_string_append_c (string, ' ');
+				g_free (tmp);
 			}
 			else {
 				g_set_error (error, 0, 0, "%s", _("Incorrect specified column name"));
@@ -825,6 +841,7 @@ gda_mysql_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP VIEW");
 
@@ -832,10 +849,10 @@ gda_mysql_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, " IF EXISTS");
 
-	value = gda_server_operation_get_value_at (op, "/VIEW_DESC_P/VIEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/VIEW_DESC_P/VIEW_NAME");
 	g_string_append_c (string, ' ');
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
diff --git a/providers/oracle/gda-oracle-ddl.c b/providers/oracle/gda-oracle-ddl.c
index cf38335..0149e4f 100644
--- a/providers/oracle/gda-oracle-ddl.c
+++ b/providers/oracle/gda-oracle-ddl.c
@@ -1,9 +1,8 @@
-/* GNOME DB Oracle Provider
- * Copyright (C) 2006 The GNOME Foundation
+/* GDA Oracle Provider
+ * Copyright (C) 2008 The GNOME Foundation
  *
  * AUTHORS:
- *         Vivien Malerba <malerba gnome-db org>
- *         Bas Driessen <bas driessen xobas com>
+ *      Vivien Malerba <malerba gnome-db org>
  *
  * This Library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public License as
@@ -21,111 +20,125 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include "gda-oracle-ddl.h"
 #include <glib/gi18n-lib.h>
-#include <libgda/gda-data-handler.h>
-
-gchar *
-gda_oracle_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc, 
-			     GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
-gchar *
-gda_oracle_render_DROP_DB (GdaServerProvider *provider, GdaConnection *cnc, 
-			   GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
+#include <libgda/libgda.h>
+#include "gda-oracle-ddl.h"
 
 gchar *
 gda_oracle_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
-gchar *
-gda_oracle_render_DROP_TABLE   (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
+			      GdaServerOperation *op, GError **error)
 {
 	GString *string;
 	const GValue *value;
+	gboolean allok = TRUE;
+	gboolean hasfields = FALSE;
+	gint nrows;
+	gint i;
+	gboolean first;
+	GSList *pkfields = NULL; /* list of GValue* composing the pkey */
+	gint nbpkfields = 0;
 	gchar *sql = NULL;
 
-	string = g_string_new ("DROP TABLE ");
+	/* CREATE TABLE */
+	string = g_string_new ("CREATE TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
+	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
 	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
 	g_string_append (string, g_value_get_string (value));
-
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/REFERENCED_ACTION");
-	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
-		g_string_append_c (string, ' ');
-		g_string_append (string, g_value_get_string (value));
+	g_string_append (string, " (");
+		
+	/* FIELDS */
+	if (allok) {
+		GdaServerOperationNode *node;
+
+		node = gda_server_operation_get_node_info (op, "/FIELDS_A");
+		g_assert (node);
+
+		/* finding if there is a composed primary key */
+		nrows = gda_data_model_get_n_rows (node->model);
+		for (i = 0; i < nrows; i++) {
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+				pkfields = g_slist_append (pkfields,
+							   (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+		}
+		nbpkfields = g_slist_length (pkfields);
+
+		/* manually defined fields */
+		first = TRUE;
+		for (i = 0; i < nrows; i++) {
+			hasfields = TRUE;
+			if (first) 
+				first = FALSE;
+			else
+				g_string_append (string, ", ");
+				
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
+			g_string_append (string, g_value_get_string (value));
+			g_string_append_c (string, ' ');
+				
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
+			g_string_append (string, g_value_get_string (value));
+				
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_DEFAULT/%d", i);
+			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+				const gchar *str = g_value_get_string (value);
+				if (str && *str) {
+					g_string_append (string, " DEFAULT ");
+					g_string_append (string, str);
+				}
+			}
+				
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NNUL/%d", i);
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+				g_string_append (string, " NOT NULL");
+
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_UNIQUE/%d", i);
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+				g_string_append (string, " UNIQUE");
+				
+			if (nbpkfields == 1) {
+				value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
+				if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
+					g_string_append (string, " PRIMARY KEY");
+			}
+				
+			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_CHECK/%d", i);
+			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
+				const gchar *str = g_value_get_string (value);
+				if (str && *str) {
+					g_string_append (string, " CHECK (");
+					g_string_append (string, str);
+					g_string_append_c (string, ')');
+				}
+			}
+		}
 	}
 
-	sql = string->str;
-	g_string_free (string, FALSE);
-
-	return sql;
-}
-
-gchar *
-gda_oracle_render_RENAME_TABLE (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
-
-gchar *
-gda_oracle_render_ADD_COLUMN   (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
-gchar *
-gda_oracle_render_DROP_COLUMN  (GdaServerProvider *provider, GdaConnection *cnc, 
-				  GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
-
-gchar *
-gda_oracle_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
-{
-	return NULL;
-}
-
-gchar *
-gda_oracle_render_DROP_INDEX   (GdaServerProvider *provider, GdaConnection *cnc, 
-				GdaServerOperation *op, GError **error)
-{
-	GString *string;
-	const GValue *value;
-	gchar *sql = NULL;
-
-	string = g_string_new ("DROP INDEX ");
+	/* composed primary key */
+	if (nbpkfields > 1) {
+		GSList *list = pkfields;
+
+		g_string_append (string, ", PRIMARY KEY (");
+		while (list) {
+			if (list != pkfields)
+				g_string_append (string, ", ");
+			g_string_append (string, g_value_get_string ((GValue*) list->data));
+			list = list->next;
+		}
+		g_string_append_c (string, ')');
+	}
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, ")");
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/REFERENCED_ACTION");
-	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
-		g_string_append_c (string, ' ');
-		g_string_append (string, g_value_get_string (value));
+	if (!hasfields) {
+		allok = FALSE;
+		g_set_error (error, 0, 0, "%s", _("Table to create must have at least one row"));
 	}
+	g_slist_free (pkfields);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
 
 	return sql;
 }
-
diff --git a/providers/postgres/gda-postgres-ddl.c b/providers/postgres/gda-postgres-ddl.c
index eec43cf..34b9791 100644
--- a/providers/postgres/gda-postgres-ddl.c
+++ b/providers/postgres/gda-postgres-ddl.c
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 The GNOME Foundation
  *
  * AUTHORS:
- *      TO_ADD: your name and email
+ *      Vivien Malerba <malerba gnome-db org>
  *
  * This Library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public License as
@@ -31,12 +31,13 @@ gda_postgres_render_CREATE_DB (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE DATABASE ");
 
-	value = gda_server_operation_get_value_at (op, "/DB_DEF_P/DB_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append_printf (string, "\"%s\"", g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/DB_DEF_P/DB_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/DB_DEF_P/OWNER");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
@@ -81,14 +82,14 @@ gda_postgres_render_DROP_DB (GdaServerProvider *provider, GdaConnection *cnc,
 			     GdaServerOperation *op, GError **error)
 {
 	GString *string;
-	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP DATABASE ");
 
-	value = gda_server_operation_get_value_at (op, "/DB_DESC_P/DB_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append_printf (string, "\"%s\"", g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/DB_DESC_P/DB_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -110,6 +111,7 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 	GSList *pkfields = NULL; /* list of GValue* composing the pkey */
 	gint nbpkfields = 0;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_TEMP");
@@ -117,9 +119,10 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 		g_string_append (string, "TEMP ");
 	g_string_append (string, "TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+							  "/TABLE_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	g_string_append (string, " (");
 		
 	/* FIELDS */
@@ -133,11 +136,13 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 		nrows = gda_data_model_get_n_rows (node->model);
 		for (i = 0; i < nrows; i++) {
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
-				pkfields = g_slist_append (pkfields,
-							   (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+										  "/FIELDS_A/@COLUMN_NAME/%d", i);
+				pkfields = g_slist_append (pkfields, tmp);
+				nbpkfields ++;
+			}
 		}
-		nbpkfields = g_slist_length (pkfields);
 
 		/* manually defined fields */
 		first = TRUE;
@@ -148,12 +153,11 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 			else
 				g_string_append (string, ", ");
 				
-			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-			g_string_append_c (string, '\"');
-			g_string_append (string, g_value_get_string (value));
-			g_string_append_c (string, '\"');
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/FIELDS_A/@COLUMN_NAME/%d", i);
+			g_string_append (string, tmp);
+			g_free (tmp);
 			g_string_append_c (string, ' ');
-				
 
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_AUTOINC/%d", i);
 			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
@@ -213,44 +217,43 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 		for (i = 0; i < nrows; i++) {
 			value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY", i);
 			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && !g_value_get_boolean (value)) {
-				value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_TABLE", i);
-				if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
-					const gchar *str = g_value_get_string (value);
-					if (str && *str) {
-						hasfields = TRUE;
-						if (first) 
-							first = FALSE;
-						else
-							g_string_append (string, ", ");
 
-						g_string_append (string, "LIKE ");
-						g_string_append (string, str);
-						value = gda_server_operation_get_value_at (op, 
-											   "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY_DEFAULTS", i);
-						if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && 
-						    g_value_get_boolean (value))
-							g_string_append (string, " INCLUDING DEFAULTS");
-					}
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									    "/TABLE_PARENTS_S/%d/TABLE_PARENT_TABLE", i);
+				if (tmp && *tmp) {
+					hasfields = TRUE;
+					if (first) 
+						first = FALSE;
+					else
+						g_string_append (string, ", ");
+					
+					g_string_append (string, "LIKE ");
+					g_string_append (string, tmp);
+					value = gda_server_operation_get_value_at (op, 
+										   "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY_DEFAULTS", i);
+					if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && 
+					    g_value_get_boolean (value))
+						g_string_append (string, " INCLUDING DEFAULTS");
 				}
+				g_free (tmp);
 			}
 		}
 	}
 
 	/* composed primary key */
 	if (nbpkfields > 1) {
-		GSList *list = pkfields;
+		GSList *list;
 
 		g_string_append (string, ", PRIMARY KEY (");
-		while (list) {
+		for (list = pkfields; list; list = list->next) {
 			if (list != pkfields)
 				g_string_append (string, ", ");
-			g_string_append_c (string, '\"');
-			g_string_append (string, g_value_get_string ((GValue*) list->data));
-			g_string_append_c (string, '\"');
-			list = list->next;
+			g_string_append (string, (gchar*) list->data);
 		}
 		g_string_append_c (string, ')');
 	}
+	g_slist_foreach (pkfields, (GFunc) g_free, NULL);
+	g_slist_free (pkfields);
 
 	/* foreign keys */
 	if (allok) {
@@ -273,13 +276,11 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 					for (j = 0; j < nbfields; j++) {
 						if (j != 0)
 							g_string_append (string, ", ");
-						value = gda_server_operation_get_value_at (op, 
-											   "/FKEY_S/%d/FKEY_FIELDS_A/@FK_FIELD/%d", i, j);
-						if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
-						{
-							g_string_append_c (string, '\"');
-							g_string_append (string, g_value_get_string (value));
-							g_string_append_c (string, '\"');
+						tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+								 "/FKEY_S/%d/FKEY_FIELDS_A/@FK_FIELD/%d", i, j);
+						if (tmp) {
+							g_string_append (string, tmp);
+							g_free (tmp);
 						}
 						else {
 							allok = FALSE;
@@ -289,9 +290,13 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 					}
 				}
 				g_string_append (string, ") REFERENCES ");
-				value = gda_server_operation_get_value_at (op, "/FKEY_S/%d/FKEY_REF_TABLE", i);
-				if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
-					g_string_append (string, g_value_get_string (value));
+
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+										  "/FKEY_S/%d/FKEY_REF_TABLE", i);
+				if (tmp) {
+					g_string_append (string, tmp);
+					g_free (tmp);
+				}
 				else {
 					allok = FALSE;
 					g_set_error (error, 0, 0, "%s", _("No referenced table specified in foreign key constraint"));
@@ -301,13 +306,11 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 				for (j = 0; j < nbfields; j++) {
 					if (j != 0)
 						g_string_append (string, ", ");
-					value = gda_server_operation_get_value_at (op, 
-										   "/FKEY_S/%d/FKEY_FIELDS_A/@FK_REF_PK_FIELD/%d", i, j);
-					if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
-					{
-						g_string_append_c (string, '\"');
-						g_string_append (string, g_value_get_string (value));
-						g_string_append_c (string, '\"');
+					tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+								"/FKEY_S/%d/FKEY_FIELDS_A/@FK_REF_PK_FIELD/%d", i, j);
+					if (tmp) {
+						g_string_append (string, tmp);
+						g_free (tmp);
 					}
 					else {
 						allok = FALSE;
@@ -340,19 +343,18 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 	for (i = 0; i < nrows; i++) {
 		value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_COPY", i);
 		if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
-			value = gda_server_operation_get_value_at (op, "/TABLE_PARENTS_S/%d/TABLE_PARENT_TABLE", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
-				const gchar *str = g_value_get_string (value);
-				if (str && *str) {
-					hasfields = TRUE;
-					if (first) {
-						g_string_append (string, " INHERITS ");
-						first = FALSE;
-					}
-					else
-						g_string_append (string, ", ");
-					g_string_append (string, str);
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/TABLE_PARENTS_S/%d/TABLE_PARENT_TABLE", i);
+			if (tmp) {
+				hasfields = TRUE;
+				if (first) {
+					g_string_append (string, " INHERITS ");
+					first = FALSE;
 				}
+				else
+					g_string_append (string, ", ");
+				g_string_append (string, tmp);
+				g_free (tmp);
 			}
 		}
 	}
@@ -368,9 +370,6 @@ gda_postgres_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cn
 			g_string_append (string, " WITH OIDS");
 	}
 
-	g_slist_free (pkfields);
-
-
 	sql = string->str;
 	g_string_free (string, FALSE);
 
@@ -384,12 +383,14 @@ gda_postgres_render_DROP_TABLE   (GdaServerProvider *provider, GdaConnection *cn
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+							  "/TABLE_DESC_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/REFERENCED_ACTION");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
@@ -408,19 +409,19 @@ gda_postgres_render_RENAME_TABLE (GdaServerProvider *provider, GdaConnection *cn
 				  GdaServerOperation *op, GError **error)
 {
 	GString *string;
-	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DESC_P/TABLE_NEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DESC_P/TABLE_NEW_NAME");
 	g_string_append (string, " RENAME TO ");
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	sql = string->str;
 	g_string_free (string, FALSE);
@@ -436,6 +437,7 @@ gda_postgres_render_ADD_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("ALTER TABLE ");
 
@@ -443,15 +445,15 @@ gda_postgres_render_ADD_COLUMN (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, "ONLY ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	g_string_append (string, " ADD COLUMN ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DEF_P/COLUMN_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/COLUMN_DEF_P/COLUMN_TYPE");
 	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
@@ -513,17 +515,17 @@ gda_postgres_render_DROP_COLUMN  (GdaServerProvider *provider, GdaConnection *cn
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("ALTER TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
-
-	value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/COLUMN_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DESC_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/COLUMN_DESC_P/COLUMN_NAME");
 	g_string_append (string, " DROP COLUMN ");
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/COLUMN_DESC_P/REFERENCED_ACTION");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
@@ -550,6 +552,7 @@ gda_postgres_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cn
 	gchar *sql = NULL;
 	GdaServerOperationNode *node;
 	gint nrows, i;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 
@@ -562,15 +565,15 @@ gda_postgres_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cn
 
 	g_string_append (string, "INDEX ");
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DEF_P/INDEX_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	g_string_append (string, " ON ");
-	
-	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_ON_TABLE");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DEF_P/INDEX_ON_TABLE");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/INDEX_DEF_P/INDEX_METHOD");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
@@ -584,13 +587,13 @@ gda_postgres_render_CREATE_INDEX (GdaServerProvider *provider, GdaConnection *cn
 	g_assert (node);
 	nrows = gda_server_operation_get_sequence_size (op, "/INDEX_FIELDS_S");
 	for (i = 0; i < nrows; i++) {
-		value = gda_server_operation_get_value_at (op, "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
-		if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value)) {
+		tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, 
+								  "/INDEX_FIELDS_S/%d/INDEX_FIELD", i);
+		if (tmp) {
 			if (i != 0)
 				g_string_append (string, ", ");
-			g_string_append_c (string, '\"');
-			g_string_append (string, g_value_get_string (value));
-			g_string_append_c (string, '\"');
+			g_string_append (string, tmp);
+			g_free (tmp);
 		}
 	}
 
@@ -622,12 +625,13 @@ gda_postgres_render_DROP_INDEX   (GdaServerProvider *provider, GdaConnection *cn
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP INDEX ");
 
-	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/INDEX_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/INDEX_DESC_P/INDEX_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/INDEX_DESC_P/REFERENCED_ACTION");
 	if (value && G_VALUE_HOLDS (value, G_TYPE_STRING)) {
@@ -649,6 +653,7 @@ gda_postgres_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc
 	const GValue *value;
 	gboolean allok = TRUE;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("CREATE ");
 
@@ -661,10 +666,10 @@ gda_postgres_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc
 		g_string_append (string, "TEMP ");
 
 	g_string_append (string, "VIEW ");
-		
-	value = gda_server_operation_get_value_at (op, "/VIEW_DEF_P/VIEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/VIEW_DEF_P/VIEW_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	
 	if (allok) {
 		GdaServerOperationNode *node;
@@ -676,16 +681,15 @@ gda_postgres_render_CREATE_VIEW (GdaServerProvider *provider, GdaConnection *cnc
 
 			nrows = gda_data_model_get_n_rows (node->model);
 			for (i = 0; i < nrows; i++) {
-				value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-				if (!value || !G_VALUE_HOLDS (value, G_TYPE_STRING))
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, 
+										  "/FIELDS_A/@COLUMN_NAME/%d", i);
+				if (!tmp)
 					continue;
-				if (!cols)
-					cols = g_string_new ("(\"");
-				else
-					g_string_append (cols, ", \"");
-				g_string_append (cols, g_value_get_string (value));
-				g_string_append_c (cols, '\"');
+				if (cols)
+					g_string_append (cols, ", ");
+				g_string_append (cols, tmp);
 				g_string_append_c (cols, ' ');
+				g_free (tmp);
 			}
 			if (cols) {
 				g_string_append_c (cols, ')');
@@ -721,6 +725,7 @@ gda_postgres_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	GString *string;
 	const GValue *value;
 	gchar *sql = NULL;
+	gchar *tmp;
 
 	string = g_string_new ("DROP VIEW");
 
@@ -728,10 +733,11 @@ gda_postgres_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 	if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
 		g_string_append (string, " IF EXISTS");
 
-	value = gda_server_operation_get_value_at (op, "/VIEW_DESC_P/VIEW_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+							  "/VIEW_DESC_P/VIEW_NAME");
 	g_string_append_c (string, ' ');
-	g_string_append (string, g_value_get_string (value));
+	g_string_append (string, tmp);
+	g_free (tmp);
 
 	value = gda_server_operation_get_value_at (op, "/VIEW_DESC_P/REFERENCED_ACTION");
 	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
diff --git a/providers/skel-implementation/capi/gda-capi-ddl.c b/providers/skel-implementation/capi/gda-capi-ddl.c
index a0e3bdc..76d4139 100644
--- a/providers/skel-implementation/capi/gda-capi-ddl.c
+++ b/providers/skel-implementation/capi/gda-capi-ddl.c
@@ -37,14 +37,14 @@ gda_capi_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 	gboolean first;
 	GSList *pkfields = NULL; /* list of GValue* composing the pkey */
 	gint nbpkfields = 0;
-	gchar *sql = NULL;
+	gchar *tmp;
 
 	/* CREATE TABLE */
 	string = g_string_new ("CREATE TABLE ");
 
-	value = gda_server_operation_get_value_at (op, "/TABLE_DEF_P/TABLE_NAME");
-	g_assert (value && G_VALUE_HOLDS (value, G_TYPE_STRING));
-	g_string_append (string, g_value_get_string (value));
+	tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider, "/TABLE_DEF_P/TABLE_NAME");
+	g_string_append (string, tmp);
+	g_free (tmp);
 	g_string_append (string, " (");
 		
 	/* FIELDS */
@@ -58,11 +58,13 @@ gda_capi_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		nrows = gda_data_model_get_n_rows (node->model);
 		for (i = 0; i < nrows; i++) {
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_PKEY/%d", i);
-			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value))
-				pkfields = g_slist_append (pkfields,
-							   (GValue *) gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i));
+			if (value && G_VALUE_HOLDS (value, G_TYPE_BOOLEAN) && g_value_get_boolean (value)) {
+				tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+										  "/FIELDS_A/@COLUMN_NAME/%d", i);
+				pkfields = g_slist_append (pkfields, tmp);
+				nbpkfields++;
+			}
 		}
-		nbpkfields = g_slist_length (pkfields);
 
 		/* manually defined fields */
 		first = TRUE;
@@ -73,8 +75,10 @@ gda_capi_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 			else
 				g_string_append (string, ", ");
 				
-			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_NAME/%d", i);
-			g_string_append (string, g_value_get_string (value));
+			tmp = gda_server_operation_get_sql_identifier_at (op, cnc, provider,
+									  "/FIELDS_A/@COLUMN_NAME/%d", i);
+			g_string_append (string, tmp);
+			g_free (tmp);
 			g_string_append_c (string, ' ');
 				
 			value = gda_server_operation_get_value_at (op, "/FIELDS_A/@COLUMN_TYPE/%d", i);
@@ -117,17 +121,18 @@ gda_capi_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 
 	/* composed primary key */
 	if (nbpkfields > 1) {
-		GSList *list = pkfields;
+		GSList *list;
 
 		g_string_append (string, ", PRIMARY KEY (");
-		while (list) {
+		for (list = pkfields; list; list = list->next) {
 			if (list != pkfields)
 				g_string_append (string, ", ");
-			g_string_append (string, g_value_get_string ((GValue*) list->data));
-			list = list->next;
+			g_string_append (string, (gchar*) list->data);
 		}
 		g_string_append_c (string, ')');
 	}
+	g_slist_foreach (pkfields, (GFunc) g_free, NULL);
+	g_slist_free (pkfields);
 
 	g_string_append (string, ")");
 
@@ -135,10 +140,6 @@ gda_capi_render_CREATE_TABLE (GdaServerProvider *provider, GdaConnection *cnc,
 		allok = FALSE;
 		g_set_error (error, 0, 0, "%s", _("Table to create must have at least one row"));
 	}
-	g_slist_free (pkfields);
-
-	sql = string->str;
-	g_string_free (string, FALSE);
 
-	return sql;
+	return g_string_free (string, FALSE);
 }



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