apache / apache/doris

[Bug] DECIMALV2 constant folding: 0 / x folds to NULL instead of 0 (divideDecimal checks wrong operand)

Open
#64,681 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
15.9k
Forks
3.9k
Avg merge
2d 23h
Merged PRs (30d)
520

Description

### Search before asking

- [x] I had searched in the [issues](https://github.com/apache/doris/issues) and found no similar issues.

### Version

master (Nereids fold-constant `divideDecimal`).

### What's Wrong?

`NumericArithmetic.divideDecimal` (the DECIMALV2 constant-folding `divide` function) guards against division by zero by checking the **numerator** (`first`) instead of the **denominator** (`second`):

```java
public static Expression divideDecimal(DecimalLiteral first, DecimalLiteral second) {
if (first.getValue().compareTo(BigDecimal.ZERO) == 0) { // wrong operand
return new NullLiteral(first.getDataType());
}
BigDecimal result = first.getValue().divide(second.getValue());
return new DecimalLiteral(result);
}
```

When both operands are constant DECIMALV2 literals (so the fold-constant rule invokes `divideDecimal`):

- `0 / x` folds to **NULL** instead of `0` — a silent wrong result.
- `x / 0` skips the guard and calls `BigDecimal.divide(ZERO)`, throwing `ArithmeticException`. This is caught by `ExpressionEvaluator.invoke` and the expression is left unfolded (BE then evaluates it, returning NULL), so it is not a crash, but the FE folding path is incorrect.

The sibling functions `divideDouble` and `divideDecimalV3` both correctly check `second`.

### What You Expected?

`0 / x` should fold to `0`. Division by zero should return NULL (Doris/MySQL semantics), consistent with `divideDouble` and `divideDecimalV3`.

### How to Reproduce?

Constant-fold a DECIMALV2 division whose numerator literal is `0`, with both operands constant DECIMALV2 literals so the Nereids fold-constant rule dispatches to `divideDecimal`. The folded result is NULL where it should be 0.

### Anything Else?

Fix proposed in PR #64675.

### Are you willing to submit PR?

- [x] Yes I am willing to submit a PR!

Contributor guide

Open the contributing guide

Research direction

Start in NumericArithmetic.divideDecimal and compare its operand check with divideDouble and divideDecimalV3. Trace the Nereids constant-folding path for DECIMALV2 literals, then verify that 0 divided by a nonzero value folds to 0 and division by zero produces NULL without an ArithmeticException escaping the folding path.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
database
Issue type
Bug
Difficulty
1/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.