libgda r3170 - in trunk: . doc/C doc/C/tmpl libgda libgda/sql-parser tools



Author: vivien
Date: Wed Jul  2 19:33:18 2008
New Revision: 3170
URL: http://svn.gnome.org/viewvc/libgda?rev=3170&view=rev

Log:
2008-07-02  Vivien Malerba <malerba gnome-db org>

	* libgda/gda-meta-struct.[ch]:
	 - added a "store" property to reference a GdaMetaStore, and use
	it in any gda_meta_struct_complement*()
	 - made the db_objects instance	attribute private,
	 - added gda_meta_struct_get_all_db_objects()
	 - added an 'outdated' attribute to the GdaMetaDbObject structure
	which tells if its contents may be outdated (compared to what's in
	the GdaMetaStore)
	* libgda/gda-meta-store.c: property doc. fixes, and adaptations
	to the GdaMetaStruct changes
	* tools/command-exec.c:
	* libgda/sql-parser/gda-statement-struct.c: adaptations to
	the GdaMetaStruct changes
	* libgda/sql-parser/gda-statement-struct-util.c:
	* libgda/gda-set.c: minor correction
	* tools/gda-sql.c: correctly handle query buffer ending with a
	';', and allow one to connect to the '~' connection to really
	connect to the GdaMetaStore's connection to work with a connection's
	meta data
	* libgda/sql-parser/gda-sql-parser.c:
	* doc/C: doc. improvements


Modified:
   trunk/ChangeLog
   trunk/doc/C/libgda-4.0-docs.sgml
   trunk/doc/C/libgda-4.0-sections.txt
   trunk/doc/C/tmpl/gda-meta-store.sgml
   trunk/doc/C/tmpl/gda-meta-struct.sgml
   trunk/doc/C/tmpl/gda-sql-statement.sgml
   trunk/doc/C/tmpl/gda-vconnection-data-model.sgml
   trunk/libgda/gda-meta-store.c
   trunk/libgda/gda-meta-struct.c
   trunk/libgda/gda-meta-struct.h
   trunk/libgda/gda-set.c
   trunk/libgda/information_schema.xml
   trunk/libgda/sql-parser/gda-sql-parser.c
   trunk/libgda/sql-parser/gda-statement-struct-util.c
   trunk/libgda/sql-parser/gda-statement-struct.c
   trunk/tools/command-exec.c
   trunk/tools/gda-sql.c

Modified: trunk/doc/C/libgda-4.0-docs.sgml
==============================================================================
--- trunk/doc/C/libgda-4.0-docs.sgml	(original)
+++ trunk/doc/C/libgda-4.0-docs.sgml	Wed Jul  2 19:33:18 2008
@@ -1273,9 +1273,12 @@
     &provider-writing;
   </part>
 
-  &fdl-appendix;
-  <index>
-    <title>Index</title>
-  </index>
+  <part id="part_index">
+    <title>Appendix</title>
+    &fdl-appendix;
+    <index>
+      <title>Index</title>
+    </index>
+  </part>
 </book>
 

Modified: trunk/doc/C/libgda-4.0-sections.txt
==============================================================================
--- trunk/doc/C/libgda-4.0-sections.txt	(original)
+++ trunk/doc/C/libgda-4.0-sections.txt	Wed Jul  2 19:33:18 2008
@@ -1368,6 +1368,7 @@
 gda_meta_struct_complement_default
 GdaMetaSortType
 gda_meta_struct_sort_db_objects
+gda_meta_struct_get_all_db_objects
 gda_meta_struct_get_db_object
 gda_meta_struct_get_table_column
 GdaMetaGraphInfo

Modified: trunk/doc/C/tmpl/gda-meta-store.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-meta-store.sgml	(original)
+++ trunk/doc/C/tmpl/gda-meta-store.sgml	Wed Jul  2 19:33:18 2008
@@ -115,13 +115,15 @@
 
 <!-- ##### STRUCT GdaMetaContext ##### -->
 <para>
-
+  The <structname>GdaMetaContext</structname> represents a meta data modification
+  context: the <emphasis>how</emphasis> when used with gda_meta_store_modify_with_context(),
+  and the <emphasis>what</emphasis> when used with gda_connection_update_meta_store().
 </para>
 
- table_name: 
- size: 
- column_names: 
- column_values: 
+ table_name: the name of the table <emphasis>in the GdaMetaStore's internal database</emphasis>
+ size: the size of the @column_names and @column_values arrays
+ column_names: an array of column names (columns of the @table_name table)
+ column_values: an array of values, one for each column named in @column_names
 
 <!-- ##### FUNCTION gda_meta_store_new ##### -->
 <para>

Modified: trunk/doc/C/tmpl/gda-meta-struct.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-meta-struct.sgml	(original)
+++ trunk/doc/C/tmpl/gda-meta-struct.sgml	Wed Jul  2 19:33:18 2008
@@ -11,10 +11,15 @@
   analyse the columns of a table (or its foreign keys) using a #GdaMetaStruct.
 </para>
 <para>
-  The #GdaMetaStruct object exports a single #GSList list of database objects as #GdaMetaDbObject structures,
-  which should not be modified. The list is the <parameter>db_objects</parameter> member of the
-  structure. Use gda_meta_struct_complement() to request that the #GdaMetaStruct object add some information
-  about some database object.
+  When created, the new #GdaMetaStruct object is empty (it does not have any information about any database object).
+  Information about database objects is computed upon request using the gda_meta_struct_complement() method. Information
+  about individual database objects is represented by #GdaMetaDbObject structures, which can be obtained using
+  gda_meta_struct_get_db_object() or gda_meta_struct_get_all_db_objects().
+</para>
+<para>
+  Note that the #GdaMetaDbObject structures may change or may be removed or replaced by others, so it not
+  advised to keep pointers to these structures: pointers to these structures should be considered valid
+  as long as gda_meta_struct_complement() and other similar functions have not been called.
 </para>
 <para>
   In the following code sample, one prints the columns names and types of a table:
@@ -95,6 +100,11 @@
 
 </para>
 
+<!-- ##### ARG GdaMetaStruct:meta-store ##### -->
+<para>
+
+</para>
+
 <!-- ##### ENUM GdaMetaStructFeature ##### -->
 <para>
 
@@ -129,6 +139,7 @@
 </para>
 
 @obj_type: 
+ outdated: 
 @obj_catalog: 
 @obj_schema: 
 @obj_name: 
@@ -234,6 +245,7 @@
 
 </para>
 
+ store: 
 @features: 
 @Returns: 
 
@@ -244,7 +256,6 @@
 </para>
 
 @mstruct: 
- store: 
 @type: 
 @catalog: 
 @schema: 
@@ -259,7 +270,6 @@
 </para>
 
 @mstruct: 
- store: 
 @catalog: 
 @schema: 
 @error: 
@@ -272,7 +282,6 @@
 </para>
 
 @mstruct: 
- store: 
 @error: 
 @Returns: 
 
@@ -296,6 +305,15 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION gda_meta_struct_get_all_db_objects ##### -->
+<para>
+
+</para>
+
+ mstruct: 
+ Returns: 
+
+
 <!-- ##### FUNCTION gda_meta_struct_get_db_object ##### -->
 <para>
 

Modified: trunk/doc/C/tmpl/gda-sql-statement.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-sql-statement.sgml	(original)
+++ trunk/doc/C/tmpl/gda-sql-statement.sgml	Wed Jul  2 19:33:18 2008
@@ -645,50 +645,6 @@
 @case_s: not %NULL if expression is a CASE WHEN ... expression
 @cast_as: not %NULL if expression must be cast to another data type
 
-<!-- ##### FUNCTION gda_sql_expr_new ##### -->
-<para>
-
-</para>
-
- parent: 
- Returns: 
-
-
-<!-- ##### FUNCTION gda_sql_expr_free ##### -->
-<para>
-
-</para>
-
- expr: 
-
-
-<!-- ##### FUNCTION gda_sql_expr_copy ##### -->
-<para>
-
-</para>
-
- expr: 
- Returns: 
-
-
-<!-- ##### FUNCTION gda_sql_expr_serialize ##### -->
-<para>
-
-</para>
-
- expr: 
- Returns: 
-
-
-<!-- ##### FUNCTION gda_sql_expr_take_select ##### -->
-<para>
-
-</para>
-
- expr: 
- stmt: 
-
-
 <!-- ##### STRUCT GdaSqlParamSpec ##### -->
 <para>
 
@@ -778,62 +734,12 @@
   This structure represents the name of a table's field.
 </para>
 
- any: 
- field_name: 
- validity_meta_table_column: 
-
-<!-- ##### FUNCTION gda_sql_field_new ##### -->
-<para>
-
-</para>
-
- parent: 
- Returns: 
-
-
-<!-- ##### FUNCTION gda_sql_field_free ##### -->
-<para>
-
-</para>
-
- field: 
-
-
-<!-- ##### FUNCTION gda_sql_field_copy ##### -->
-<para>
-
-</para>
-
- field: 
- Returns: 
-
-
-<!-- ##### FUNCTION gda_sql_field_serialize ##### -->
-<para>
-
-</para>
-
- field: 
- Returns: 
-
-
-<!-- ##### FUNCTION gda_sql_field_take_name ##### -->
-<para>
-
-</para>
-
- field: 
- value: 
-
 
 <!-- ##### STRUCT GdaSqlTable ##### -->
 <para>
   This structure represents the name of a table.
 </para>
 
- any: 
- table_name: 
- validity_meta_object: 
 
 <!-- ##### FUNCTION gda_sql_table_new ##### -->
 <para>

Modified: trunk/doc/C/tmpl/gda-vconnection-data-model.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-vconnection-data-model.sgml	(original)
+++ trunk/doc/C/tmpl/gda-vconnection-data-model.sgml	Wed Jul  2 19:33:18 2008
@@ -25,16 +25,6 @@
 </para>
 
 
-<!-- ##### USER_FUNCTION GdaVConnectionDataModelFunc ##### -->
-<para>
-
-</para>
-
- model: 
- table_name: 
- data: 
-
-
 <!-- ##### STRUCT GdaVconnectionDataModelSpec ##### -->
 <para>
 

Modified: trunk/libgda/gda-meta-store.c
==============================================================================
--- trunk/libgda/gda-meta-store.c	(original)
+++ trunk/libgda/gda-meta-store.c	Wed Jul  2 19:33:18 2008
@@ -368,17 +368,16 @@
 	object_class->set_property = gda_meta_store_set_property;
 	object_class->get_property = gda_meta_store_get_property;
 	g_object_class_install_property (object_class, PROP_CNC_STRING,
-		g_param_spec_string ("cnc-string", _ ("Connection string for the internal connection to use"), NULL, NULL,
+		g_param_spec_string ("cnc-string", NULL, _ ("Connection string for the internal connection to use"), NULL,
 		(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
 	g_object_class_install_property (object_class, PROP_CNC_OBJECT,
-		g_param_spec_object ("cnc", _ ("Connection object internally used"),
-		NULL, GDA_TYPE_CONNECTION,
+		g_param_spec_object ("cnc", NULL, _ ("Connection object internally used"), GDA_TYPE_CONNECTION,
 		(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
 	g_object_class_install_property (object_class, PROP_CATALOG,
-		g_param_spec_string ("catalog", _ ("Catalog in which the database objects will be created"), NULL, NULL,
+		g_param_spec_string ("catalog", NULL, _ ("Catalog in which the database objects will be created"), NULL,
 		(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
 	g_object_class_install_property (object_class, PROP_SCHEMA,
-		g_param_spec_string ("schema", _ ("Schema in which the database objects will be created"), NULL, NULL,
+		g_param_spec_string ("schema", NULL, _ ("Schema in which the database objects will be created"), NULL,
 		(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
 	
 	object_class->constructor = gda_meta_store_constructor;
@@ -2811,11 +2810,11 @@
 	if (!model)
 		return NULL;
 
-	mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_ALL);
+	mstruct = gda_meta_struct_new (pstore, GDA_META_STRUCT_FEATURE_ALL);
 	nrows = gda_data_model_get_n_rows (model);
 	for (i = 0; i < nrows; i++) {
 		/* FIXME: only take into account the database objects which have a corresponding DbObject */
-		if (!gda_meta_struct_complement (mstruct, pstore, GDA_META_DB_UNKNOWN,
+		if (!gda_meta_struct_complement (mstruct, GDA_META_DB_UNKNOWN,
 						 gda_data_model_get_value_at (model, 0, i),
 						 gda_data_model_get_value_at (model, 1, i),
 						 gda_data_model_get_value_at (model, 2, i), error)) {
@@ -3104,9 +3103,9 @@
 	GdaMetaDbObject *eobj;
 	gboolean needs_creation = TRUE;
 	pstore = gda_connection_get_meta_store (store->priv->cnc);
-	mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_ALL);
+	mstruct = gda_meta_struct_new (pstore, GDA_META_STRUCT_FEATURE_ALL);
 	g_value_set_string ((value = gda_value_new (G_TYPE_STRING)), dbo->obj_name);
-	if (!(eobj = gda_meta_struct_complement (mstruct, pstore, GDA_META_DB_UNKNOWN,
+	if (!(eobj = gda_meta_struct_complement (mstruct, GDA_META_DB_UNKNOWN,
 						 NULL, NULL, value, &lerror))) {
 		if (lerror && (lerror->domain == GDA_META_STRUCT_ERROR) &&
 		    (lerror->code == GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR))

Modified: trunk/libgda/gda-meta-struct.c
==============================================================================
--- trunk/libgda/gda-meta-struct.c	(original)
+++ trunk/libgda/gda-meta-struct.c	Wed Jul  2 19:33:18 2008
@@ -31,6 +31,7 @@
  */
 static void gda_meta_struct_class_init (GdaMetaStructClass *klass);
 static void gda_meta_struct_init (GdaMetaStruct *mstruct);
+static void gda_meta_struct_dispose (GObject *object);
 static void gda_meta_struct_finalize (GObject *object);
 
 static void gda_meta_struct_set_property (GObject *object,
@@ -43,10 +44,15 @@
                                          GParamSpec *pspec);
 
 
+static void meta_store_changed_cb (GdaMetaStore *store, GSList *changes, GdaMetaStruct *mstruct);
+static void meta_store_reset_cb (GdaMetaStore *store, GdaMetaStruct *mstruct);
+
 struct _GdaMetaStructPrivate {
-	GHashTable *index; /* key = [catalog].[schema].[name], value = a GdaMetaDbObject. Note: catalog, schema and name 
-			    * are case sensitive (and don't have any double quote around them) */
-	guint       features;
+	GdaMetaStore *store;
+	GSList       *db_objects; /* list of GdaMetaDbObject structures */
+	GHashTable   *index; /* key = [catalog].[schema].[name], value = a GdaMetaDbObject. Note: catalog, schema and name 
+			      * are case sensitive (and don't have any double quote around them) */
+	guint         features;
 };
 
 static GdaMetaDbObject *_meta_struct_get_db_object (GdaMetaStruct *mstruct, 
@@ -64,6 +70,7 @@
 /* properties */
 enum {
         PROP_0,
+	PROP_STORE,
         PROP_FEATURES
 };
 
@@ -107,6 +114,14 @@
 	/* Properties */
         object_class->set_property = gda_meta_struct_set_property;
         object_class->get_property = gda_meta_struct_get_property;
+	g_object_class_install_property (object_class, PROP_STORE,
+					 /* To translators: GdaMetaStore is an object holding meta data information
+					  * which will be used as an information source */
+					 g_param_spec_object ("meta-store", NULL,
+							      _ ("GdaMetaStore object to fetch information from"),  
+							      GDA_TYPE_META_STORE, 
+							      (G_PARAM_WRITABLE | G_PARAM_READABLE | 
+							       G_PARAM_CONSTRUCT_ONLY)));
         g_object_class_install_property (object_class, PROP_FEATURES,
 					 /* To translators: The GdaMetaStruct object computes lists of tables, views,
 					  * and some other information, the "Features to compute" allows one to avoid
@@ -118,6 +133,7 @@
 							     G_PARAM_CONSTRUCT_ONLY)));
 
 	/* virtual methods */
+	object_class->dispose = gda_meta_struct_dispose;
 	object_class->finalize = gda_meta_struct_finalize;
 }
 
@@ -125,12 +141,14 @@
 static void
 gda_meta_struct_init (GdaMetaStruct *mstruct) {
 	mstruct->priv = g_new0 (GdaMetaStructPrivate, 1);
+	mstruct->priv->store = NULL;
 	mstruct->priv->index = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 }
 
 
 /**
  * gda_meta_struct_new
+ * @store: a #GdaMetaStore from which the new #GdaMetaStruct object will fetch information
  * @features: the kind of extra information the new #GdaMetaStruct object will compute
  *
  * Creates a new #GdaMetaStruct object. The @features specifies the extra features which will also be computed:
@@ -140,13 +158,35 @@
  * Returns: the newly created #GdaMetaStruct object
  */
 GdaMetaStruct *
-gda_meta_struct_new (GdaMetaStructFeature features) 
+gda_meta_struct_new (GdaMetaStore *store, GdaMetaStructFeature features) 
 {
-	return (GdaMetaStruct*) g_object_new (GDA_TYPE_META_STRUCT, "features", features, NULL);
+	g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
+	return (GdaMetaStruct*) g_object_new (GDA_TYPE_META_STRUCT, "meta-store", store, "features", features, NULL);
 }
 
 static void
-gda_meta_struct_finalize (GObject   * object) {
+gda_meta_struct_dispose (GObject *object) {
+	GdaMetaStruct *mstruct;
+	
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GDA_IS_META_STRUCT (object));
+	
+	mstruct = GDA_META_STRUCT (object);
+	if (mstruct->priv->store) {
+		g_signal_handlers_disconnect_by_func (G_OBJECT (mstruct->priv->store),
+						      G_CALLBACK (meta_store_changed_cb), mstruct);
+		g_signal_handlers_disconnect_by_func (G_OBJECT (mstruct->priv->store),
+						      G_CALLBACK (meta_store_reset_cb), mstruct);
+		g_object_ref (mstruct->priv->store);
+		mstruct->priv->store = NULL;
+	}
+	
+	/* parent class */
+	parent_class->finalize (object);
+}
+
+static void
+gda_meta_struct_finalize (GObject *object) {
 	GdaMetaStruct *mstruct;
 	
 	g_return_if_fail (object != NULL);
@@ -154,8 +194,8 @@
 	
 	mstruct = GDA_META_STRUCT (object);
 	if (mstruct->priv) {
-		g_slist_foreach (mstruct->db_objects, (GFunc) gda_meta_db_object_free, NULL);
-		g_slist_free (mstruct->db_objects);
+		g_slist_foreach (mstruct->priv->db_objects, (GFunc) gda_meta_db_object_free, NULL);
+		g_slist_free (mstruct->priv->db_objects);
 		g_hash_table_destroy (mstruct->priv->index);
 		g_free (mstruct->priv);
 		mstruct->priv = NULL;
@@ -176,6 +216,16 @@
         mstruct = GDA_META_STRUCT (object);
         if (mstruct->priv) {
                 switch (param_id) {
+		case PROP_STORE:
+			mstruct->priv->store = g_value_get_object (value);
+			if (mstruct->priv->store) {
+				g_object_ref (mstruct->priv->store);
+				g_signal_connect (G_OBJECT (mstruct->priv->store), "meta_changed",
+						  G_CALLBACK (meta_store_changed_cb), mstruct);
+				g_signal_connect (G_OBJECT (mstruct->priv->store), "meta_reset",
+						  G_CALLBACK (meta_store_reset_cb), mstruct);
+			}
+			break;
 		case PROP_FEATURES:
 			mstruct->priv->features = g_value_get_uint (value);
 			break;
@@ -196,6 +246,9 @@
 
         if (mstruct->priv) {
                 switch (param_id) {
+		case PROP_STORE:
+			g_value_set_object (value, mstruct->priv->store);
+			break;
 		case PROP_FEATURES:
 			g_value_set_uint (value, mstruct->priv->features);
 			break;
@@ -205,9 +258,25 @@
 	}
 }
 
+static void
+meta_store_changed_cb (GdaMetaStore *store, GSList *changes, GdaMetaStruct *mstruct)
+{
+	/* for now we mark ALL the db objects as outdated */
+	meta_store_reset_cb (store, mstruct);
+}
 
 static void
-compute_view_dependencies (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObject *view_dbobj, GdaSqlStatement *sqlst) 
+meta_store_reset_cb (GdaMetaStore *store, GdaMetaStruct *mstruct)
+{
+	/* mark ALL the db objects as outdated */
+	GSList *list;
+	for (list = mstruct->priv->db_objects; list; list = list->next)
+		GDA_META_DB_OBJECT (list->data)->outdated = TRUE;
+}
+
+
+static void
+compute_view_dependencies (GdaMetaStruct *mstruct, GdaMetaDbObject *view_dbobj, GdaSqlStatement *sqlst) 
 {	
 	if (sqlst->stmt_type == GDA_SQL_STATEMENT_SELECT) {
 		GdaSqlStatementSelect *selst;
@@ -225,17 +294,18 @@
 			if (!t->table_name)
 				continue;
 			
-			m2 = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_NONE);
+			m2 = gda_meta_struct_new (mstruct->priv->store, GDA_META_STRUCT_FEATURE_NONE);
 			g_value_set_string ((vname = gda_value_new (G_TYPE_STRING)), t->table_name);
-			if (! (tmp_obj = gda_meta_struct_complement (m2, store, GDA_META_DB_TABLE, NULL, NULL, vname, NULL)))
-				tmp_obj = gda_meta_struct_complement (m2, store, GDA_META_DB_VIEW, NULL, NULL, vname, NULL);
+			if (! (tmp_obj = gda_meta_struct_complement (m2, 
+								     GDA_META_DB_TABLE, NULL, NULL, vname, NULL)))
+				tmp_obj = gda_meta_struct_complement (m2,
+								      GDA_META_DB_VIEW, NULL, NULL, vname, NULL);
 			gda_value_free (vname);
+			g_object_unref (m2);
 
-			if (!tmp_obj) {
+			if (!tmp_obj) 
 				/* could not find dependency */
-				g_object_unref (m2);
 				continue;
-			}
 
 			/* the dependency exists, and is identified by tmp_obj->obj_catalog, tmp_obj->obj_schema 
 			 * and tmp_obj->obj_name */
@@ -251,13 +321,12 @@
 				ref_obj->obj_schema = g_strdup (tmp_obj->obj_schema);
 				ref_obj->obj_name = g_strdup (tmp_obj->obj_name);
 
-				mstruct->db_objects = g_slist_append (mstruct->db_objects, ref_obj);
+				mstruct->priv->db_objects = g_slist_append (mstruct->priv->db_objects, ref_obj);
 				str = g_strdup_printf ("%s.%s.%s", tmp_obj->obj_catalog,
 						       tmp_obj->obj_schema, tmp_obj->obj_name);
 				g_hash_table_insert (mstruct->priv->index, str, ref_obj);
 			}
 			g_assert (ref_obj);
-			g_object_unref (m2);
 			gda_value_free (catalog);
 			gda_value_free (schema);
 			gda_value_free (name);
@@ -270,25 +339,25 @@
 		GSList *list;
 		cst = (GdaSqlStatementCompound*) (sqlst->contents);
 		for (list = cst->stmt_list; list; list = list->next)
-			compute_view_dependencies (mstruct, store, view_dbobj, (GdaSqlStatement*) list->data);
+			compute_view_dependencies (mstruct, view_dbobj, (GdaSqlStatement*) list->data);
 	}
 	else
 		g_assert_not_reached ();
 }
 
-static GdaMetaDbObject * _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObjectType type,
+static GdaMetaDbObject * _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
 						  const GValue *icatalog, const GValue *ischema, const GValue *iname, 
 						  const GValue *short_name, const GValue *full_name, 
 						  const GValue *owner, GError **error);
-static gboolean determine_db_object_from_schema_and_name (GdaMetaStruct *mstruct, GdaMetaStore *store, 
+static gboolean determine_db_object_from_schema_and_name (GdaMetaStruct *mstruct,
 							  GdaMetaDbObjectType *int_out_type, GValue **out_catalog,
 							  GValue **out_short_name, GValue **out_full_name,
 							  GValue **out_owner, const GValue *schema, const GValue *name);
-static gboolean determine_db_object_from_short_name (GdaMetaStruct *mstruct, GdaMetaStore *store, 
+static gboolean determine_db_object_from_short_name (GdaMetaStruct *mstruct,
 						     GdaMetaDbObjectType *int_out_type, GValue **out_catalog,
 						     GValue **out_schema, GValue **out_name, GValue **out_short_name, 
 						     GValue **out_full_name, GValue **out_owner, const GValue *name);
-static gboolean determine_db_object_from_missing_type (GdaMetaStruct *mstruct, GdaMetaStore *store, 
+static gboolean determine_db_object_from_missing_type (GdaMetaStruct *mstruct,
 						       GdaMetaDbObjectType *out_type, GValue **out_short_name, 
 						       GValue **out_full_name, GValue **out_owner, const GValue *catalog, 
 						       const GValue *schema, const GValue *name);
@@ -297,7 +366,6 @@
 /**
  * gda_meta_struct_complement
  * @mstruct: a #GdaMetaStruct object
- * @store: the #GdaMetaStore to use
  * @type: the type of object to add (which can be GDA_META_DB_UNKNOWN)
  * @catalog: the catalog the object belongs to (as a G_TYPE_STRING GValue), or %NULL
  * @schema: the schema the object belongs to (as a G_TYPE_STRING GValue), or %NULL
@@ -324,7 +392,7 @@
  * Returns: the #GdaMetaDbObject corresponding to the database object if no error occurred, or %NULL
  */
 GdaMetaDbObject *
-gda_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObjectType type,
+gda_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
 			    const GValue *catalog, const GValue *schema, const GValue *name, 
 			    GError **error)
 {
@@ -334,9 +402,13 @@
 	GValue *icatalog = NULL, *ischema = NULL, *iname = NULL; /* GValue with identifiers ready to be compared */
 
 	/* checks */
-	g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
+	g_return_val_if_fail (mstruct->priv->store, NULL);
 	g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
 	g_return_val_if_fail (name && (G_VALUE_TYPE (name) == G_TYPE_STRING), NULL);
+	if (catalog && (gda_value_is_null (catalog) || !g_value_get_string (catalog)))
+		catalog = NULL;
+	if (schema && (gda_value_is_null (schema) || !g_value_get_string (schema)))
+		schema = NULL;
 	g_return_val_if_fail (!catalog || (catalog && schema), NULL);
 	g_return_val_if_fail (!catalog || (G_VALUE_TYPE (catalog) == G_TYPE_STRING), NULL);
 	g_return_val_if_fail (!schema || (G_VALUE_TYPE (schema) == G_TYPE_STRING), NULL);
@@ -361,7 +433,7 @@
 	if (!catalog) {
 		if (schema) {
 			g_return_val_if_fail (schema && (G_VALUE_TYPE (schema) == G_TYPE_STRING), NULL);
-			if (! determine_db_object_from_schema_and_name (mstruct, store, &real_type, &icatalog, 
+			if (! determine_db_object_from_schema_and_name (mstruct, &real_type, &icatalog, 
 									&short_name, &full_name, &owner,
 									ischema, iname)) {
 				g_set_error (error, GDA_META_STRUCT_ERROR, GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
@@ -374,7 +446,7 @@
 		}
 		else {
 			GValue *real_name = NULL;
-			if (! determine_db_object_from_short_name (mstruct, store, &real_type, &icatalog, 
+			if (! determine_db_object_from_short_name (mstruct, &real_type, &icatalog, 
 								   &ischema, &real_name, 
 								   &short_name, &full_name, &owner, iname)) {
 				g_set_error (error, GDA_META_STRUCT_ERROR, GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
@@ -389,7 +461,7 @@
 		}
 	}
 	else if (type == GDA_META_DB_UNKNOWN) {
-		if (! determine_db_object_from_missing_type (mstruct, store, &real_type, &short_name, &full_name, &owner,
+		if (! determine_db_object_from_missing_type (mstruct, &real_type, &short_name, &full_name, &owner,
 							     icatalog, ischema, iname)) {
 			g_set_error (error, GDA_META_STRUCT_ERROR, GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
 				     _("Could not find object named '%s.%s.%s'"), g_value_get_string (catalog),
@@ -401,7 +473,7 @@
 		}
 	}
 	type = real_type;
-	dbo = _meta_struct_complement (mstruct, store, type, icatalog, ischema, iname, short_name, full_name, owner, error);
+	dbo = _meta_struct_complement (mstruct, type, icatalog, ischema, iname, short_name, full_name, owner, error);
 
 	gda_value_free (icatalog);
 	gda_value_free (ischema);
@@ -414,7 +486,7 @@
 }
 
 static GdaMetaDbObject *
-_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObjectType type,
+_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
 			 const GValue *icatalog, const GValue *ischema, const GValue *iname, 
 			 const GValue *short_name, const GValue *full_name, const GValue *owner, GError **error)
 {
@@ -458,7 +530,8 @@
 		gint nrows;
 		GdaMetaView *mv;
 
-		model = gda_meta_store_extract (store, sql, error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, 
+						error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
 		if (!model) 
 			goto onerror;
 		nrows = gda_data_model_get_n_rows (model);
@@ -496,7 +569,7 @@
 			     (gda_statement_get_statement_type (stmt) == GDA_SQL_STATEMENT_COMPOUND))) {
 				GdaSqlStatement *sqlst;
 				g_object_get (G_OBJECT (stmt), "structure", &sqlst, NULL);
-				compute_view_dependencies (mstruct, store, dbo, sqlst);
+				compute_view_dependencies (mstruct, dbo, sqlst);
 				gda_sql_statement_free (sqlst);
 				g_object_unref (stmt);
 				
@@ -517,7 +590,8 @@
 		GdaDataModel *model;
 		gint i, nrows;
 
-		model = gda_meta_store_extract (store, sql, error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, 
+						error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
 		if (!model) 
 			goto onerror;
 
@@ -550,7 +624,7 @@
 			if (cstr && *cstr)
 				tcol->column_type = g_strdup (cstr);
 			else 
-				tcol->column_type = array_type_to_sql (store, 
+				tcol->column_type = array_type_to_sql (mstruct->priv->store, 
 								       gda_data_model_get_value_at (model, 8, i));
 			tcol->gtype = gda_g_type_from_string (g_value_get_string (gda_data_model_get_value_at (model, 2, i)));
 			tcol->nullok = g_value_get_boolean (gda_data_model_get_value_at (model, 3, i));
@@ -566,7 +640,8 @@
 
 		/* primary key */
 		sql = "SELECT constraint_name FROM _table_constraints WHERE constraint_type='PRIMARY KEY' AND table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
-		model = gda_meta_store_extract (store, sql, error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, 
+						error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
 		if (!model) 
 			goto onerror;
 
@@ -574,7 +649,7 @@
 		if (nrows >= 1) {
 			GdaDataModel *pkmodel;
 			sql = "SELECT column_name FROM _key_column_usage WHERE table_catalog = ##cc::string AND table_schema = ##cs::string AND table_name = ##tname::string AND constraint_name = ##cname::string ORDER BY ordinal_position";
-			pkmodel = gda_meta_store_extract (store, sql, error, 
+			pkmodel = gda_meta_store_extract (mstruct->priv->store, sql, error, 
 							  "cc", icatalog,
 							  "cs", ischema,
 							  "tname", iname,
@@ -607,8 +682,11 @@
 
 		/* foreign keys */
 		if (mstruct->priv->features & GDA_META_STRUCT_FEATURE_FOREIGN_KEYS) { 
-			sql = "SELECT ref_table_catalog, ref_table_schema, ref_table_name FROM _referential_constraints WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
-			model = gda_meta_store_extract (store, sql, error, "tc", icatalog, "ts", ischema, "tname", iname, NULL);
+			sql = "SELECT ref_table_catalog, ref_table_schema, ref_table_name, constraint_name, ref_constraint_name FROM _referential_constraints WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
+			model = gda_meta_store_extract (mstruct->priv->store, sql, error, 
+							"tc", icatalog, 
+							"ts", ischema, 
+							"tname", iname, NULL);
 			if (!model) 
 				goto onerror;
 			
@@ -630,7 +708,7 @@
 					tfk->depend_on->obj_catalog = g_strdup (g_value_get_string (fk_catalog));
 					tfk->depend_on->obj_schema = g_strdup (g_value_get_string (fk_schema));
 					tfk->depend_on->obj_name = g_strdup (g_value_get_string (fk_name));
-					mstruct->db_objects = g_slist_append (mstruct->db_objects, tfk->depend_on);
+					mstruct->priv->db_objects = g_slist_append (mstruct->priv->db_objects, tfk->depend_on);
 					str = g_strdup_printf ("%s.%s.%s", g_value_get_string (fk_catalog), 
 							       g_value_get_string (fk_schema), 
 							       g_value_get_string (fk_name));
@@ -644,6 +722,63 @@
 				
 				/* FIXME: compute @cols_nb, and all the @*_array members (ref_pk_cols_array must be
 				 * initialized with -1 values everywhere */
+				sql = "SELECT k.column_name, c.ordinal_position FROM _key_column_usage k INNER JOIN _columns c ON (c.table_catalog = k.table_catalog AND c.table_schema = k.table_schema AND c.table_name=k.table_name AND c.column_name=k.column_name) WHERE k.table_catalog = ##tc::string AND k.table_schema = ##ts::string AND k.table_name = ##tname::string AND k.constraint_name = ##cname::string ORDER BY k.ordinal_position";
+				GdaDataModel *fk_cols, *ref_pk_cols;
+				gboolean fkerror = FALSE;
+				fk_cols = gda_meta_store_extract (mstruct->priv->store, sql, error, 
+								  "tc", icatalog, 
+								  "ts", ischema, 
+								  "tname", iname, 
+								  "cname", gda_data_model_get_value_at (model, 3, i), NULL);
+				ref_pk_cols = gda_meta_store_extract (mstruct->priv->store, sql, error, 
+								      "tc", fk_catalog,
+								      "ts", fk_schema,
+								      "tname", fk_name,
+								      "cname", gda_data_model_get_value_at (model, 4, i), NULL);
+				if (fk_cols && ref_pk_cols) {
+					gint fk_nrows, ref_pk_nrows;
+					fk_nrows = gda_data_model_get_n_rows (fk_cols);
+					ref_pk_nrows = gda_data_model_get_n_rows (ref_pk_cols);
+					if (fk_nrows != ref_pk_nrows)
+						fkerror = TRUE;
+					else {
+						gint n;
+						tfk->cols_nb = fk_nrows;
+						tfk->fk_cols_array = g_new0 (gint, fk_nrows);
+						tfk->fk_names_array = g_new0 (gchar *, fk_nrows);
+						tfk->ref_pk_cols_array = g_new0 (gint, fk_nrows);
+						tfk->ref_pk_names_array = g_new0 (gchar *, fk_nrows);
+						for (n = 0; n < fk_nrows; n++) {
+							const GValue *cv;
+							cv = gda_data_model_get_value_at (fk_cols, 1, n);
+							tfk->fk_cols_array [n] = g_value_get_int (cv);
+							cv = gda_data_model_get_value_at (fk_cols, 0, n);
+							tfk->fk_names_array [n] = g_value_dup_string (cv);
+
+							cv = gda_data_model_get_value_at (ref_pk_cols, 1, n);
+							tfk->ref_pk_cols_array [n] = g_value_get_int (cv);
+							cv = gda_data_model_get_value_at (ref_pk_cols, 0, n);
+							tfk->ref_pk_names_array [n] = g_value_dup_string (cv);
+						}
+					}
+				}
+				else
+					fkerror = TRUE;
+
+				if (fkerror)
+					g_warning (_("Meta data incoherence in foreign key constraint for table %s.%s.%s "
+						     "referencing table %s.%s.%s"),
+						   g_value_get_string (icatalog), 
+						   g_value_get_string (ischema), 
+						   g_value_get_string (iname),
+						   g_value_get_string (fk_catalog), 
+						   g_value_get_string (fk_schema), 
+						   g_value_get_string (fk_name));
+				if (fk_cols)
+					g_object_unref (fk_cols);
+				if (ref_pk_cols)
+					g_object_unref (ref_pk_cols);
+				
 				
 				mt->fk_list = g_slist_prepend (mt->fk_list, tfk);
 			}
@@ -658,9 +793,9 @@
 		TO_IMPLEMENT;
 	}
 
-	if (dbo && !g_slist_find (mstruct->db_objects, dbo)) {
+	if (dbo && !g_slist_find (mstruct->priv->db_objects, dbo)) {
 		gchar *str;
-		mstruct->db_objects = g_slist_append (mstruct->db_objects, dbo);
+		mstruct->priv->db_objects = g_slist_append (mstruct->priv->db_objects, dbo);
 		str = g_strdup_printf ("%s.%s.%s", g_value_get_string (icatalog), 
 				       g_value_get_string (ischema), 
 				       g_value_get_string (iname));
@@ -670,7 +805,7 @@
 	    (mstruct->priv->features & GDA_META_STRUCT_FEATURE_FOREIGN_KEYS)) {
 		/* compute GdaMetaTableForeignKey's @ref_pk_cols_array arrays and GdaMetaTable' @reverse_fk_list lists*/
 		GSList *list;
-		for (list = mstruct->db_objects; list; list = list->next) {
+		for (list = mstruct->priv->db_objects; list; list = list->next) {
 			GdaMetaDbObject *tmpdbo;
 			tmpdbo = GDA_META_DB_OBJECT (list->data);
 			if (tmpdbo->obj_type != GDA_META_DB_TABLE)
@@ -765,7 +900,6 @@
 /**
  * gda_meta_struct_complement_schema
  * @mstruct: a #GdaMetaStruct object
- * @store: a #GdaMetaStore object
  * @catalog: name of a catalog, or %NULL
  * @schema: name of a schema, or %NULL
  * @error: a place to store errors, or %NULL
@@ -778,7 +912,7 @@
  * Returns: TRUE if no error occurred
  */
 gboolean
-gda_meta_struct_complement_schema (GdaMetaStruct *mstruct, GdaMetaStore *store, const GValue *catalog, const GValue *schema,
+gda_meta_struct_complement_schema (GdaMetaStruct *mstruct, const GValue *catalog, const GValue *schema,
 				   GError **error)
 {
 	GdaDataModel *tables_model = NULL, *views_model = NULL;
@@ -810,30 +944,32 @@
 		"FROM _tables WHERE table_type='VIEW' "
 		"ORDER BY table_schema, table_name";
 
-	g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
 	g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), FALSE);
+	g_return_val_if_fail (mstruct->priv->store, FALSE);
 	g_return_val_if_fail (!catalog || (catalog && schema), FALSE);
 	g_return_val_if_fail (!catalog || (G_VALUE_TYPE (catalog) == G_TYPE_STRING), FALSE);
 	g_return_val_if_fail (!schema || (G_VALUE_TYPE (schema) == G_TYPE_STRING), FALSE);
 
 	if (schema) {
 		if (catalog) {
-			tables_model = gda_meta_store_extract (store, sql1, error, 
+			tables_model = gda_meta_store_extract (mstruct->priv->store, sql1, error, 
 							       "cat", catalog, "schema", schema, NULL);
 			if (tables_model)
-				views_model = gda_meta_store_extract (store, sql2, error, 
+				views_model = gda_meta_store_extract (mstruct->priv->store, sql2, error, 
 								      "cat", catalog, "schema", schema, NULL);
 		}
 		else {
-			tables_model = gda_meta_store_extract (store, sql3, error, "schema", schema, NULL);
+			tables_model = gda_meta_store_extract (mstruct->priv->store, sql3, 
+							       error, "schema", schema, NULL);
 			if (tables_model)
-				views_model = gda_meta_store_extract (store, sql4, error, "schema", schema, NULL);
+				views_model = gda_meta_store_extract (mstruct->priv->store, sql4, 
+								      error, "schema", schema, NULL);
 		}
 	}
 	else {
-		tables_model = gda_meta_store_extract (store, sql5, error, NULL);
+		tables_model = gda_meta_store_extract (mstruct->priv->store, sql5, error, NULL);
 		if (tables_model)
-			views_model = gda_meta_store_extract (store, sql6, error, NULL);
+			views_model = gda_meta_store_extract (mstruct->priv->store, sql6, error, NULL);
 	}
 
 	if (!tables_model || !views_model)
@@ -842,7 +978,7 @@
 	/* tables */
 	nrows = gda_data_model_get_n_rows (tables_model);
 	for (i = 0; i < nrows; i++) {
-		if (!_meta_struct_complement (mstruct, store, GDA_META_DB_TABLE,
+		if (!_meta_struct_complement (mstruct, GDA_META_DB_TABLE,
 					      catalog ? catalog : gda_data_model_get_value_at (tables_model, 4, i),
 					      schema ? schema : gda_data_model_get_value_at (tables_model, 5, i),
 					      gda_data_model_get_value_at (tables_model, 3, i), 
@@ -859,7 +995,7 @@
 	/* tables */
 	nrows = gda_data_model_get_n_rows (views_model);
 	for (i = 0; i < nrows; i++) {
-		if (!_meta_struct_complement (mstruct, store, GDA_META_DB_VIEW,
+		if (!_meta_struct_complement (mstruct, GDA_META_DB_VIEW,
 					      catalog ? catalog : gda_data_model_get_value_at (views_model, 4, i),
 					      schema ? schema : gda_data_model_get_value_at (views_model, 5, i),
 					      gda_data_model_get_value_at (views_model, 3, i), 
@@ -878,7 +1014,6 @@
 /**
  * gda_meta_struct_complement_default
  * @mstruct: a #GdaMetaStruct object
- * @store: a #GdaMetaStore object
  * @error: a place to store errors, or %NULL
  *
  * This method is similar to gda_meta_struct_complement() but creates #GdaMetaDbObject for all the
@@ -888,7 +1023,7 @@
  * Returns: TRUE if no error occurred
  */
 gboolean
-gda_meta_struct_complement_default (GdaMetaStruct *mstruct, GdaMetaStore *store, GError **error)
+gda_meta_struct_complement_default (GdaMetaStruct *mstruct, GError **error)
 {
 	GdaDataModel *model;
 	gint i, nrows;
@@ -899,16 +1034,16 @@
 		"FROM _tables WHERE table_short_name = table_name AND table_type='VIEW' "
 		"ORDER BY table_schema, table_name";
 
-	g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
 	g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), FALSE);
+	g_return_val_if_fail (mstruct->priv->store, FALSE);
 
 	/* tables */
-	model = gda_meta_store_extract (store, sql1, error, NULL);
+	model = gda_meta_store_extract (mstruct->priv->store, sql1, error, NULL);
 	if (!model)
 		return FALSE;
 	nrows = gda_data_model_get_n_rows (model);
 	for (i = 0; i < nrows; i++) {
-		if (!_meta_struct_complement (mstruct, store, GDA_META_DB_TABLE,
+		if (!_meta_struct_complement (mstruct, GDA_META_DB_TABLE,
 					      gda_data_model_get_value_at (model, 0, i),
 					      gda_data_model_get_value_at (model, 1, i),
 					      gda_data_model_get_value_at (model, 2, i),
@@ -922,12 +1057,12 @@
 	g_object_unref (model);
 
 	/* views */
-	model = gda_meta_store_extract (store, sql2, error, NULL);
+	model = gda_meta_store_extract (mstruct->priv->store, sql2, error, NULL);
 	if (!model)
 		return FALSE;
 	nrows = gda_data_model_get_n_rows (model);
 	for (i = 0; i < nrows; i++) {
-		if (!_meta_struct_complement (mstruct, store, GDA_META_DB_VIEW,
+		if (!_meta_struct_complement (mstruct, GDA_META_DB_VIEW,
 					      gda_data_model_get_value_at (model, 0, i),
 					      gda_data_model_get_value_at (model, 1, i),
 					      gda_data_model_get_value_at (model, 2, i),
@@ -945,7 +1080,6 @@
 /**
  * gda_meta_struct_complement_depend
  * @mstruct: a #GdaMetaStruct object
- * @store: a #GdaMetaStore object
  * @dbo: a #GdaMetaDbObject part of @mstruct
  * @error: a place to store errors, or %NULL
  *
@@ -955,15 +1089,15 @@
  * Returns: TRUE if no error occurred
  */
 gboolean
-gda_meta_struct_complement_depend (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObject *dbo,
+gda_meta_struct_complement_depend (GdaMetaStruct *mstruct, GdaMetaDbObject *dbo,
 				   GError **error)
 {
 	GSList *list;
 
-	g_return_val_if_fail (GDA_IS_META_STORE (store), FALSE);
 	g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), FALSE);
+	g_return_val_if_fail (mstruct->priv->store, FALSE);
 	g_return_val_if_fail (dbo, FALSE);
-	g_return_val_if_fail (g_slist_find (mstruct->db_objects, dbo), FALSE);
+	g_return_val_if_fail (g_slist_find (mstruct->priv->db_objects, dbo), FALSE);
 
 	for (list = dbo->depend_list; list; list = list->next) {
 		GdaMetaDbObject *dep_dbo = GDA_META_DB_OBJECT (list->data);
@@ -981,7 +1115,7 @@
 					     g_strdup_printf ("\"%s\"", dep_dbo->obj_schema));
 		g_value_take_string ((name = gda_value_new (G_TYPE_STRING)), 
 				     g_strdup_printf ("\"%s\"", dep_dbo->obj_name));
-		tmpobj = gda_meta_struct_complement (mstruct, store, GDA_META_DB_UNKNOWN, cat, schema, name, error);
+		tmpobj = gda_meta_struct_complement (mstruct, GDA_META_DB_UNKNOWN, cat, schema, name, error);
 		if (cat) gda_value_free (cat);
 		if (schema) gda_value_free (schema);
 		gda_value_free (name);
@@ -1057,17 +1191,17 @@
 
 	switch (sort_type) {
 	case GDA_META_SORT_ALHAPETICAL:
-		mstruct->db_objects = g_slist_sort (mstruct->db_objects, (GCompareFunc) db_object_sort_func);
-		ordered_list = mstruct->db_objects;
+		mstruct->priv->db_objects = g_slist_sort (mstruct->priv->db_objects, (GCompareFunc) db_object_sort_func);
+		ordered_list = mstruct->priv->db_objects;
 		break;
 	case GDA_META_SORT_DEPENDENCIES:
 		g_return_val_if_fail (mstruct, FALSE);
-		for (pass_list = build_pass (mstruct->db_objects, ordered_list); 
+		for (pass_list = build_pass (mstruct->priv->db_objects, ordered_list); 
 		     pass_list; 
-		     pass_list = build_pass (mstruct->db_objects, ordered_list)) 
+		     pass_list = build_pass (mstruct->priv->db_objects, ordered_list)) 
 			ordered_list = g_slist_concat (ordered_list, pass_list);
-		g_slist_free (mstruct->db_objects);
-		mstruct->db_objects = ordered_list;
+		g_slist_free (mstruct->priv->db_objects);
+		mstruct->priv->db_objects = ordered_list;
 		break;
 	default:
 		TO_IMPLEMENT;
@@ -1117,7 +1251,7 @@
 			obj_schema = g_value_get_string (schema);
 		}
 
-		for (list = mstruct->db_objects; list; list = list->next) {
+		for (list = mstruct->priv->db_objects; list; list = list->next) {
 			GdaMetaDbObject *dbo;
 			dbo = GDA_META_DB_OBJECT (list->data);
 			if (gda_identifier_equal (dbo->obj_name, obj_name) &&
@@ -1141,6 +1275,25 @@
 }
 
 /**
+ * gda_meta_struct_get_all_db_objects
+ * @mstruct: a #GdaMetaStruct object
+ *
+ * Get a list of all the #GdaMetaDbObject structures representing database objects in @mstruct. Note that
+ * no #GdaMetaDbObject structure must not be modified.
+ *
+ * Returns: a new #GSList list of pointers which must be destroyed after usage using g_slist_free().
+ */
+GSList *
+gda_meta_struct_get_all_db_objects (GdaMetaStruct *mstruct)
+{
+	g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
+	if (mstruct->priv->db_objects)
+		return g_slist_copy (mstruct->priv->db_objects);
+	else
+		return NULL;
+}
+
+/**
  * gda_meta_struct_get_db_object
  * @mstruct: a #GdaMetaStruct object
  * @catalog: the catalog the object belongs to (as a G_TYPE_STRING GValue), or %NULL
@@ -1233,7 +1386,7 @@
 	
 	string = g_string_new ("digraph G {\nrankdir = BT;\nnode [shape = plaintext];\n");
 	GSList *dbo_list;
-	for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
+	for (dbo_list = mstruct->priv->db_objects; dbo_list; dbo_list = dbo_list->next) {
 		gchar *objname, *fullname;
 		GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (dbo_list->data);
 		GSList *list;
@@ -1411,7 +1564,7 @@
 }
 
 static gboolean 
-determine_db_object_from_schema_and_name (GdaMetaStruct *mstruct, GdaMetaStore *store, 
+determine_db_object_from_schema_and_name (GdaMetaStruct *mstruct, 
 					  GdaMetaDbObjectType *in_out_type, GValue **out_catalog,
 					  GValue **out_short_name, 
 					  GValue **out_full_name, GValue **out_owner, 
@@ -1425,14 +1578,14 @@
 	switch (*in_out_type) {
 	case GDA_META_DB_UNKNOWN: {
 		GdaMetaDbObjectType type = GDA_META_DB_TABLE;
-		if (determine_db_object_from_schema_and_name (mstruct, store, &type, out_catalog,
+		if (determine_db_object_from_schema_and_name (mstruct, &type, out_catalog,
 							      out_short_name, out_full_name, out_owner,
 							      schema, name)) {
 			*in_out_type = GDA_META_DB_TABLE;
 			return TRUE;
 		}
 		type = GDA_META_DB_VIEW;
-		if (determine_db_object_from_schema_and_name (mstruct, store, &type, out_catalog,
+		if (determine_db_object_from_schema_and_name (mstruct, &type, out_catalog,
 							      out_short_name, out_full_name, out_owner,
 							      schema, name)) {
 			*in_out_type = GDA_META_DB_VIEW;
@@ -1446,7 +1599,7 @@
 		const gchar *sql = "SELECT table_catalog, table_short_name, table_full_name, table_owner FROM _tables as t WHERE table_schema = ##ts::string AND table_short_name = ##tname::string AND table_name NOT IN (SELECT v.table_name FROM _views as v WHERE v.table_catalog=t.table_catalog AND v.table_schema=t.table_schema)";
 		GdaDataModel *model;
 		gint nrows;
-		model = gda_meta_store_extract (store, sql, NULL, "ts", schema, "tname", name, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, NULL, "ts", schema, "tname", name, NULL);
 		if (!model) 
 			return FALSE;
 
@@ -1467,7 +1620,7 @@
 		const gchar *sql = "SELECT table_catalog, table_short_name, table_full_name, table_owner FROM _tables NATURAL JOIN _views WHERE table_schema = ##ts::string AND table_short_name = ##tname::string";
 		GdaDataModel *model;
 		gint nrows;
-		model = gda_meta_store_extract (store, sql, NULL, "ts", schema, "tname", name, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, NULL, "ts", schema, "tname", name, NULL);
 		if (!model) 
 			return FALSE;
 
@@ -1491,7 +1644,7 @@
 }
 
 static gboolean
-determine_db_object_from_short_name (GdaMetaStruct *mstruct, GdaMetaStore *store, 
+determine_db_object_from_short_name (GdaMetaStruct *mstruct,
 				     GdaMetaDbObjectType *in_out_type, GValue **out_catalog,
 				     GValue **out_schema, GValue **out_name, GValue **out_short_name, 
 				     GValue **out_full_name, GValue **out_owner, const GValue *name)
@@ -1507,13 +1660,13 @@
 	switch (*in_out_type) {
 	case GDA_META_DB_UNKNOWN: {
 		GdaMetaDbObjectType type = GDA_META_DB_TABLE;
-		if (determine_db_object_from_short_name (mstruct, store, &type, out_catalog, out_schema, out_name,
+		if (determine_db_object_from_short_name (mstruct, &type, out_catalog, out_schema, out_name,
 							 out_short_name, out_full_name, out_owner, name)) {
 			*in_out_type = GDA_META_DB_TABLE;
 			return TRUE;
 		}
 		type = GDA_META_DB_VIEW;
-		if (determine_db_object_from_short_name (mstruct, store, &type, out_catalog, out_schema, out_name,
+		if (determine_db_object_from_short_name (mstruct, &type, out_catalog, out_schema, out_name,
 							 out_short_name, out_full_name, out_owner, name)) {
 			*in_out_type = GDA_META_DB_VIEW;
 			return TRUE;
@@ -1526,7 +1679,7 @@
 		const gchar *sql = "SELECT table_catalog, table_schema, table_name, table_short_name, table_full_name, table_owner FROM _tables as t WHERE table_short_name = ##tname::string AND table_name NOT IN (SELECT v.table_name FROM _views as v WHERE v.table_catalog=t.table_catalog AND v.table_schema=t.table_schema)";
 		GdaDataModel *model;
 		gint nrows;
-		model = gda_meta_store_extract (store, sql, NULL, "tname", name, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, NULL, "tname", name, NULL);
 		if (!model) 
 			return FALSE;
 
@@ -1549,7 +1702,7 @@
 		const gchar *sql = "SELECT table_catalog, table_schema, table_name, table_short_name, table_full_name, table_owner FROM _tables NATURAL JOIN _views WHERE table_short_name = ##tname::string";
 		GdaDataModel *model;
 		gint nrows;
-		model = gda_meta_store_extract (store, sql, NULL, "tname", name, NULL);
+		model = gda_meta_store_extract (mstruct->priv->store, sql, NULL, "tname", name, NULL);
 		if (!model) 
 			return FALSE;
 
@@ -1589,7 +1742,7 @@
 			}
 			g_value_take_string ((sv = gda_value_new (G_TYPE_STRING)), _identifier_unquote (obj_schema));
 			g_value_take_string ((nv = gda_value_new (G_TYPE_STRING)), _identifier_unquote (obj_name));
-			retval = determine_db_object_from_schema_and_name (mstruct, store, in_out_type, out_catalog, 
+			retval = determine_db_object_from_schema_and_name (mstruct, in_out_type, out_catalog, 
 									   out_short_name, out_full_name, out_owner, 
 									   sv, nv);
 			if (retval) {
@@ -1608,7 +1761,7 @@
 }
 
 static gboolean
-determine_db_object_from_missing_type (GdaMetaStruct *mstruct, GdaMetaStore *store, 
+determine_db_object_from_missing_type (GdaMetaStruct *mstruct, 
 				       GdaMetaDbObjectType *out_type, GValue **out_short_name, 
 				       GValue **out_full_name, GValue **out_owner, const GValue *catalog, 
 				       const GValue *schema, const GValue *name)
@@ -1617,7 +1770,7 @@
 	const gchar *sql = "SELECT table_short_name, table_full_name, table_owner FROM _tables NATURAL JOIN _views WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
 	GdaDataModel *model;
 
-	model = gda_meta_store_extract (store, sql, NULL, "tc", catalog, "ts", schema, "tname", name, NULL);
+	model = gda_meta_store_extract (mstruct->priv->store, sql, NULL, "tc", catalog, "ts", schema, "tname", name, NULL);
 	if (model && (gda_data_model_get_n_rows (model) == 1)) {
 		*out_type = GDA_META_DB_VIEW;
 		*out_short_name = gda_value_copy (gda_data_model_get_value_at (model, 0, 0));
@@ -1630,7 +1783,7 @@
 
 	/* try as a table */
 	sql = "SELECT table_short_name, table_full_name, table_owner FROM _tables WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
-	model = gda_meta_store_extract (store, sql, NULL, "tc", catalog, "ts", schema, "tname", name, NULL);
+	model = gda_meta_store_extract (mstruct->priv->store, sql, NULL, "tc", catalog, "ts", schema, "tname", name, NULL);
 	if (model && (gda_data_model_get_n_rows (model) == 1)) {
 		*out_type = GDA_META_DB_TABLE;
 		*out_short_name = gda_value_copy (gda_data_model_get_value_at (model, 0, 0));

Modified: trunk/libgda/gda-meta-struct.h
==============================================================================
--- trunk/libgda/gda-meta-struct.h	(original)
+++ trunk/libgda/gda-meta-struct.h	Wed Jul  2 19:33:18 2008
@@ -47,8 +47,7 @@
 /* struct for the object's data */
 struct _GdaMetaStruct
 {
-	GObject               object;
-	GSList                *db_objects; /* list of GdaMetaDbObject structures */
+	GObject                object;
 	GdaMetaStructPrivate  *priv;
 };
 
@@ -128,6 +127,7 @@
 		GdaMetaView     meta_view;
 	}                       extra;
 	GdaMetaDbObjectType     obj_type;
+	gboolean                outdated;
 	gchar                  *obj_catalog;
 	gchar                  *obj_schema;
 	gchar                  *obj_name;
@@ -164,28 +164,29 @@
 #define GDA_META_TABLE_FOREIGN_KEY(x) ((GdaMetaTableForeignKey*)(x))
 
 
-GType               gda_meta_struct_get_type          (void) G_GNUC_CONST;
-GdaMetaStruct      *gda_meta_struct_new               (GdaMetaStructFeature features);
-GdaMetaDbObject    *gda_meta_struct_complement        (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObjectType type,
-						       const GValue *catalog, const GValue *schema, const GValue *name,
-						       GError **error);
-gboolean            gda_meta_struct_complement_schema (GdaMetaStruct *mstruct, GdaMetaStore *store,
-						       const GValue *catalog, const GValue *schema, GError **error);
-gboolean            gda_meta_struct_complement_default (GdaMetaStruct *mstruct, GdaMetaStore *store, GError **error);
-gboolean            gda_meta_struct_complement_depend (GdaMetaStruct *mstruct, GdaMetaStore *store, GdaMetaDbObject *dbo,
-						       GError **error);
-
-gboolean            gda_meta_struct_sort_db_objects   (GdaMetaStruct *mstruct, GdaMetaSortType sort_type, GError **error);
-GdaMetaDbObject    *gda_meta_struct_get_db_object     (GdaMetaStruct *mstruct,
-						       const GValue *catalog, const GValue *schema, const GValue *name);
-GdaMetaTableColumn *gda_meta_struct_get_table_column  (GdaMetaStruct *mstruct, GdaMetaTable *table,
-						       const GValue *col_name);
+GType               gda_meta_struct_get_type           (void) G_GNUC_CONST;
+GdaMetaStruct      *gda_meta_struct_new                (GdaMetaStore *store, GdaMetaStructFeature features);
+GdaMetaDbObject    *gda_meta_struct_complement         (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
+							const GValue *catalog, const GValue *schema, const GValue *name,
+							GError **error);
+gboolean            gda_meta_struct_complement_schema  (GdaMetaStruct *mstruct,
+							const GValue *catalog, const GValue *schema, GError **error);
+gboolean            gda_meta_struct_complement_default (GdaMetaStruct *mstruct, GError **error);
+gboolean            gda_meta_struct_complement_depend  (GdaMetaStruct *mstruct, GdaMetaDbObject *dbo,
+							GError **error);
+
+gboolean            gda_meta_struct_sort_db_objects    (GdaMetaStruct *mstruct, GdaMetaSortType sort_type, GError **error);
+GSList             *gda_meta_struct_get_all_db_objects (GdaMetaStruct *mstruct);
+GdaMetaDbObject    *gda_meta_struct_get_db_object      (GdaMetaStruct *mstruct,
+						        const GValue *catalog, const GValue *schema, const GValue *name);
+GdaMetaTableColumn *gda_meta_struct_get_table_column   (GdaMetaStruct *mstruct, GdaMetaTable *table,
+						        const GValue *col_name);
 
 typedef enum {
 	GDA_META_GRAPH_COLUMNS = 1 << 0
 } GdaMetaGraphInfo;
 
-gchar              *gda_meta_struct_dump_as_graph     (GdaMetaStruct *mstruct, GdaMetaGraphInfo info, GError **error);
+gchar              *gda_meta_struct_dump_as_graph      (GdaMetaStruct *mstruct, GdaMetaGraphInfo info, GError **error);
 
 G_END_DECLS
 

Modified: trunk/libgda/gda-set.c
==============================================================================
--- trunk/libgda/gda-set.c	(original)
+++ trunk/libgda/gda-set.c	Wed Jul  2 19:33:18 2008
@@ -1218,8 +1218,8 @@
 gda_set_add_holder (GdaSet *set, GdaHolder *holder)
 {
 	gboolean added;
-	g_return_if_fail (GDA_IS_SET (set));
-	g_return_if_fail (GDA_IS_HOLDER (holder));
+	g_return_val_if_fail (GDA_IS_SET (set), FALSE);
+	g_return_val_if_fail (GDA_IS_HOLDER (holder), FALSE);
 
 	added = gda_set_real_add_holder (set, holder);
 	if (added)

Modified: trunk/libgda/information_schema.xml
==============================================================================
--- trunk/libgda/information_schema.xml	(original)
+++ trunk/libgda/information_schema.xml	Wed Jul  2 19:33:18 2008
@@ -413,8 +413,7 @@
     <column name="table_name" pkey="TRUE"/>
     <column name="constraint_name" pkey="TRUE"/>
     <column name="column_name" pkey="TRUE"/>
-
-    <column name="ordinal_position" type="gint" pkey="TRUE"/>
+    <column name="ordinal_position" type="gint" pkey="TRUE" descr="Ordinal position of the column within the constraint key (count starts at 1)"/>
     <fkey ref_table="_table_constraints">
       <part column="table_catalog"/>
       <part column="table_schema"/>

Modified: trunk/libgda/sql-parser/gda-sql-parser.c
==============================================================================
--- trunk/libgda/sql-parser/gda-sql-parser.c	(original)
+++ trunk/libgda/sql-parser/gda-sql-parser.c	Wed Jul  2 19:33:18 2008
@@ -608,7 +608,7 @@
  * @error: location to store error, or %NULL
  *
  * Parse @sql and creates a #GdaBatch object which contains all the #GdaStatement objects created while parsing (one object
- * per SQL statement).
+ * per SQL statement). Empty statements (composed of spaces only) do not appear in the resulting object.
  *
  * @sql is parsed and #GdaStatement objects are created as long as no error is found in @sql. If an error is found 
  * at some point, then the parsing stops and @remain may contain a non %NULL pointer, @error may be set, and %NULL

Modified: trunk/libgda/sql-parser/gda-statement-struct-util.c
==============================================================================
--- trunk/libgda/sql-parser/gda-statement-struct-util.c	(original)
+++ trunk/libgda/sql-parser/gda-statement-struct-util.c	Wed Jul  2 19:33:18 2008
@@ -300,6 +300,8 @@
 gchar *
 _identifier_unquote (gchar *str)
 {
+	if (!str)
+		return NULL;
 	if (*str == '"')
 		return _remove_quotes (str);
 	else {

Modified: trunk/libgda/sql-parser/gda-statement-struct.c
==============================================================================
--- trunk/libgda/sql-parser/gda-statement-struct.c	(original)
+++ trunk/libgda/sql-parser/gda-statement-struct.c	Wed Jul  2 19:33:18 2008
@@ -280,7 +280,7 @@
 		/* prepare data */
 		data.cnc = cnc;
 		data.store = gda_connection_get_meta_store (cnc);
-		data.mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_NONE);
+		data.mstruct = gda_meta_struct_new (data.store, GDA_META_STRUCT_FEATURE_NONE);
 		
 		/* attach the GdaMetaStruct to @stmt */
 		stmt->validity_meta_struct = data.mstruct;
@@ -518,7 +518,7 @@
 
 	/* use @name as the table or view's real name */
 	g_value_set_string (g_value_init (&value, G_TYPE_STRING), name);
-	dbo = gda_meta_struct_complement (data->mstruct, data->store, GDA_META_DB_UNKNOWN,
+	dbo = gda_meta_struct_complement (data->mstruct, GDA_META_DB_UNKNOWN,
 					  NULL, NULL, &value, &lerror);
 	g_value_unset (&value);
 	if (!dbo) {
@@ -541,7 +541,7 @@
 							continue;
 						g_value_set_string (g_value_init (&value, G_TYPE_STRING), 
 								    target->table_name);
-						dbo = gda_meta_struct_complement (data->mstruct, data->store, 
+						dbo = gda_meta_struct_complement (data->mstruct, 
 										  GDA_META_DB_UNKNOWN,
 										  NULL, NULL, &value, NULL);
 						g_value_unset (&value);

Modified: trunk/tools/command-exec.c
==============================================================================
--- trunk/tools/command-exec.c	(original)
+++ trunk/tools/command-exec.c	Wed Jul  2 19:33:18 2008
@@ -606,13 +606,14 @@
 	gint index;
 	const gchar *arg;
 	GdaMetaStore *store;
+	GSList *objlist;
 
 	store = gda_connection_get_meta_store (cnc);
-	mstruct = gda_meta_struct_new (GDA_META_STRUCT_FEATURE_ALL);
+	mstruct = gda_meta_struct_new (store, GDA_META_STRUCT_FEATURE_ALL);
 
 	if (!args[0]) {
 		/* use all tables or views */
-		if (!gda_meta_struct_complement_default (mstruct, store, error))
+		if (!gda_meta_struct_complement_default (mstruct, error))
 			goto onerror;
 	}
 
@@ -628,32 +629,34 @@
 			str[strlen (str) - 2] = 0;
 			g_value_take_string (v, str);
 
-			if (!gda_meta_struct_complement_schema (mstruct, store, NULL, v, error))
+			if (!gda_meta_struct_complement_schema (mstruct, NULL, v, error))
 				goto onerror;
 		}
 		else {
 			/* try to find it as a table or view */
-			if (!gda_meta_struct_complement (mstruct, store, GDA_META_DB_UNKNOWN, NULL, NULL, v, NULL)) {
+			if (!gda_meta_struct_complement (mstruct, GDA_META_DB_UNKNOWN, NULL, NULL, v, NULL)) {
 				if (g_str_has_suffix (arg, "=") && (*arg != '=')) {
 					GdaMetaDbObject *dbo;
 					gchar *str;
 					str = g_strdup (arg);
 					str[strlen (str) - 1] = 0;
 					g_value_take_string (v, str);
-					dbo = gda_meta_struct_complement (mstruct, store, GDA_META_DB_UNKNOWN, 
+					dbo = gda_meta_struct_complement (mstruct, GDA_META_DB_UNKNOWN, 
 									  NULL, NULL, v, NULL);
 					if (dbo)
-						gda_meta_struct_complement_depend (mstruct, store, dbo, NULL);
+						gda_meta_struct_complement_depend (mstruct, dbo, NULL);
 				}
 			}
 		}
 	}
 
-	if (!mstruct->db_objects) {
+	objlist = gda_meta_struct_get_all_db_objects (mstruct);
+	if (!objlist) {
 		g_set_error (error, 0, 0,
 			     _("No object found"));
 		goto onerror;
 	}
+	g_slist_free (objlist);
 	gda_meta_struct_sort_db_objects (mstruct, GDA_META_SORT_ALHAPETICAL, NULL);
 	return mstruct;
 
@@ -688,14 +691,15 @@
 	}
 
 	GdaMetaStruct *mstruct;
-	GSList *dbo_list;
+	GSList *dbo_list, *tmplist;
 	mstruct = gda_internal_command_build_meta_struct (cnc, args, error);
 	if (!mstruct)
 		return NULL;
-
+	
 	/* compute the number of known database objects */
 	gint nb_objects = 0;
-	for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
+	tmplist = gda_meta_struct_get_all_db_objects (mstruct);
+	for (dbo_list = tmplist; dbo_list; dbo_list = dbo_list->next) {
 		GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (dbo_list->data);
 		if (dbo->obj_type != GDA_META_DB_UNKNOWN)
 			nb_objects++;
@@ -708,7 +712,7 @@
 		gda_data_model_set_column_title (model, 1, _("Name"));
 		gda_data_model_set_column_title (model, 2, _("Type"));
 		gda_data_model_set_column_title (model, 3, _("Owner"));
-		for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
+		for (dbo_list = tmplist; dbo_list; dbo_list = dbo_list->next) {
 			GdaMetaDbObject *dbo = GDA_META_DB_OBJECT (dbo_list->data);
 			GList *values = NULL;
 			GValue *val;
@@ -746,10 +750,12 @@
 		res = g_new0 (GdaInternalCommandResult, 1);
 		res->type = GDA_INTERNAL_COMMAND_RESULT_DATA_MODEL;
 		res->u.model = model;
+		g_slist_free (tmplist);
 		return res;
 	}
 	else if (nb_objects == 0) {
 		g_set_error (error, 0, 0, _("No object found"));
+		g_slist_free (tmplist);
 		return NULL;
 	}
 
@@ -761,7 +767,7 @@
 	res->u.multiple_results = NULL;
 	GdaMetaDbObject *dbo;
 
-	for (dbo_list = mstruct->db_objects; dbo_list; dbo_list = dbo_list->next) {
+	for (dbo_list = tmplist; dbo_list; dbo_list = dbo_list->next) {
 		dbo = GDA_META_DB_OBJECT (dbo_list->data);
 		if (dbo->obj_type == GDA_META_DB_UNKNOWN)
 			dbo = NULL;
@@ -769,6 +775,7 @@
 			break;
 	}
 	g_assert (dbo);
+	g_slist_free (tmplist);
 
 	if ((dbo->obj_type == GDA_META_DB_VIEW) || (dbo->obj_type == GDA_META_DB_TABLE)) {
 		GdaInternalCommandResult *subres;

Modified: trunk/tools/gda-sql.c
==============================================================================
--- trunk/tools/gda-sql.c	(original)
+++ trunk/tools/gda-sql.c	Wed Jul  2 19:33:18 2008
@@ -626,22 +626,42 @@
 execute_external_command (MainData *data, const gchar *command, GError **error)
 {
 	GdaInternalCommandResult *res = NULL;
+	GdaBatch *batch;
+	const GSList *stmt_list;
 	GdaStatement *stmt;
 	GdaSet *params;
 	GObject *obj;
 	const gchar *remain = NULL;
 
-	stmt = gda_sql_parser_parse_string (data->current->parser, command, &remain, error);
-	if (! stmt)
+	batch = gda_sql_parser_parse_string_as_batch (data->current->parser, command, &remain, error);
+	if (!batch)
 		return NULL;
 	if (remain) {
+		g_object_unref (batch);
+		return NULL;
+	}
+	
+	stmt_list = gda_batch_get_statements (batch);
+	if (!stmt_list) {
+		g_object_unref (batch);
+		return NULL;
+	}
+
+	if (stmt_list->next) {
 		g_set_error (error, 0, 0,
-			     _("More than one SQL statement, remaining is: %s"), remain);
+			     _("More than one SQL statement"));
+		g_object_unref (batch);
 		return NULL;
 	}
+		
+	stmt = GDA_STATEMENT (stmt_list->data);
+	g_object_ref (stmt);
+	g_object_unref (batch);
 
-	if (!gda_statement_get_parameters (stmt, &params, error))
+	if (!gda_statement_get_parameters (stmt, &params, error)) {
+		g_object_unref (stmt);
 		return NULL;
+	}
 
 	/* fill parameters with some defined parameters */
 	if (params && params->holders) {
@@ -1729,17 +1749,45 @@
 			}
 			else {
 				if (*args [0] == '~') {
-					cs = find_connection_from_name (data, args[0] + 1);
-					if (!cs) {
+					if (*(args[0] + 1)) {
+						cs = find_connection_from_name (data, args[0] + 1);
+						if (!cs) {
+							g_set_error (error, 0, 0,
+								     _("No connection named '%s' found"), args[0] + 1);
+							return NULL;
+						}
+					}
+					else if (!data->current) {
 						g_set_error (error, 0, 0,
-							     _("No connection named '%s' found"), args[0] + 1);
+							     _("No current connection"));
 						return NULL;
 					}
+					else {
+						if (* (data->current->name) == '~') 
+							cs = find_connection_from_name (data, data->current->name + 1);
+						if (!cs) {
+							gchar *tmp;
+							tmp = g_strdup_printf ("~%s", data->current->name);
+							cs = find_connection_from_name (data, tmp);
+							g_free (tmp);
+						}
+						if (cs) {
+							GdaInternalCommandResult *res;
+							
+							res = g_new0 (GdaInternalCommandResult, 1);
+							res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
+							data->current = cs;
+							return res;
+						}
+
+						cs = data->current;
+					}
+
 					ConnectionSetting *ncs = g_new0 (ConnectionSetting, 1);
 					GdaMetaStore *store;
 					GdaInternalCommandResult *res;
 					
-					ncs->name = g_strdup (args[0]);
+					ncs->name = g_strdup_printf ("~%s", cs->name);
 					store = gda_connection_get_meta_store (cs->cnc);
 					ncs->cnc = gda_meta_store_get_internal_connection (store);
 					g_object_ref (ncs->cnc);



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