duckdb / duckdb/duckdb

ConstantOrderNormalizationRule reorders integer chains without a range check

Open
#25,532 1 comment 0 reactions 0 assignees View on GitHub
PR submitted
Dominant language
C++
Stars
41.5k
Forks
3.8k
Avg merge
2d 7h
Merged PRs (30d)
515

Description

### What happens?

`ConstantOrderNormalizationRule` hoists the foldable leaves of a commutative integer chain to the front with no range check, so the chain is evaluated in an order the query did not write and an addition that fits raises an overflow error. It flips back under `disabled_optimizers = 'expression_rewriter'`.

### To Reproduce

```sql
CREATE TABLE t(a INTEGER, b INTEGER);
INSERT INTO t VALUES (2147483645, -2);

SET disabled_optimizers = 'expression_rewriter';
SELECT (a + 1) + (b + 2) FROM t;

SET disabled_optimizers = '';
SELECT (a + 1) + (b + 2) FROM t;
```

```
2147483646
Out of Range Error: Overflow in addition of INT32 (3 + 2147483645)!
```

PostgreSQL 17.11 gives `2147483646` and its plan keeps the written order.

With `explain_output = 'OPTIMIZED_ONLY'` the projection is `((3 + a) + b)`: the rule flattens the chain and moves the foldable leaves to the front, `ConstantFoldingRule` folds `1 + 2` into `3`, and `3 + a` is evaluated first, which overflows where the written order does not. The rule is registered at `src/optimizer/optimizer.cpp:50` and `ConstantFoldingRule` at `:51`.
### OS:

macOS 26.6.2, arm64 (Darwin 25.6.0)

### DuckDB Version:

v1.5.5

### DuckDB Client:

CLI

### Hardware:

Apple M5 Pro, 48 GB

### Full Name:

Ryan Lin

### Affiliation:

Student, University of Waterloo

### Did you include all relevant configuration (e.g., CPU architecture, Linux distribution) to reproduce the issue?

- [x] Yes, I have

### Did you include all code required to reproduce the issue?

- [x] Yes, I have

### Did you include all relevant data sets for reproducing the issue?

Not applicable - the reproduction does not require a data set

Contributor guide

Open the contributing guide

Research direction

Reproduce the SQL example with and without expression_rewriter, then inspect the ConstantOrderNormalizationRule and ConstantFoldingRule registered in src/optimizer/optimizer.cpp:50-51. Trace how the integer chain becomes ((3 + a) + b), and add a regression test showing that the written-order result succeeds without an overflow.】【。

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, sql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.