in c/driver/sqlite/statement_reader.c [458:559]
int StatementReaderGetOneValue(struct StatementReader* reader, int col,
struct ArrowArray* out) {
int sqlite_type = sqlite3_column_type(reader->stmt, col);
if (sqlite_type == SQLITE_NULL) {
return ArrowArrayAppendNull(out, 1);
}
switch (reader->types[col]) {
case NANOARROW_TYPE_INT64: {
switch (sqlite_type) {
case SQLITE_INTEGER: {
int64_t value = sqlite3_column_int64(reader->stmt, col);
return ArrowArrayAppendInt(out, value);
}
case SQLITE_FLOAT: {
// TODO: behavior needs to be configurable
snprintf(reader->error.message, sizeof(reader->error.message),
"[SQLite] Type mismatch in column %d: expected INT64 but got DOUBLE",
col);
return EIO;
}
case SQLITE_TEXT:
case SQLITE_BLOB: {
snprintf(
reader->error.message, sizeof(reader->error.message),
"[SQLite] Type mismatch in column %d: expected INT64 but got STRING/BINARY",
col);
return EIO;
}
default: {
snprintf(reader->error.message, sizeof(reader->error.message),
"[SQLite] Type mismatch in column %d: expected INT64 but got unknown "
"type %d",
col, sqlite_type);
return ENOTSUP;
}
}
break;
}
case NANOARROW_TYPE_DOUBLE: {
switch (sqlite_type) {
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
// Let SQLite convert
double value = sqlite3_column_double(reader->stmt, col);
return ArrowArrayAppendDouble(out, value);
}
case SQLITE_TEXT:
case SQLITE_BLOB: {
snprintf(reader->error.message, sizeof(reader->error.message),
"[SQLite] Type mismatch in column %d: expected DOUBLE but got "
"STRING/BINARY",
col);
return EIO;
}
default: {
snprintf(reader->error.message, sizeof(reader->error.message),
"[SQLite] Type mismatch in column %d: expected DOUBLE but got unknown "
"type %d",
col, sqlite_type);
return ENOTSUP;
}
}
break;
}
case NANOARROW_TYPE_STRING: {
switch (sqlite_type) {
case SQLITE_INTEGER:
case SQLITE_FLOAT:
case SQLITE_TEXT:
case SQLITE_BLOB: {
// Let SQLite convert
struct ArrowStringView value = {
.data = (const char*)sqlite3_column_text(reader->stmt, col),
.size_bytes = sqlite3_column_bytes(reader->stmt, col),
};
return ArrowArrayAppendString(out, value);
}
default: {
snprintf(reader->error.message, sizeof(reader->error.message),
"[SQLite] Type mismatch in column %d: expected STRING but got unknown "
"type %d",
col, sqlite_type);
return ENOTSUP;
}
}
break;
}
default: {
snprintf(reader->error.message, sizeof(reader->error.message),
"[SQLite] Internal error: unknown inferred column type %d",
reader->types[col]);
return ENOTSUP;
}
}
return 0;
}