diff --git a/libgda/gda-data-model.c b/libgda/gda-data-model.c
index 0ac0b04..3b23be1 100644
--- a/libgda/gda-data-model.c
+++ b/libgda/gda-data-model.c
@@ -2308,16 +2308,16 @@ real_gda_data_model_dump_as_string (GdaDataModel *model, gboolean dump_attribute
 				else {
 					str = NULL;
 					if (null_as_empty) {
-						if (!value || gda_value_is_null (value))
+						if (gda_value_is_null (value))
 							str = g_strdup ("");
 					}
 					if (!str)
-						str = value ? gda_value_stringify ((GValue*)value) : g_strdup ("_null_");
+        				str = gda_value_stringify ((GValue*)value);
 					if (str) {
 						gint w;
-						string_get_dimensions (str, &w, NULL);
-						cols_size [i + col_offset] = MAX (cols_size [i + col_offset], w);
-						g_free (str);
+					    string_get_dimensions (str, &w, NULL);
+					    cols_size [i + col_offset] = MAX (cols_size [i + col_offset], w);
+					    g_free(str);			
 					}
 				}
 			}
diff --git a/libgda/gda-holder.c b/libgda/gda-holder.c
index 4db44d5..82511bb 100644
--- a/libgda/gda-holder.c
+++ b/libgda/gda-holder.c
@@ -32,7 +32,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 
@@ -575,7 +574,7 @@ gda_holder_set_property (GObject *object,
 			gda_holder_set_attribute_static (holder, GDA_ATTRIBUTE_DESCRIPTION, value);
 			break;
 		case PROP_GDA_TYPE:
-			if (holder->priv->g_type == GDA_TYPE_NULL) {
+			if (holder->priv->g_type == G_TYPE_INVALID) {
 				holder->priv->g_type = g_value_get_gtype (value);
 				g_object_notify ((GObject*) holder, "g-type");
 			}
@@ -589,11 +588,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_is_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_is_null (holder->priv->value)))
 					holder->priv->valid = FALSE;
 				
 				g_signal_emit (holder, gda_holder_signals[CHANGED], 0);
@@ -772,7 +771,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_is_null (current_val))
                 return NULL;
         else {
                 if (!dh)
@@ -924,11 +923,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_is_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_is_null ((GValue *)current_val)) && newnull)
 		changed = FALSE;
 	else if (value && current_val &&
 		 (G_VALUE_TYPE (value) == G_VALUE_TYPE ((GValue *)current_val)))
@@ -1058,11 +1057,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_is_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_is_null (current_val)) && newnull) 
 		changed = FALSE;
 	else if (value && current_val &&
 		 (G_VALUE_TYPE (value) == G_VALUE_TYPE (current_val))) 
@@ -1386,8 +1385,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_is_null (value) &&
+		    (!current || gda_value_is_null (current)))
 			holder->priv->default_forced = TRUE;
 		else if ((G_VALUE_TYPE (value) == holder->priv->g_type) &&
 			 current && !gda_value_compare (value, current))
@@ -1671,12 +1670,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_is_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_is_null ((GValue*)cvalue))
 		value1 = gda_value_copy ((GValue*)cvalue);
 		
 	
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index 7562d11..cbefc2d 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -251,6 +251,94 @@ set_from_string (GValue *value, const gchar *as_string)
 }
 
 /* 
+ * Register the GdaNull 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. A string to null is always null. */
+}
+
+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_take_string(dest, g_strdup("_null_"));
+}
+
+static gpointer
+gda_null_copy (gpointer boxed)
+{
+	return (gpointer)g_new0(GdaNull, 1);
+}
+
+static void
+gda_null_free (gpointer boxed)
+{
+	g_free (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;
+}
+
+
+/**
+ * gda_value_set_null:
+ * @value: a #GValue that will store a #GdaNull.
+ *
+ * Resets @value and set it to a #GDA_TYPE_NULL representing a NULL in the database.
+ */
+void
+gda_value_set_null (GValue *value)
+{
+	g_return_if_fail (value);
+
+	gda_value_reset_with_type(value, GDA_TYPE_NULL);
+	g_value_set_boxed(value, g_new0(GdaNull, 1));
+}
+
+/**
+ * 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 ()
+{
+	GValue *value;
+	value = gda_value_new(GDA_TYPE_NULL);
+	g_value_set_boxed(value, g_new0(GdaNull, 1));
+	return value;
+}
+
+/* 
  * Register the GdaBinary type in the GType system 
  */
 
@@ -1385,10 +1473,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)
-			return;
-		else
-			g_value_init (value, type);
+		g_value_init (value, type);
 	}
 }
 
@@ -1406,7 +1491,7 @@ gboolean
 gda_value_is_null (const GValue *value)
 {
 	g_return_val_if_fail (value, FALSE);
-	return !G_IS_VALUE (value);
+	return GDA_VALUE_HOLDS_NULL (value);
 }
 
 /**
@@ -1643,20 +1728,6 @@ gda_value_set_list (GValue *value, const GdaValueList *val)
 }
 
 /**
- * gda_value_set_null:
- * @value: a #GValue that will store a value of type #GDA_TYPE_NULL.
- *
- * Sets the type of @value to #GDA_TYPE_NULL.
- */
-void
-gda_value_set_null (GValue *value)
-{
-	g_return_if_fail (value);
-
-	l_g_value_unset (value);
-}
-
-/**
  * gda_value_get_numeric
  * @value: a #GValue whose value we want to get.
  *
@@ -1861,7 +1932,9 @@ gda_value_set_from_string (GValue *value,
  * Sets the value of a #GValue from another #GValue. This
  * is different from #gda_value_copy, which creates a new #GValue.
  * #gda_value_set_from_value, on the other hand, copies the contents
- * of @copy into @value, which must already be allocated.
+ * 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.
  *
  * Returns: %TRUE if successful, %FALSE otherwise.
  */
@@ -1902,61 +1975,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);
-				}
+	g_return_val_if_fail(value, 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");
-			}
-			else if (type == GDA_TYPE_LIST) {
-				const GdaValueList *list;
-				const GList *ptr;
-				GString *string;
-				gchar *tmp;
-
-				string = g_string_new ("[");
-				list = gda_value_get_list (value);
-				for (ptr = list; ptr; ptr = ptr->next) {
-					tmp = gda_value_stringify ((GValue *) ptr->data);
-					if (ptr != list)
-						g_string_append_c (string, ',');
-					g_string_append (string, tmp);
-					g_free (tmp);
-				}
-				g_string_append_c (string, ']');
-				tmp = string->str;
-				g_string_free (string, FALSE);
-				return tmp;
+					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");
 }
 	
 /**
diff --git a/libgda/gda-value.h b/libgda/gda-value.h
index ac1d5d5..67c979a 100644
--- a/libgda/gda-value.h
+++ b/libgda/gda-value.h
@@ -37,7 +37,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())
@@ -50,6 +50,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)
@@ -60,6 +61,17 @@ G_BEGIN_DECLS
 #define GDA_VALUE_HOLDS_TIME(value)            G_VALUE_HOLDS(value, GDA_TYPE_TIME)
 #define GDA_VALUE_HOLDS_TIMESTAMP(value)       G_VALUE_HOLDS(value, GDA_TYPE_TIMESTAMP)
 
+/**
+ * GdaNull:
+ * @value: (default 0): an #uint8 setted always to cero. This value is useless for any other purpose than to fill a content in this struct.
+ * 
+ * A dummy private struct to represent a NULL value in a database.
+ */
+typedef struct {
+    /*< private >*/
+	guint8 value;
+} GdaNull;
+
 typedef struct {
 	gdouble x;
 	gdouble y;
@@ -116,6 +128,7 @@ typedef GList GdaValueList;
 
 GValue                           *gda_value_new (GType type);
 
+GValue                           *gda_value_new_null();
 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);
@@ -127,8 +140,9 @@ 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); 
+void                              gda_value_set_null (GValue *value);
+
 gboolean                          gda_value_is_number (const GValue *value); 
 GValue                           *gda_value_copy (const GValue *value);
 
@@ -144,7 +158,6 @@ G_CONST_RETURN GdaGeometricPoint *gda_value_get_geometric_point (const GValue *v
 void                              gda_value_set_geometric_point (GValue *value, const GdaGeometricPoint *val);
 G_CONST_RETURN GdaValueList      *gda_value_get_list (const GValue *value);
 void                              gda_value_set_list (GValue *value, const GdaValueList *val);
-void                              gda_value_set_null (GValue *value);
 G_CONST_RETURN GdaNumeric        *gda_value_get_numeric (const GValue *value);
 void                              gda_value_set_numeric (GValue *value, const GdaNumeric *val);
 gshort                            gda_value_get_short (const GValue *value);
@@ -177,6 +190,8 @@ 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);
@@ -210,9 +225,6 @@ GType                             gda_value_list_get_type (void) G_GNUC_CONST;
 GType                             gda_short_get_type (void) G_GNUC_CONST;
 GType                             gda_ushort_get_type (void) G_GNUC_CONST;
 
-/* Helper macros */
-#define                           gda_value_new_null() (g_new0 (GValue, 1))
-
 G_END_DECLS
 
 #endif
diff --git a/libgda/sqlite/gda-sqlite-recordset.c b/libgda/sqlite/gda-sqlite-recordset.c
index 60bcab7..0d34d27 100644
--- a/libgda/sqlite/gda-sqlite-recordset.c
+++ b/libgda/sqlite/gda-sqlite-recordset.c
@@ -217,43 +217,47 @@ _gda_sqlite_recordset_new (GdaConnection *cnc, GdaSqlitePStmt *ps, GdaSet *exec_
 	g_assert (! ps->stmt_used);
         ps->stmt_used = TRUE;
         if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
-		/* create prepared statement's columns */
-		GSList *list;
-		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
-			_GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, 
-									 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 */
-		if (col_types) {
-			for (i = 0; ; i++) {
-				if (col_types [i] > 0) {
-					if (col_types [i] == G_TYPE_NONE)
-						break;
-					if (i >= _GDA_PSTMT (ps)->ncols)
-						g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i,
-							   _GDA_PSTMT (ps)->ncols - 1);
-					else 
-						_GDA_PSTMT (ps)->types [i] = col_types [i];
-				}
-			}
-		}
+		    /* create prepared statement's columns */
+		    GSList *list;
+		    for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
+			    _GDA_PSTMT (ps)->tmpl_columns = g_slist_prepend (_GDA_PSTMT (ps)->tmpl_columns, 
+									     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 */
+		    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) {
+					    if (col_types [i] == G_TYPE_NONE)
+						    break;
+					    if (i >= _GDA_PSTMT (ps)->ncols)
+						    g_warning (_("Column %d out of range (0-%d), ignoring its specified type"), i,
+							       _GDA_PSTMT (ps)->ncols - 1);
+					    else 
+						    _GDA_PSTMT (ps)->types [i] = col_types [i];
+				    }
+			    }
+		    }
 		
-		/* fill GdaColumn's data */
-		for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
-		     i < GDA_PSTMT (ps)->ncols; 
-		     i++, list = list->next) {
-			GdaColumn *column;
-			gint real_col = i + ps->nb_rowid_columns;
+		    /* fill GdaColumn's data */
+		    for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
+		         i < GDA_PSTMT (ps)->ncols; 
+		         i++, list = list->next) {
+			    GdaColumn *column;
+			    gint real_col = i + ps->nb_rowid_columns;
 			
-			column = GDA_COLUMN (list->data);
-			gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col));
-			gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col));
-			gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col));
-			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
-				gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]);
-		}
+			    column = GDA_COLUMN (list->data);
+			    gda_column_set_description (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col));
+			    gda_column_set_name (column, SQLITE3_CALL (sqlite3_column_name) (ps->sqlite_stmt, real_col));
+			    gda_column_set_dbms_type (column, SQLITE3_CALL (sqlite3_column_decltype) (ps->sqlite_stmt, real_col));
+			    if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
+				    gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]);
+		    }
         }
 
 	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported; if CURSOR BACKWARD
