james-willis opened a new pull request, #26951:
URL: https://github.com/apache/datafusion/pull/26951

   ## Which issue does this PR close?
   
   - Part of #24860.
   
   **Depends on #26145.** This PR makes the simplifier copy the CASE's field 
metadata onto the NULL it folds to. On `main`, a CASE's field has no metadata 
yet (#26145 fixes that), so this change has no effect there, and the new tests 
fail until #26145 merges. They pass with this commit applied on top of #26145.
   
   ## Rationale for this change
   
   `CASE WHEN false THEN x END` (including forms that constant-fold to `false`, 
such as `WHEN 1 = 0`) loses the Arrow extension type of `x`. Planning sees the 
CASE's field, but the simplifier then replaces the CASE with a bare `NULL` 
literal without metadata, so a function that checks its argument's extension 
type sees a different type after optimization than during planning.
   
   With #26145 and #26158 applied, this is the only remaining place where the 
following query loses the extension type:
   
   ```sql
   select arrow_metadata(
     case when 1 = 0 then with_metadata(name, 'ARROW:extension:name', 'a.type') 
end,
     'ARROW:extension:name')
   from table_with_metadata;
   -- a.type with this PR + #26145; NULL without this PR
   ```
   
   `EXPLAIN` shows the CASE has already become `Utf8(NULL)` before physical 
planning, so the physical CASE fix in #26158 does not reach it.
   
   ## What changes are included in this PR?
   
   - `CASE WHEN false THEN A END --> NULL` (every WHEN is false and there is no 
ELSE) now builds the NULL from the CASE's own field: its type and its metadata. 
The merge policy stays in `Expr::Case`'s `to_field` (#26145); the simplifier 
does not compute it separately.
   - The other folds in the same rule are unchanged. `CASE WHEN false THEN A 
ELSE B END --> B` and `CASE WHEN true THEN A ... END --> A` already return the 
surviving branch, which carries its own metadata.
   
   ## What is the testing strategy for this PR?
   
   - `metadata.slt`: the query above, checking the extension type at execution 
after the fold.
   - `expr_simplifier.rs`: 
`simplify_expr_case_when_false_keeps_field_metadata`, checking the folded 
literal carries the metadata of the column it replaced.
   - The existing CASE simplifier tests still pass.
   - Run locally: on `main`, only the two new tests fail (the literal has no 
metadata). With this commit on top of #26145, all `datafusion-optimizer` lib 
tests and `metadata.slt` pass.
   
   ## Are there any user-facing changes?
   
   No API changes. A CASE that is folded to `NULL` keeps its field metadata.
   


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