You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Linux amd64, CPU build, Go 1.26.4. Local isolated CN/TN/logservice with MinIO, GOMAXPROCS=2. Reproduced on actual SQL execution, not only plan inspection.
Actual Behavior
The planner algebraically transposes top-level arithmetic equality without proving preservation of floating rounding or integer overflow behavior. This produces incorrect rows and suppresses an arithmetic error. A logically equivalent OR wrapper uses the guarded Boolean normalization and gives different results.
Steps to Reproduce
CREATEDATABASEqa_transpose;
USE qa_transpose;
CREATETABLEfp(v DOUBLE);
INSERT INTO fp VALUES (1e-17), (0), (NULL);
SELECT v, v + 1e0 = 1e0 FROM fp ORDER BY v;
-- NULL NULL; 0 true; 0.00000000000000001 trueSELECT v FROM fp WHERE v + 1e0 = 1e0 ORDER BY v;
-- Actual: only 0. Expected: 0 and 0.00000000000000001.SELECT v FROM fp WHERE v + 1e0 = 1e0 OR v IS NULLORDER BY v;
-- Actual: all three rows, including 1e-17.
EXPLAIN SELECT v FROM fp WHERE v + 1e0 = 1e0;
-- Filter Cond: (fp.v = 0)CREATETABLEov(v BIGINT);
INSERT INTO ov VALUES (9223372036854775807);
SELECT v FROM ov WHERE v +1=9223372036854775807;
-- Actual: empty result, no error.SELECT v, v +1FROM ov;
-- ERROR 1690 (22003): int64 out of range (9223372036854775807 + 1).
Expected Behavior
Filter evaluation must preserve SQL arithmetic semantics. For binary64, 1e-17 + 1 rounds to 1, so transposing this equality to v=0 is invalid. Integer overflow must not disappear because a predicate is algebraically rearranged.
Additional Information
pkg/sql/plan/utils.go:ConstantTranspose still performs legacy equality algebra using canTranspose/getPath and inverse +/- operations. normalizeNativeRangeDirection protects Boolean subtrees, but top-level equality falls through to the old transformation. The existing planner normalization should own a consistent arithmetic safety policy across both paths; avoid a separate competing rewrite or merely patching this literal example.
Found during integrated QA of the latest ten author commits, including #29525. Attribution is not part of this report. The new Boolean guard does not close the shared top-level arithmetic domain invariant.
Suggested regression coverage: DOUBLE/FLOAT absorbed increments, cancellation and subtraction direction, prepared bindings, AND/OR nesting, integer overflow/underflow, safe exact controls, and indexed/composite-sortkey filters. Compare actual row sets and error behavior to independently evaluated expressions, not only expected generated plans.
Activity
fix: preserve arithmetic filter semantics through scan pruning (#29544)
Ariznawlll commentedon Oct 2, 2026
测试版本
maind50a2d475a406829f67127fef7b2ad4abc1c1d3dmo-service,独立数据目录;MySQL 文本协议与 server-side PREPARE原问题验证
按 issue 原始语义在上述 commit 重新执行并重复 3 次。浮点谓词改写后同时保留 0 与 1e-17 两行;BIGINT 溢出仍返回 ERROR 1690。
Happy Path 覆盖
覆盖等式移项前后、正负极小量和常量侧交换。
Unhappy Path 覆盖
覆盖整数越界、NULL、NaN/Inf;未因优化改写改变错误或结果集合。
白盒验证
关联修复 #29544 已进入当前
main。同时将本 issue 的可公开观察契约固化为独立回归,避免只依赖实现细节或共享测试间接判断。回归测试
suites/14_issue_regression/t/issue_recent_pruning_contracts.test714/714条语句通过。测试证据
d50a2d475a406829f67127fef7b2ad4abc1c1d3d14_issue_regression中观察到的旧 GOROOT/历史 golden/并发锁冲突属于既有无关失败,以上新增用例单独重跑均稳定通过。测试结论
测试通过。
Ariznawlll commentedon Oct 8, 2026
在当前 main
bab4b3286a0dd5683a9b291763817722233e586c上补充了算术谓词的交换方向、prepared、索引和 DML 原子性覆盖。DOUBLE 表含
-1e-17 / 0 / 1e-17 / NULL / -1 / 1 / 2 / 1e16并建立二级索引:(v+1=1) IS TRUE与 WHEREv+1=1均返回前三个微小值;1+v=1、v-1=-1、1-v=1返回同一集合;v+1e16=1e16返回-1e-17,0,1e-17,-1,1,保留 binary64 吸收/half-even 行为;((v + 1) = 1),没有代数改写成v=0;1/1 → 1e16/1e16 → NULL/1 → 1/1复用时,结果集合依次准确且能恢复。BIGINT 表含 MinInt64、-1、0、1、MaxInt64 并建立二级索引:
v+1、1+v、v-1、-1+v的上下溢出路径都返回明确 1690,而不是被转置隐藏;0/0,同一 handle 能恢复并只返回 v=0 行;UPDATE ... WHERE v+1=MaxInt64返回溢出后,五行 n 均保持 0,未发生部分更新;本轮浮点行集与逐行表达式一致,整数错误可见性及 DML 原子性也保持一致。