fix(P0): v0.6.2 数据正确性专项 — 深度审计 6 项修复 + 22 回归
CI / test (22.x) (push) Successful in 17m6s
CI / test (18.x) (push) Failing after 17m45s
CI / test (20.x) (push) Successful in 18m7s
CI / test (24.x) (push) Failing after 14m40s
CI / e2e (push) Successful in 9m54s

- KVStoreEngine 数值主键 update 丢行(P0):String 化主键回查不命中 → 误删 KV 行
  (重启丢数据);改为单次全表扫描 + 受影响集合过滤(兼消 O(N×M) 回查开销)
- update 主键撞已有主键静默覆盖(P0,Memory/Aria):抛 DUPLICATE_KEY,事务路径同拦截
- Aria 二级索引范围查询边界算法错误(P1):Number(v)±1 构造 key 漏小数/字符串数据;
  改全索引扫描 + matchWhere 过滤,边界语义统一
- Aria 索引列 IS NULL 返回空(P1):null 等值/含 null 的 IN 不走索引(回退全表)
- AriaEngine unique 约束未强制(P1):insert 整批预检(批内互查+索引扫描,失败整批
  不落库)+ update 排除自身旧条目检查;新增 LSM.prefetchPrefixRanges 批量预加载
- 非主键 update 索引旧值残留:统一传旧行清理(消除唯一性误报与索引膨胀)
- EXPLAIN 写语句产生真实副作用(P2):仅 SELECT 执行,UPDATE/DELETE 用 count 估算

测试 1092 → 1114(70 套件);行覆盖率 89.6%;版本 0.6.2
This commit is contained in:
thzxx
2026-08-13 09:51:26 +08:00
parent a91ac368e2
commit ef1934a38c
20 changed files with 1284 additions and 118 deletions
+39
View File
@@ -2,6 +2,45 @@
All notable changes to MetonaSqlark will be documented in this file.
## [0.6.2] - 2026-08-13
### 深度审计修复(数据正确性专项)
> 全源码通读 + 针对性实验验证,修复 6 个测试盲区中的数据丢失/查询错误/约束缺失问题。
### Fixed
- **KVStoreEngine 数值主键 update 丢行(P0)** — 非主键更新路径把受影响主键 `String()` 化后按
`where { [pkCol]: pk }` 回查内存行,数值型主键(123 !== "123")不命中 → 行被误判删除 →
重启后该行永久丢失。改为单次全表扫描 + 受影响集合过滤(同时消除 O(N×M) 逐主键回查开销),
字符串/数值主键语义统一
- **update 主键变更撞已有主键静默覆盖(P0** — MemoryEngine / AriaEngine 更新主键为目标已
存在值时静默覆盖另一行(数据丢失)。现在抛 `DUPLICATE_KEY`(与 insert 语义对齐),
事务内路径(txnSnapshot + 主 LSM 双查)同样拦截
- **Aria 二级索引范围查询边界算法错误(P1)** — `$gt/$gte/$lt/$lte``Number(v)±1` 构造边界
key:小数数值($gt:2 → "3:",漏 2.5)与字符串("NaN:" 前缀错位,数字/大写开头值被漏)
静默丢数据。改为全索引扫描 + 行级 matchWhere 过滤(与主键范围路径同方案),边界语义与
where-matcher 完全一致;新增小数/字符串/大写/数字开头/整数 flush 前后一致性回归
- **Aria 索引列 IS NULL 返回空(P1** — `$eq: null` 走索引路径时 `String(null)="null"` 查找
返回空并短路全表扫描 → 索引列 IS NULL 恒空。null 等值/含 null 的 IN 列表不再走索引
(回退全表扫描),与全表扫描语义一致
- **AriaEngine unique 约束未强制(P1** — 此前 insert/update 仅检查主键重复,唯一列重复值
被静默接受(MemoryEngine 已强制)。补齐:insert 整批预检(批内互查 + 索引 LSM 前缀扫描,
失败整批不落库);update 排除自身旧索引条目后检查;null 不受唯一约束(对齐 Memory);
新增 LSM.prefetchPrefixRanges(批量前缀范围预加载,一次 drainChain 避免逐行性能悬崖)
- **非主键 update 索引旧值残留** — update 时旧行未传给 `updateSecondaryIndexes`(仅主键变更
时传),索引 LSM 旧条目累积 → 唯一性检查误报 / 索引存储膨胀。统一传旧行清理旧值
- **EXPLAIN 写语句产生真实副作用(P2)** — `EXPLAIN DELETE/UPDATE/INSERT` 此前真实执行语句
(删/改数据)。现在仅 SELECT 类执行(只读),UPDATE/DELETE 用 count 估算影响行数,
INSERT/DDL 仅输出计划
### Changed
- 测试 1092 → **1114**70 套件,+22 个 v0.6.2 回归);新增 `tests/v062-fixes.test.ts`
(数值主键持久化 ×3 / 主键碰撞 ×3 / 索引范围 ×4 / IS NULL ×3 / unique ×7 / EXPLAIN ×2
---
## [0.6.1] - 2026-08-10
### 生产可用性深度审查(异常场景)