in c/driver/sqlite/statement_reader.c [973:1126]
AdbcStatusCode StatementReaderInferOneValue(
sqlite3_stmt* stmt, int col, struct ArrowBitmap* validity, struct ArrowBuffer* data,
struct ArrowBuffer* binary, enum ArrowType* current_type, struct AdbcError* error) {
// TODO: static_assert sizeof(int64) == sizeof(double)
int sqlite_type = sqlite3_column_type(stmt, col);
switch (sqlite_type) {
case SQLITE_NULL: {
ArrowBitmapAppendUnsafe(validity, /*set=*/0, /*length=*/1);
switch (*current_type) {
case NANOARROW_TYPE_INT64: {
int64_t value = 0;
ArrowBufferAppendUnsafe(data, &value, sizeof(int64_t));
break;
}
case NANOARROW_TYPE_DOUBLE: {
double value = 0.0;
ArrowBufferAppendUnsafe(data, &value, sizeof(int64_t));
break;
}
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_BINARY: {
const int32_t offset = ((int32_t*)data->data)[data->size_bytes / 4 - 1];
CHECK_NA(INTERNAL, ArrowBufferAppend(data, &offset, sizeof(offset)), error);
return ADBC_STATUS_OK;
}
default:
return ADBC_STATUS_INTERNAL;
}
break;
}
case SQLITE_INTEGER: {
ArrowBitmapAppendUnsafe(validity, /*set=*/1, /*length=*/1);
switch (*current_type) {
case NANOARROW_TYPE_INT64: {
int64_t value = sqlite3_column_int64(stmt, col);
ArrowBufferAppendUnsafe(data, &value, sizeof(int64_t));
break;
}
case NANOARROW_TYPE_DOUBLE: {
double value = sqlite3_column_double(stmt, col);
ArrowBufferAppendUnsafe(data, &value, sizeof(int64_t));
break;
}
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_BINARY: {
int32_t offset = ((int32_t*)data->data)[data->size_bytes / 4 - 1];
return StatementReaderAppendInt64ToBinary(
data, binary, sqlite3_column_int64(stmt, col), &offset, error);
}
default:
return ADBC_STATUS_INTERNAL;
}
break;
}
case SQLITE_FLOAT: {
ArrowBitmapAppendUnsafe(validity, /*set=*/1, /*length=*/1);
switch (*current_type) {
case NANOARROW_TYPE_INT64: {
AdbcStatusCode status = StatementReaderUpcastInt64ToDouble(data, error);
if (status != ADBC_STATUS_OK) return status;
*current_type = NANOARROW_TYPE_DOUBLE;
double value = sqlite3_column_double(stmt, col);
ArrowBufferAppendUnsafe(data, &value, sizeof(double));
break;
}
case NANOARROW_TYPE_DOUBLE: {
double value = sqlite3_column_double(stmt, col);
ArrowBufferAppendUnsafe(data, &value, sizeof(double));
break;
}
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_BINARY: {
int32_t offset = ((int32_t*)data->data)[data->size_bytes / 4 - 1];
return StatementReaderAppendDoubleToBinary(
data, binary, sqlite3_column_double(stmt, col), &offset, error);
}
default:
return ADBC_STATUS_INTERNAL;
}
break;
}
case SQLITE_TEXT: {
ArrowBitmapAppendUnsafe(validity, /*set=*/1, /*length=*/1);
switch (*current_type) {
case NANOARROW_TYPE_INT64: {
AdbcStatusCode status = StatementReaderUpcastInt64ToBinary(data, binary, error);
if (status != ADBC_STATUS_OK) return status;
*current_type = NANOARROW_TYPE_STRING;
break;
}
case NANOARROW_TYPE_DOUBLE: {
AdbcStatusCode status =
StatementReaderUpcastDoubleToBinary(data, binary, error);
if (status != ADBC_STATUS_OK) return status;
*current_type = NANOARROW_TYPE_STRING;
break;
}
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_BINARY:
break;
default:
return ADBC_STATUS_INTERNAL;
}
const unsigned char* value = sqlite3_column_text(stmt, col);
const int size = sqlite3_column_bytes(stmt, col);
const int32_t offset = ((int32_t*)data->data)[data->size_bytes / 4 - 1] + size;
CHECK_NA(INTERNAL, ArrowBufferAppend(binary, value, size), error);
CHECK_NA(INTERNAL, ArrowBufferAppend(data, &offset, sizeof(offset)), error);
break;
}
case SQLITE_BLOB: {
ArrowBitmapAppendUnsafe(validity, /*set=*/1, /*length=*/1);
switch (*current_type) {
case NANOARROW_TYPE_INT64: {
AdbcStatusCode status = StatementReaderUpcastInt64ToBinary(data, binary, error);
if (status != ADBC_STATUS_OK) return status;
*current_type = NANOARROW_TYPE_BINARY;
break;
}
case NANOARROW_TYPE_DOUBLE: {
AdbcStatusCode status =
StatementReaderUpcastDoubleToBinary(data, binary, error);
if (status != ADBC_STATUS_OK) return status;
*current_type = NANOARROW_TYPE_BINARY;
break;
}
case NANOARROW_TYPE_STRING:
*current_type = NANOARROW_TYPE_BINARY;
break;
case NANOARROW_TYPE_BINARY:
break;
default:
return ADBC_STATUS_INTERNAL;
}
const void* value = sqlite3_column_blob(stmt, col);
const int size = sqlite3_column_bytes(stmt, col);
const int32_t offset = ((int32_t*)data->data)[data->size_bytes / 4 - 1] + size;
CHECK_NA(INTERNAL, ArrowBufferAppend(binary, value, size), error);
CHECK_NA(INTERNAL, ArrowBufferAppend(data, &offset, sizeof(offset)), error);
break;
}
default: {
return ADBC_STATUS_NOT_IMPLEMENTED;
}
}
return ADBC_STATUS_OK;
} // NOLINT(whitespace/indent)