Copy column names to driver-allocated memory.
Fixes issue #14 by copying out column names before memory can be overwritten by another statement.
This commit is contained in:
@@ -507,7 +507,7 @@ static int bind_parameters(
|
|||||||
|
|
||||||
static void get_columns(
|
static void get_columns(
|
||||||
sqlite3_drv_t *drv, sqlite3_stmt *statement, int column_count, int base,
|
sqlite3_drv_t *drv, sqlite3_stmt *statement, int column_count, int base,
|
||||||
int *p_term_count, int *p_term_allocated, ErlDrvTermData **p_dataset) {
|
int *p_term_count, int *p_term_allocated, ptr_list** p_ptrs, ErlDrvTermData **p_dataset) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*p_term_count += column_count * 3 + 3;
|
*p_term_count += column_count * 3 + 3;
|
||||||
@@ -516,12 +516,16 @@ static void get_columns(
|
|||||||
*p_dataset = driver_realloc(*p_dataset, sizeof(ErlDrvTermData) * *p_term_allocated);
|
*p_dataset = driver_realloc(*p_dataset, sizeof(ErlDrvTermData) * *p_term_allocated);
|
||||||
}
|
}
|
||||||
for (i = 0; i < column_count; i++) {
|
for (i = 0; i < column_count; i++) {
|
||||||
char *column_name = (char *) sqlite3_column_name(statement, i);
|
const char *column_name = sqlite3_column_name(statement, i);
|
||||||
TRACE((drv->log, "Column: %s\n", column_name));
|
size_t column_name_length = strlen(column_name);
|
||||||
|
char *column_name_copy = driver_alloc(sizeof(char *) * (column_name_length + 1));
|
||||||
|
strcpy(column_name_copy, column_name);
|
||||||
|
*p_ptrs = add_to_ptr_list(*p_ptrs, column_name_copy);
|
||||||
|
TRACE((drv->log, "Column: %s\n", column_name_copy));
|
||||||
|
|
||||||
(*p_dataset)[base + (i * 3)] = ERL_DRV_STRING;
|
(*p_dataset)[base + (i * 3)] = ERL_DRV_STRING;
|
||||||
(*p_dataset)[base + (i * 3) + 1] = (ErlDrvTermData) column_name;
|
(*p_dataset)[base + (i * 3) + 1] = (ErlDrvTermData) column_name_copy;
|
||||||
(*p_dataset)[base + (i * 3) + 2] = strlen(column_name);
|
(*p_dataset)[base + (i * 3) + 2] = column_name_length;
|
||||||
}
|
}
|
||||||
(*p_dataset)[base + column_count * 3 + 0] = ERL_DRV_NIL;
|
(*p_dataset)[base + column_count * 3 + 0] = ERL_DRV_NIL;
|
||||||
(*p_dataset)[base + column_count * 3 + 1] = ERL_DRV_LIST;
|
(*p_dataset)[base + column_count * 3 + 1] = ERL_DRV_LIST;
|
||||||
@@ -620,7 +624,7 @@ static int sql_exec_one_statement(
|
|||||||
(*dataset_p)[*term_count_p - 1] = drv->atom_columns;
|
(*dataset_p)[*term_count_p - 1] = drv->atom_columns;
|
||||||
base_term_count = *term_count_p;
|
base_term_count = *term_count_p;
|
||||||
get_columns(
|
get_columns(
|
||||||
drv, statement, column_count, base_term_count, term_count_p, term_allocated_p, dataset_p);
|
drv, statement, column_count, base_term_count, term_count_p, term_allocated_p, ptrs_p, dataset_p);
|
||||||
*term_count_p += 4;
|
*term_count_p += 4;
|
||||||
if (*term_count_p > *term_allocated_p) {
|
if (*term_count_p > *term_allocated_p) {
|
||||||
*term_allocated_p = max(*term_count_p, *term_allocated_p*2);
|
*term_allocated_p = max(*term_count_p, *term_allocated_p*2);
|
||||||
@@ -1138,6 +1142,7 @@ static int prepared_columns(sqlite3_drv_t *drv, char *buffer, int buffer_size) {
|
|||||||
int index = 0, term_count = 0, term_allocated = 0, column_count;
|
int index = 0, term_count = 0, term_allocated = 0, column_count;
|
||||||
sqlite3_stmt *statement;
|
sqlite3_stmt *statement;
|
||||||
ErlDrvTermData *dataset = NULL;
|
ErlDrvTermData *dataset = NULL;
|
||||||
|
ptr_list* ptrs = NULL;
|
||||||
|
|
||||||
ei_decode_version(buffer, &index, NULL);
|
ei_decode_version(buffer, &index, NULL);
|
||||||
ei_decode_long(buffer, &index, &long_prepared_index);
|
ei_decode_long(buffer, &index, &long_prepared_index);
|
||||||
@@ -1165,11 +1170,13 @@ static int prepared_columns(sqlite3_drv_t *drv, char *buffer, int buffer_size) {
|
|||||||
column_count = sqlite3_column_count(statement);
|
column_count = sqlite3_column_count(statement);
|
||||||
|
|
||||||
get_columns(
|
get_columns(
|
||||||
drv, statement, column_count, 2, &term_count, &term_allocated, &dataset);
|
drv, statement, column_count, 2, &term_count, &term_allocated, &ptrs, &dataset);
|
||||||
dataset[term_count - 2] = ERL_DRV_TUPLE;
|
dataset[term_count - 2] = ERL_DRV_TUPLE;
|
||||||
dataset[term_count - 1] = 2;
|
dataset[term_count - 1] = 2;
|
||||||
|
|
||||||
return driver_output_term(drv->port, dataset, term_count);
|
driver_output_term(drv->port, dataset, term_count);
|
||||||
|
free_ptr_list(ptrs, driver_free_fun);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prepared_step(sqlite3_drv_t *drv, char *buffer, int buffer_size) {
|
static int prepared_step(sqlite3_drv_t *drv, char *buffer, int buffer_size) {
|
||||||
|
|||||||
Reference in New Issue
Block a user