The DuckDB C Query API has two ways to extract values from a query result. One way is to use the duckdb_value_TYPE functions which take a row and col and return a value, the other, more dangerous, way is to use the duckdb_column_data function which returns a pointer.
proc duckdb_column_data*(result: ptr duckdb_result; col: idx_t): pointer {.
importc, cdecl, impduckdbDyn.}
If I have a query like SELECT i from integers LIMIT 4 the proc below echos an array with the correct values. In the example below I know the row and type in advance. I can dynamically determine the row and and type I just can't use the same approach below to specify an array dynamically.
proc getColVeryUnsafe*(result: var duckdb_result, colnum: idx_t) =
var p = duckdb_column_data(result.addr, colnum)
echo cast[ptr array[4, int32]](p)[]
duckdb_destroy_result(result.addr)
Here is a more complete example of the duckdb_column_data functions in C and I'm wondering how I might translate this:
int32_t *i_data = (int32_t *) duckdb_column_data(&result, 0);
int32_t *j_data = (int32_t *) duckdb_column_data(&result, 1);
bool *i_mask = duckdb_nullmask_data(&result, 0);
bool *j_mask = duckdb_nullmask_data(&result, 1);
idx_t row_count = duckdb_row_count(&result);
for(idx_t row = 0; row < row_count; row++) {
if (i_mask[row]) {
printf("NULL");
} else {
printf("%d", i_data[row]);
}
printf(",");
if (j_mask[row]) {
printf("NULL");
} else {
printf("%d", j_data[row]);
}
printf("\n");
}
First, I would not use array[N, T] for C interop but ptr UncheckedArray[T] instead.
Usually database query returns a string or a seq[string] (when multiple values); a string in Nim a string can be used as a buffer and then it's up to the user to convert the result.
See db_sqlite getValue proc for example.