[libgda] gda: added new GdaText for large strings



commit 55ae87243ad797cc6d79f5fa92054ead0b5ce85e
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date:   Tue Jan 15 14:44:00 2019 -0600

    gda: added new GdaText for large strings
    
    GdaText is a new boxed type to be used when you have
    large texts to load. Some providers, like MySQL, uses
    varchar(30) as default, if your string is larger,
    any update or insert will fail; in that cases we introduce
    a new 'text' type and providers support it now.

 .gitlab-ci.yml                             |   5 +-
 NEWS                                       |   5 +-
 libgda/gda-connection.c                    |  36 +++--
 libgda/gda-data-handler.c                  |   2 +
 libgda/gda-holder.c                        |  53 ++++---
 libgda/gda-init.c                          |   2 +
 libgda/gda-meta-store.c                    |   2 +-
 libgda/gda-server-provider.c               |   9 ++
 libgda/gda-util.c                          |   6 +-
 libgda/gda-value.c                         | 186 ++++++++++++++++++++--
 libgda/gda-value.h                         |  13 +-
 libgda/handlers/Makefile.am                |   2 +
 libgda/handlers/gda-handler-text.c         | 243 +++++++++++++++++++++++++++++
 libgda/handlers/gda-handler-text.h         |  54 +++++++
 libgda/handlers/meson.build                |   2 +
 libgda/information_schema.xml              |  22 +--
 libgda/meson.build                         |   1 -
 libgda/sqlite/gda-sqlite-provider.c        |   7 +
 libgda/sqlite/gda-sqlite-recordset.c       |   6 +
 providers/mysql/gda-mysql-provider.c       |   5 +-
 providers/postgres/gda-postgres-provider.c |   2 +
 providers/reuseable/mysql/gda-mysql-meta.c |   2 +-
 22 files changed, 600 insertions(+), 65 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 92e09eefd..8a7cd6d95 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -46,6 +46,9 @@ variables:
   POSTGRESQL_DBCREATE_PARAMS: "HOST=postgres;ADM_LOGIN=$POSTGRES_USER;ADM_PASSWORD=$POSTGRES_PASSWORD"
   POSTGRESQL_CNC_PARAMS: "HOST=postgres;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD"
   POSTGRESQL_META_CNC: 
"DB_NAME=$POSTGRES_DB;HOST=postgres;USERNAME=$POSTGRES_USER;PASSWORD=$POSTGRES_PASSWORD"
+  MYSQL_DBCREATE_PARAMS: "HOST=mysql;ADM_LOGIN=$MYSQL_USER;ADM_PASSWORD=$MYSQL_PASSWORD"
+  MYSQL_CNC_PARAMS: "HOST=mysql;USERNAME=$MYSQL_USER;PASSWORD=$MYSQL_PASSWORD"
+  MYSQL_META_CNC: "DB_NAME=$MYSQL_DB;HOST=mysql;USERNAME=$MYSQL_USER;PASSWORD=$MYSQL_PASSWORD"
   
 before_script:
   - apt update && apt -y install $DEPENDENCIES
@@ -160,4 +163,4 @@ pages:
   - mv doc/C/libgdaui/html public/C/libgdaui-6.0
   artifacts:
     paths:
-    - public
+    - public
\ No newline at end of file
diff --git a/NEWS b/NEWS
index 15789239b..de2792b30 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,12 @@
 libgda 5.91.0
+ - Added support for PostgreSQL version up to 11.0
+ - Added new GdaText type for large texts types support
+ - Added new GdaHandlerText type for large texts types handler support
+ - GdaHandler now supports value transformation, if possible, before set it
  - Ported almost all public API to use g_autoptr() and remove public private struct
  - Fixed segfaults
  - Fixed meta data generation engine
  - Fixed PostgresSQL provider meta data generation integration
- - Added support for PostgreSQL version up to 11.0
  - Fixed open connections to SQLite, PostgreSQL and MySQL providers
  - Blacklisted providers: FireBird, Oracle, Java ODBC, MS Access, BDB, LDAP, MySQL
  - Fixed warnings
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index cd4935004..980bbdee8 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -20,7 +20,7 @@
  * Copyright (C) 2008 Johannes Schmid <jschmid openismus com>
  * Copyright (C) 2010 David King <davidk openismus com>
  * Copyright (C) 2010 Jonh Wendell <jwendell gnome org>
- * Copyright (C) 2011, 2018 Daniel Espinosa <esodan gmail com>
+ * Copyright (C) 2011, 2018-2019 Daniel Espinosa <esodan gmail com>
  * Copyright (C) 2013 Miguel Angel Cabrera Moya <madmac2501 gmail com>
  * Copyright (C) 2014 Anders Jonsson <anders jonsson norsjovallen se>
  *
@@ -4410,19 +4410,27 @@ local_meta_update (GdaServerProvider *provider, GdaConnection *cnc, GdaMetaConte
                         *  -0- @specific_catalog, @specific_schema, @specific_name
                         *  -1- @specific_catalog, @specific_schema
                         */
-                       i = check_parameters (context, error, 2,
-                                             &catalog, G_TYPE_STRING,
-                                             &schema, G_TYPE_STRING,
-                                             &name, G_TYPE_STRING, NULL,
-                                             "specific_catalog", &catalog, "specific_schema", &schema, 
"specific_name", &name, NULL,
-                                             "specific_catalog", &catalog, "specific_schema", &schema, NULL);
-                       if (i < 0)
-                               return FALSE;
-                       
-                       ASSERT_TABLE_NAME (tname, "routines");
-                       retval = _gda_server_provider_meta_3arg (provider, cnc, store, context,
-                                                                GDA_SERVER_META_ROUTINES, catalog, schema, 
name, error);
-                       WARN_META_UPDATE_FAILURE (retval, "routines");
+                       if (gda_meta_context_get_n_columns (context) == 0) {
+                               ASSERT_TABLE_NAME (tname, "routines");
+                               retval = _gda_server_provider_meta_0arg (provider, cnc, store, context,
+                                                                        GDA_SERVER_META__ROUTINES, error);
+                               WARN_META_UPDATE_FAILURE (retval, "routines");
+                       } else {
+                               i = check_parameters (context, error, 2,
+                                                           &catalog, G_TYPE_STRING,
+                                                           &schema, G_TYPE_STRING,
+                                                           &name, G_TYPE_STRING, NULL,
+                                                           "specific_catalog", &catalog, "specific_schema", 
&schema, "specific_name", &name, NULL,
+                                                           "specific_catalog", &catalog, "specific_schema", 
&schema, NULL);
+                               if (i < 0)
+                                       return FALSE;
+
+                               ASSERT_TABLE_NAME (tname, "routines");
+                               retval = _gda_server_provider_meta_3arg (provider, cnc, store, context,
+                                                                        GDA_SERVER_META_ROUTINES, catalog, 
schema, name, error);
+                               WARN_META_UPDATE_FAILURE (retval, "routines");
+                       }
+
                        return retval;
                }
                else {
diff --git a/libgda/gda-data-handler.c b/libgda/gda-data-handler.c
index 1757d4a5f..3fb265140 100644
--- a/libgda/gda-data-handler.c
+++ b/libgda/gda-data-handler.c
@@ -27,6 +27,7 @@
 #include "handlers/gda-handler-boolean.h"
 #include "handlers/gda-handler-numerical.h"
 #include "handlers/gda-handler-string.h"
+#include "handlers/gda-handler-text.h"
 #include "handlers/gda-handler-time.h"
 #include "handlers/gda-handler-type.h"
 
@@ -291,6 +292,7 @@ gda_data_handler_get_default (GType for_type)
                 g_hash_table_insert (hash, (gpointer) GDA_TYPE_SHORT, gda_handler_numerical_new ());
                 g_hash_table_insert (hash, (gpointer) GDA_TYPE_USHORT, gda_handler_numerical_new ());
                 g_hash_table_insert (hash, (gpointer) G_TYPE_STRING, gda_handler_string_new ());
+                g_hash_table_insert (hash, (gpointer) GDA_TYPE_TEXT, gda_handler_text_new ());
                 g_hash_table_insert (hash, (gpointer) GDA_TYPE_TIME, gda_handler_time_new ());
                 g_hash_table_insert (hash, (gpointer) G_TYPE_DATE_TIME, gda_handler_time_new ());
                 g_hash_table_insert (hash, (gpointer) G_TYPE_CHAR, gda_handler_numerical_new ());
diff --git a/libgda/gda-holder.c b/libgda/gda-holder.c
index 3bec9913e..4c69a832e 100644
--- a/libgda/gda-holder.c
+++ b/libgda/gda-holder.c
@@ -947,6 +947,7 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
        const GValue *current_val;
        gboolean newnull;
        gboolean was_valid;
+       GValue *new_value = NULL;
 #define DEBUG_HOLDER
 #undef DEBUG_HOLDER
 
@@ -961,17 +962,27 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
                g_warning (_("Can't use this method to set value because there is already a static value"));
                return FALSE;
        }
-               
+       // If value's type is compatible to current holder's value's type transform it
+       if (value && priv->g_type != G_VALUE_TYPE (value)
+          && g_value_type_transformable (G_VALUE_TYPE (value), priv->g_type))
+       {
+               new_value = gda_value_new (priv->g_type);
+               g_value_transform (value, new_value);
+               if (!do_copy && value)
+                       gda_value_free (value);
+       } else {
+               new_value = value;
+       }
        /* holder will be changed? */
-       newnull = !value || GDA_VALUE_HOLDS_NULL (value);
+       newnull = !new_value || GDA_VALUE_HOLDS_NULL (new_value);
        current_val = gda_holder_get_value (holder);
-       if (current_val == value)
+       if (current_val == new_value)
                changed = FALSE;
        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)))
-               changed = gda_value_differ (value, (GValue *)current_val);
+       else if (new_value && current_val &&
+                (G_VALUE_TYPE (new_value) == G_VALUE_TYPE ((GValue *)current_val)))
+               changed = gda_value_differ (new_value, (GValue *)current_val);
                
        /* holder's validity */
        newvalid = TRUE;
@@ -982,12 +993,12 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
                newvalid = FALSE;
                changed = TRUE;
        }
-       else if (!newnull && (G_VALUE_TYPE (value) != priv->g_type)) {
+       else if (!newnull && (G_VALUE_TYPE (new_value) != priv->g_type)) {
                g_set_error (error, GDA_HOLDER_ERROR, GDA_HOLDER_VALUE_TYPE_ERROR,
                             _("(%s): Wrong Holder value type, expected type '%s' when value's type is '%s'"),
                             priv->id,
                             gda_g_type_to_string (priv->g_type),
-                            gda_g_type_to_string (G_VALUE_TYPE (value)));
+                            gda_g_type_to_string (G_VALUE_TYPE (new_value)));
                newvalid = FALSE;
                changed = TRUE;
        }
@@ -999,16 +1010,16 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
        g_print ("Holder to change %p (%s): value %s --> %s \t(type %d -> %d) VALID: %d->%d CHANGED: %d\n", 
                 holder, priv->id,
                 gda_value_stringify ((GValue *)current_val),
-                gda_value_stringify ((value)),
+                gda_value_stringify ((new_value)),
                 current_val ? G_VALUE_TYPE ((GValue *)current_val) : 0,
-                value ? G_VALUE_TYPE (value) : 0, 
+                new_value ? G_VALUE_TYPE (new_value) : 0,
                 was_valid, newvalid, changed);
 #endif
 
        /* end of procedure if the value has not been changed, after calculating the holder's validity */
        if (!changed) {
-               if (!do_copy && value)
-                       gda_value_free (value);
+               if (!do_copy && new_value)
+                       gda_value_free (new_value);
                priv->invalid_forced = FALSE;
                if (priv->invalid_error) {
                        g_error_free (priv->invalid_error);
@@ -1022,7 +1033,7 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
        /* check if we are allowed to change value */
        if (priv->validate_changes) {
                GError *lerror = NULL;
-               g_signal_emit (holder, gda_holder_signals[VALIDATE_CHANGE], 0, value, &lerror);
+               g_signal_emit (holder, gda_holder_signals[VALIDATE_CHANGE], 0, new_value, &lerror);
                if (lerror) {
                        /* change refused by signal callback */
 #ifdef DEBUG_HOLDER
@@ -1031,7 +1042,7 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
 #endif
                        g_propagate_error (error, lerror);
                        if (!do_copy) 
-                               gda_value_free (value);
+                               gda_value_free (new_value);
                        gda_holder_unlock ((GdaLockable*) holder);
                        return FALSE;
                }
@@ -1053,8 +1064,8 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
                if ((G_VALUE_TYPE (priv->default_value) == GDA_TYPE_NULL) && newnull)
                        priv->default_forced = TRUE;
                else if ((G_VALUE_TYPE (priv->default_value) == priv->g_type) &&
-                        value && (G_VALUE_TYPE (value) == priv->g_type))
-                       priv->default_forced = !gda_value_compare (priv->default_value, value);
+                        new_value && (G_VALUE_TYPE (new_value) == priv->g_type))
+                       priv->default_forced = !gda_value_compare (priv->default_value, new_value);
        }
        GValue att_value = {0};
        g_value_init (&att_value, G_TYPE_BOOLEAN);
@@ -1068,7 +1079,7 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
                         holder, priv->full_bind, priv->full_bind);
 #endif
                gda_holder_unlock ((GdaLockable*) holder);
-               return real_gda_holder_set_value (priv->full_bind, value, do_copy, error);
+               return real_gda_holder_set_value (priv->full_bind, new_value, do_copy, error);
        }
        else {
                if (priv->value) {
@@ -1076,15 +1087,15 @@ real_gda_holder_set_value (GdaHolder *holder, GValue *value, gboolean do_copy, G
                        priv->value = NULL;
                }
 
-               if (value) {
+               if (new_value) {
                        if (newvalid) {
                                if (do_copy)
-                                       priv->value = gda_value_copy (value);
+                                       priv->value = gda_value_copy (new_value);
                                else
-                                       priv->value = value;
+                                       priv->value = new_value;
                        }
                        else if (!do_copy) 
-                               gda_value_free (value);
+                               gda_value_free (new_value);
                }
 
                gda_holder_unlock ((GdaLockable*) holder);
diff --git a/libgda/gda-init.c b/libgda/gda-init.c
index 1d75a1723..3083a5b07 100644
--- a/libgda/gda-init.c
+++ b/libgda/gda-init.c
@@ -167,6 +167,8 @@ gda_init (void)
        g_assert (type);
        type = GDA_TYPE_TIME;
        g_assert (type);
+       type = GDA_TYPE_TEXT;
+       g_assert (type);
        type = G_TYPE_DATE;
        g_assert (type);
        type = G_TYPE_DATE_TIME;
diff --git a/libgda/gda-meta-store.c b/libgda/gda-meta-store.c
index 2673e4ffc..2c2001da9 100644
--- a/libgda/gda-meta-store.c
+++ b/libgda/gda-meta-store.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2008 - 2015 Vivien Malerba <malerba gnome-db org>
  * Copyright (C) 2010 David King <davidk openismus com>
  * Copyright (C) 2010 Jonh Wendell <jwendell gnome org>
- * Copyright (C) 2011 - 2013 Daniel Espinosa <esodan gmail com>
+ * Copyright (C) 2011 - 2013, 2018-2019 Daniel Espinosa <esodan gmail com>
  * Copyright (C) 2013 Carl-Anton Ingmarsson <ca ingmarsson gmail com>
  * Copyright (C) 2013 Miguel Angel Cabrera Moya <madmac2501 gmail com>
  * Copyright (C) 2015 Corentin Noël <corentin elementary io>
diff --git a/libgda/gda-server-provider.c b/libgda/gda-server-provider.c
index ceaa797a9..36ca26a8d 100644
--- a/libgda/gda-server-provider.c
+++ b/libgda/gda-server-provider.c
@@ -51,6 +51,7 @@
 #include <libgda/gda-debug-macros.h>
 #include <libgda/handlers/gda-handler-boolean.h>
 #include <libgda/handlers/gda-handler-string.h>
+#include <libgda/handlers/gda-handler-text.h>
 #include <libgda/handlers/gda-handler-type.h>
 #include <libgda/handlers/gda-handler-numerical.h>
 #include "providers-support/gda-data-select-priv.h"
@@ -4094,6 +4095,14 @@ gda_server_provider_handler_use_default (GdaServerProvider *provider, GType type
                        g_object_unref (dh);
                }
        }
+       else if (type == GDA_TYPE_TEXT) {
+               dh = gda_server_provider_handler_find (provider, NULL, type, NULL);
+               if (!dh) {
+                       dh = gda_handler_text_new ();
+                       gda_server_provider_handler_declare (provider, dh, NULL, GDA_TYPE_TEXT, NULL);
+                       g_object_unref (dh);
+               }
+       }
        else if (type == G_TYPE_GTYPE) {
                dh = gda_server_provider_handler_find (provider, NULL, type, NULL);
                if (!dh) {
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index 448969425..fe4256f10 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -93,7 +93,7 @@ gda_g_type_to_string (GType type)
                return "date";                  
        else if (type == GDA_TYPE_TIME)
                return "time";
-       else if (g_type_is_a (type, G_TYPE_DATE_TIME))
+       else if (type == G_TYPE_DATE_TIME)
                return "timestamp";
        else if (type == G_TYPE_BOOLEAN)
                return "boolean";
@@ -101,6 +101,8 @@ gda_g_type_to_string (GType type)
                return "blob";
        else if (type == GDA_TYPE_BINARY)
                return "binary";
+       else if (type == GDA_TYPE_TEXT)
+               return "text";
   else
                return g_type_name (type);
 }
@@ -148,6 +150,8 @@ gda_g_type_from_string (const gchar *str)
                        type = G_TYPE_UINT;
                else if (!g_ascii_strcasecmp (str, "string"))
                        type = G_TYPE_STRING;
+               else if (!g_ascii_strcasecmp (str, "text"))
+                       type = GDA_TYPE_TEXT;
                else if (!g_ascii_strcasecmp (str, "date"))
                        type = G_TYPE_DATE;
                else if (!g_ascii_strcasecmp (str, "time"))
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index 0271969c4..2c61e1f91 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -329,14 +329,6 @@ gda_null_get_type (void)
                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;
@@ -398,6 +390,139 @@ gda_default_get_type (void)
        return type;
 }
 
+// Declare GDA_TYPE_TEXT
+
+struct _GdaText {
+       gchar *str;
+};
+
+/**
+ * gda_text_new:
+ *
+ * Creates a new #GdaText object, initialy with no string.
+ * Use #gda_text_set_string() to set a string to.
+ *
+ * Returns: (transfer full): a new #GdaText object
+ */
+GdaText*
+gda_text_new () {
+       GdaText *t = g_new0 (GdaText, 1);
+       t->str = NULL;
+       return t;
+}
+
+
+/**
+ * gda_text_free:
+ * @text: a #GdaText object
+ *
+ * Free resources on #GdaText object.
+ */
+void
+gda_text_free (GdaText *text)
+{
+       g_return_if_fail (text);
+       if (text->str != NULL) {
+               g_free (text);
+       }
+}
+
+/**
+ * gda_text_get_string:
+ * @text: a #GdaText object
+ *
+ * Returns: (transfer none): a string represented by #GdaText
+ */
+const gchar*
+gda_text_get_string (GdaText *text) {
+       return (const gchar*) text->str;
+}
+
+/**
+ * gda_text_set_string:
+ * @text: a #GdaText object
+ * @str: a string to set from
+ *
+ * Set string. The string is duplicated.
+ */
+void
+gda_text_set_string (GdaText *text, const gchar *str) {
+  g_return_if_fail (text);
+  if (text->str != NULL) {
+    g_free (text->str);
+  }
+  if (str != NULL) {
+    text->str = g_strdup (str);
+  } else {
+    text->str = NULL;
+  }
+}
+
+/**
+ * gda_text_take_string:
+ * @text: a #GdaText object
+ * @str: a string to take ownership on
+ *
+ * Takes ownership on a given string, so you don't need to free it.
+ */
+void
+gda_text_take_string (GdaText *text, gchar *str) {
+  g_return_if_fail (text);
+  if (text->str != NULL) {
+    g_free (text->str);
+  }
+  text->str = NULL;
+}
+static void
+string_to_text (const GValue *src, GValue *dest)
+{
+       GdaText *t;
+
+       g_return_if_fail (G_VALUE_HOLDS_STRING (src) && GDA_VALUE_HOLDS_TEXT (dest));
+
+       t = gda_text_new ();
+       if (t->str) {
+               g_free (t->str);
+       }
+       gda_text_set_string (t, g_value_get_string (src));
+       g_value_take_boxed (dest, t);
+}
+
+static void
+text_to_string (const GValue *src, GValue *dest)
+{
+       g_return_if_fail (G_VALUE_HOLDS_STRING (dest) && GDA_VALUE_HOLDS_TEXT (src));
+
+       GdaText *text;
+
+       text = (GdaText*) g_value_get_boxed (src);
+       if (text != NULL) {
+               g_value_set_string (dest, gda_text_get_string (text));
+       } else {
+               g_value_set_string (dest, NULL);
+       }
+}
+
+static GdaText*
+gda_text_copy (GdaText *boxed)
+{
+       GdaText *t = gda_text_new ();
+       t->str = g_strdup (boxed->str);
+       return t;
+}
+
+static void
+register_transformation_func (GType type) {
+       g_value_register_transform_func (G_TYPE_STRING,
+                                        type,
+                                        string_to_text);
+       g_value_register_transform_func (type,
+                                        G_TYPE_STRING,
+                                        text_to_string);
+}
+
+G_DEFINE_BOXED_TYPE_WITH_CODE(GdaText, gda_text, gda_text_copy, gda_text_free,
+                               register_transformation_func(g_define_type_id))
 
 // GdaBinary
 
@@ -2702,6 +2827,14 @@ gda_value_stringify (const GValue *value)
     GDateTime *ts;
     ts = (GDateTime*) g_value_get_boxed (value);
     return g_date_time_format (ts, "%FT%H:%M:%S%:::z");
+  }
+  else if (g_type_is_a (type, GDA_TYPE_NULL)) {
+    return g_strdup ("NULL");
+  }
+  else if (g_type_is_a (type, GDA_TYPE_TEXT)) {
+    GdaText *text;
+    text = (GdaText*) g_value_get_boxed (value);
+    return g_strdup (gda_text_get_string (text));
   }
        else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) {
                GValue *string;
@@ -2826,7 +2959,19 @@ gda_value_differ (const GValue *value1, const GValue *value2)
                str1 = g_value_get_string (value1);
                str2 = g_value_get_string (value2);
                if (str1 && str2)
-                       return strcmp (str1, str2);
+                       return g_strcmp0 (str1, str2);
+               return 1;
+       }
+
+       else if (type == GDA_TYPE_TEXT) {
+               GdaText *t1, *t2;
+               const gchar *str1, *str2;
+               t1 = g_value_get_boxed (value1);
+               t2 = g_value_get_boxed (value2);
+               str1 = gda_text_get_string (t1);
+               str2 = gda_text_get_string (t2);
+               if (str1 && str2)
+                       return g_strcmp0 (str1, str2);
                return 1;
        }
 
@@ -3108,6 +3253,29 @@ gda_value_compare (const GValue *value1, const GValue *value2)
                return retval;
        }
 
+       else if (type == GDA_TYPE_TEXT) {
+               GdaText *t1, *t2;
+               t1 = g_value_get_boxed (value1);
+               t2 = g_value_get_boxed (value2);
+               const gchar *str1, *str2;
+               str1 = gda_text_get_string (t1);
+               str2 = gda_text_get_string (t2);
+               if (str1 && str2)
+                       retval = g_strcmp0 (str1, str2);
+               else {
+                       if (str1)
+                               return 1;
+                       else {
+                               if (str2)
+                                       return -1;
+                               else
+                                       return 0;
+                       }
+               }
+
+               return retval;
+       }
+
        else if (type == GDA_TYPE_TIME) {
                const GdaTime *t1, *t2;
                t1 = gda_value_get_time (value1);
diff --git a/libgda/gda-value.h b/libgda/gda-value.h
index f3ab10154..8fff3c605 100644
--- a/libgda/gda-value.h
+++ b/libgda/gda-value.h
@@ -48,7 +48,7 @@ G_BEGIN_DECLS
 #define        GDA_TYPE_SHORT (gda_short_get_type()) 
 #define        GDA_TYPE_USHORT (gda_ushort_get_type())
 #define GDA_TYPE_TIME (gda_time_get_type())
-
+#define GDA_TYPE_TEXT (gda_text_get_type())
 
 /* Definition of the GDA_VALUE_HOLDS macros */
 #define GDA_VALUE_HOLDS_NULL(value)            G_VALUE_HOLDS(value, GDA_TYPE_NULL)
@@ -58,7 +58,18 @@ G_BEGIN_DECLS
 #define GDA_VALUE_HOLDS_SHORT(value)           G_VALUE_HOLDS(value, GDA_TYPE_SHORT)
 #define GDA_VALUE_HOLDS_USHORT(value)          G_VALUE_HOLDS(value, GDA_TYPE_USHORT)
 #define GDA_VALUE_HOLDS_TIME(value)            G_VALUE_HOLDS(value, GDA_TYPE_TIME)
+#define GDA_VALUE_HOLDS_TEXT(value)            G_VALUE_HOLDS(value, GDA_TYPE_TEXT)
+
+/* GdaText */
+
+typedef struct _GdaText GdaText;
 
+GType                             gda_text_get_type (void) G_GNUC_CONST;
+GdaText                          *gda_text_new ();
+void                              gda_text_free (GdaText *text);
+const gchar                      *gda_text_get_string (GdaText *text);
+void                              gda_text_set_string (GdaText *text, const gchar *str);
+void                              gda_text_take_string (GdaText *text, gchar *str);
 
 /* GdaNumeric */
 typedef struct _GdaNumeric GdaNumeric;
diff --git a/libgda/handlers/Makefile.am b/libgda/handlers/Makefile.am
index 9852f7ecc..cf2bc1f4b 100644
--- a/libgda/handlers/Makefile.am
+++ b/libgda/handlers/Makefile.am
@@ -12,6 +12,7 @@ libgda_handlers_headers = \
        gda-handler-numerical.h \
        gda-handler-string.h \
        gda-handler-time.h \
+       gda-handler-text.h \
        gda-handler-type.h
 
 
libgda_handlersincludedir=$(includedir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)/libgda/handlers
@@ -23,5 +24,6 @@ libgda_handlers_6_0_la_SOURCES = \
        gda-handler-boolean.c \
        gda-handler-numerical.c \
        gda-handler-string.c \
+       gda-handler-text.c \
        gda-handler-time.c \
        gda-handler-type.c
diff --git a/libgda/handlers/gda-handler-text.c b/libgda/handlers/gda-handler-text.c
new file mode 100644
index 000000000..f1426e2ca
--- /dev/null
+++ b/libgda/handlers/gda-handler-text.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2019 Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "gda-handler-text.h"
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <libgda/gda-util.h>
+#include <libgda/gda-server-provider.h>
+
+typedef struct
+{
+  GWeakRef cnc;
+} GdaHandlerTextPrivate;
+
+static void data_handler_iface_init (GdaDataHandlerInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(GdaHandlerText, gda_handler_text, G_TYPE_OBJECT,
+                         G_ADD_PRIVATE(GdaHandlerText)
+                         G_IMPLEMENT_INTERFACE (GDA_TYPE_DATA_HANDLER, data_handler_iface_init))
+
+/**
+ * gda_handler_text_new:
+ *
+ * Creates a data handler for large strings
+ *
+ * Returns: (transfer full): the new object
+ */
+GdaDataHandler*
+gda_handler_text_new (void)
+{
+  GObject *obj;
+
+  obj = g_object_new (GDA_TYPE_HANDLER_TEXT, NULL);
+
+  return (GdaDataHandler *) obj;
+}
+
+/**
+ * gda_handler_text_new_with_connection:
+ * @cnc: (nullable): a #GdaConnection object
+ *
+ * Creates a data handler for strings, which will use some specific methods implemented
+ * by the provider object associated with @cnc.
+ *
+ * Returns: (type GdaHandlerText) (transfer full): the new object
+ */
+GdaDataHandler *
+gda_handler_text_new_with_connection (GdaConnection *cnc)
+{
+  GObject *obj;
+  GdaHandlerText *dh;
+
+  g_return_val_if_fail (cnc != NULL, NULL);
+
+  obj = g_object_new (GDA_TYPE_HANDLER_TEXT, NULL);
+  dh = (GdaHandlerText*) obj;
+
+  GdaHandlerTextPrivate *priv = gda_handler_text_get_instance_private (dh);
+
+  g_weak_ref_set (&priv->cnc, cnc);
+
+  return (GdaDataHandler *) obj;
+}
+
+static gchar *
+gda_handler_text_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
+{
+  g_return_val_if_fail (GDA_IS_HANDLER_TEXT (iface), NULL);
+  g_return_val_if_fail (value != NULL, NULL);
+
+  gchar *str, *retval;
+  GdaHandlerText *hdl;
+  GdaConnection *cnc;
+
+  hdl = (GdaHandlerText*) (iface);
+
+  GdaHandlerTextPrivate *priv = gda_handler_text_get_instance_private (hdl);
+
+  str = gda_value_stringify ((GValue *) value);
+  if (str) {
+    gchar *str2;
+    cnc = g_weak_ref_get (&priv->cnc);
+    if (cnc != NULL) {
+      str2 = gda_server_provider_escape_string (gda_connection_get_provider (cnc), cnc, str);
+    } else {
+      str2 = gda_default_escape_string (str);
+    }
+    retval = g_strdup_printf ("'%s'", str2);
+    g_free (str2);
+    g_free (str);
+  } else {
+    retval = g_strdup ("NULL");
+  }
+
+  return retval;
+}
+
+static gchar *
+gda_handler_text_get_str_from_value (G_GNUC_UNUSED GdaDataHandler *iface, const GValue *value)
+{
+  g_assert (value);
+  return gda_value_stringify ((GValue *) value);
+}
+
+static GValue *
+gda_handler_text_get_value_from_sql (GdaDataHandler *iface, const gchar *sql, G_GNUC_UNUSED GType type)
+{
+  GValue *value = NULL;
+
+  g_return_val_if_fail (iface != NULL, NULL);
+  g_return_val_if_fail (GDA_IS_HANDLER_TEXT (iface), NULL);
+  g_return_val_if_fail (g_utf8_validate (sql, -1, NULL), NULL);
+
+  if (sql != NULL) {
+    gchar *unstr = NULL;
+    if (g_str_has_prefix (sql, "'") && g_str_has_suffix (sql, "'")) {
+      glong len = g_utf8_strlen (sql, -1);
+      unstr = g_utf8_substring (sql, 1, len - 1);
+    } else {
+      unstr = g_strdup (sql);
+    }
+    GdaText *text = gda_text_new ();
+    gda_text_set_string (text, unstr);
+    value = gda_value_new (GDA_TYPE_TEXT);
+    g_value_take_boxed (value, text);
+    g_free (unstr);
+  }
+  else
+    value = gda_value_new_null ();
+
+  return value;
+}
+
+static GValue *
+gda_handler_text_get_value_from_str (G_GNUC_UNUSED GdaDataHandler *iface, const gchar *str, G_GNUC_UNUSED 
GType type)
+{
+  GValue *value;
+
+  GdaText *text = gda_text_new ();
+  gda_text_set_string (text, str);
+  value = gda_value_new (GDA_TYPE_TEXT);
+  g_value_take_boxed (value, text);
+
+  return value;
+}
+
+static GValue *
+gda_handler_text_get_sane_init_value (G_GNUC_UNUSED GdaDataHandler *iface, G_GNUC_UNUSED GType type)
+{
+  GValue *value;
+
+  GdaText *text = gda_text_new ();
+  gda_text_set_string (text, "");
+  value = gda_value_new (GDA_TYPE_TEXT);
+  g_value_take_boxed (value, text);
+
+  return value;
+}
+
+static gboolean
+gda_handler_text_accepts_g_type (GdaDataHandler *iface, GType type)
+{
+  g_return_val_if_fail (iface != NULL, FALSE);
+
+  gboolean ret = FALSE;
+
+  if (g_type_is_a (type, GDA_TYPE_TEXT)) {
+    ret = TRUE;
+  } else if (g_type_is_a (type, G_TYPE_STRING)) {
+    ret = TRUE;
+  } else if (g_value_type_compatible (type, GDA_TYPE_TEXT)) {
+    ret = TRUE;
+  }
+  return ret;
+}
+
+static const gchar *
+gda_handler_text_get_descr (GdaDataHandler *iface)
+{
+  g_return_val_if_fail (GDA_IS_HANDLER_TEXT (iface), NULL);
+  return g_object_get_data (G_OBJECT (iface), "descr");
+}
+
+static void
+gda_handler_text_init (GdaHandlerText * hdl)
+{
+  GdaHandlerTextPrivate *priv = gda_handler_text_get_instance_private (hdl);
+  g_weak_ref_init (&priv->cnc, NULL);
+  /* Handler support */
+  g_object_set_data (G_OBJECT (hdl), "name", _("InternalLargeString"));
+  g_object_set_data (G_OBJECT (hdl), "descr", _("Large String representation"));
+}
+
+static void
+gda_handler_text_dispose (GObject   *object)
+{
+  GdaHandlerText *hdl = (GdaHandlerText *) object;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GDA_IS_HANDLER_TEXT (object));
+
+  GdaHandlerTextPrivate *priv = gda_handler_text_get_instance_private (hdl);
+  g_weak_ref_clear (&priv->cnc);
+
+  /* for the parent class */
+  G_OBJECT_CLASS (gda_handler_text_parent_class)->dispose (object);
+}
+
+static void
+data_handler_iface_init (GdaDataHandlerInterface *iface)
+{
+       iface->get_sql_from_value = gda_handler_text_get_sql_from_value;
+       iface->get_str_from_value = gda_handler_text_get_str_from_value;
+       iface->get_value_from_sql = gda_handler_text_get_value_from_sql;
+       iface->get_value_from_str = gda_handler_text_get_value_from_str;
+       iface->get_sane_init_value = gda_handler_text_get_sane_init_value;
+       iface->accepts_g_type = gda_handler_text_accepts_g_type;
+       iface->get_descr = gda_handler_text_get_descr;
+}
+
+static void
+gda_handler_text_class_init (GdaHandlerTextClass * class)
+{
+       GObjectClass   *object_class = G_OBJECT_CLASS (class);
+
+       object_class->dispose = gda_handler_text_dispose;
+}
diff --git a/libgda/handlers/gda-handler-text.h b/libgda/handlers/gda-handler-text.h
new file mode 100644
index 000000000..e9fddabf2
--- /dev/null
+++ b/libgda/handlers/gda-handler-text.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 Daniel Espinosa <esodan gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __GDA_HANDLER_TEXT__
+#define __GDA_HANDLER_TEXT__
+
+#include <glib-object.h>
+#include <libgda/gda-data-handler.h>
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION:gda-handler-text
+ * @short_description: Default handler for large string values
+ * @title: GdaHanderText
+ * @stability: Stable
+ * @see_also: #GdaDataHandler interface
+ *
+ * You should normally not need to use this API, refer to the #GdaDataHandler
+ * interface documentation for more information.
+ */
+
+
+#define GDA_TYPE_HANDLER_TEXT (gda_handler_text_get_type())
+
+G_DECLARE_DERIVABLE_TYPE(GdaHandlerText, gda_handler_text, GDA, HANDLER_TEXT, GObject)
+
+struct _GdaHandlerTextClass
+{
+  GObjectClass parent_class;
+};
+
+GdaDataHandler   *gda_handler_text_new                  (void);
+GdaDataHandler   *gda_handler_text_new_with_connection  (GdaConnection *cnc);
+
+G_END_DECLS
+
+#endif
diff --git a/libgda/handlers/meson.build b/libgda/handlers/meson.build
index 11e3eae11..055696c51 100644
--- a/libgda/handlers/meson.build
+++ b/libgda/handlers/meson.build
@@ -3,6 +3,7 @@ libgda_handlers_headers = files([
        'gda-handler-boolean.h',
        'gda-handler-numerical.h',
        'gda-handler-string.h',
+       'gda-handler-text.h',
        'gda-handler-time.h',
        'gda-handler-type.h'
        ])
@@ -16,6 +17,7 @@ libgda_handlers_sources = files([
        'gda-handler-boolean.c',
        'gda-handler-numerical.c',
        'gda-handler-string.c',
+       'gda-handler-text.c',
        'gda-handler-time.c',
        'gda-handler-type.c'
        ])
diff --git a/libgda/information_schema.xml b/libgda/information_schema.xml
index 27e56fc1d..90d454961 100644
--- a/libgda/information_schema.xml
+++ b/libgda/information_schema.xml
@@ -24,7 +24,7 @@
       <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint64" replace_with="int"/>
     </provider>
     <provider name="MySQL">
-      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="string" replace_with="varchar (30)"/>
+      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="string" replace_with="varchar(35)"/>
       <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint" replace_with="int"/>
       <ignore context="/FKEY_S"/>
       <ignore context="/FIELDS_A/@COLUMN_PKEY"/>
@@ -59,7 +59,7 @@
     <column name="short_type_name" descr="Short name of the data type"/>
     <column name="full_type_name" pkey="TRUE" descr="Full name of the data type"/>
     <column name="gtype" nullok="TRUE"/>
-    <column name="comments" nullok="TRUE"/>
+    <column name="comments" type="text" nullok="TRUE"/>
     <column name="synonyms" nullok="TRUE"/>
     <column name="internal" type="boolean" descr="Tells if the data type is reserved for the database 
implementation and should not be used in applications"/>
     <unique>
@@ -72,7 +72,7 @@
     <column name="udt_schema" pkey="TRUE" descr="Name of the schema that contains the data type" 
ident="TRUE"/>
     <column name="udt_name" pkey="TRUE" descr="Name of the data type" ident="TRUE"/>
     <column name="udt_gtype" nullok="TRUE" descr="GType associated to the data type"/>
-    <column name="udt_comments" nullok="TRUE"/>
+    <column name="udt_comments" type="text" nullok="TRUE"/>
     <column name="udt_short_name" ident="TRUE"/>
     <column name="udt_full_name" ident="TRUE"/>
     <column name="udt_internal" type="boolean" descr="Tells if the data type is reserved for the database 
implementation and should not be used in applications"/>
@@ -163,7 +163,7 @@
     <column name="numeric_precision" type="gint" nullok="TRUE"/>
     <column name="numeric_scale" type="gint" nullok="TRUE"/>
     <column name="domain_default" nullok="TRUE"/>
-    <column name="domain_comments" nullok="TRUE"/>
+    <column name="domain_comments" type="text" nullok="TRUE"/>
     <column name="domain_short_name" ident="TRUE"/>
     <column name="domain_full_name" ident="TRUE"/>
     <column name="domain_internal" type="boolean"/>
@@ -191,7 +191,7 @@
     <column name="table_name" pkey="TRUE" descr="Name of the table" ident="TRUE"/>
     <column name="table_type" descr="Type of table: BASE TABLE, VIEW, LOCAL TEMPORARY, SYSTEM TABLE, GLOBAL 
TEMPORARY, ALIAS or SYNONYM"/>
     <column name="is_insertable_into" type="boolean" nullok="TRUE" descr="Tells if the table's contents can 
be modified"/>
-    <column name="table_comments" nullok="TRUE"/>
+    <column name="table_comments" type="text" nullok="TRUE"/>
     <column name="table_short_name" ident="TRUE"/>
     <column name="table_full_name" ident="TRUE"/>
     <column name="table_owner" nullok="TRUE"/>
@@ -222,7 +222,7 @@
     <column name="collation_catalog" pkey="TRUE" ident="TRUE"/>
     <column name="collation_schema" pkey="TRUE" ident="TRUE"/>
     <column name="collation_name" pkey="TRUE" ident="TRUE"/>
-    <column name="collation_comments" nullok="TRUE"/>
+    <column name="collation_comments" type="text" nullok="TRUE"/>
     <column name="collation_short_name" ident="TRUE"/>
     <column name="collation_full_name" ident="TRUE"/>
     <fkey ref_table="_schemata">
@@ -241,7 +241,7 @@
     <column name="default_collate_catalog" nullok="TRUE"/>
     <column name="default_collate_schema" nullok="TRUE" ident="TRUE"/>
     <column name="default_collate_name" nullok="TRUE" ident="TRUE"/>
-    <column name="character_set_comments" nullok="TRUE"/>
+    <column name="character_set_comments" type="text" nullok="TRUE"/>
     <column name="character_set_short_name" ident="TRUE"/>
     <column name="character_set_full_name" ident="TRUE"/>
     <fkey ref_table="_schemata">
@@ -277,7 +277,7 @@
     <column name="is_deterministic" type="boolean" nullok="TRUE" descr="Tells if the routine returns the 
same results given the same arguments forever"/>
     <column name="sql_data_access" nullok="TRUE" descr="Whether the routine contains SQL and whether it 
reads or modifies data (NONE, CONTAINS, READS, MODIFIES)"/>
     <column name="is_null_call" type="boolean" nullok="TRUE" descr="Tells if the routine will be called if 
any one of its arguments is NULL"/>
-    <column name="routine_comments" nullok="TRUE"/>
+    <column name="routine_comments" type="text" nullok="TRUE"/>
     <column name="routine_short_name" ident="TRUE"/>
     <column name="routine_full_name" ident="TRUE"/>
     <column name="routine_owner" nullok="TRUE"/>
@@ -302,7 +302,7 @@
     <column name="action_statement" nullok="TRUE" descr="Statement that is executed by the trigger"/>
     <column name="action_orientation" descr="Identifies whether the trigger fires once for each processed 
row or once for each statement (ROW or STATEMENT)"/>
     <column name="condition_timing" descr="Time at which the trigger fires (BEFORE or AFTER)"/>
-    <column name="trigger_comments" nullok="TRUE"/>
+    <column name="trigger_comments" type="text" nullok="TRUE"/>
     <column name="trigger_short_name" ident="TRUE"/>
     <column name="trigger_full_name" ident="TRUE"/>
     <fkey ref_table="_schemata">
@@ -343,7 +343,7 @@
     <column name="collation_name" nullok="TRUE" ident="TRUE"/>
     <column name="extra" nullok="TRUE" descr="CSV string with: AUTO_INCREMENT"/> <!-- set the gda-enums.h 
file -->
     <column name="is_updatable" type="boolean" nullok="TRUE"/>
-    <column name="column_comments" nullok="TRUE"/>
+    <column name="column_comments" type="text" nullok="TRUE"/>
     <fkey ref_table="_tables">
       <part column="table_catalog"/>
       <part column="table_schema"/>
@@ -595,7 +595,7 @@
     <column name="index_type" nullok="TRUE" descr="Database specific type of index such as BTREE, ..."/>
     <column name="extra" nullok="TRUE" descr="CSV string with: ASCENDING, ..."/>
     <column name="index_owner" nullok="TRUE"/>
-    <column name="index_comments" nullok="TRUE"/>
+    <column name="index_comments" type="text" nullok="TRUE"/>
     <fkey ref_table="_tables">
       <part column="table_catalog"/>
       <part column="table_schema"/>
diff --git a/libgda/meson.build b/libgda/meson.build
index 59dbdea16..8dd31c8db 100644
--- a/libgda/meson.build
+++ b/libgda/meson.build
@@ -279,7 +279,6 @@ libgda_cargs = [
                meson.build_root() + '/config.h',
                '-DABI_VERSION='+project_api_version,
                '-DABI_NAME='+project_api_name,
-                '-DLIBGDAPREFIX='+get_option('datadir')
        ]
 
 libgda_cargs += sqlite_cargs
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index bb79e6e25..91e8e8faf 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -2153,6 +2153,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 == GDA_TYPE_TEXT) ||
            (type == G_TYPE_INVALID))
                return "string";
 
@@ -3574,6 +3575,12 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
                else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
                        SQLITE3_CALL (sqlite3_bind_text) (ps->sqlite_stmt, i,
                                                          g_value_get_string (value), -1, SQLITE_TRANSIENT);
+               else if (G_VALUE_TYPE (value) == GDA_TYPE_TEXT) {
+                       GdaText *text = (GdaText*) g_value_get_boxed (value);
+                       const gchar *tstr = gda_text_get_string (text);
+                       SQLITE3_CALL (sqlite3_bind_text) (ps->sqlite_stmt, i,
+                                                         tstr, -1, SQLITE_TRANSIENT);
+    }
                else if (G_VALUE_TYPE (value) == G_TYPE_INT)
                        SQLITE3_CALL (sqlite3_bind_int) (ps->sqlite_stmt, i, g_value_get_int (value));
                else if (G_VALUE_TYPE (value) == G_TYPE_LONG)
diff --git a/libgda/sqlite/gda-sqlite-recordset.c b/libgda/sqlite/gda-sqlite-recordset.c
index fa163f306..c470ff521 100644
--- a/libgda/sqlite/gda-sqlite-recordset.c
+++ b/libgda/sqlite/gda-sqlite-recordset.c
@@ -484,6 +484,12 @@ fetch_next_sqlite_row (GdaSqliteRecordset *model, gboolean do_store, GError **er
                                else if (type == G_TYPE_STRING)
                                        g_value_set_string (value, (gchar *) SQLITE3_CALL 
(sqlite3_column_text) (ps->sqlite_stmt,
                                                                                                  real_col));
+                               else if (type == GDA_TYPE_TEXT) {
+                                       GdaText *text = gda_text_new ();
+                                       gda_text_set_string (text, (const gchar *) SQLITE3_CALL 
(sqlite3_column_text) (ps->sqlite_stmt,
+                                                                                                 real_col));
+                                       g_value_take_boxed (value, text);
+                               }
                                else if (type == GDA_TYPE_BINARY) {
                                        GdaBinary *bin;
                                        
diff --git a/providers/mysql/gda-mysql-provider.c b/providers/mysql/gda-mysql-provider.c
index 79b475fce..826684fa0 100644
--- a/providers/mysql/gda-mysql-provider.c
+++ b/providers/mysql/gda-mysql-provider.c
@@ -1340,7 +1340,7 @@ gda_mysql_provider_get_default_dbms_type (GdaServerProvider  *provider,
                return "double";
        if (type == GDA_TYPE_GEOMETRIC_POINT)
                return "point";
-       if (type == G_TYPE_OBJECT)
+       if (type == GDA_TYPE_TEXT)
                return "text";
        if (type == G_TYPE_INT)
                return "int";
@@ -2616,8 +2616,7 @@ gda_mysql_provider_statement_execute (GdaServerProvider               *provider,
                                                                             G_VALUE_TYPE (value));
                        if (data_handler == NULL) {
                                /* there is an error here */
-                               str = g_strdup_printf(_("Unhandled data type '%s', please report this bug to "
-                                                       "http://gitlab.gnome.org/GNOME/libgda/issues";),
+                               str = g_strdup_printf(_("Unhandled data type '%s', please report this bug to 
http://gitlab.gnome.org/GNOME/libgda/issues";),
                                                      gda_g_type_to_string (G_VALUE_TYPE (value)));
                                event = gda_connection_point_available_event (cnc, 
GDA_CONNECTION_EVENT_ERROR);
                                gda_connection_event_set_description (event, str);
diff --git a/providers/postgres/gda-postgres-provider.c b/providers/postgres/gda-postgres-provider.c
index 13f773997..dd7d3e100 100644
--- a/providers/postgres/gda-postgres-provider.c
+++ b/providers/postgres/gda-postgres-provider.c
@@ -1498,6 +1498,8 @@ gda_postgres_provider_get_default_dbms_type (GdaServerProvider *provider, GdaCon
                 return "int2";
         if (type == G_TYPE_STRING)
                 return "varchar";
+        if (type == GDA_TYPE_TEXT)
+                return "text";
         if (type == GDA_TYPE_TIME)
                 return "time";
         if (type == G_TYPE_DATE_TIME)
diff --git a/providers/reuseable/mysql/gda-mysql-meta.c b/providers/reuseable/mysql/gda-mysql-meta.c
index 338aea9a8..1f17dc229 100644
--- a/providers/reuseable/mysql/gda-mysql-meta.c
+++ b/providers/reuseable/mysql/gda-mysql-meta.c
@@ -359,7 +359,7 @@ _gda_mysql_meta__btypes (G_GNUC_UNUSED GdaServerProvider  *prov,
                { "MEDIUMTEXT", "GdaBinary", "A TEXT column with a maximum length of 16,777,215 (224 - 1) 
characters. The effective maximum length is less if the value contains multi-byte characters. Each MEDIUMTEXT 
value is stored using a three-byte length prefix that indicates the number of bytes in the value.", "" },
                { "SET DATA TYPE", "gchararray", "A set. A string object that can have zero or more values, 
each of which must be chosen from the list of values 'value1', 'value2', ... A SET column can have a maximum 
of 64 members. SET values are represented internally as integers.", "" },
                { "SMALLINT", "gshort", "A small integer. The signed range is -32768 to 32767. The unsigned 
range is 0 to 65535.", "" },
-               { "TEXT", "GdaBinary", "A TEXT column with a maximum length of 65,535 (216 - 1) characters. 
The effective maximum length is less if the value contains multi-byte characters. Each TEXT value is stored 
using a two-byte length prefix that indicates the number of bytes in the value.", "" },
+               { "TEXT", "GdaText", "A TEXT column with a maximum length of 65,535 (216 - 1) characters. The 
effective maximum length is less if the value contains multi-byte characters. Each TEXT value is stored using 
a two-byte length prefix that indicates the number of bytes in the value.", "" },
                { "TIME", "GdaTime", "A time. The range is '-838:59:59' to '838:59:59'. MySQL displays TIME 
values in 'HH:MM:SS' format, but allows assignment of values to TIME columns using either strings or 
numbers.", "" },
                { "TIMESTAMP", "GDateTime", "A timestamp. The range is '1970-01-01 00:00:01' UTC to partway 
through the year 2038. TIMESTAMP values are stored as the number of seconds since the epoch ('1970-01-01 
00:00:00' UTC). A TIMESTAMP cannot represent the value '1970-01-01 00:00:00' because that is equivalent to 0 
seconds from the epoch and the value 0 is reserved for representing '0000-00-00 00:00:00', the \"zero\" 
TIMESTAMP value.", "" },
                { "TINYBLOB", "GdaBinary", "A BLOB column with a maximum length of 255 (28 - 1) bytes. Each 
TINYBLOB value is stored using a one-byte length prefix that indicates the number of bytes in the value.", "" 
},



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