Describe the bug, including details regarding any error messages, version, and platform.
Description
Arrow Go permits unsigned Arrow integer types as typed_value fields in the arrow.parquet.variant extension type. When such an array is written to Parquet, the unsigned Arrow type is materialized directly as an unsigned Parquet integer column.
For example, an Arrow Uint32 Variant typed_value produces:
optional int32 typed_value (Int(bitWidth=32, isSigned=false));
This is not a valid shredded Variant type according to the Parquet Variant shredding specification. Its supported integer representations are:
int8 → INT32 / INT(8, true)
int16 → INT32 / INT(16, true)
int32 → INT32
int64 → INT64
Unsigned Parquet integer logical types are not supported.
The current Arrow canonical Variant extension specification permits unsigned Arrow storage types through widening mappings:
Uint8 → Variant Int16
Uint16 → Variant Int32
Uint32 → Variant Int64
Interoperability test
The parquet-testing interoperability suite includes case 127, which expects INTEGER(32,false) to be rejected:
{
"case_number": 127,
"test": "testUnsignedInteger",
"parquet_file": "case-127.parquet",
"error_message": "Unsupported shredded value type: INTEGER(32,false)"
}
Arrow Go currently skips that case with:
s.T().Skip("Skipping case 127: test says uint32 should error, we just upcast to int64")
The Parquet column is not upcast to int64. It is materialized as Arrow Uint32, retained as array.Uint32, and written back to Parquet as INT32 / INT(32,false).
Variant reconstruction may encode the value as a signed Variant integer, using Int64 where necessary, but that does not make the shredded Parquet schema valid.
Expected behavior
At minimum, Arrow Go should cast unsigned Arrow typed_value columns to their signed, widened Variant representations when writing Parquet:
Uint8 → signed Int16
Uint16 → signed Int32
Uint32 → signed Int64
The resulting Parquet typed_value columns must use the corresponding signed shredded types rather than unsigned integer logical annotations.
The more complete resolution is to drop unsigned typed_value support from the Arrow Variant extension type altogether. If the Arrow specification change below is accepted, Arrow Go can reject unsigned Variant typed_value schemas directly, without requiring fine-grained conversions in the Parquet writer.
The interoperability test for case 127 should no longer be skipped. Its skip comment should also be removed or corrected because no Parquet schema upcast currently occurs.
Related Arrow specification change
The current Arrow canonical extension specification permits these unsigned mappings, creating a representation that cannot map directly to a conforming Parquet shredded schema.
The following PR proposes aligning Arrow’s Variant primitive mappings with the Parquet shredding specification by removing unsupported mappings such as unsigned integers and Null:
Relevant links
Generated with codex and proof read
Component(s)
Parquet
Describe the bug, including details regarding any error messages, version, and platform.
Description
Arrow Go permits unsigned Arrow integer types as
typed_valuefields in thearrow.parquet.variantextension type. When such an array is written to Parquet, the unsigned Arrow type is materialized directly as an unsigned Parquet integer column.For example, an Arrow
Uint32Varianttyped_valueproduces:This is not a valid shredded Variant type according to the Parquet Variant shredding specification. Its supported integer representations are:
int8→INT32 / INT(8, true)int16→INT32 / INT(16, true)int32→INT32int64→INT64Unsigned Parquet integer logical types are not supported.
The current Arrow canonical Variant extension specification permits unsigned Arrow storage types through widening mappings:
Uint8→ VariantInt16Uint16→ VariantInt32Uint32→ VariantInt64Interoperability test
The parquet-testing interoperability suite includes case 127, which expects
INTEGER(32,false)to be rejected:{ "case_number": 127, "test": "testUnsignedInteger", "parquet_file": "case-127.parquet", "error_message": "Unsupported shredded value type: INTEGER(32,false)" }Arrow Go currently skips that case with:
The Parquet column is not upcast to
int64. It is materialized as ArrowUint32, retained asarray.Uint32, and written back to Parquet asINT32 / INT(32,false).Variant reconstruction may encode the value as a signed Variant integer, using
Int64where necessary, but that does not make the shredded Parquet schema valid.Expected behavior
At minimum, Arrow Go should cast unsigned Arrow
typed_valuecolumns to their signed, widened Variant representations when writing Parquet:Uint8→ signedInt16Uint16→ signedInt32Uint32→ signedInt64The resulting Parquet
typed_valuecolumns must use the corresponding signed shredded types rather than unsigned integer logical annotations.The more complete resolution is to drop unsigned
typed_valuesupport from the Arrow Variant extension type altogether. If the Arrow specification change below is accepted, Arrow Go can reject unsigned Varianttyped_valueschemas directly, without requiring fine-grained conversions in the Parquet writer.The interoperability test for case 127 should no longer be skipped. Its skip comment should also be removed or corrected because no Parquet schema upcast currently occurs.
Related Arrow specification change
The current Arrow canonical extension specification permits these unsigned mappings, creating a representation that cannot map directly to a conforming Parquet shredded schema.
The following PR proposes aligning Arrow’s Variant primitive mappings with the Parquet shredding specification by removing unsupported mappings such as unsigned integers and Null:
typed_valueprimitive type mappings with the Parquet shredding spec arrow#50810typed_valueprimitive type mappings with the Parquet shredding spec arrow#50622Relevant links
INTEGER(32,false)maps to ArrowUint32array.Uint32Generated with codex and proof read
Component(s)
Parquet