|
ArrowSchema* schema, PostgresType* out, |
|
ArrowError* error) { |
|
ArrowSchemaView schema_view; |
|
NANOARROW_RETURN_NOT_OK(ArrowSchemaViewInit(&schema_view, schema, error)); |
|
|
|
if (schema_view.extension_name.data != nullptr && |
|
std::string_view(schema_view.extension_name.data, |
|
schema_view.extension_name.size_bytes) |
|
.compare("arrow.json") == 0) { |
|
switch (schema_view.type) { |
|
case NANOARROW_TYPE_STRING: |
|
case NANOARROW_TYPE_LARGE_STRING: |
|
case NANOARROW_TYPE_STRING_VIEW: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kJson), out, error); |
|
default: |
|
break; |
|
} |
|
ArrowErrorSet( |
|
error, "Field '%s' is of type arrow.json but storage type is not a string type", |
|
schema_view.schema->name); |
|
return EINVAL; |
|
} |
|
|
|
switch (schema_view.type) { |
|
case NANOARROW_TYPE_BOOL: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kBool), out, error); |
|
case NANOARROW_TYPE_INT8: |
|
case NANOARROW_TYPE_UINT8: |
|
case NANOARROW_TYPE_INT16: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kInt2), out, error); |
|
case NANOARROW_TYPE_UINT16: |
|
case NANOARROW_TYPE_INT32: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kInt4), out, error); |
|
case NANOARROW_TYPE_UINT32: |
|
case NANOARROW_TYPE_INT64: |
|
case NANOARROW_TYPE_UINT64: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kInt8), out, error); |
|
case NANOARROW_TYPE_HALF_FLOAT: |
|
case NANOARROW_TYPE_FLOAT: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kFloat4), out, error); |
|
case NANOARROW_TYPE_DOUBLE: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kFloat8), out, error); |
|
case NANOARROW_TYPE_STRING: |
|
case NANOARROW_TYPE_LARGE_STRING: |
|
case NANOARROW_TYPE_STRING_VIEW: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kText), out, error); |
|
case NANOARROW_TYPE_BINARY: |
|
case NANOARROW_TYPE_LARGE_BINARY: |
|
case NANOARROW_TYPE_FIXED_SIZE_BINARY: |
|
case NANOARROW_TYPE_BINARY_VIEW: |
|
return resolver.Find(resolver.GetOID(PostgresTypeId::kBytea), out, error); |
What happened?
adbc_driver_postgresqlbinds a canonical Arrow UUID parameter as PostgreSQLbyteainstead ofuuid.PyArrow 25.0.0 infers a Python
uuid.UUIDvalue asextension<arrow.uuid>withfixed_size_binary[16]storage. The PostgreSQLdriver's
PostgresType::FromSchema()recognizesarrow.json, but does notrecognize
arrow.uuid; it falls through to the storage-type switch, where allFixedSizeBinaryvalues resolve to PostgreSQLbytea.As a result, using the parameter against a PostgreSQL
uuidcolumn fails whilethe statement is prepared:
Stack Trace
Expected behavior: a field carrying the canonical
arrow.uuidextension nameand valid
FixedSizeBinary(16)storage should bind as PostgreSQLuuid.Unannotated
FixedSizeBinary(16)should continue to bind asbytea.How can we reproduce the bug?
This reproduction uses ADBC directly; SQLSpec is not involved.
Relevant source:
arrow-adbc/c/driver/postgresql/postgres_type.h
Lines 588 to 638 in 84a56fe
Arrow UUID specification:
https://arrow.apache.org/docs/format/CanonicalExtensions.html#uuid
Environment/Setup
adbc-driver-postgresql==1.11.0adbc-driver-manager==1.11.0pyarrow==25.0.0