[libgda: 1/2] GdaDataHandler: Fixing memory leak
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda: 1/2] GdaDataHandler: Fixing memory leak
- Date: Thu, 30 Jan 2020 23:54:22 +0000 (UTC)
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]