[libgda] GDA_TYPE_NULL is not 0 anymore, for bug #647633



commit 3f7456ef94b1b0f539267d02f32d8563dc9bb541
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Jun 13 17:01:41 2011 +0200

    GDA_TYPE_NULL is not 0 anymore, for bug #647633

 doc/C/libgda-5.0-docs.sgml                         |    1 +
 doc/C/libgda-sections.txt                          |   19 ++
 doc/C/migration3.xml                               |   37 ++++
 .../gdaui-data-cell-renderer-textual.c             |    6 +-
 libgda-ui/data-entries/gdaui-entry-bin.c           |    1 -
 libgda-ui/data-entries/gdaui-entry-boolean.c       |    1 -
 libgda-ui/data-entries/gdaui-entry-common-time.c   |    1 -
 libgda-ui/data-entries/gdaui-entry-none.c          |    2 +-
 libgda-ui/data-entries/gdaui-entry-number.c        |    1 -
 libgda-ui/data-entries/gdaui-entry-string.c        |    1 -
 libgda-ui/data-entries/gdaui-entry-wrapper.c       |    2 +-
 .../plugins/gdaui-data-cell-renderer-password.c    |    2 +-
 libgda-ui/data-entries/plugins/gdaui-entry-cidr.c  |    1 -
 .../data-entries/plugins/gdaui-entry-filesel.c     |    1 -
 .../data-entries/plugins/gdaui-entry-password.c    |    1 -
 libgda-ui/data-entries/plugins/gdaui-entry-pict.c  |    1 -
 libgda-ui/data-entries/plugins/gdaui-entry-rt.c    |    1 -
 libgda-ui/data-entries/plugins/gdaui-entry-text.c  |    1 -
 libgda-ui/gdaui-init.c                             |    2 +-
 libgda/gda-column.c                                |    2 +-
 libgda/gda-data-model-array.c                      |    3 +-
 libgda/gda-data-model-import.c                     |    2 +-
 libgda/gda-data-model.c                            |   13 +-
 libgda/gda-data-proxy.c                            |    1 +
 libgda/gda-holder.c                                |   36 ++--
 libgda/gda-init.c                                  |    5 +-
 libgda/gda-row.c                                   |    8 +-
 libgda/gda-server-provider.c                       |    6 +-
 libgda/gda-statement.c                             |    4 +-
 libgda/gda-util.c                                  |    6 +-
 libgda/gda-value.c                                 |  173 ++++++++++++++------
 libgda/gda-value.h                                 |   16 +--
 libgda/handlers/gda-handler-bin.c                  |    1 -
 libgda/handlers/gda-handler-boolean.c              |   10 -
 libgda/handlers/gda-handler-numerical.c            |    1 -
 libgda/handlers/gda-handler-string.c               |    1 -
 libgda/handlers/gda-handler-time.c                 |    1 -
 libgda/handlers/gda-handler-type.c                 |    1 -
 libgda/libgda.symbols                              |    1 +
 libgda/sql-parser/gda-statement-struct-parts.c     |    5 +-
 libgda/sql-parser/gda-statement-struct-pspec.c     |   30 ++--
 libgda/sql-parser/gda-statement-struct-trans.c     |   10 +-
 libgda/sql-parser/gda-statement-struct-util.c      |    5 +-
 libgda/sqlite/gda-sqlite-handler-bin.c             |    1 -
 libgda/sqlite/gda-sqlite-handler-boolean.c         |    1 -
 libgda/sqlite/gda-sqlite-meta.c                    |    4 +-
 libgda/sqlite/gda-sqlite-provider.c                |    7 +-
 libgda/sqlite/gda-sqlite-recordset.c               |   10 +-
 libgda/sqlite/virtual/gda-vconnection-hub.c        |    3 +-
 libgda/sqlite/virtual/gda-vprovider-data-model.c   |    7 +-
 libgda/thread-wrapper/gda-thread-wrapper.c         |   12 +-
 providers/firebird/gda-firebird-provider.c         |   11 +-
 providers/firebird/gda-firebird-recordset.c        |    7 +-
 providers/jdbc/GdaJValue.c                         |   28 ++--
 providers/jdbc/gda-jdbc-provider.c                 |    9 +-
 providers/jdbc/gda-jdbc-recordset.c                |    7 +-
 providers/jdbc/jni-wrapper.c                       |   38 ++---
 providers/jdbc/libmain.c                           |    3 +-
 providers/mysql/gda-mysql-handler-boolean.c        |    1 -
 providers/mysql/gda-mysql-provider.c               |   10 +-
 providers/mysql/gda-mysql-recordset.c              |   12 +-
 providers/oracle/gda-oracle-provider.c             |    9 +-
 providers/oracle/gda-oracle-recordset.c            |    7 +-
 providers/postgres/gda-postgres-handler-bin.c      |    1 -
 providers/postgres/gda-postgres-provider.c         |   10 +-
 providers/postgres/gda-postgres-recordset.c        |    7 +-
 .../skel-implementation/capi/gda-capi-provider.c   |    9 +-
 .../skel-implementation/capi/gda-capi-recordset.c  |    7 +-
 providers/web/gda-web-provider.c                   |    2 +
 providers/web/gda-web-recordset.c                  |    7 +-
 tests/data-model-errors.c                          |    8 +-
 tests/multi-threading/check_wrapper.c              |    6 +-
 tests/value-holders/common.c                       |    5 +-
 73 files changed, 387 insertions(+), 285 deletions(-)
---
diff --git a/doc/C/libgda-5.0-docs.sgml b/doc/C/libgda-5.0-docs.sgml
index 16548f6..fb1904a 100644
--- a/doc/C/libgda-5.0-docs.sgml
+++ b/doc/C/libgda-5.0-docs.sgml
@@ -308,6 +308,7 @@
     <xi:include href="gettingstarted.xml"/>
     <xi:include href="migration.xml"/>
     <xi:include href="migration2.xml"/>
+    <xi:include href="migration3.xml"/>
     <xi:include href="prov-notes.xml"/>
     <xi:include href="limitations.xml"/>
   </part>  
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 179f523..4eaf272 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -810,7 +810,26 @@ gda_blob_op_get_type
 <FILE>gda-value</FILE>
 <TITLE>Gda Value</TITLE>
 gda_value_new
+GDA_TYPE_NULL
+GDA_VALUE_HOLDS_NULL
+GDA_TYPE_BINARY
+GDA_VALUE_HOLDS_BINARY
+GDA_TYPE_BLOB
+GDA_VALUE_HOLDS_BLOB
+GDA_TYPE_GEOMETRIC_POINT
+GDA_VALUE_HOLDS_GEOMETRIC_POINT
+GDA_TYPE_NUMERIC
+GDA_VALUE_HOLDS_NUMERIC
+GDA_TYPE_SHORT
+GDA_VALUE_HOLDS_SHORT
+GDA_TYPE_USHORT
+GDA_VALUE_HOLDS_USHORT
+GDA_TYPE_TIME
+GDA_VALUE_HOLDS_TIME
+GDA_TYPE_TIMESTAMP
+GDA_VALUE_HOLDS_TIMESTAMP
 gda_value_new_null
+gda_value_set_null
 gda_value_copy
 gda_value_free
 gda_value_new_from_string
diff --git a/doc/C/migration3.xml b/doc/C/migration3.xml
new file mode 100644
index 0000000..a74cf9c
--- /dev/null
+++ b/doc/C/migration3.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+          "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";[
+<!ENTITY LIBGDA          "<application>Libgda</application>">
+]>
+<chapter id="migration-3" xmlns:xi="http://www.w3.org/2003/XInclude";>
+  <title>Migration from 4.X versions</title>
+  <sect1><title>Overview</title>
+    <para>Version 5.0 of &LIBGDA; is a small evolution to adapt to the GTK3 environment; as such it is API
+    compatible with versions 4.0.x or 4.2.x. However there are some few behavioural changes explicited
+    below.
+    </para>
+  </sect1>  
+
+  <sect1><title>GDA_TYPE_NULL</title>
+    <para>
+      Previous versions of &LIBGDA; represented SQL NULL values as a <link linkend="GValue">GValue</link> completely filled
+      with zeros (i.e. of type G_TYPE_INVALID), and GDA_TYPE_NULL was thus equivalent to G_TYPE_INVALID.
+    </para>
+    <para>
+      This new version introduces a new specific type for the same GDA_TYPE_NULL (which means
+      GDA_TYPE_NULL no longer equals G_TYPE_INVALID). The most common sources of errors brought by this
+      change are:
+      <itemizedlist>
+	<listitem><para>if you used <link linkend="g-value-init">g_value_init()</link> on a
+	value of type GDA_TYPE_NULL, then you'll have to eight clear the value first, or replace
+	that call with a call to <link linkend="gda-value-reset-with-type">gda_value_reset_with_type()</link></para></listitem>
+	<listitem><para>creating a GValue using <link linkend="g-new0">g_new0()</link> resulted
+	in a GDA_TYPE_NULL value, which is not longer the case; the value needs to be initialized
+	with a call to <link linkend="g-value-init">g_value_init()</link></para></listitem>
+	<listitem><para>testing for NULL values using G_IS_VALUE does not work anymore, you'll have to
+	replace them with <link linkend="GDA-VALUE-HOLDS-NULL:CAPS">GDA_VALUE_HOLDS_NULL()</link></para></listitem>
+      </itemizedlist>
+    </para>
+  </sect1>  
+
+</chapter>
diff --git a/libgda-ui/data-entries/gdaui-data-cell-renderer-textual.c b/libgda-ui/data-entries/gdaui-data-cell-renderer-textual.c
index ad8573a..6c0ace4 100644
--- a/libgda-ui/data-entries/gdaui-data-cell-renderer-textual.c
+++ b/libgda-ui/data-entries/gdaui-data-cell-renderer-textual.c
@@ -151,7 +151,7 @@ gdaui_data_cell_renderer_textual_init (GdauiDataCellRendererTextual *datacell)
 {
 	datacell->priv = g_new0 (GdauiDataCellRendererTextualPrivate, 1);
 	datacell->priv->dh = NULL;
-	datacell->priv->type = G_TYPE_INVALID;
+	datacell->priv->type = GDA_TYPE_NULL;
 	datacell->priv->type_forced = FALSE;
 	datacell->priv->value = NULL;
 	datacell->priv->options = NULL;
@@ -429,7 +429,7 @@ gdaui_data_cell_renderer_textual_set_property (GObject *object,
 				if (G_VALUE_TYPE (gval) != datacell->priv->type) {
 					if (!datacell->priv->type_forced) {
 						datacell->priv->type_forced = TRUE;
-						if (datacell->priv->type != G_TYPE_INVALID)
+						if (datacell->priv->type != GDA_TYPE_NULL)
 							g_warning (_("Data cell renderer's specified type (%s) "
 								     "differs from actual "
 								     "value to display type (%s)"),
@@ -451,7 +451,7 @@ gdaui_data_cell_renderer_textual_set_property (GObject *object,
 				if (! OPTIMIZE)
 					datacell->priv->value = gda_value_copy (gval);
 
-				if (!datacell->priv->dh && (datacell->priv->type != G_TYPE_INVALID))
+				if (!datacell->priv->dh && (datacell->priv->type != GDA_TYPE_NULL))
 					datacell->priv->dh = g_object_ref (gda_data_handler_get_default (datacell->priv->type));
 
 				if (datacell->priv->dh) {
diff --git a/libgda-ui/data-entries/gdaui-entry-bin.c b/libgda-ui/data-entries/gdaui-entry-bin.c
index 5fcb862..10bb661 100644
--- a/libgda-ui/data-entries/gdaui-entry-bin.c
+++ b/libgda-ui/data-entries/gdaui-entry-bin.c
@@ -160,7 +160,6 @@ gdaui_entry_bin_new (GdaDataHandler *dh, GType type)
 	GdauiEntryBin *dbin;
 
 	g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_BIN, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/gdaui-entry-boolean.c b/libgda-ui/data-entries/gdaui-entry-boolean.c
index a775c7d..3178626 100644
--- a/libgda-ui/data-entries/gdaui-entry-boolean.c
+++ b/libgda-ui/data-entries/gdaui-entry-boolean.c
@@ -115,7 +115,6 @@ gdaui_entry_boolean_new (GdaDataHandler *dh, GType type)
 	GdauiEntryBoolean *mgbool;
 
 	g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_BOOLEAN, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/gdaui-entry-common-time.c b/libgda-ui/data-entries/gdaui-entry-common-time.c
index b641796..19683ea 100644
--- a/libgda-ui/data-entries/gdaui-entry-common-time.c
+++ b/libgda-ui/data-entries/gdaui-entry-common-time.c
@@ -194,7 +194,6 @@ gdaui_entry_common_time_new (GdaDataHandler *dh, GType type)
 	GdauiEntryCommonTime *mgtim;
 
 	g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_COMMON_TIME, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/gdaui-entry-none.c b/libgda-ui/data-entries/gdaui-entry-none.c
index bd367f8..490753d 100644
--- a/libgda-ui/data-entries/gdaui-entry-none.c
+++ b/libgda-ui/data-entries/gdaui-entry-none.c
@@ -110,7 +110,7 @@ gdaui_entry_none_new (GType type)
 	GObject *obj;
 	GdauiEntryNone *entry;
 
-	g_return_val_if_fail ((type == G_TYPE_INVALID) || (type != GDA_TYPE_NULL) , NULL);
+	g_return_val_if_fail (type != GDA_TYPE_NULL , NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_NONE, NULL);
 	entry = GDAUI_ENTRY_NONE (obj);
diff --git a/libgda-ui/data-entries/gdaui-entry-number.c b/libgda-ui/data-entries/gdaui-entry-number.c
index 1c832ff..b29e120 100644
--- a/libgda-ui/data-entries/gdaui-entry-number.c
+++ b/libgda-ui/data-entries/gdaui-entry-number.c
@@ -200,7 +200,6 @@ gdaui_entry_number_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GdauiEntryNumber *mgstr;
 
 	g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 	g_return_val_if_fail (gdaui_entry_number_is_type_numeric (type), NULL);
 
diff --git a/libgda-ui/data-entries/gdaui-entry-string.c b/libgda-ui/data-entries/gdaui-entry-string.c
index 52d167d..c554d42 100644
--- a/libgda-ui/data-entries/gdaui-entry-string.c
+++ b/libgda-ui/data-entries/gdaui-entry-string.c
@@ -204,7 +204,6 @@ gdaui_entry_string_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GdauiEntryString *mgstr;
 
 	g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 	g_return_val_if_fail (type == G_TYPE_STRING, NULL);
 
diff --git a/libgda-ui/data-entries/gdaui-entry-wrapper.c b/libgda-ui/data-entries/gdaui-entry-wrapper.c
index 0e3ab03..7b55bb9 100644
--- a/libgda-ui/data-entries/gdaui-entry-wrapper.c
+++ b/libgda-ui/data-entries/gdaui-entry-wrapper.c
@@ -240,7 +240,7 @@ gdaui_entry_wrapper_init (GdauiEntryWrapper *mgwrap)
 	mgwrap->priv->real_class = NULL;
 	mgwrap->priv->signals_blocked = 0;
 
-	mgwrap->priv->type = G_TYPE_INVALID;
+	mgwrap->priv->type = GDA_TYPE_NULL;
 	mgwrap->priv->value_ref = NULL;
 	mgwrap->priv->value_default = NULL;
 
diff --git a/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-password.c b/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-password.c
index d66e521..b396398 100644
--- a/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-password.c
+++ b/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-password.c
@@ -134,7 +134,7 @@ gdaui_data_cell_renderer_password_init (GdauiDataCellRendererPassword *datacell)
 {
 	datacell->priv = g_new0 (GdauiDataCellRendererPasswordPrivate, 1);
 	datacell->priv->dh = NULL;
-	datacell->priv->type = G_TYPE_INVALID;
+	datacell->priv->type = GDA_TYPE_NULL;
 	datacell->priv->type_forced = FALSE;
 	datacell->priv->value = NULL;
 	datacell->priv->options = NULL;
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c b/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
index 4b868b5..f8e26ad 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-cidr.c
@@ -129,7 +129,6 @@ gdaui_entry_cidr_new (GdaDataHandler *dh, GType type)
 	GdauiEntryCidr *mgcidr;
 
 	g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_CIDR, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c b/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
index d91c227..48154da 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-filesel.c
@@ -118,7 +118,6 @@ gdaui_entry_filesel_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GdauiEntryFilesel *filesel;
 
 	g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_FILESEL, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-password.c b/libgda-ui/data-entries/plugins/gdaui-entry-password.c
index 97878c8..d2c822f 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-password.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-password.c
@@ -123,7 +123,6 @@ gdaui_entry_password_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GdauiEntryPassword *mgtxt;
 
 	g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_ENTRY_PASSWORD_TYPE, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-pict.c b/libgda-ui/data-entries/plugins/gdaui-entry-pict.c
index d1828f7..bc16038 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-pict.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-pict.c
@@ -144,7 +144,6 @@ gdaui_entry_pict_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GdauiEntryPict *mgpict;
 
 	g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_PICT, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-rt.c b/libgda-ui/data-entries/plugins/gdaui-entry-rt.c
index 3a4e152..68029f6 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-rt.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-rt.c
@@ -114,7 +114,6 @@ gdaui_entry_rt_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GObject *obj;
 
 	g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_RT, "handler", dh, NULL);
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-text.c b/libgda-ui/data-entries/plugins/gdaui-entry-text.c
index 8f83e37..4fd061c 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-text.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-text.c
@@ -134,7 +134,6 @@ gdaui_entry_text_new (GdaDataHandler *dh, GType type, const gchar *options)
 	GdauiEntryText *mgtxt;
 
 	g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
-	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
 	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
 
 	obj = g_object_new (GDAUI_TYPE_ENTRY_TEXT, "handler", dh, NULL);
diff --git a/libgda-ui/gdaui-init.c b/libgda-ui/gdaui-init.c
index f9ee85d..b2214a7 100644
--- a/libgda-ui/gdaui-init.c
+++ b/libgda-ui/gdaui-init.c
@@ -112,7 +112,7 @@ gdaui_new_data_entry (GType type, const gchar *plugin_name)
 	if (!gdaui_plugins_hash)
 		gdaui_plugins_hash = init_plugins_hash ();
 
-	if (type == G_TYPE_INVALID)
+	if (type == GDA_TYPE_NULL)
 		return (GdauiDataEntry *) gdaui_entry_none_new (GDA_TYPE_NULL);
 
 	dh = gda_data_handler_get_default (type);
diff --git a/libgda/gda-column.c b/libgda/gda-column.c
index 86f0b4a..6828921 100644
--- a/libgda/gda-column.c
+++ b/libgda/gda-column.c
@@ -146,7 +146,7 @@ gda_column_init (GdaColumn *column, G_GNUC_UNUSED GdaColumnClass *klass)
 	column->priv = g_new0 (GdaColumnPrivate, 1);
 	column->priv->defined_size = 0;
 	column->priv->id = NULL;
-	column->priv->g_type = G_TYPE_INVALID;
+	column->priv->g_type = GDA_TYPE_NULL;
 	column->priv->allow_null = TRUE;
 	column->priv->auto_increment = FALSE;
 	column->priv->auto_increment_start = 0;
diff --git a/libgda/gda-data-model-array.c b/libgda/gda-data-model-array.c
index 357af0c..4db79e8 100644
--- a/libgda/gda-data-model-array.c
+++ b/libgda/gda-data-model-array.c
@@ -528,8 +528,7 @@ column_g_type_changed_cb (GdaColumn *column, G_GNUC_UNUSED GType old, GType new,
         gint nb_warnings = 0;
 	const gint max_warnings = 5;
 
-        if ((new == G_TYPE_INVALID) ||
-            (new == GDA_TYPE_NULL))
+        if ((new == G_TYPE_INVALID) || (new == GDA_TYPE_NULL))
                 return;
 
         col = gda_column_get_position (column);
diff --git a/libgda/gda-data-model-import.c b/libgda/gda-data-model-import.c
index 481234b..91deffe 100644
--- a/libgda/gda-data-model-import.c
+++ b/libgda/gda-data-model-import.c
@@ -987,7 +987,7 @@ csv_parser_field_read_cb (char *s, size_t len, void *data)
 	GdaDataModelImport *model = pdata->model;
 	GValue *value = NULL;
 	GdaColumn *column;
-	GType type = G_TYPE_INVALID;
+	GType type = GDA_TYPE_NULL;
 	gchar *copy;
 
 	if (pdata->model->priv->extract.csv.ignore_first_line) 
diff --git a/libgda/gda-data-model.c b/libgda/gda-data-model.c
index 5e3e0e0..bc4b1b2 100644
--- a/libgda/gda-data-model.c
+++ b/libgda/gda-data-model.c
@@ -256,7 +256,7 @@ gda_data_model_row_inserted (GdaDataModel *model, gint row)
 		for (i = 0; i < nbcols; i++) {
 			column = gda_data_model_describe_column (model, i);
 			value = gda_data_model_get_value_at (model, i, 0, NULL);
-			if (value && (gda_column_get_g_type (column) == G_TYPE_INVALID))
+			if (value && (gda_column_get_g_type (column) == GDA_TYPE_NULL))
 				gda_column_set_g_type (column, G_VALUE_TYPE ((GValue *)value));
 		}
 	}
@@ -1622,8 +1622,7 @@ add_xml_row (GdaDataModel *model, xmlNodePtr xml_row, GError **error)
 		}
 
 		gdatype = gda_column_get_g_type (column);
-		if ((gdatype == G_TYPE_INVALID) ||
-		    (gdatype == GDA_TYPE_NULL)) {
+		if ((gdatype == G_TYPE_INVALID) || (gdatype == GDA_TYPE_NULL)) {
 			g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_XML_FORMAT_ERROR,
 				      "%s", _("Cannot retrieve column data type (type is UNKNOWN or not specified)"));
 			retval = FALSE;
@@ -1642,14 +1641,12 @@ add_xml_row (GdaDataModel *model, xmlNodePtr xml_row, GError **error)
 			value = g_new0 (GValue, 1);
 			gchar* nodeval = (gchar*)xmlNodeGetContent (xml_field);
 			if (nodeval) {
-				if (!gda_value_set_from_string (value, nodeval, gdatype)) {
-					g_free (value);
-					value = gda_value_new_null ();
-				}
+				if (!gda_value_set_from_string (value, nodeval, gdatype))
+					gda_value_set_null (value);
 				xmlFree(nodeval);
 			}
 			else
-				value = gda_value_new_null ();	
+				gda_value_set_null (value);
 		}
 
 		g_ptr_array_index (values, pos) = value;
diff --git a/libgda/gda-data-proxy.c b/libgda/gda-data-proxy.c
index 399f721..834ad14 100644
--- a/libgda/gda-data-proxy.c
+++ b/libgda/gda-data-proxy.c
@@ -471,6 +471,7 @@ row_modifs_new (GdaDataProxy *proxy, gint proxy_row)
 		rm->orig_values = g_new0 (GValue *, proxy->priv->model_nb_cols);
 		rm->orig_values_size = proxy->priv->model_nb_cols;
 		model_row = proxy_row_to_model_row (proxy, proxy_row);
+
 		if (model_row >= 0) {
 			for (i=0; i<proxy->priv->model_nb_cols; i++) {
 				const GValue *oval;
diff --git a/libgda/gda-holder.c b/libgda/gda-holder.c
index fd4c820..ef6cac4 100644
--- a/libgda/gda-holder.c
+++ b/libgda/gda-holder.c
@@ -36,8 +36,6 @@
 #include <libgda/gda-custom-marshal.h>
 #include <libgda/gda-types.h>
 
-#define __gda_value_is_null(value) (!G_IS_VALUE (value))
-
 /* 
  * Main static functions 
  */
@@ -307,7 +305,7 @@ gda_holder_init (GdaHolder *holder)
 
 	holder->priv->id = NULL;
 
-	holder->priv->g_type = G_TYPE_INVALID;
+	holder->priv->g_type = GDA_TYPE_NULL;
 	holder->priv->full_bind = NULL;
 	holder->priv->simple_bind = NULL;
 	holder->priv->simple_bind_notify_signal_id = 0;
@@ -593,11 +591,11 @@ gda_holder_set_property (GObject *object,
 				
 				/* updating the holder's validity regarding the NULL value */
 				if (!not_null && 
-				    (!holder->priv->value || __gda_value_is_null (holder->priv->value)))
+				    (!holder->priv->value || GDA_VALUE_HOLDS_NULL (holder->priv->value)))
 					holder->priv->valid = TRUE;
 				
 				if (not_null && 
-				    (!holder->priv->value || __gda_value_is_null (holder->priv->value)))
+				    (!holder->priv->value || GDA_VALUE_HOLDS_NULL (holder->priv->value)))
 					holder->priv->valid = FALSE;
 				
 				g_signal_emit (holder, gda_holder_signals[CHANGED], 0);
@@ -776,7 +774,7 @@ gda_holder_get_value_str (GdaHolder *holder, GdaDataHandler *dh)
 	g_return_val_if_fail (holder->priv, NULL);
 
 	current_val = gda_holder_get_value (holder);
-        if (!current_val || __gda_value_is_null (current_val))
+        if (!current_val || GDA_VALUE_HOLDS_NULL (current_val))
                 return NULL;
         else {
                 if (!dh)
@@ -851,21 +849,21 @@ gda_holder_set_value_str (GdaHolder *holder, GdaDataHandler *dh, const gchar *va
 
 	if (!value || !g_ascii_strcasecmp (value, "NULL")) 
                 return gda_holder_set_value (holder, NULL, error);
-    else {
+	else {
 		GValue *gdaval = NULL;
-
+		
 		if (!dh)
 			dh = gda_data_handler_get_default (holder->priv->g_type);
 		if (dh)
 			gdaval = gda_data_handler_get_value_from_str (dh, value, holder->priv->g_type);
-
+		
 		if (gdaval)
 			return real_gda_holder_set_value (holder, gdaval, FALSE, error);
-        else {
+		else {
 			g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_STRING_CONVERSION_ERROR,
 				     _("Unable to convert string to '%s' type"), 
 				     gda_g_type_to_string (holder->priv->g_type));
-        	return FALSE;
+			return FALSE;
 		}
 	}
 }
@@ -928,11 +926,11 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
 	}
 		
 	/* holder will be changed? */
-	newnull = !value || __gda_value_is_null (value);
+	newnull = !value || GDA_VALUE_HOLDS_NULL (value);
 	current_val = gda_holder_get_value (holder);
 	if (current_val == value)
 		changed = FALSE;
-	else if ((!current_val || __gda_value_is_null ((GValue *)current_val)) && newnull)
+	else if ((!current_val || GDA_VALUE_HOLDS_NULL ((GValue *)current_val)) && newnull)
 		changed = FALSE;
 	else if (value && current_val &&
 		 (G_VALUE_TYPE (value) == G_VALUE_TYPE ((GValue *)current_val)))
@@ -1062,11 +1060,11 @@ real_gda_holder_set_const_value (GdaHolder *holder, const GValue *value,
 #endif
 
 	/* holder will be changed? */
-	newnull = !value || __gda_value_is_null (value);
+	newnull = !value || GDA_VALUE_HOLDS_NULL (value);
 	current_val = gda_holder_get_value (holder);
 	if (current_val == value)
 		changed = FALSE;
-	else if ((!current_val || __gda_value_is_null (current_val)) && newnull) 
+	else if ((!current_val || GDA_VALUE_HOLDS_NULL (current_val)) && newnull) 
 		changed = FALSE;
 	else if (value && current_val &&
 		 (G_VALUE_TYPE (value) == G_VALUE_TYPE (current_val))) 
@@ -1390,8 +1388,8 @@ gda_holder_set_default_value (GdaHolder *holder, const GValue *value)
 		const GValue *current = gda_holder_get_value (holder);
 
 		/* check if default is equal to current value */
-		if (__gda_value_is_null (value) &&
-		    (!current || __gda_value_is_null (current)))
+		if (GDA_VALUE_HOLDS_NULL (value) &&
+		    (!current || GDA_VALUE_HOLDS_NULL (current)))
 			holder->priv->default_forced = TRUE;
 		else if ((G_VALUE_TYPE (value) == holder->priv->g_type) &&
 			 current && !gda_value_compare (value, current))
@@ -1675,12 +1673,12 @@ gda_holder_set_full_bind (GdaHolder *holder, GdaHolder *alias_of)
 		g_return_if_fail (alias_of->priv);
 		g_return_if_fail (holder->priv->g_type == alias_of->priv->g_type);
 		cvalue = gda_holder_get_value (alias_of);
-		if (cvalue && !__gda_value_is_null ((GValue*)cvalue))
+		if (cvalue && !GDA_VALUE_HOLDS_NULL ((GValue*)cvalue))
 			value2 = gda_value_copy ((GValue*)cvalue);
 	}
 
 	cvalue = gda_holder_get_value (holder);
-	if (cvalue && !__gda_value_is_null ((GValue*)cvalue))
+	if (cvalue && !GDA_VALUE_HOLDS_NULL ((GValue*)cvalue))
 		value1 = gda_value_copy ((GValue*)cvalue);
 		
 	
diff --git a/libgda/gda-init.c b/libgda/gda-init.c
index 804b790..926a204 100644
--- a/libgda/gda-init.c
+++ b/libgda/gda-init.c
@@ -156,7 +156,10 @@ gda_init (void)
 	if (!g_module_supported ())
 		g_error (_("libgda needs GModule. Finishing..."));
 
-	/* create the required Gda types */
+	/* create the required Gda types, to avoid multiple simultaneous type creation when
+	 * multi threads are used */
+	type = GDA_TYPE_NULL;
+	g_assert (type);
 	type = G_TYPE_DATE;
 	g_assert (type);
 	type = GDA_TYPE_BINARY;
diff --git a/libgda/gda-row.c b/libgda/gda-row.c
index ce4cb3b..040d47e 100644
--- a/libgda/gda-row.c
+++ b/libgda/gda-row.c
@@ -137,12 +137,16 @@ gda_row_set_property (GObject *object,
         row = GDA_ROW (object);
         if (row->priv) {
                 switch (param_id) {
-		case PROP_NB_VALUES:
+		case PROP_NB_VALUES: {
+			gint i;
 			g_return_if_fail (!row->priv->fields);
 
 			row->priv->nfields = g_value_get_int (value);
-			row->priv->fields = g_new0 (GValue, row->priv->nfields);			
+			row->priv->fields = g_new0 (GValue, row->priv->nfields);
+			for (i = 0; i < row->priv->nfields; i++)
+				gda_value_set_null (& (row->priv->fields [i]));
 			break;
+		}
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
diff --git a/libgda/gda-server-provider.c b/libgda/gda-server-provider.c
index 6c1ad6a..a4912e6 100644
--- a/libgda/gda-server-provider.c
+++ b/libgda/gda-server-provider.c
@@ -753,7 +753,7 @@ gda_server_provider_get_data_handler_dbms (GdaServerProvider *provider, GdaConne
  *
  * The returned value may be %NULL either if the provider does not implement that method, or if
  * there is no DBMS data type which could contain data of the @g_type type (for example %NULL may be
- * returned if a DBMS has integers only up to 4 bytes and a G_TYPE_INT64 is requested).
+ * returned if a DBMS has integers only up to 4 bytes and a #G_TYPE_INT64 is requested).
  *
  * Returns: (transfer none) (allow-none): the name of the DBMS type, or %NULL
  */
@@ -781,14 +781,14 @@ gda_server_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConne
  * @provider: a server provider.
  * @cnc: (allow-none): a #GdaConnection object, or %NULL
  * @string: the SQL string to convert to a value
- * @preferred_type: a #GType, or G_TYPE_INVALID
+ * @preferred_type: a #GType, or #G_TYPE_INVALID
  * @dbms_type: (allow-none): place to get the actual database type used if the conversion succeeded, or %NULL
  *
  * Use @provider to create a new #GValue from a single string representation. 
  *
  * The @preferred_type can optionally ask @provider to return a #GValue of the requested type 
  * (but if such a value can't be created from @string, then %NULL is returned); 
- * pass G_TYPE_INVALID if any returned type is acceptable.
+ * pass #G_TYPE_INVALID if any returned type is acceptable.
  *
  * The returned value is either a new #GValue or %NULL in the following cases:
  * - @string cannot be converted to @preferred_type type
diff --git a/libgda/gda-statement.c b/libgda/gda-statement.c
index 3150dcb..a119b5b 100644
--- a/libgda/gda-statement.c
+++ b/libgda/gda-statement.c
@@ -482,7 +482,7 @@ get_params_foreach_func (GdaSqlAnyPart *node, GdaSet **params, GError **error)
 	    (pspec = ((GdaSqlExpr*) node)->param_spec)) {
 		GdaHolder *h;
 
-		if (pspec->g_type == 0) {
+		if (pspec->g_type == GDA_TYPE_NULL) {
 			g_set_error (error, GDA_STATEMENT_ERROR, GDA_STATEMENT_PARAM_TYPE_ERROR,
 				     _("Could not determine GType for parameter '%s'"),
 				     pspec->name ? pspec->name : _("Unnamed"));
@@ -1335,7 +1335,7 @@ default_render_param_spec (GdaSqlParamSpec *pspec, GdaSqlExpr *expr, GdaSqlRende
 		else {
 			g_string_append (string, "##");
 			g_string_append (string, pspec->name);
-			if (pspec->g_type != G_TYPE_INVALID) {
+			if (pspec->g_type != GDA_TYPE_NULL) {
 				g_string_append (string, "::");
 				g_string_append (string, gda_g_type_to_string (pspec->g_type));
 				if (pspec->nullok) 
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index a0d156f..544be33 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -984,7 +984,7 @@ gda_compute_unique_table_row_condition_with_cnc (GdaConnection *cnc, GdaSqlState
 				opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
 				pspec = g_new0 (GdaSqlParamSpec, 1);
 				pspec->name = g_strdup_printf ("-%d", index);
-				pspec->g_type = tcol->gtype != G_TYPE_INVALID ? tcol->gtype: G_TYPE_STRING;
+				pspec->g_type = (tcol->gtype != GDA_TYPE_NULL) ? tcol->gtype: G_TYPE_STRING;
 				pspec->nullok = tcol->nullok;
 				opexpr->param_spec = pspec;
 				op->operands = g_slist_append (op->operands, opexpr);
@@ -1178,7 +1178,7 @@ gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gbool
 		if (insert_stmt) {
 			GdaSqlParamSpec *pspec = g_new0 (GdaSqlParamSpec, 1);
 			pspec->name = g_strdup_printf ("+%d", colindex);
-			pspec->g_type = tcol->gtype != G_TYPE_INVALID ? tcol->gtype: G_TYPE_STRING;
+			pspec->g_type = (tcol->gtype != GDA_TYPE_NULL) ? tcol->gtype: G_TYPE_STRING;
 			pspec->nullok = tcol->nullok;
 			expr = gda_sql_expr_new (GDA_SQL_ANY_PART (ist));
 			expr->param_spec = pspec;
@@ -1187,7 +1187,7 @@ gda_compute_dml_statements (GdaConnection *cnc, GdaStatement *select_stmt, gbool
 		if (update_stmt) {
 			GdaSqlParamSpec *pspec = g_new0 (GdaSqlParamSpec, 1);
 			pspec->name = g_strdup_printf ("+%d", colindex);
-			pspec->g_type = tcol->gtype != G_TYPE_INVALID ? tcol->gtype: G_TYPE_STRING;
+			pspec->g_type = (tcol->gtype != GDA_TYPE_NULL) ? tcol->gtype: G_TYPE_STRING;
 			pspec->nullok = tcol->nullok;
 			expr = gda_sql_expr_new (GDA_SQL_ANY_PART (ust));
 			expr->param_spec = pspec;
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index 8c1d058..20cbbed 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -64,9 +64,13 @@ set_from_string (GValue *value, const gchar *as_string)
 
 	g_return_val_if_fail (value, FALSE);
 	if (! G_IS_VALUE (value)) {
-		g_warning ("Can't determine the GType of a NULL GValue");
+		g_warning ("Can't set value for a G_TYPE_INVALID GValue");
 		return FALSE;
 	}
+	else if (GDA_VALUE_HOLDS_NULL (value)) {
+		g_warning ("Can't set value for a NULL GValue");
+                return FALSE;
+        }
 
 	type = G_VALUE_TYPE (value);
 	g_value_reset (value);
@@ -262,6 +266,56 @@ set_from_string (GValue *value, const gchar *as_string)
 }
 
 /* 
+ * Register the NULL type in the GType system 
+ */
+static void
+string_to_null (const GValue *src, GValue *dest)
+{
+       g_return_if_fail (G_VALUE_HOLDS_STRING (src) && GDA_VALUE_HOLDS_NULL (dest));
+       /* Do nothing just a dummy function to register */
+}
+
+static void
+null_to_string (const GValue *src, GValue *dest)
+{
+       g_return_if_fail (G_VALUE_HOLDS_STRING (dest) && GDA_VALUE_HOLDS_NULL (src));
+       g_value_set_string (dest, "NULL");
+}
+
+static gpointer
+gda_null_copy (G_GNUC_UNUSED gpointer boxed)
+{
+	return (gpointer) NULL;
+}
+
+static void
+gda_null_free (G_GNUC_UNUSED gpointer boxed)
+{
+}
+
+GType
+gda_null_get_type (void)
+{
+       static GType type = 0;
+
+       if (G_UNLIKELY (type == 0)) {
+               type = g_boxed_type_register_static ("GdaNull",
+                                                    (GBoxedCopyFunc) gda_null_copy,
+                                                    (GBoxedFreeFunc) gda_null_free);
+
+               g_value_register_transform_func (G_TYPE_STRING,
+                                                type,
+                                                string_to_null);
+
+               g_value_register_transform_func (type,
+                                                G_TYPE_STRING,
+                                                null_to_string);
+       }
+
+       return type;
+}
+
+/* 
  * Register the GdaBinary type in the GType system 
  */
 
@@ -1065,6 +1119,20 @@ gda_value_new (GType type)
 }
 
 /**
+ * gda_value_new_null:
+ *
+ * Creates a new #GValue initiated to a #GdaNull structure with a #GDA_TYPE_NULL, to
+ * represent a NULL in the database.
+ *
+ * Returns: (transfer full): a new #GValue of the type #GDA_TYPE_NULL
+ */
+GValue*
+gda_value_new_null (void)
+{
+	return gda_value_new (GDA_TYPE_NULL);
+}
+
+/**
  * gda_value_new_binary:
  * @val: value to set for the new #GValue.
  * @size: the size of the memory pool pointer to by @val.
@@ -1277,20 +1345,21 @@ gda_value_new_from_xml (const xmlNodePtr node)
 
 /**
  * gda_value_free:
- * @value: (transfer full): the resource to free.
+ * @value: (transfer full) (allow-none): the resource to free (or %NULL)
  *
  * Deallocates all memory associated to a #GValue.
  */
 void
 gda_value_free (GValue *value)
 {
-	g_return_if_fail (value);
-
+	if (!value)
+		return;
 	l_g_value_unset (value);
 	g_free (value);
 }
 
-/* gda_value_reset_with_type
+/**
+ * gda_value_reset_with_type:
  * @value: the #GValue to be reseted
  * @type:  the #GType to set to
  *
@@ -1305,7 +1374,7 @@ gda_value_reset_with_type (GValue *value, GType type)
 		g_value_reset (value);
 	else {
 		l_g_value_unset (value);
-		if (type == GDA_TYPE_NULL || type == G_TYPE_INVALID)
+		if (type == G_TYPE_INVALID)
 			return;
 		else
 			g_value_init (value, type);
@@ -1326,7 +1395,7 @@ gboolean
 gda_value_is_null (const GValue *value)
 {
 	g_return_val_if_fail (value, FALSE);
-	return !G_IS_VALUE (value);
+	return gda_value_isa (value, GDA_TYPE_NULL);
 }
 
 /**
@@ -1340,7 +1409,7 @@ gda_value_is_null (const GValue *value)
 gboolean
 gda_value_is_number (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE(value), FALSE);
+	g_return_val_if_fail (value, FALSE);
 	if(G_VALUE_HOLDS_INT(value) ||
 		G_VALUE_HOLDS_INT64(value) ||
 		G_VALUE_HOLDS_UINT(value) ||
@@ -1390,7 +1459,7 @@ gda_value_get_binary (const GValue *value)
 {
 	GdaBinary *val;
 
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_BINARY), NULL);
 
 	val = (GdaBinary*) g_value_get_boxed (value);
@@ -1469,7 +1538,7 @@ gda_value_get_blob (const GValue *value)
 {
 	GdaBlob *val;
 
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_BLOB), NULL);
 
 	val = (GdaBlob*) g_value_get_boxed (value);
@@ -1505,7 +1574,7 @@ gda_value_take_blob (GValue *value, GdaBlob *blob)
 G_CONST_RETURN GdaGeometricPoint *
 gda_value_get_geometric_point (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_GEOMETRIC_POINT), NULL);
 	return (const GdaGeometricPoint *) g_value_get_boxed(value);
 }
@@ -1538,8 +1607,7 @@ void
 gda_value_set_null (GValue *value)
 {
 	g_return_if_fail (value);
-
-	l_g_value_unset (value);
+	gda_value_reset_with_type (value, GDA_TYPE_NULL);
 }
 
 /**
@@ -1551,7 +1619,7 @@ gda_value_set_null (GValue *value)
 G_CONST_RETURN GdaNumeric *
 gda_value_get_numeric (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_NUMERIC), NULL);
 	return (const GdaNumeric *) g_value_get_boxed(value);
 }
@@ -1583,7 +1651,7 @@ gda_value_set_numeric (GValue *value, const GdaNumeric *val)
 gshort
 gda_value_get_short (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE (value), -1);
+	g_return_val_if_fail (value, -1);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_SHORT), -1);
 	return (gshort) value->data[0].v_int;
 }
@@ -1614,7 +1682,7 @@ gda_value_set_short (GValue *value, gshort val)
 gushort
 gda_value_get_ushort (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE (value), -1);
+	g_return_val_if_fail (value, -1);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_USHORT), -1);
 	return (gushort) value->data[0].v_uint;
 }
@@ -1646,7 +1714,7 @@ gda_value_set_ushort (GValue *value, gushort val)
 const GdaTime *
 gda_value_get_time (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_TIME), NULL);
 	return (const GdaTime *) g_value_get_boxed(value);
 }
@@ -1678,7 +1746,7 @@ gda_value_set_time (GValue *value, const GdaTime *val)
 const GdaTimestamp *
 gda_value_get_timestamp (const GValue *value)
 {
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 	g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_TIMESTAMP), NULL);
 	return (const GdaTimestamp *) g_value_get_boxed(value);
 }
@@ -1749,6 +1817,9 @@ gda_value_set_from_string (GValue *value,
  * #gda_value_set_from_value, on the other hand, copies the contents
  * of @copy into @value, which must already be allocated.
  *
+ * If values are incompatible (see @g_value_type_compatible) then @value is set to a
+ * #GDA_TYPE_NULL, and %FALSE is returned.
+ *
  * Returns: %TRUE if successful, %FALSE otherwise.
  */
 gboolean
@@ -1763,8 +1834,10 @@ gda_value_set_from_value (GValue *value, const GValue *from)
 			g_value_copy (from, value);
 			return TRUE;
 		}
-		else
+		else {
+			gda_value_set_null (value);
 			return FALSE;
+		}
 	}
 	else {
 		l_g_value_unset (value);
@@ -1788,41 +1861,39 @@ gda_value_set_from_value (GValue *value, const GValue *from)
 gchar *
 gda_value_stringify (const GValue *value)
 {
-	if (value && G_IS_VALUE (value)) {
-		if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) {
-			GValue *string;
-			gchar *str;
-			
-			string = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING);
-			g_value_transform (value, string);
-			str = g_value_dup_string (string);
-			gda_value_free (string);
-			return str;
-		}
-		else {
-			GType type = G_VALUE_TYPE (value);
-			if (type == G_TYPE_DATE) {
-				GDate *date;
-				date = (GDate *) g_value_get_boxed (value);
-				if (date) {
-					if (g_date_valid (date))
-						return g_strdup_printf ("%04u-%02u-%02u",
-									g_date_get_year (date),
-									g_date_get_month (date),
-									g_date_get_day (date));
-					else
-						return g_strdup_printf ("%04u-%02u-%02u",
-									date->year, date->month, date->day);
-				}
+	if (!value)
+		return g_strdup ("NULL");
+	if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) {
+		GValue *string;
+		gchar *str;
+
+		string = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING);
+		g_value_transform (value, string);
+		str = g_value_dup_string (string);
+		gda_value_free (string);
+		return str;
+	}
+	else {
+		GType type = G_VALUE_TYPE (value);
+		if (type == G_TYPE_DATE) {
+			GDate *date;
+			date = (GDate *) g_value_get_boxed (value);
+			if (date) {
+				if (g_date_valid (date))
+					return g_strdup_printf ("%04u-%02u-%02u",
+								g_date_get_year (date),
+								g_date_get_month (date),
+								g_date_get_day (date));
 				else
-					return g_strdup ("0000-00-00");
+					return g_strdup_printf ("%04u-%02u-%02u",
+								date->year, date->month, date->day);
 			}
 			else
-				return g_strdup ("");
+				return g_strdup ("0000-00-00");
 		}
+		else
+			return g_strdup ("");
 	}
-	else
-		return g_strdup ("NULL");
 }
 	
 /**
@@ -2263,7 +2334,7 @@ to_string (const GValue *value)
 {
 	gchar *retval = NULL;
 
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 
 	if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
 		if (g_value_get_boolean (value))
@@ -2292,7 +2363,7 @@ gda_value_to_xml (const GValue *value)
 	gchar *valstr;
 	xmlNodePtr retval;
 
-	g_return_val_if_fail (value && G_IS_VALUE (value), NULL);
+	g_return_val_if_fail (value, NULL);
 
 	valstr = to_string (value);
 
diff --git a/libgda/gda-value.h b/libgda/gda-value.h
index 12e2180..74ee2d3 100644
--- a/libgda/gda-value.h
+++ b/libgda/gda-value.h
@@ -40,7 +40,7 @@ G_BEGIN_DECLS
 #define GDA_TIMEZONE_INVALID (2*12*60*60)
 
 /* Definition of the GType's values used in GValue*/
-#define GDA_TYPE_NULL 0
+#define GDA_TYPE_NULL (gda_null_get_type())
 #define	GDA_TYPE_BINARY (gda_binary_get_type())
 #define GDA_TYPE_BLOB (gda_blob_get_type())
 #define	GDA_TYPE_GEOMETRIC_POINT (gda_geometricpoint_get_type())
@@ -52,6 +52,7 @@ G_BEGIN_DECLS
 
 
 /* Definition of the GDA_VALUE_HOLDS macros */
+#define GDA_VALUE_HOLDS_NULL(value)            G_VALUE_HOLDS(value, GDA_TYPE_NULL)
 #define GDA_VALUE_HOLDS_BINARY(value)          G_VALUE_HOLDS(value, GDA_TYPE_BINARY)
 #define GDA_VALUE_HOLDS_BLOB(value)            G_VALUE_HOLDS(value, GDA_TYPE_BLOB)
 #define GDA_VALUE_HOLDS_GEOMETRIC_POINT(value) G_VALUE_HOLDS(value, GDA_TYPE_GEOMETRIC_POINT)
@@ -186,6 +187,7 @@ typedef struct {
 
 GValue                           *gda_value_new (GType type);
 
+GValue                           *gda_value_new_null (void);
 GValue                           *gda_value_new_binary (const guchar *val, glong size);
 GValue                           *gda_value_new_blob (const guchar *val, glong size);
 GValue                           *gda_value_new_blob_from_file (const gchar *filename);
@@ -197,7 +199,6 @@ GValue                           *gda_value_new_from_xml (const xmlNodePtr node)
 void                              gda_value_free (GValue *value);
 void                              gda_value_reset_with_type (GValue *value, GType type);
 
-
 gboolean                          gda_value_is_null (const GValue *value); 
 gboolean                          gda_value_is_number (const GValue *value); 
 GValue                           *gda_value_copy (const GValue *value);
@@ -245,6 +246,7 @@ GdaBlob                          *gda_string_to_blob (const gchar *str);
 
 /* Custom data types */
 
+GType                             gda_null_get_type (void) G_GNUC_CONST;
 GType                             gda_numeric_get_type (void) G_GNUC_CONST;
 gpointer                          gda_numeric_copy (gpointer boxed);
 void                              gda_numeric_free (gpointer boxed);
@@ -277,16 +279,6 @@ void                              gda_blob_set_op (GdaBlob *blob, GdaBlobOp *op)
 GType                             gda_short_get_type (void) G_GNUC_CONST;
 GType                             gda_ushort_get_type (void) G_GNUC_CONST;
 
-/* Helper macros */
-/**
- * gda_value_new_null:
- * 
- * Creates a new #GValue of type %GDA_TYPE_NULL representing a NULL value
- *
- * Returns: (transfer full): a new #GValue
- */
-#define                           gda_value_new_null() (g_new0 (GValue, 1))
-
 G_END_DECLS
 
 #endif
diff --git a/libgda/handlers/gda-handler-bin.c b/libgda/handlers/gda-handler-bin.c
index 6d9c37c..be2f1d4 100644
--- a/libgda/handlers/gda-handler-bin.c
+++ b/libgda/handlers/gda-handler-bin.c
@@ -308,7 +308,6 @@ gda_handler_bin_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_HANDLER_BIN (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_HANDLER_BIN (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/handlers/gda-handler-boolean.c b/libgda/handlers/gda-handler-boolean.c
index db98d72..6c339dd 100644
--- a/libgda/handlers/gda-handler-boolean.c
+++ b/libgda/handlers/gda-handler-boolean.c
@@ -229,17 +229,8 @@ gda_handler_boolean_get_value_from_str (GdaDataHandler *iface, const gchar *str,
 	lcstr = g_utf8_strdown (str, -1);
 	if (!strcmp (lcstr, "true") || (*lcstr == 't'))
 		g_value_set_boolean (value, TRUE);
-	if (!value && (!strcmp (lcstr, "FALSE") || (*lcstr == 'f')))
-		g_value_set_boolean (value, FALSE);
 	g_free (lcstr);
 
-	if (! G_IS_VALUE (value)) {
-		g_value_set_boolean (value, TRUE);
-		lcstr = gda_value_stringify (value);
-		if (strcmp (str, lcstr))
-			g_value_set_boolean (value, FALSE);
-	}
-
 	return value;
 }
 
@@ -268,7 +259,6 @@ gda_handler_boolean_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_HANDLER_BOOLEAN (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_HANDLER_BOOLEAN (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/handlers/gda-handler-numerical.c b/libgda/handlers/gda-handler-numerical.c
index f252acb..f097e1e 100644
--- a/libgda/handlers/gda-handler-numerical.c
+++ b/libgda/handlers/gda-handler-numerical.c
@@ -394,7 +394,6 @@ gda_handler_numerical_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_HANDLER_NUMERICAL (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_HANDLER_NUMERICAL (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/handlers/gda-handler-string.c b/libgda/handlers/gda-handler-string.c
index 913e36e..b3330cb 100644
--- a/libgda/handlers/gda-handler-string.c
+++ b/libgda/handlers/gda-handler-string.c
@@ -319,7 +319,6 @@ gda_handler_string_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_HANDLER_STRING (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_HANDLER_STRING (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/handlers/gda-handler-time.c b/libgda/handlers/gda-handler-time.c
index 1cb1da9..d9e7996 100644
--- a/libgda/handlers/gda-handler-time.c
+++ b/libgda/handlers/gda-handler-time.c
@@ -1186,7 +1186,6 @@ gda_handler_time_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_HANDLER_TIME (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_HANDLER_TIME (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/handlers/gda-handler-type.c b/libgda/handlers/gda-handler-type.c
index 18edf9a..9898737 100644
--- a/libgda/handlers/gda-handler-type.c
+++ b/libgda/handlers/gda-handler-type.c
@@ -269,7 +269,6 @@ gda_handler_type_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_HANDLER_TYPE (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_HANDLER_TYPE (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/libgda.symbols b/libgda/libgda.symbols
index 97ef362..8487e29 100644
--- a/libgda/libgda.symbols
+++ b/libgda/libgda.symbols
@@ -477,6 +477,7 @@
 	gda_mutex_new
 	gda_mutex_trylock
 	gda_mutex_unlock
+	gda_null_get_type
 	gda_numeric_copy
 	gda_numeric_free
 	gda_numeric_get_type
diff --git a/libgda/sql-parser/gda-statement-struct-parts.c b/libgda/sql-parser/gda-statement-struct-parts.c
index 89c8e8a..dde0f93 100644
--- a/libgda/sql-parser/gda-statement-struct-parts.c
+++ b/libgda/sql-parser/gda-statement-struct-parts.c
@@ -79,10 +79,7 @@ gda_sql_expr_free (GdaSqlExpr *expr)
 	if (!expr) return;
 
 	_gda_sql_expr_check_clean (expr);
-	if (expr->value) {
-		g_value_unset (expr->value);
-		g_free (expr->value);
-	}
+	gda_value_free (expr->value);
 	gda_sql_param_spec_free (expr->param_spec);
 	gda_sql_function_free (expr->func);
 	gda_sql_operation_free (expr->cond);
diff --git a/libgda/sql-parser/gda-statement-struct-pspec.c b/libgda/sql-parser/gda-statement-struct-pspec.c
index dee9d89..04b6f98 100644
--- a/libgda/sql-parser/gda-statement-struct-pspec.c
+++ b/libgda/sql-parser/gda-statement-struct-pspec.c
@@ -28,7 +28,7 @@
 /**
  * gda_sql_param_spec_take_name:
  * @pspec: a #GdaSqlParamSpec pointer
- * @value: a G_TYPE_STRING #GValue
+ * @value: (transfer full): a G_TYPE_STRING #GValue
  *
  * Sets @pspec's name. @value's ownership is transferred to
  * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
@@ -42,15 +42,14 @@ gda_sql_param_spec_take_name (GdaSqlParamSpec *pspec, GValue *value)
 	}
 	if (value) {
 		pspec->name = _remove_quotes (g_value_dup_string (value));
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 	}
 }
 
 /**
  * gda_sql_param_spec_take_descr:
  * @pspec: a #GdaSqlParamSpec pointer
- * @value: a G_TYPE_STRING #GValue
+ * @value: (transfer full): a G_TYPE_STRING #GValue
  *
  * Sets @pspec's description. @value's ownership is transferred to
  * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
@@ -64,15 +63,14 @@ gda_sql_param_spec_take_descr (GdaSqlParamSpec *pspec, GValue *value)
 	}
 	if (value) {
 		pspec->descr = _remove_quotes (g_value_dup_string (value));
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 	}
 }
 
 /**
  * gda_sql_param_spec_take_nullok:
  * @pspec: a #GdaSqlParamSpec pointer
- * @value: a G_TYPE_STRING #GValue. 
+ * @value: (transfer full): a G_TYPE_STRING #GValue. 
  *
  * Sets @pspec's ability of being NULL. @value's ownership is transferred to
  * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
@@ -90,15 +88,14 @@ gda_sql_param_spec_take_nullok (GdaSqlParamSpec *pspec, GValue *value)
 			if ((*str == 't') || (*str == 'T'))
 				pspec->nullok = TRUE;
 		}
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 	}
 }
 
 /**
  * gda_sql_param_spec_take_type:
  * @pspec: a #GdaSqlParamSpec pointer
- * @value: a G_TYPE_STRING #GValue
+ * @value: (transfer full): a G_TYPE_STRING #GValue
  *
  * Sets @pspec's data type. @value's ownership is transferred to
  * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
@@ -108,12 +105,11 @@ gda_sql_param_spec_take_nullok (GdaSqlParamSpec *pspec, GValue *value)
 void
 gda_sql_param_spec_take_type (GdaSqlParamSpec *pspec, GValue *value)
 {
-	pspec->g_type = 0;
+	pspec->g_type = GDA_TYPE_NULL;
 	if (value) {
 		gchar *tmp;
 		tmp = _remove_quotes (g_value_dup_string (value));
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 
 		pspec->g_type = gda_g_type_from_string (tmp);
 		g_free (tmp);
@@ -122,7 +118,7 @@ gda_sql_param_spec_take_type (GdaSqlParamSpec *pspec, GValue *value)
 
 /**
  * gda_sql_param_spec_new:
- * @value: a G_TYPE_STRING #GValue
+ * @value: (transfer full): a G_TYPE_STRING #GValue
  *
  * @value must contain a string representing a variable, see the documentation associated to the
  * #GdaSqlParser object.
@@ -139,6 +135,7 @@ gda_sql_param_spec_new (GValue *value)
 	pspec =g_new0 (GdaSqlParamSpec, 1);
 	pspec->is_param = TRUE;
 	pspec->nullok = FALSE;
+	pspec->g_type = GDA_TYPE_NULL;
 
 	if (value) {
 		gchar *str = (gchar *) g_value_get_string (value);
@@ -168,8 +165,7 @@ gda_sql_param_spec_new (GValue *value)
 				str = ptr;
 			}
 		}
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 	}
 
 	return pspec;
@@ -244,7 +240,7 @@ gda_sql_param_spec_serialize (GdaSqlParamSpec *pspec)
 	g_string_append_printf (string, ",\"descr\":%s", str);
 	g_free (str);
 
-	if (pspec->g_type != G_TYPE_INVALID) {
+	if (pspec->g_type != GDA_TYPE_NULL) {
 		str = _json_quote_string (gda_g_type_to_string (pspec->g_type));
 		g_string_append_printf (string, ",\"type\":%s", str);
 		g_free (str);
diff --git a/libgda/sql-parser/gda-statement-struct-trans.c b/libgda/sql-parser/gda-statement-struct-trans.c
index 46ecc07..fe9892c 100644
--- a/libgda/sql-parser/gda-statement-struct-trans.c
+++ b/libgda/sql-parser/gda-statement-struct-trans.c
@@ -252,7 +252,7 @@ gda_sql_statement_trans_serialize (gpointer stmt)
 /**
  * gda_sql_statement_trans_take_name
  * @stmt: a #GdaSqlStatement pointer
- * @value: a G_TYPE_STRING value
+ * @value: (transfer full): a G_TYPE_STRING value
  *
  * Sets the name of the transaction
  *
@@ -269,15 +269,14 @@ gda_sql_statement_trans_take_name (GdaSqlStatement *stmt, GValue *value)
 	}
 	if (value) {
 		trans->trans_name = g_value_dup_string (value);
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 	}
 }
 
 /**
  * gda_sql_statement_trans_take_mode
  * @stmt: a #GdaSqlStatement pointer
- * @value: a G_TYPE_STRING value
+ * @value: (transfer full): a G_TYPE_STRING value
  *
  * Sets the model of the transaction
  *
@@ -294,8 +293,7 @@ gda_sql_statement_trans_take_mode (GdaSqlStatement *stmt, GValue *value)
 	}
 	if (value) {
 		trans->trans_mode = g_value_dup_string (value);
-		g_value_unset (value);
-		g_free (value);
+		gda_value_free (value);
 	}
 }
 
diff --git a/libgda/sql-parser/gda-statement-struct-util.c b/libgda/sql-parser/gda-statement-struct-util.c
index 70b4876..4cc6840 100644
--- a/libgda/sql-parser/gda-statement-struct-util.c
+++ b/libgda/sql-parser/gda-statement-struct-util.c
@@ -33,7 +33,7 @@
 gchar *
 gda_sql_value_stringify (const GValue *value)
 {
-        if (value && G_IS_VALUE (value)) {
+        if (value && !GDA_VALUE_HOLDS_NULL (value)) {
                 if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) {
                         GValue *string;
                         gchar *str;
@@ -41,8 +41,7 @@ gda_sql_value_stringify (const GValue *value)
                         string = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING);
                         g_value_transform (value, string);
                         str = g_value_dup_string (string);
-                        g_value_unset (string);
-			g_free (string);
+			gda_value_free (string);
                         return str;
                 }
                 else {
diff --git a/libgda/sqlite/gda-sqlite-handler-bin.c b/libgda/sqlite/gda-sqlite-handler-bin.c
index 8d1eefd..8487496 100644
--- a/libgda/sqlite/gda-sqlite-handler-bin.c
+++ b/libgda/sqlite/gda-sqlite-handler-bin.c
@@ -348,7 +348,6 @@ gda_sqlite_handler_bin_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BIN (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_SQLITE_HANDLER_BIN (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/sqlite/gda-sqlite-handler-boolean.c b/libgda/sqlite/gda-sqlite-handler-boolean.c
index c0d73d6..7ffe31f 100644
--- a/libgda/sqlite/gda-sqlite-handler-boolean.c
+++ b/libgda/sqlite/gda-sqlite-handler-boolean.c
@@ -254,7 +254,6 @@ gda_sqlite_handler_boolean_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/libgda/sqlite/gda-sqlite-meta.c b/libgda/sqlite/gda-sqlite-meta.c
index 239cc81..e2d2058 100644
--- a/libgda/sqlite/gda-sqlite-meta.c
+++ b/libgda/sqlite/gda-sqlite-meta.c
@@ -981,7 +981,7 @@ fill_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata,
 		const gchar *this_col_name;
 		const GValue *this_col_pname;
 		GValue *nthis_col_pname;
-		GType gtype = 0;
+		GType gtype = G_TYPE_INVALID;
 		const GValue *cvalue;
 		
 		this_col_pname = gda_data_model_get_value_at (tmpmodel, 1, i, error);
@@ -1058,7 +1058,7 @@ fill_columns_model (GdaConnection *cnc, SqliteConnectionData *cdata,
 			gtype = pg ? (GType) *pg : GDA_TYPE_NULL;
 			g_free (tmp);
 		}
-		if (gtype == 0) 
+		if (gtype == G_TYPE_INVALID)
 			/* default to string if nothing else */
 			g_value_set_string ((v6 = gda_value_new (G_TYPE_STRING)), "string");
 		else
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index cff9f42..e0423b8 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -1729,8 +1729,7 @@ gda_sqlite_provider_get_default_dbms_type (G_GNUC_UNUSED GdaServerProvider *prov
 	if ((type == GDA_TYPE_GEOMETRIC_POINT) ||
 	    (type == G_TYPE_OBJECT) ||
 	    (type == G_TYPE_STRING) ||
-	    (type == G_TYPE_INVALID) ||
-	    (type == G_TYPE_GTYPE))
+	    (type == G_TYPE_INVALID))
 		return "string";
 
 	if ((type == G_TYPE_DOUBLE) ||
@@ -1744,6 +1743,10 @@ gda_sqlite_provider_get_default_dbms_type (G_GNUC_UNUSED GdaServerProvider *prov
 		return "timestamp";
 	if (type == G_TYPE_DATE)
 		return "date";
+	
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
 
 	return "text";
 }
diff --git a/libgda/sqlite/gda-sqlite-recordset.c b/libgda/sqlite/gda-sqlite-recordset.c
index 55f477a..8e6f539 100644
--- a/libgda/sqlite/gda-sqlite-recordset.c
+++ b/libgda/sqlite/gda-sqlite-recordset.c
@@ -228,8 +228,11 @@ _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
@@ -379,8 +382,7 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
 				gda_value_set_null (value);
 			}
 			else {
-				if (type != GDA_TYPE_NULL)
-					g_value_init (value, type);
+				gda_value_reset_with_type (value, type);
 				
 				if (type == GDA_TYPE_NULL)
 					;
diff --git a/libgda/sqlite/virtual/gda-vconnection-hub.c b/libgda/sqlite/virtual/gda-vconnection-hub.c
index 09f9db6..dbe2d8b 100644
--- a/libgda/sqlite/virtual/gda-vconnection-hub.c
+++ b/libgda/sqlite/virtual/gda-vconnection-hub.c
@@ -578,8 +578,7 @@ create_value_from_sqlite3_gvalue (GType type, GValue *svalue, GError **error)
 	gboolean allok = TRUE;
 	value = g_new0 (GValue, 1);
 
-	if (type != GDA_TYPE_NULL)
-		g_value_init (value, type);
+	g_value_init (value, type);
 
 	if (type == GDA_TYPE_NULL)
 		;
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index 1d34792..3703974 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -759,10 +759,8 @@ virtualRowid (sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid)
 			cvalue = gda_data_model_iter_get_value_at (cursor->iter, i);
 			gvalue = gda_row_get_value (grow, i);
 			if (cvalue) {
-				if (G_VALUE_TYPE (cvalue) != GDA_TYPE_NULL) {
-					g_value_init (gvalue, G_VALUE_TYPE (cvalue));
-					g_value_copy (cvalue, gvalue);
-				}
+				gda_value_reset_with_type (gvalue, G_VALUE_TYPE (cvalue));
+				g_value_copy (cvalue, gvalue);
 			}
 			else
 				gda_row_invalidate_value (grow, gvalue);
@@ -808,6 +806,7 @@ create_value_from_sqlite3_value_notype (sqlite3_value *svalue)
 		break;
 	}
 	case SQLITE_NULL:
+		gda_value_set_null (value);
 		break;
 	case SQLITE3_TEXT:
 	default:
diff --git a/libgda/thread-wrapper/gda-thread-wrapper.c b/libgda/thread-wrapper/gda-thread-wrapper.c
index fd72451..3e1ff7f 100644
--- a/libgda/thread-wrapper/gda-thread-wrapper.c
+++ b/libgda/thread-wrapper/gda-thread-wrapper.c
@@ -1300,10 +1300,8 @@ worker_thread_closure_marshal (GClosure *closure,
 		src = param_values + i;
 		dest = job->u.signal.param_values + i - 1;
 
-		if (G_VALUE_TYPE (src) != GDA_TYPE_NULL) {
-			g_value_init (dest, G_VALUE_TYPE (src));
-			g_value_copy (src, dest);
-		}
+		g_value_init (dest, G_VALUE_TYPE (src));
+		g_value_copy (src, dest);
 	}
 
 	g_async_queue_push (sigspec->reply_queue, job);
@@ -1348,10 +1346,8 @@ worker_thread_closure_marshal_anythread (GClosure *closure,
 		src = param_values + i;
 		dest = job->u.signal.param_values + i - 1;
 
-		if (G_VALUE_TYPE (src) != GDA_TYPE_NULL) {
-			g_value_init (dest, G_VALUE_TYPE (src));
-			g_value_copy (src, dest);
-		}
+		g_value_init (dest, G_VALUE_TYPE (src));
+		g_value_copy (src, dest);
 	}
 
 	g_async_queue_push (sigspec->reply_queue, job);
diff --git a/providers/firebird/gda-firebird-provider.c b/providers/firebird/gda-firebird-provider.c
index 38a9320..3e53d24 100644
--- a/providers/firebird/gda-firebird-provider.c
+++ b/providers/firebird/gda-firebird-provider.c
@@ -897,8 +897,8 @@ static const gchar*
 gda_firebird_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnection *cnc, GType type)
 {
 	if (cnc) {
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 	}
 
 	TO_IMPLEMENT;
@@ -926,8 +926,7 @@ gda_firebird_provider_get_default_dbms_type (GdaServerProvider *provider, GdaCon
 	    (type == G_TYPE_OBJECT) ||
 	    (type == G_TYPE_STRING) ||
 	    (type == GDA_TYPE_TIME) ||
-	    (type == GDA_TYPE_TIMESTAMP) ||
-	    (type == G_TYPE_INVALID))
+	    (type == GDA_TYPE_TIMESTAMP))
 		return "string";
 
 	if ((type == G_TYPE_DOUBLE) ||
@@ -942,6 +941,10 @@ gda_firebird_provider_get_default_dbms_type (GdaServerProvider *provider, GdaCon
 	if (type == G_TYPE_DATE)
 		return "date";
 
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
+
 	return "text";
 }
 
diff --git a/providers/firebird/gda-firebird-recordset.c b/providers/firebird/gda-firebird-recordset.c
index 669ac2d..cfd8745 100644
--- a/providers/firebird/gda-firebird-recordset.c
+++ b/providers/firebird/gda-firebird-recordset.c
@@ -170,8 +170,11 @@ gda_firebird_recordset_new (GdaConnection *cnc, GdaFirebirdPStmt *ps, GdaDataMod
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
diff --git a/providers/jdbc/GdaJValue.c b/providers/jdbc/GdaJValue.c
index 5ae42d7..82c2a91 100644
--- a/providers/jdbc/GdaJValue.c
+++ b/providers/jdbc/GdaJValue.c
@@ -76,7 +76,7 @@ JNICALL Java_GdaJValue_setCString (JNIEnv *jenv, G_GNUC_UNUSED jobject obj, jlon
 		g_free (tmp);
 		return;
 	}
-	g_value_init (value, G_TYPE_STRING);
+	gda_value_reset_with_type (value, G_TYPE_STRING);
 	g_value_take_string (value, tmp);
 }
 
@@ -94,7 +94,7 @@ JNICALL Java_GdaJValue_setCInt (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jobjec
 				jint col, jint i)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_INT);
+	gda_value_reset_with_type (value, G_TYPE_INT);
 	g_value_set_int (value, i);
 }
 
@@ -109,7 +109,7 @@ JNICALL Java_GdaJValue_setCChar (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jobje
 				 jint col, jbyte b)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_CHAR);
+	gda_value_reset_with_type (value, G_TYPE_CHAR);
 	g_value_set_char (value, b);
 }
 
@@ -124,7 +124,7 @@ JNICALL Java_GdaJValue_setCDouble (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED job
 				   jint col, jdouble d)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_DOUBLE);
+	gda_value_reset_with_type (value, G_TYPE_DOUBLE);
 	g_value_set_double (value, d);
 }
 
@@ -139,7 +139,7 @@ JNICALL Java_GdaJValue_setCFloat (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jobj
 				  jint col, jfloat f)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_FLOAT);
+	gda_value_reset_with_type (value, G_TYPE_FLOAT);
 	g_value_set_float (value, f);
 }
 
@@ -154,7 +154,7 @@ JNICALL Java_GdaJValue_setCBoolean (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jo
 				    jint col, jboolean b)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_BOOLEAN);
+	gda_value_reset_with_type (value, G_TYPE_BOOLEAN);
 	g_value_set_boolean (value, b);
 }
 
@@ -173,7 +173,7 @@ JNICALL Java_GdaJValue_setCDate (JNIEnv *jenv, G_GNUC_UNUSED jobject obj, jlong
 	date = g_date_new_dmy (day, month, year);
 	if (g_date_valid (date)) {
 		GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-		g_value_init (value, G_TYPE_DATE);
+		gda_value_reset_with_type (value, G_TYPE_DATE);
 		g_value_take_boxed (value, date);
 	}
 	else {
@@ -229,7 +229,7 @@ JNICALL Java_GdaJValue_setCTime (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jobje
 	tim->second = sec;
 
 	value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, GDA_TYPE_TIME);
+	gda_value_reset_with_type (value, GDA_TYPE_TIME);
 	g_value_take_boxed (value, tim);
 }
 
@@ -277,7 +277,7 @@ JNICALL Java_GdaJValue_setCTimestamp (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED
 	ts->second = sec;
 
 	value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, GDA_TYPE_TIMESTAMP);
+	gda_value_reset_with_type (value, GDA_TYPE_TIMESTAMP);
 	g_value_take_boxed (value, ts);
 }
 
@@ -324,7 +324,7 @@ JNICALL Java_GdaJValue_setCBinary (JNIEnv *jenv, G_GNUC_UNUSED jobject obj, jlon
 	(*jenv)->GetByteArrayRegion(jenv, bytes, 0, len, (jbyte *) bin->data);
 
 	value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, GDA_TYPE_BINARY);
+	gda_value_reset_with_type (value, GDA_TYPE_BINARY);
 	g_value_take_boxed (value, bin);
 }
 
@@ -368,7 +368,7 @@ JNICALL Java_GdaJValue_setCBlob (JNIEnv *jenv, G_GNUC_UNUSED jobject obj, jlong
 	blob->op = gda_jdbc_blob_op_new_with_jblob (GDA_CONNECTION ((gpointer) cnc_c_pointer), jenv, blobop);
 
 	value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, GDA_TYPE_BLOB);
+	gda_value_reset_with_type (value, GDA_TYPE_BLOB);
 	g_value_take_boxed (value, blob);
 }
 
@@ -444,7 +444,7 @@ JNIEXPORT void
 JNICALL Java_GdaJValue_setCLong (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jobject obj, jlong c_pointer, jint col, jlong l)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_INT64);
+	gda_value_reset_with_type (value, G_TYPE_INT64);
 	g_value_set_int64 (value, l);
 }
 
@@ -459,7 +459,7 @@ JNICALL Java_GdaJValue_setCShort (G_GNUC_UNUSED JNIEnv *jenv, G_GNUC_UNUSED jobj
 				  jint col, jshort s)
 {
 	GValue *value = gda_row_get_value (GDA_ROW ((gpointer) c_pointer), col);
-	g_value_init (value, G_TYPE_INT64);
+	gda_value_reset_with_type (value, G_TYPE_INT64);
 	gda_value_set_short (value, s);
 }
 
@@ -496,7 +496,7 @@ JNICALL Java_GdaJValue_setCNumeric (JNIEnv *jenv, G_GNUC_UNUSED jobject obj, jlo
 	num->number = tmp;
 	num->precision = precision;
 	num->width = scale;
-	g_value_init (value, GDA_TYPE_NUMERIC);
+	gda_value_reset_with_type (value, GDA_TYPE_NUMERIC);
 	g_value_take_boxed (value, num);
 }
 
diff --git a/providers/jdbc/gda-jdbc-provider.c b/providers/jdbc/gda-jdbc-provider.c
index 476141d..02700ae 100644
--- a/providers/jdbc/gda-jdbc-provider.c
+++ b/providers/jdbc/gda-jdbc-provider.c
@@ -962,8 +962,8 @@ static const gchar*
 gda_jdbc_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnection *cnc, GType type)
 {
 	if (cnc) {
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 	}
 
 	TO_IMPLEMENT;
@@ -992,7 +992,6 @@ gda_jdbc_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnect
 	    (type == G_TYPE_STRING) ||
 	    (type == GDA_TYPE_TIME) ||
 	    (type == GDA_TYPE_TIMESTAMP) ||
-	    (type == G_TYPE_INVALID) ||
 	    (type == G_TYPE_GTYPE))
 		return "string";
 
@@ -1008,6 +1007,10 @@ gda_jdbc_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnect
 	if (type == G_TYPE_DATE)
 		return "date";
 
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
+
 	return "text";
 }
 
diff --git a/providers/jdbc/gda-jdbc-recordset.c b/providers/jdbc/gda-jdbc-recordset.c
index 0967e0c..75dde5d 100644
--- a/providers/jdbc/gda-jdbc-recordset.c
+++ b/providers/jdbc/gda-jdbc-recordset.c
@@ -267,8 +267,11 @@ gda_jdbc_recordset_new (GdaConnection *cnc, GdaJdbcPStmt *ps, GdaSet *exec_param
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
diff --git a/providers/jdbc/jni-wrapper.c b/providers/jdbc/jni-wrapper.c
index 58b6956..c425a48 100644
--- a/providers/jdbc/jni-wrapper.c
+++ b/providers/jdbc/jni-wrapper.c
@@ -290,8 +290,7 @@ jni_wrapper_instantiate_object (JNIEnv *jenv, jclass klass, const gchar *signatu
 	va_end (args);
 	
 	if (jni_wrapper_handle_exception (jenv, NULL, NULL, error)) {
-		g_value_unset (retval);
-		g_free (retval);
+		gda_value_free (retval);
 		retval = NULL;
 	}
 
@@ -352,8 +351,7 @@ jni_wrapper_handle_exception (JNIEnv *jenv, gint *out_error_code, gchar **out_sq
 				if (res) {
 					if (G_VALUE_TYPE (res) == G_TYPE_INT)
 						*out_error_code = g_value_get_int (res);
-					g_value_unset (res);
-					g_free (res);
+					gda_value_free (res);
 				}
 			}
 			if (out_sql_state) {
@@ -364,8 +362,7 @@ jni_wrapper_handle_exception (JNIEnv *jenv, gint *out_error_code, gchar **out_sq
 				if (res) {
 					if (G_VALUE_TYPE (res) == G_TYPE_STRING)
 						*out_sql_state = g_value_dup_string (res);
-					g_value_unset (res);
-					g_free (res);
+					gda_value_free (res);
 				}
 			}
 		}
@@ -381,13 +378,10 @@ jni_wrapper_handle_exception (JNIEnv *jenv, gint *out_error_code, gchar **out_sq
 			if (res) {
 				if (G_VALUE_TYPE (res) == G_TYPE_STRING) {
 					g_set_error (error, 0, 0, "%s", g_value_get_string (res));
-					g_value_unset (res);
-					g_free (res);
+					gda_value_free (res);
 				}
 				else {
-					if (G_VALUE_TYPE (res) != 0) /* GDA_TYPE_NULL */
-						g_value_unset (res);
-					g_free (res);
+					gda_value_free (res);
 					goto fallback;
 				}
 			}
@@ -398,20 +392,13 @@ jni_wrapper_handle_exception (JNIEnv *jenv, gint *out_error_code, gchar **out_sq
 			goto fallback;
 	}
 
-	if (exc_value) {
-		g_value_unset (exc_value);
-		g_free (exc_value);
-	}
+	gda_value_free (exc_value);
 
 	return TRUE;
 
  fallback:
-	g_set_error (error, 0, 0, "%s", 
-		     "An exception occurred");
-	if (exc_value) {
-		g_value_unset (exc_value);
-		g_free (exc_value);
-	}
+	g_set_error (error, 0, 0, "%s", "An exception occurred");
+	gda_value_free (exc_value);
 	(*jenv)->DeleteLocalRef(jenv, exc);
 	return TRUE;
 }
@@ -502,6 +489,7 @@ jni_wrapper_method_call (JNIEnv *jenv, JniWrapperMethod *method, GValue *object,
 			(*jenv)->CallStaticVoidMethodV (jenv, method->klass, method->mid, args);
 		else
 			(*jenv)->CallVoidMethodV (jenv, jobj, method->mid, args);
+		gda_value_set_null (retval);
 		break;
 	case '[':
 	case 'L': 
@@ -628,9 +616,7 @@ jni_wrapper_method_call (JNIEnv *jenv, JniWrapperMethod *method, GValue *object,
 	va_end (args);
 
 	if (jni_wrapper_handle_exception (jenv, out_error_code, out_sql_state, error)) {
-		if (G_VALUE_TYPE (retval) != 0)
-			g_value_unset (retval);
-		g_free (retval);
+		gda_value_free (retval);
 		return NULL;
 	}
  
@@ -841,9 +827,7 @@ jni_wrapper_field_get (JNIEnv *jenv, JniWrapperField *field, GValue *object, GEr
 	}
 
 	if (jni_wrapper_handle_exception (jenv, NULL, NULL, error)) {
-		if (G_VALUE_TYPE (retval) != 0)
-			g_value_unset (retval);
-		g_free (retval);
+		gda_value_free (retval);
 		return NULL;
 	}
  
diff --git a/providers/jdbc/libmain.c b/providers/jdbc/libmain.c
index 59d86d6..a00d206 100644
--- a/providers/jdbc/libmain.c
+++ b/providers/jdbc/libmain.c
@@ -170,8 +170,7 @@ plugin_get_sub_names (void)
 	}
 	if (!gda_value_is_null (lvalue)) {
 		sub_names = g_strsplit (g_value_get_string (lvalue), ":", 0);
-		g_value_unset (lvalue);
-		g_free (lvalue);
+		gda_value_free (lvalue);
 		
 		describe_driver_names ();
 		
diff --git a/providers/mysql/gda-mysql-handler-boolean.c b/providers/mysql/gda-mysql-handler-boolean.c
index 852632a..2d60043 100644
--- a/providers/mysql/gda-mysql-handler-boolean.c
+++ b/providers/mysql/gda-mysql-handler-boolean.c
@@ -252,7 +252,6 @@ gda_mysql_handler_boolean_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/providers/mysql/gda-mysql-provider.c b/providers/mysql/gda-mysql-provider.c
index c43be07..5e13726 100644
--- a/providers/mysql/gda-mysql-provider.c
+++ b/providers/mysql/gda-mysql-provider.c
@@ -1330,8 +1330,8 @@ gda_mysql_provider_get_default_dbms_type (GdaServerProvider  *provider,
 					  GType               type)
 {
 	if (cnc) {
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 	}
 
 	if (type == G_TYPE_INT64)
@@ -1376,8 +1376,10 @@ gda_mysql_provider_get_default_dbms_type (GdaServerProvider  *provider,
 		return "bigint unsigned";
 	if (type == G_TYPE_UINT)
 		return "int unsigned";
-	if (type == G_TYPE_INVALID)
-		return "text";
+
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
 
 	return "text";
 }
diff --git a/providers/mysql/gda-mysql-recordset.c b/providers/mysql/gda-mysql-recordset.c
index c97f7cc..4cd4708 100644
--- a/providers/mysql/gda-mysql-recordset.c
+++ b/providers/mysql/gda-mysql-recordset.c
@@ -313,7 +313,7 @@ static GType
 _gda_mysql_type_to_gda (MysqlConnectionData *cdata,
 			enum enum_field_types  mysql_type, unsigned int charsetnr)
 {
-	GType gtype = 0;
+	GType gtype;
 	switch (mysql_type) {
 	case MYSQL_TYPE_TINY:
 	case MYSQL_TYPE_SHORT:
@@ -559,8 +559,11 @@ gda_mysql_recordset_new (GdaConnection            *cnc,
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
@@ -825,8 +828,7 @@ new_row_from_mysql_stmt (GdaMysqlRecordset *imodel, gint rownum, GError **error)
 			}
 			break;
 		case MYSQL_TYPE_NULL:
-			if (G_IS_VALUE(value))
-				g_value_unset (value);
+			gda_value_set_null (value);
 			break;
 		case MYSQL_TYPE_TIME:
 		case MYSQL_TYPE_DATE:
diff --git a/providers/oracle/gda-oracle-provider.c b/providers/oracle/gda-oracle-provider.c
index fd2001c..a53e724 100644
--- a/providers/oracle/gda-oracle-provider.c
+++ b/providers/oracle/gda-oracle-provider.c
@@ -1187,8 +1187,8 @@ static const gchar*
 gda_oracle_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnection *cnc, GType type)
 {
 	if (cnc) {
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 	}
 
 	TO_IMPLEMENT;
@@ -1217,7 +1217,6 @@ gda_oracle_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConne
 	    (type == G_TYPE_STRING) ||
 	    (type == GDA_TYPE_TIME) ||
 	    (type == GDA_TYPE_TIMESTAMP) ||
-	    (type == G_TYPE_INVALID) ||
 	    (type == G_TYPE_GTYPE))
 		return "VARCHAR2";
 
@@ -1233,6 +1232,10 @@ gda_oracle_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConne
 	if (type == G_TYPE_DATE)
 		return "DATE";
 
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
+
 	return "VARCHAR2";
 }
 
diff --git a/providers/oracle/gda-oracle-recordset.c b/providers/oracle/gda-oracle-recordset.c
index 55b3a92..f91b3c0 100644
--- a/providers/oracle/gda-oracle-recordset.c
+++ b/providers/oracle/gda-oracle-recordset.c
@@ -229,8 +229,11 @@ gda_oracle_recordset_new (GdaConnection *cnc, GdaOraclePStmt *ps, GdaSet *exec_p
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
diff --git a/providers/postgres/gda-postgres-handler-bin.c b/providers/postgres/gda-postgres-handler-bin.c
index ea3aebf..d421dbe 100644
--- a/providers/postgres/gda-postgres-handler-bin.c
+++ b/providers/postgres/gda-postgres-handler-bin.c
@@ -321,7 +321,6 @@ gda_postgres_handler_bin_accepts_g_type (GdaDataHandler *iface, GType type)
 	gboolean found = FALSE;
 
 	g_return_val_if_fail (iface && GDA_IS_POSTGRES_HANDLER_BIN (iface), FALSE);
-	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
 	hdl = GDA_POSTGRES_HANDLER_BIN (iface);
 	g_return_val_if_fail (hdl->priv, 0);
 
diff --git a/providers/postgres/gda-postgres-provider.c b/providers/postgres/gda-postgres-provider.c
index a037e07..5a02ffc 100644
--- a/providers/postgres/gda-postgres-provider.c
+++ b/providers/postgres/gda-postgres-provider.c
@@ -1373,8 +1373,8 @@ static const gchar*
 gda_postgres_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnection *cnc, GType type)
 {
 	if (cnc) {
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 	}
 
 	if (type == G_TYPE_INT64)
@@ -1421,8 +1421,10 @@ gda_postgres_provider_get_default_dbms_type (GdaServerProvider *provider, GdaCon
                 return "varchar";
         if (type == G_TYPE_UINT)
                 return "int4";
-        if (type == G_TYPE_INVALID)
-                return "text";
+
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
 
         return "text";
 }
diff --git a/providers/postgres/gda-postgres-recordset.c b/providers/postgres/gda-postgres-recordset.c
index 99bec23..d0182e2 100644
--- a/providers/postgres/gda-postgres-recordset.c
+++ b/providers/postgres/gda-postgres-recordset.c
@@ -280,8 +280,11 @@ finish_prep_stmt_init (PostgresConnectionData *cdata, GdaPostgresPStmt *ps, PGre
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
diff --git a/providers/skel-implementation/capi/gda-capi-provider.c b/providers/skel-implementation/capi/gda-capi-provider.c
index af988f9..c5f3e30 100644
--- a/providers/skel-implementation/capi/gda-capi-provider.c
+++ b/providers/skel-implementation/capi/gda-capi-provider.c
@@ -829,8 +829,8 @@ static const gchar*
 gda_capi_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnection *cnc, GType type)
 {
 	if (cnc) {
-		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
-		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
+		g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
+		g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 	}
 
 	TO_IMPLEMENT;
@@ -859,7 +859,6 @@ gda_capi_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnect
 	    (type == G_TYPE_STRING) ||
 	    (type == GDA_TYPE_TIME) ||
 	    (type == GDA_TYPE_TIMESTAMP) ||
-	    (type == G_TYPE_INVALID) ||
 	    (type == G_TYPE_GTYPE))
 		return "string";
 
@@ -875,6 +874,10 @@ gda_capi_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnect
 	if (type == G_TYPE_DATE)
 		return "date";
 
+	if ((type == GDA_TYPE_NULL) ||
+	    (type == G_TYPE_GTYPE))
+		return NULL;
+
 	return "text";
 }
 
diff --git a/providers/skel-implementation/capi/gda-capi-recordset.c b/providers/skel-implementation/capi/gda-capi-recordset.c
index 49b031a..7fa42b4 100644
--- a/providers/skel-implementation/capi/gda-capi-recordset.c
+++ b/providers/skel-implementation/capi/gda-capi-recordset.c
@@ -169,8 +169,11 @@ gda_capi_recordset_new (GdaConnection *cnc, GdaCapiPStmt *ps, GdaSet *exec_param
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
diff --git a/providers/web/gda-web-provider.c b/providers/web/gda-web-provider.c
index 91f7331..ba511ef 100644
--- a/providers/web/gda-web-provider.c
+++ b/providers/web/gda-web-provider.c
@@ -1197,6 +1197,8 @@ gtype_to_webtype (GType type)
                 return "text";
         if (type == G_TYPE_UINT)
                 return "integer";
+        if (type == GDA_TYPE_NULL)
+                return "text";
         if (type == G_TYPE_INVALID)
                 return "text";
 
diff --git a/providers/web/gda-web-recordset.c b/providers/web/gda-web-recordset.c
index b7217b5..046db82 100644
--- a/providers/web/gda-web-recordset.c
+++ b/providers/web/gda-web-recordset.c
@@ -206,8 +206,11 @@ gda_web_recordset_new (GdaConnection *cnc, GdaWebPStmt *ps, GdaSet *exec_params,
 									 gda_column_new ());
 		_GDA_PSTMT (ps)->tmpl_columns = g_slist_reverse (_GDA_PSTMT (ps)->tmpl_columns);
 
-		/* create prepared statement's types */
-		_GDA_PSTMT (ps)->types = g_new0 (GType, _GDA_PSTMT (ps)->ncols); /* all types are initialized to GDA_TYPE_NULL */
+		/* create prepared statement's types, all types are initialized to GDA_TYPE_NULL */
+		_GDA_PSTMT (ps)->types = g_new (GType, _GDA_PSTMT (ps)->ncols);
+		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			_GDA_PSTMT (ps)->types [i] = GDA_TYPE_NULL;
+
 		if (col_types) {
 			for (i = 0; ; i++) {
 				if (col_types [i] > 0) {
diff --git a/tests/data-model-errors.c b/tests/data-model-errors.c
index 171f36e..2510312 100644
--- a/tests/data-model-errors.c
+++ b/tests/data-model-errors.c
@@ -132,7 +132,7 @@ data_model_errors_init (DataModelErrors *model,
 			if (*arow->col0 == '-')
 				G_VALUE_TYPE (value) = G_MAXINT;
 			else {
-				g_value_init (value, G_TYPE_STRING);
+				gda_value_reset_with_type (value, G_TYPE_STRING);
 				g_value_set_string (value, arow->col0);
 			}
 		}
@@ -142,7 +142,7 @@ data_model_errors_init (DataModelErrors *model,
 			if (*arow->col1 == '-')
 				G_VALUE_TYPE (value) = G_MAXINT;
 			else {
-				g_value_init (value, G_TYPE_STRING);
+				gda_value_reset_with_type (value, G_TYPE_STRING);
 				g_value_set_string (value, arow->col1);
 			}
 		}
@@ -152,7 +152,7 @@ data_model_errors_init (DataModelErrors *model,
 			if (*arow->col2 == '-')
 				G_VALUE_TYPE (value) = G_MAXINT;
 			else {
-				g_value_init (value, G_TYPE_STRING);
+				gda_value_reset_with_type (value, G_TYPE_STRING);
 				g_value_set_string (value, arow->col2);
 			}
 		}
@@ -162,7 +162,7 @@ data_model_errors_init (DataModelErrors *model,
 			if (*arow->col3 == '-')
 				G_VALUE_TYPE (value) = G_MAXINT;
 			else {
-				g_value_init (value, G_TYPE_STRING);
+				gda_value_reset_with_type (value, G_TYPE_STRING);
 				g_value_set_string (value, arow->col3);
 			}
 		}
diff --git a/tests/multi-threading/check_wrapper.c b/tests/multi-threading/check_wrapper.c
index 63e2416..dab23fe 100644
--- a/tests/multi-threading/check_wrapper.c
+++ b/tests/multi-threading/check_wrapper.c
@@ -521,10 +521,8 @@ wrapper_callback (GdaThreadWrapper *wrapper, gpointer instance, const gchar *sig
 	for (i = 0; i < n_param_values; i++) {
 		GValue *dest = ts->param_values + i;
 		const GValue *src = param_values + i;
-		if (G_VALUE_TYPE (src) != GDA_TYPE_NULL) {
-			g_value_init (dest, G_VALUE_TYPE (src));
-			g_value_copy (src, dest);
-		}
+		g_value_init (dest, G_VALUE_TYPE (src));
+		g_value_copy (src, dest);
 	}
 	*sig_list = g_slist_append (*sig_list, ts);
 }
diff --git a/tests/value-holders/common.c b/tests/value-holders/common.c
index 28da9f6..4bde198 100644
--- a/tests/value-holders/common.c
+++ b/tests/value-holders/common.c
@@ -392,11 +392,12 @@ gboolean
 tests_common_check_set (GHashTable *data, const gchar *id, GdaSet *set, GError **error)
 {
 	gchar *s;
-	const gchar *got;
+	const gchar *got = NULL;
 
 	s = tests_common_set_serialize (set);
 	
-	got = g_hash_table_lookup (data, id);
+	if (id)
+		got = g_hash_table_lookup (data, id);
 	if (!got) {
 #ifdef HAVE_JSON_GLIB
 		JsonParser *jparser;



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