cblp opened a new issue, #26851:
URL: https://github.com/apache/datafusion/issues/26851

   ### Describe the bug
   
   When DataFusion infers the schema of Parquet files and 
`datafusion.execution.parquet.skip_metadata` is `true` (the default), 
`clear_metadata` in `datafusion/datasource-parquet/src/file_format.rs` replaces 
the metadata of every top-level field with an empty map. This also removes 
`ARROW:extension:name` and `ARROW:extension:metadata`, so a column with an 
Arrow extension type (`arrow.uuid`, `arrow.json`, `geoarrow.*`, 
`arrow.parquet.variant`, ...) is read as its plain storage type.
   
   As a result, DataFusion cannot read back the extension types it writes: a 
table with an extension-typed column written with `COPY ... TO 'file.parquet'` 
comes back without the extension type. Extension-aware UDFs and type planners 
then see a plain `FixedSizeBinary` / `Binary` / `Struct`.
   
   The problem affects any number of files, not only multi-file tables: 
`clear_metadata` runs before `Schema::try_merge` in 
`ParquetFormat::infer_schema` whenever `skip_metadata` is set.
   
   This is the item "Parquet schema inference clears all field metadata before 
`Schema::try_merge` when `skip_metadata = true`" in the Variant epic #26517, 
filed here as a separate issue.
   
   ### To Reproduce
   
   With `datafusion` 55.0.0 from PyPI (`clear_metadata` is unchanged on `main` 
at e8940acd4):
   
   ```python
   import datafusion
   import pyarrow as pa
   import pyarrow.parquet as pq
   
   # An extension type unknown to pyarrow, so that pyarrow keeps it as field 
metadata
   field = pa.field("u", pa.binary(16), metadata={"ARROW:extension:name": 
"example.ext"})
   table = pa.table({"u": pa.array([b"\x00" * 16], pa.binary(16))}, 
schema=pa.schema([field]))
   pq.write_table(table, "ext.parquet")
   print("written:", pq.read_schema("ext.parquet").field("u").metadata)
   
   ctx = datafusion.SessionContext()
   for skip_metadata in [True, False]:
       df = ctx.read_parquet("ext.parquet", skip_metadata=skip_metadata)
       print(f"skip_metadata = {skip_metadata}:", 
df.schema().field("u").metadata)
   ```
   
   Output:
   
   ```
   written: {b'ARROW:extension:name': b'example.ext'}
   skip_metadata = True: None
   skip_metadata = False: {b'ARROW:extension:name': b'example.ext'}
   ```
   
   The example uses an extension name unknown to pyarrow (`example.ext`): 
pyarrow turns a known name such as `arrow.uuid` into its own extension type, so 
the metadata would not be visible from Python. The behavior of DataFusion is 
the same for any extension name.
   
   ### Expected behavior
   
   The extension type keys `ARROW:extension:name` and 
`ARROW:extension:metadata` are kept, and the rest of the field metadata is 
cleared as before:
   
   ```
   skip_metadata = True: {b'ARROW:extension:name': b'example.ext'}
   ```
   
   The extension type is part of the type of a column, not a writer annotation, 
so `skip_metadata` should not remove it. Turning `skip_metadata` off is not a 
good workaround: it also keeps the schema-level metadata and all other field 
metadata, which brings back the merge conflicts that the option exists to avoid.
   
   ### Additional context
   
   Proposed fix: in `clear_metadata`, keep the `ARROW:extension:*` keys of each 
field and drop the rest. This is the fix suggested in #26517.
   
   Points to agree on:
   
   - **Behavior change.** Files with extension-typed columns will now be read 
with the extension type by default. Plans and type coercion over such columns 
may change.
   - **Merging files.** If a column has an extension type in one file and not 
in another, or different `ARROW:extension:metadata` in different files, 
`Schema::try_merge` may now fail where it used to succeed. I think an error is 
right here because the types differ, but this needs agreement.
   - **Nested fields.** `clear_metadata` only touches top-level fields. 
Metadata of nested fields (list items, struct children) is not cleared today, 
so nested extension types already survive. The fix keeps that as is.
   
   Related: #12644 (extension types), #26810 (extension metadata through 
`UNION`).
   
   ### Willingness to contribute
   
   I plan to contribute a fix for this bug independently


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to