[libgda: 1/2] GdaDataHandler: Fixing memory leak



commit 006541614d046d00f4106b0cc01b1755ae1cb828
Author: Pavlo Solntsev <p sun fun gmail com>
Date:   Thu Jan 30 23:54:00 2020 +0000

    GdaDataHandler: Fixing memory leak
    
     * gda_data_handler_get_default() API documentation was fixed
     * Fixed memory leak for each call of gda_data_handler_get_default()
     * Memory fix in test-sql-builder
    
     See #205

 libgda/gda-data-handler.c             |  2 +-
 libgda/gda-data-model.c               | 14 ++++++++++++--
 libgda/gda-holder.c                   | 25 +++++++++++++++++--------
 libgda/gda-sql-builder.c              |  1 +
 libgda/gda-statement.c                | 22 ++++++++++++++++++----
 libgda/sqlite/gda-sqlite-provider.c   | 11 +++++++++--
 providers/postgres/gda-postgres-ddl.c | 21 +++++++++++++++++++--
 tests/test-sql-builder.c              |  1 +
 8 files changed, 78 insertions(+), 19 deletions(-)
---
diff --git a/libgda/gda-data-handler.c b/libgda/gda-data-handler.c
index 76b6e6b84..2257091b4 100644
--- a/libgda/gda-data-handler.c
+++ b/libgda/gda-data-handler.c
@@ -252,7 +252,7 @@ gda_data_handler_get_descr (GdaDataHandler *dh)
  *
  * The returned pointer is %NULL if there is no default data handler available for the @for_type data type
  *
- * Returns: (transfer full): a #GdaDataHandler which must not be modified or destroyed.
+ * Returns: (transfer full): a #GdaDataHandler which must be destroyed using g_object_unref()
  *
  * Since: 4.2.3
  */
diff --git a/libgda/gda-data-model.c b/libgda/gda-data-model.c
index 13c97db7c..16a50200c 100644
--- a/libgda/gda-data-model.c
+++ b/libgda/gda-data-model.c
@@ -2565,8 +2565,13 @@ real_gda_data_model_dump_as_string (GdaDataModel *model, gboolean dump_attribute
                                                                        }
                                                                        if (!dh)
                                                                                dh = 
gda_data_handler_get_default (G_VALUE_TYPE (value));
-                                                                       if (dh)
+                                                                       else
+                                                                               g_object_ref (dh);
+
+                                                                       if (dh) {
                                                                                str = 
gda_data_handler_get_str_from_value (dh, value);
+                                                                               g_object_unref (dh);
+                                                                       }
                                                                        else
                                                                                str = gda_value_stringify 
((GValue*)value);
                                                                }
@@ -2711,8 +2716,13 @@ real_gda_data_model_dump_as_string (GdaDataModel *model, gboolean dump_attribute
                                                                        }
                                                                        if (!dh)
                                                                                dh = 
gda_data_handler_get_default (G_VALUE_TYPE (value));
-                                                                       if (dh)
+                                                                       else
+                                                                               g_object_ref (dh);
+
+                                                                       if (dh) {
                                                                                str = 
gda_data_handler_get_str_from_value (dh, value);
+                                                                               g_object_unref (dh);
+                                                                       }
                                                                        else
                                                                                str = gda_value_stringify 
((GValue*)value);
                                                                }
diff --git a/libgda/gda-holder.c b/libgda/gda-holder.c
index 259b42cc0..3ece6b3b0 100644
--- a/libgda/gda-holder.c
+++ b/libgda/gda-holder.c
@@ -834,6 +834,7 @@ gchar *
 gda_holder_get_value_str (GdaHolder *holder, GdaDataHandler *dh)
 {
        const GValue *current_val;
+       GdaDataHandler *dhl = NULL;
 
        g_return_val_if_fail (GDA_IS_HOLDER (holder), NULL);
        GdaHolderPrivate *priv = gda_holder_get_instance_private (holder);
@@ -847,9 +848,13 @@ gda_holder_get_value_str (GdaHolder *holder, GdaDataHandler *dh)
         else {
                gchar *retval = NULL;
                 if (!dh)
-                       dh = gda_data_handler_get_default (priv->g_type);
-               if (dh)
-                        retval = gda_data_handler_get_str_from_value (dh, current_val);
+                       dhl = gda_data_handler_get_default (priv->g_type);
+               else
+                       dhl = g_object_ref (dh);
+               if (dhl) {
+                        retval = gda_data_handler_get_str_from_value (dhl, current_val);
+                       g_object_unref (dhl);
+               }
                gda_holder_unlock ((GdaLockable*) holder);
                return retval;
         }
@@ -920,14 +925,18 @@ gda_holder_set_value_str (GdaHolder *holder, GdaDataHandler *dh, const gchar *va
        else {
                GValue *gdaval = NULL;
                gboolean retval = FALSE;
+               GdaDataHandler *ldh = NULL;
 
                gda_holder_lock ((GdaLockable*) holder);
                if (!dh)
-                       dh = gda_data_handler_get_default (priv->g_type);
-               if (dh) {
-                       gdaval = gda_data_handler_get_value_from_str (dh, value, priv->g_type);
-      g_object_unref (dh);
-    }
+                       ldh = gda_data_handler_get_default (priv->g_type);
+               else
+                       ldh = g_object_ref (dh);
+
+               if (ldh) {
+                       gdaval = gda_data_handler_get_value_from_str (ldh, value, priv->g_type);
+                       g_object_unref (ldh);
+               }
                
                if (gdaval)
                        retval = real_gda_holder_set_value (holder, gdaval, FALSE, error);
diff --git a/libgda/gda-sql-builder.c b/libgda/gda-sql-builder.c
index 0ae337369..32910fbc5 100644
--- a/libgda/gda-sql-builder.c
+++ b/libgda/gda-sql-builder.c
@@ -812,6 +812,7 @@ gda_sql_builder_add_expr_value (GdaSqlBuilder *builder, const GValue *value)
           ldh = gda_data_handler_get_default (G_TYPE_STRING);
           expr->value = gda_value_new (G_TYPE_STRING);
           g_value_take_string (expr->value, gda_data_handler_get_sql_from_value (ldh, value));
+         g_object_unref (ldh);
         }
       else
         expr->value = gda_value_copy (value);
diff --git a/libgda/gda-statement.c b/libgda/gda-statement.c
index 333a938d0..0a5c200cc 100644
--- a/libgda/gda-statement.c
+++ b/libgda/gda-statement.c
@@ -478,6 +478,8 @@ get_params_foreach_func (GdaSqlAnyPart *node, GdaSet **params, GError **error)
                                value = gda_data_handler_get_value_from_sql (dh,
                                                                             g_value_get_string (evalue),
                                                                             pspec->g_type);
+                               g_object_unref (dh);
+
                                if (!value)
                                        value = gda_value_new_default (g_value_get_string (evalue));
                                gda_holder_set_default_value (h, value);
@@ -739,8 +741,10 @@ default_render_value (const GValue *value, GdaSqlRenderingContext *context, GErr
 {
        if (value && !gda_value_is_null (value)) {
                GdaDataHandler *dh;
-               if (context->provider)
+               if (context->provider) {
                        dh = gda_server_provider_get_data_handler_g_type (context->provider, context->cnc, 
G_VALUE_TYPE (value));
+                       g_object_ref (dh); // dh here is not a full transfer.
+               }
                else                    
                        dh = gda_data_handler_get_default (G_VALUE_TYPE (value));
 
@@ -789,7 +793,12 @@ default_render_value (const GValue *value, GdaSqlRenderingContext *context, GErr
                        }
                }
 
-               return gda_data_handler_get_sql_from_value (dh, value);
+               gchar *res;
+
+               res = gda_data_handler_get_sql_from_value (dh, value);
+               g_object_unref (dh);
+
+               return res;
        }
        else
                return g_strdup ("NULL");
@@ -1550,13 +1559,18 @@ default_render_expr (GdaSqlExpr *expr, GdaSqlRenderingContext *context, gboolean
                                prov = gda_connection_get_provider (context->cnc);
                                dh = gda_server_provider_get_data_handler_g_type (prov, context->cnc,
                                                                                  G_VALUE_TYPE (expr->value));
-                               if (!dh) goto err;
+                               if (!dh)
+                                 goto err;
+                               else
+                                 g_object_ref (dh); // We need this, since dh is not a full transfer
                        }
                        else
                                dh = gda_data_handler_get_default (G_VALUE_TYPE (expr->value));
 
-                       if (dh)
+                       if (dh) {
                                str = gda_data_handler_get_sql_from_value (dh, expr->value);
+                               g_object_unref (dh);
+                       }
                        else
                                str = gda_value_stringify (expr->value);
                        if (!str) goto err;
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 039ef0ec9..20f732a1f 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -2638,13 +2638,18 @@ sqlite_render_expr (GdaSqlExpr *expr, GdaSqlRenderingContext *context, gboolean
                                prov = gda_connection_get_provider (context->cnc);
                                dh = gda_server_provider_get_data_handler_g_type (prov, context->cnc,
                                                                                  G_VALUE_TYPE (expr->value));
-                               if (!dh) goto err;
+                               if (!dh)
+                                 goto err;
+                               else
+                                 g_object_ref (dh);
                        }
                        else
                                dh = gda_data_handler_get_default (G_VALUE_TYPE (expr->value));
 
-                       if (dh)
+                       if (dh) {
                                str = gda_data_handler_get_sql_from_value (dh, expr->value);
+                               g_object_unref (dh);
+                       }
                        else
                                str = gda_value_stringify (expr->value);
                        if (!str) goto err;
@@ -3967,6 +3972,7 @@ scalar_gda_hex_print_func (sqlite3_context *context, int argc, sqlite3_value **a
        gda_value_take_binary ((value = gda_value_new (GDA_TYPE_BINARY)), bin);
        dh = gda_data_handler_get_default (GDA_TYPE_BINARY);
        str = gda_data_handler_get_str_from_value (dh, value);
+       g_object_unref (dh);
 
        gda_value_free (value);
        (s3r->sqlite3_result_text) (context, str, -1, g_free);
@@ -3998,6 +4004,7 @@ scalar_gda_hex_print_func2 (sqlite3_context *context, int argc, sqlite3_value **
        gda_value_take_binary ((value = gda_value_new (GDA_TYPE_BINARY)), bin);
        dh = gda_data_handler_get_default (GDA_TYPE_BINARY);
        str = gda_data_handler_get_str_from_value (dh, value);
+       g_object_unref (dh);
 
        gda_value_free (value);
 
diff --git a/providers/postgres/gda-postgres-ddl.c b/providers/postgres/gda-postgres-ddl.c
index 31fbea7be..ed4f111a6 100644
--- a/providers/postgres/gda-postgres-ddl.c
+++ b/providers/postgres/gda-postgres-ddl.c
@@ -849,7 +849,7 @@ gda_postgres_render_DROP_VIEW (GdaServerProvider *provider, GdaConnection *cnc,
 
 gchar *
 gda_postgres_render_CREATE_USER (GdaServerProvider *provider, GdaConnection *cnc, 
-                                GdaServerOperation *op, G_GNUC_UNUSED GError **error)
+                                GdaServerOperation *op, GError **error)
 {
        GString *string;
        const GValue *value;
@@ -898,8 +898,21 @@ gda_postgres_render_CREATE_USER (GdaServerProvider *provider, GdaConnection *cnc
                dh = gda_server_provider_get_data_handler_g_type (provider, cnc, G_TYPE_STRING);
                if (!dh)
                        dh = gda_data_handler_get_default (G_TYPE_STRING);
+               else
+                       g_object_ref (dh);
+
+               if (!dh) {
+                   g_set_error (error,
+                                GDA_SERVER_OPERATION_ERROR,
+                                GDA_SERVER_OPERATION_INCORRECT_VALUE_ERROR,
+                                "%s: %s",
+                                G_STRLOC,
+                                _ ("Dataholder type is unknown."));
+                   return NULL;
+               }
 
                tmp = gda_data_handler_get_sql_from_value (dh, value);
+               g_object_unref (dh);
                g_string_append (string, tmp);
                g_free (tmp);
        }
@@ -1058,9 +1071,13 @@ gda_postgres_render_CREATE_USER (GdaServerProvider *provider, GdaConnection *cnc
                        dh = gda_server_provider_get_data_handler_g_type (provider, cnc, G_TYPE_DATE_TIME);
                        if (!dh)
                                dh = gda_data_handler_get_default (G_TYPE_DATE_TIME);
-                       
+                       else
+                               g_object_ref (dh);
+               
+                       g_assert (dh); // If fails, the type in dh is not implemented. It is a bug.
                        g_string_append (string, " VALID UNTIL ");
                        tmp = gda_data_handler_get_sql_from_value (dh, value);
+                       g_object_unref (dh);
                        g_string_append (string, tmp);
                        g_free (tmp);
                }
diff --git a/tests/test-sql-builder.c b/tests/test-sql-builder.c
index 99a115619..72541b412 100644
--- a/tests/test-sql-builder.c
+++ b/tests/test-sql-builder.c
@@ -635,6 +635,7 @@ build13 (void)
        gda_sql_builder_add_field_value_id (b,
                                            gda_sql_builder_add_expr (b, NULL, GDA_TYPE_BINARY, bin), 0);
 
+       gda_binary_free (bin);
 
 #ifdef DEBUG
        {


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