[libgda] Fix segfault on virtual connections
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Fix segfault on virtual connections
- Date: Tue, 26 Feb 2019 23:15:52 +0000 (UTC)
commit 892407cb9033396d527bdba594dc4cc982a5d622
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Tue Feb 26 17:07:40 2019 -0600
Fix segfault on virtual connections
.../virtual/gda-vconnection-data-model-private.h | 4 +-
libgda/sqlite/virtual/gda-vconnection-data-model.c | 23 +++++-----
libgda/sqlite/virtual/gda-vprovider-data-model.c | 51 +++++++++-------------
tests/data-models/check_vcnc.c | 36 +++++++++++++--
4 files changed, 67 insertions(+), 47 deletions(-)
---
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
b/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
index 6a1e0a0ed..90ddf2977 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model-private.h
@@ -40,7 +40,7 @@ typedef struct VirtualFilteredData VirtualFilteredData;
struct VContext{
GWeakRef context_object;
- GArray *context_data;
+ GPtrArray *context_data;
GdaVConnectionTableData *vtable;
};
@@ -71,7 +71,7 @@ struct VirtualFilteredData {
/* data */
GdaDataModel *model;
GdaDataModelIter *iter; /* not NULL while nrows == -1 */
- GArray *values_array;
+ GPtrArray *values_array;
gint ncols;
gint nrows; /* -1 until known */
};
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model.c
b/libgda/sqlite/virtual/gda-vconnection-data-model.c
index 5282c04d5..8dd7a7e1c 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model.c
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model.c
@@ -157,12 +157,15 @@ gda_vconnection_data_model_dispose (GObject *object)
g_return_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc));
- /* free memory */
- priv->being_disposed = TRUE;
- while (priv->table_data_list) {
- GdaVConnectionTableData *td;
- td = (GdaVConnectionTableData *) priv->table_data_list->data;
- get_rid_of_vtable (cnc, td, TRUE, NULL);
+ if (priv->table_data_list != NULL) {
+ /* free memory */
+ priv->being_disposed = TRUE;
+ while (priv->table_data_list) {
+ GdaVConnectionTableData *td;
+ td = (GdaVConnectionTableData *) priv->table_data_list->data;
+ get_rid_of_vtable (cnc, td, TRUE, NULL);
+ }
+ priv->table_data_list = NULL;
}
gda_connection_close ((GdaConnection *) cnc, NULL);
@@ -302,7 +305,7 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
if (rc != SQLITE_OK) {
g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_INTERNAL_ERROR,
- "%s", zErrMsg);
+ _("Internal Error: when trying to add data model spec for virtual connetion:
%s"), zErrMsg);
SQLITE3_CALL (sqlite3_free) (zErrMsg);
_gda_vconnection_data_model_table_data_free (td);
priv->table_data_list = g_slist_remove (priv->table_data_list, td);
@@ -580,7 +583,7 @@ vcontext_free (VContext *context)
g_object_unref (obj);
}
if (context->context_data) {
- g_array_free (context->context_data, TRUE);
+ g_ptr_array_free (context->context_data, TRUE);
context->context_data = NULL;
}
g_free (context);
@@ -611,9 +614,7 @@ _gda_vconnection_set_working_obj (GdaVconnectionDataModel *cnc, GObject *obj)
if (! vc) {
vc = g_new0 (VContext, 1);
g_weak_ref_set (&(vc->context_object), obj);
- vc->context_data = g_array_new (FALSE, FALSE,
- sizeof (VirtualFilteredData*));
- g_array_set_clear_func (vc->context_data, (GDestroyNotify)
_gda_vconnection_virtual_filtered_data_unref);
+ vc->context_data = g_ptr_array_new_full (1, (GDestroyNotify)
_gda_vconnection_virtual_filtered_data_unref);
vc->vtable = td;
g_hash_table_insert (td->context.hash, obj, vc);
#ifdef DEBUG_VCONTEXT
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c
b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index fc3cd06a2..664d57500 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -218,7 +218,7 @@ virtual_filtered_data_new (VirtualTable *vtable, GdaDataModel *model,
gint n;
n = gda_data_model_get_n_columns (model);
n = (n >= 0) ? n : 1;
- data->values_array = g_array_new (FALSE, FALSE, sizeof (GValue));
+ data->values_array = g_ptr_array_new_full (1, (GDestroyNotify) gda_value_free);
data->ncols = gda_data_model_get_n_columns (model);
data->nrows = -1;
data->rowid_offset = vtable->rows_offset;
@@ -249,13 +249,7 @@ virtual_filtered_data_free (VirtualFilteredData *data)
g_object_unref (data->iter);
if (data->values_array) {
- guint i;
- for (i = 0; i < data->values_array->len; i++) {
- GValue *value;
- value = & g_array_index (data->values_array, GValue, i);
- g_value_reset (value);
- }
- g_array_free (data->values_array, TRUE);
+ g_ptr_array_free (data->values_array, TRUE);
}
g_free (data);
@@ -874,25 +868,22 @@ virtualNext (sqlite3_vtab_cursor *cur)
GdaHolder *h = (GdaHolder*) list->data;
GError *lerror = NULL;
if (! gda_holder_is_valid_e (h, &lerror)) {
- GValue value = {0};
- g_value_init (&value, G_TYPE_ERROR);
- g_value_take_boxed (&value, lerror);
- g_array_append_val (data->values_array, value);
+ GValue *value = gda_value_new (G_TYPE_ERROR);
+ g_value_take_boxed (value, lerror);
+ g_ptr_array_insert (data->values_array, -1, value);
}
else {
const GValue *cvalue;
cvalue = gda_holder_get_value (h);
if (cvalue && (G_VALUE_TYPE (cvalue) != 0)) {
- GValue copy = {0};
- g_value_init (©, G_VALUE_TYPE (cvalue));
- g_value_copy (cvalue, ©);
- g_array_append_val (data->values_array, copy);
+ GValue *copy = gda_value_new (G_VALUE_TYPE (cvalue));
+ g_value_copy (cvalue, copy);
+ g_ptr_array_insert (data->values_array, -1, copy);
}
else {
- GValue value = {0};
- g_value_init (&value, G_TYPE_ERROR);
- g_value_take_boxed (&value, lerror);
- g_array_append_val (data->values_array, value);
+ GValue *value = gda_value_new (G_TYPE_ERROR);
+ g_value_take_boxed (value, lerror);
+ g_ptr_array_insert (data->values_array, -1, value);
}
}
}
@@ -944,10 +935,10 @@ get_data_value (VirtualTable *vtable, VirtualCursor *cursor, gint row, gint64 ro
g_assert (vtable->td->context.current_vcontext);
guint i;
- GArray *values_array = vtable->td->context.current_vcontext->context_data;
+ GPtrArray *values_array = vtable->td->context.current_vcontext->context_data;
for (i = 0; i < values_array->len; i++) {
VirtualFilteredData *vd;
- vd = g_array_index (values_array, VirtualFilteredData*, i);
+ vd = g_ptr_array_index (values_array, i);
if (vd->rowid_offset == (guint32) (rowid >> 32)) {
data = vd;
break;
@@ -956,7 +947,7 @@ get_data_value (VirtualTable *vtable, VirtualCursor *cursor, gint row, gint64 ro
}
if (data)
- value = & g_array_index (data->values_array, GValue, row * data->ncols + col);
+ value = g_ptr_array_index (data->values_array, row * data->ncols + col);
if (!value)
g_set_error (error, GDA_VPROVIDER_DATA_MODEL_ERROR, GDA_VPROVIDER_DATA_MODEL_GENERAL_ERROR,
@@ -1180,13 +1171,13 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
/* find a VirtualFilteredData corresponding to this filter */
VirtualFilteredData *data = NULL;
g_assert (vtable->td->context.current_vcontext);
- GArray *values_array = vtable->td->context.current_vcontext->context_data;
+ GPtrArray *values_array = vtable->td->context.current_vcontext->context_data;
if (values_array->len > 0) {
guint i;
for (i = 0; i < values_array->len; i++) {
VirtualFilteredData *vd;
- vd = g_array_index (values_array, VirtualFilteredData*, i);
+ vd = g_ptr_array_index (values_array, i);
if (vd->reuseable &&
(vd->idxNum == idxNum) &&
(vd->argc == argc) &&
@@ -1232,7 +1223,7 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
if (! vtable->td->real_model)
return SQLITE_ERROR;
data = virtual_filtered_data_new (vtable, vtable->td->real_model, idxNum, idxStr, argc, argv);
- g_array_prepend_val (values_array, data);
+ g_ptr_array_insert (values_array, -1, data);
#ifdef DEBUG_VCONTEXT
g_print ("VData %p prepended to array %p wt %d\n", data, values_array,
values_array->len);
@@ -1241,9 +1232,9 @@ virtualFilter (sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr,
VirtualFilteredData *ldata;
gint index;
index = values_array->len - 1;
- ldata = g_array_index (values_array, VirtualFilteredData*, index);
+ ldata = g_ptr_array_index (values_array, index);
_gda_vconnection_virtual_filtered_data_unref (ldata);
- g_array_remove_index (values_array, index);
+ g_ptr_array_remove_index (values_array, index);
}
}
@@ -1598,12 +1589,12 @@ virtualUpdate (sqlite3_vtab *tab, int nData, sqlite3_value **apData, sqlite_int6
TRACE (tab, NULL);
g_assert (vtable->td->context.current_vcontext);
- GArray *values_array = vtable->td->context.current_vcontext->context_data;
+ GPtrArray *values_array = vtable->td->context.current_vcontext->context_data;
if (values_array) {
guint i;
for (i = 0; i < values_array->len; i++) {
VirtualFilteredData *data;
- data = g_array_index (values_array, VirtualFilteredData*, i);
+ data = g_ptr_array_index (values_array, i);
data->reuseable = FALSE;
}
}
diff --git a/tests/data-models/check_vcnc.c b/tests/data-models/check_vcnc.c
index bd63fca70..008ab8ee9 100644
--- a/tests/data-models/check_vcnc.c
+++ b/tests/data-models/check_vcnc.c
@@ -91,6 +91,7 @@ test1 (Data *data) {
provider = gda_vprovider_hub_new ();
virtual = gda_virtual_connection_open (provider, GDA_CONNECTION_OPTIONS_NONE, NULL);
g_assert (virtual);
+ g_assert (GDA_IS_VCONNECTION_HUB (virtual));
/* load CSV data models */
GdaDataModel *country_model, *city_model;
@@ -104,7 +105,8 @@ test1 (Data *data) {
g_free (file);
g_object_unref (options);
- g_message ("Add data models to connection: city");
+ g_message ("Adding data models to virtal connection as inputs");
+ g_message ("Add data models to virtual connection: city");
if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (virtual),
city_model, "city", &error)) {
g_message ("Add city model error: %s", error->message);
@@ -112,7 +114,7 @@ test1 (Data *data) {
g_main_loop_quit (data->loop);
return G_SOURCE_REMOVE;
}
- g_message ("Add data models to connection: country");
+ g_message ("Add data models to virtual connection: country");
if (!gda_vconnection_data_model_add_model (GDA_VCONNECTION_DATA_MODEL (virtual),
country_model, "country", &error)) {
g_message ("Add country model error: %s", error->message);
@@ -120,9 +122,35 @@ test1 (Data *data) {
g_main_loop_quit (data->loop);
return G_SOURCE_REMOVE;
}
+ // Test data models in virtal connection
+ GdaDataModel *datamodel;
+ datamodel = gda_connection_execute_select_command (virtual, "SELECT * FROM city", &error);
+ if (datamodel == NULL) {
+ g_message ("Select data from city model error: %s", error->message);
+ g_clear_error (&error);
+ g_main_loop_quit (data->loop);
+ return G_SOURCE_REMOVE;
+ }
+ gchar *dump = NULL;
+ dump = gda_data_model_dump_as_string (datamodel);
+ g_message ("Selected data from imported data model city:\n%s", dump);
+ g_free (dump);
+ g_object_unref (datamodel);
+
+ datamodel = gda_connection_execute_select_command (virtual, "SELECT * FROM country", &error);
+ if (datamodel == NULL) {
+ g_message ("Select data from city model error: %s", error->message);
+ g_clear_error (&error);
+ g_main_loop_quit (data->loop);
+ return G_SOURCE_REMOVE;
+ }
+ dump = gda_data_model_dump_as_string (datamodel);
+ g_message ("Selected data from imported data model country:\n%s", dump);
+ g_free (dump);
+ g_object_unref (datamodel);
/* SQLite connection for outputs */
- g_message ("SQLite connection for outputs");
+ g_message ("Open SQLite connection for outputs");
out_cnc = open_destination_connection (data, &error);
if (out_cnc == NULL) {
g_message ("Error opening destination %s", error->message);
@@ -132,7 +160,7 @@ test1 (Data *data) {
}
/* adding connections to the virtual connection */
- g_message ("Add data models to connection");
+ g_message ("Add output connection to virtual connection hub");
if (!gda_vconnection_hub_add (GDA_VCONNECTION_HUB (virtual), out_cnc, "out", &error)) {
g_message ("Could not add connection to virtual connection: %s",
error->message);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]