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

   **Describe the bug**
   
   `datafusion.execution.parquet.binary_as_string = true` changes a Parquet 
`Binary` column to a string type in the schema that DataFusion gives to the 
Parquet reader. If the column holds bytes that are not valid UTF-8, the reader 
returns an invalid string array and reports no error. The first operation that 
decodes those bytes then stops the process with SIGSEGV. The user gets no 
message and no error code from the query.
   
   This is not limited to unusual schemas. A top level column is sufficient.
   
   **To Reproduce**
   
   ```shell
   datafusion-cli -c "COPY (SELECT decode('ff','hex') AS b) TO 'bin.parquet'" 
-c "set datafusion.execution.parquet.binary_as_string = true" -c "SELECT b FROM 
'bin.parquet'"
   ```
   
   ```
   DataFusion CLI v54.0.0
   +-------+
   | count |
   +-------+
   | 1     |
   +-------+
   1 row(s) fetched.
   Elapsed 0.010 seconds.
   
   0 row(s) fetched.
   Elapsed 0.001 seconds.
   ```
   
   The exit code is 139. The macOS crash report shows `SIGSEGV` with the fault 
in `comfy_table::Row::max_content_widths`, which measures the width of the 
invalid string. With `SELECT upper(b)` the fault moves to 
`alloc::str::to_uppercase`.
   
   Measured on the released `datafusion-cli` 54.0.0 and on a debug build of 
`main` at 4e907557ad (arrow and parquet 59.3.0):
   
   | Column type and target | Build | Result |
   | --- | --- | --- |
   | `Binary` to `Utf8View` (defaults) | release | SIGSEGV |
   | `Binary` to `Utf8View` (defaults) | debug | non-unwinding panic from the 
`core::str::validations` UB check, then abort |
   | `Binary` to `Utf8` (`schema_force_view_types = false`) | release | SIGSEGV 
|
   | `Binary` to `Utf8` | debug | panic in 
`parquet-59.3.0/src/arrow/buffer/offset_buffer.rs:141`: `Invalid UTF8 sequence 
at string index 0` |
   | `LargeBinary` to `LargeUtf8` | release | SIGSEGV |
   | `BinaryView` to `Utf8View` | release | SIGSEGV |
   
   `count(*)`, `octet_length(b)` and the byte-wise comparison `b = 'ok'` all 
succeed, because they do not decode UTF-8. The invalid array moves through the 
plan without a sign of a problem.
   
   An explicit cast is safe, which shows the difference:
   
   ```shell
   datafusion-cli -c "COPY (SELECT decode('ff','hex') AS b) TO 'bin.parquet'" 
-c "SELECT arrow_cast(b, 'Utf8') FROM 'bin.parquet'"
   ```
   
   ```
   Error: Arrow error: Invalid argument error: Encountered non UTF-8 data: 
invalid utf-8 sequence of 1 bytes from index 0
   ```
   
   Valid multibyte UTF-8 in a `Binary` column reads correctly with the option 
on.
   
   **Expected behavior**
   
   The query must fail with an error, in the same way as the explicit cast. 
DataFusion must not give an invalid string array to the rest of the plan.
   
   **Additional context**
   
   The cause is in parquet-rs. `ByteArrayColumnValueDecoder::new` selects UTF-8 
validation from the physical Parquet annotation only:
   
   ```rust
   // parquet/src/arrow/array_reader/byte_array.rs:192
   let validate_utf8 = desc.converted_type() == ConvertedType::UTF8;
   ```
   
   A plain BYTE_ARRAY column has no `UTF8` annotation, so the target Arrow type 
that DataFusion supplies through `ArrowReaderOptions::with_schema` has no 
effect. `OffsetBuffer::into_array` then uses 
`ArrayDataBuilder::build_unchecked` in release builds. Upstream report: 
PLACEHOLDER_ARROW
   
   Found while reviewing https://github.com/apache/datafusion/pull/25342. That 
PR does not introduce the problem. It applies the same override to map 
children, so it makes more reads reach this path.
   


-- 
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