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

   ### Describe the bug
   
   `simplify_expressions` folds `A * 0` to a zero literal typed from the 
*operands*
   rather than from the multiplication's *result type*. When those differ, the
   rewritten plan compares two differently-typed decimals, which fails.
   
   On an empty table it fails while planning, with an internal error:
   
   ```
   Internal error: Assertion failed: lhs_type == rhs_type (left: Decimal128(20, 
0), right: Decimal128(38, 0)): Only intervals with the same data type are 
comparable, lhs:Decimal128(20, 0), rhs:Decimal128(38, 0).
   ```
   
   With rows it fails at execution instead:
   
   ```
   Arrow error: Invalid argument error: Invalid comparison operation: 
Decimal128(20, 0) >= Decimal128(38, 0)
   ```
   
   `EXPLAIN VERBOSE` shows type coercion doing the right thing and the 
simplifier
   then dropping the result type:
   
   ```
   Filter: t.c * Int64(0) >= Int64(2)
   
   after type_coercion:
   Filter: CAST(t.c AS Decimal128(20, 0)) * CAST(Int64(0) AS Decimal128(20, 0)) 
>= CAST(Int64(2) AS Decimal128(38, 0))
   
   after simplify_expressions:
   Filter: Decimal128(0,20,0) >= Decimal128(2,38,0)
   ```
   
   Coercion is correct: `Decimal128(20, 0) * Decimal128(20, 0)` has result type
   `Decimal128(38, 0)`, so casting the literal `2` to `Decimal128(38, 0)` is 
right.
   The simplifier then replaces the whole multiplication with the zero operand,
   which is `Decimal128(20, 0)`, and the comparison no longer matches.
   
   ### To Reproduce
   
   ```sql
   CREATE TABLE t(c UBIGINT NOT NULL);
   SELECT c FROM t WHERE (c * 0) >= 2;
   ```
   
   Every part of that is load-bearing, which I think points at the cause:
   
   | variation | result |
   | --- | --- |
   | `c UBIGINT NOT NULL` | fails |
   | `c UBIGINT` (nullable) | plans fine — `A * 0 -> 0` requires non-nullable 
`A`, so no fold happens |
   | `c * 1`, `c * 2`, `c * -1`, `c * c` | plan fine — `A * 1` already 
preserves the result type, via `simplify_right_is_one_case` |
   | `(c * 0) = 2` | plans fine — `Interval::equal` tolerates differing types, 
unlike `gt`/`gt_eq` |
   | `(c * 0) BETWEEN 2 AND 3` | fails (desugars to `>=` and `<=`) |
   | `USMALLINT`, `UTINYINT` | plan fine — only the 64-bit unsigned width 
reaches `Decimal128` |
   
   ### Expected behavior
   
   The query should plan and run, returning no rows: `c * 0` is `0`, and `0 >= 
2`
   is false.
   
   ### Additional context
   
   Reproduced on `datafusion-cli 55.1.0` built from commit `e8940acd4`
   (2026-10-28), Linux x86_64.
   
   The internal-error form is an instance of the class #22028 describes. That 
tree
   already contains #22027 (`631f189f0`, "coerce operand types in Interval
   mul/div/intersect/union/contains"), which is why the failure surfaces in
   `Interval::gt_eq` — the comparison path it did not cover. Coercing there too
   turns the planning-time internal error into the Arrow error above, so the
   interval assertion is a symptom; the type loss in the simplifier is the 
cause.
   Closed #13186 and #17814 report the same assertion text with different types 
and
   repros.
   
   Found with a metamorphic/differential SQL testing tool I am building for a
   university software-engineering course.
   
   ### Willingness to contribute
   
   I have a fix ready and will open a PR referencing this issue: the `A * 0` and
   `0 * A` arms check `BinaryTypeCoercer::get_result_type()` and cast the zero 
when
   it differs, mirroring what `simplify_right_is_one_case` already does for
   `A * 1`. Two lines changed plus one helper, with a test.
   


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