bert-beyondloops opened a new issue, #25329:
URL: https://github.com/apache/datafusion/issues/25329

   ### Describe the bug
   
    When a non-pushable (`KeepInPlace`) function call appears once bare and 
once wrapped in `get_field(...)`, 
   
   `CommonSubexprEliminate` correctly deduplicates the bare occurrence into a 
`__common_expr_N` column — but leaf-expression pushdown 
(`ExtractLeafExpressions` / `PushDownLeafProjections`) then re-derives the full 
original call a second time when it tries to  push the `get_field` expression 
down, because `__common_expr_N`'s Column reference is indistinguishable, at the 
`ExpressionPlacement` level, from a genuine cheap base-table column.            
                                 
                                                                                
                                                                                
                                                                      
     Net effect: the function is evaluated twice instead of once.         
   
   ### To Reproduce
   
   Using here the `arrow_field` UDF as an example since this function returns a 
struct type. 
   
   ```sql                                                                       
                                                                                
                                                                    
     CREATE TABLE t (a INT) AS VALUES (1), (2);                                 
                                                                                
                                                                      
                                                                                
                                                                                
                                                                      
     EXPLAIN SELECT                                                             
                                                                                
                                                                      
         CASE WHEN arrow_field(a) IS NOT NULL                                   
                                                                                
                                                                      
              THEN get_field(arrow_field(a), 'name') END AS c1                  
                                                                                
                                                                      
     FROM t;   
   ```
   
    **Actual physical plan**                                                    
                                                                                
                                                         
                                                                                
                                                                                
                                                                      
                 
   ```                                                                          
                                                                                
                                                            
   +---------------+-------------------------------+
   | plan_type     | plan                          |
   +---------------+-------------------------------+
   | physical_plan | ┌───────────────────────────┐ |
   |               | │       ProjectionExec      │ |
   |               | │    --------------------   │ |
   |               | │            c1:            │ |
   |               | │  CASE WHEN arrow_field(a) │ |
   |               | │      IS NOT NULL THEN     │ |
   |               | │          get_field        │ |
   |               | │      (arrow_field(a),     │ |
   |               | │          name) END        │ |
   |               | └─────────────┬─────────────┘ |
   |               | ┌─────────────┴─────────────┐ |
   |               | │       DataSourceExec      │ |
   |               | │    --------------------   │ |
   |               | │         bytes: 112        │ |
   |               | │       format: memory      │ |
   |               | │          rows: 1          │ |
   |               | └───────────────────────────┘ |
   |               |                               |
   +---------------+-------------------------------+                            
                                                                                
                  
    ```                                                                         
                                                                                
               
                                                                                
                                                                                
                                                                      
    The function (arrow_field)  is called **twice**.                            
                                                                                
                                                                                
  
      
   
   ### Expected behavior
   
    **Expected physical plan**                                                  
                                                                                
                                                           
                                        
   ```
   +---------------+-------------------------------+
   | plan_type     | plan                          |
   +---------------+-------------------------------+
   | physical_plan | ┌───────────────────────────┐ |
   |               | │       ProjectionExec      │ |
   |               | │    --------------------   │ |
   |               | │            c1:            │ |
   |               | │ CASE WHEN __common_expr_1 │ |
   |               | │      IS NOT NULL THEN     │ |
   |               | │          get_field        │ |
   |               | │     (__common_expr_1,     │ |
   |               | │          name) END        │ |
   |               | └─────────────┬─────────────┘ |
   |               | ┌─────────────┴─────────────┐ |
   |               | │       ProjectionExec      │ |
   |               | │    --------------------   │ |
   |               | │      __common_expr_1:     │ |
   |               | │       arrow_field(a)      │ |
   |               | └─────────────┬─────────────┘ |
   |               | ┌─────────────┴─────────────┐ |
   |               | │       DataSourceExec      │ |
   |               | │    --------------------   │ |
   |               | │         bytes: 112        │ |
   |               | │       format: memory      │ |
   |               | │          rows: 1          │ |
   |               | └───────────────────────────┘ |
   |               |                               |
   +---------------+-------------------------------+
   
   ```
                                                                                
                                                                                
               
   The function (arrow_field) is called **once**; 
   `get_field` references the shared `__common_expr_1` column.               
   
   
   ### Additional context
   
   _No response_


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