static void sql_exec_one_statement( sqlite3_stmt *statement, async_sqlite3_command *async_command, int *term_count_p, int *term_allocated_p, ErlDrvTermData **dataset_p) { int column_count = sqlite3_column_count(statement); int row_count = 0, next_row; int base_term_count; sqlite3_drv_t *drv = async_command->driver_data; ptr_list **ptrs_p = &(async_command->ptrs); ptr_list **binaries_p = &(async_command->binaries); // printf("\nStart of sql_exec_one_statement: term_count=%d, term_allocated=%d", *term_count_p, *term_allocated_p); int i; if (column_count > 0) { *term_count_p += 2; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM; (*dataset_p)[*term_count_p - 1] = drv->atom_columns; base_term_count = *term_count_p; get_columns( drv, statement, column_count, base_term_count, term_count_p, term_allocated_p, dataset_p); *term_count_p += 4; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[base_term_count + column_count * 3 + 3] = ERL_DRV_TUPLE; (*dataset_p)[base_term_count + column_count * 3 + 4] = 2; (*dataset_p)[base_term_count + column_count * 3 + 5] = ERL_DRV_ATOM; (*dataset_p)[base_term_count + column_count * 3 + 6] = drv->atom_rows; // printf("\nAfter adding columns: column_count=%d, term_count=%d, term_allocated=%d", column_count, *term_count_p, *term_allocated_p); } #ifdef DEBUG fprintf(drv->log, "Exec: %s\n", sqlite3_sql(statement)); fflush(drv->log); #endif while ((next_row = sqlite3_step(statement)) == SQLITE_ROW) { for (i = 0; i < column_count; i++) { #ifdef DEBUG fprintf(drv->log, "Column %d type: %d\n", i, sqlite3_column_type(statement, i)); fflush(drv->log); #endif switch (sqlite3_column_type(statement, i)) { case SQLITE_INTEGER: { ErlDrvSInt64 *int64_ptr = driver_alloc(sizeof(ErlDrvSInt64)); *int64_ptr = (ErlDrvSInt64) sqlite3_column_int64(statement, i); *ptrs_p = add_to_ptr_list(*ptrs_p, int64_ptr); *term_count_p += 2; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 2] = ERL_DRV_INT64; (*dataset_p)[*term_count_p - 1] = (ErlDrvTermData) int64_ptr; break; } case SQLITE_FLOAT: { double *float_ptr = driver_alloc(sizeof(double)); *float_ptr = sqlite3_column_double(statement, i); *ptrs_p = add_to_ptr_list(*ptrs_p, float_ptr); *term_count_p += 2; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 2] = ERL_DRV_FLOAT; (*dataset_p)[*term_count_p - 1] = (ErlDrvTermData) float_ptr; break; } case SQLITE_BLOB: { int bytes = sqlite3_column_bytes(statement, i); ErlDrvBinary* binary = driver_alloc_binary(bytes); binary->orig_size = bytes; memcpy(binary->orig_bytes, sqlite3_column_blob(statement, i), bytes); *binaries_p = add_to_ptr_list(*binaries_p, binary); *term_count_p += 8; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 8] = ERL_DRV_ATOM; (*dataset_p)[*term_count_p - 7] = drv->atom_blob; (*dataset_p)[*term_count_p - 6] = ERL_DRV_BINARY; (*dataset_p)[*term_count_p - 5] = (ErlDrvTermData) binary; (*dataset_p)[*term_count_p - 4] = bytes; (*dataset_p)[*term_count_p - 3] = 0; (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE; (*dataset_p)[*term_count_p - 1] = 2; break; } case SQLITE_TEXT: { int bytes = sqlite3_column_bytes(statement, i); ErlDrvBinary* binary = driver_alloc_binary(bytes); binary->orig_size = bytes; memcpy(binary->orig_bytes, sqlite3_column_blob(statement, i), bytes); *binaries_p = add_to_ptr_list(*binaries_p, binary); *term_count_p += 4; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 4] = ERL_DRV_BINARY; (*dataset_p)[*term_count_p - 3] = (ErlDrvTermData) binary; (*dataset_p)[*term_count_p - 2] = bytes; (*dataset_p)[*term_count_p - 1] = 0; break; } case SQLITE_NULL: { *term_count_p += 2; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM; (*dataset_p)[*term_count_p - 1] = drv->atom_null; break; } } } *term_count_p += 2; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE; (*dataset_p)[*term_count_p - 1] = column_count; row_count++; } if (next_row == SQLITE_BUSY) { return_error(drv, SQLITE_BUSY, "SQLite3 database is busy", &async_command->dataset, &async_command->term_count, &async_command->error_code); return; } if (next_row != SQLITE_DONE) { return_error(drv, next_row, sqlite3_errmsg(drv->db), &async_command->dataset, &async_command->term_count, &async_command->error_code); return; } printf("\nAfter adding rows: column_count=%d, term_count=%d, term_allocated=%d", column_count, *term_count_p, *term_allocated_p); if (column_count > 0) { *term_count_p += 3+2+3; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 8] = ERL_DRV_NIL; (*dataset_p)[*term_count_p - 7] = ERL_DRV_LIST; (*dataset_p)[*term_count_p - 6] = row_count + 1; (*dataset_p)[*term_count_p - 5] = ERL_DRV_TUPLE; (*dataset_p)[*term_count_p - 4] = 2; (*dataset_p)[*term_count_p - 3] = ERL_DRV_NIL; (*dataset_p)[*term_count_p - 2] = ERL_DRV_LIST; (*dataset_p)[*term_count_p - 1] = 3; printf("\nEnd if branch 1"); } else if (sql_is_insert(sqlite3_sql(statement))) { ErlDrvSInt64 *rowid_ptr = driver_alloc(sizeof(ErlDrvSInt64)); *rowid_ptr = (ErlDrvSInt64) sqlite3_last_insert_rowid(drv->db); *ptrs_p = add_to_ptr_list(*ptrs_p, rowid_ptr); *term_count_p += 6; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 6] = ERL_DRV_ATOM; (*dataset_p)[*term_count_p - 5] = drv->atom_rowid; (*dataset_p)[*term_count_p - 4] = ERL_DRV_INT64; (*dataset_p)[*term_count_p - 3] = (ErlDrvTermData) rowid_ptr; (*dataset_p)[*term_count_p - 2] = ERL_DRV_TUPLE; (*dataset_p)[*term_count_p - 1] = 2; } else { *term_count_p += 2; if (*term_count_p > *term_allocated_p) { *term_allocated_p = max(*term_count_p, *term_allocated_p*2); *dataset_p = driver_realloc(*dataset_p, sizeof(ErlDrvTermData) * *term_allocated_p); } (*dataset_p)[*term_count_p - 2] = ERL_DRV_ATOM; (*dataset_p)[*term_count_p - 1] = drv->atom_ok; } printf("\nEnd if"); printf("\nEnd of sql_exec_one_statement"); #ifdef DEBUG fprintf(drv->log, "Total term count: %p %d, rows count: %dx%d\n", statement, *term_count_p, column_count, row_count); fflush(drv->log); #endif async_command->finalize_statement_on_free = 1; }