Commit Graph
47 Commits
Author SHA1 Message Date
thzxx 841db2e049 fix(A22/A23/A25/A26/A27/A29/A30/A36): 查询层 8 项缺陷根治 + 单一语义收敛
每项都先用可执行探针复现出**错误的实际输出**,再修根因、补永久回归套件
(tests/v080-query-layer.test.ts,8 项 × 4 引擎 + 跨引擎项,共 111 断言)。

A22 GROUP BY 引用 SELECT 别名
  修复前:`SELECT g AS grp, COUNT(*) FROM t GROUP BY grp` 抛
  `COLUMN_NOT_FOUND Unknown column "g" in SELECT list` —— 错误信息与真正原因
  (GROUP BY 用了别名)无关,因为 grp 取到 undefined 使全表并成一组,
  投影阶段又发现 g 不在输出行里。
  修复:GROUP BY 项先解析回**基列**(别名 → 源表达式)再分组,输出键与
  "按基列分组"完全一致。

A23 HAVING 引用未出现在 SELECT 里的聚合
  修复前:`SELECT g FROM t GROUP BY g HAVING SUM(n) > 25` → `[]`
  (SUM(n) 从未被求值 → HAVING 的键在分组行里不存在 → UNKNOWN)。
  修复:需要计算的聚合 = SELECT 列 ∪ HAVING 中的聚合(并集),
  并在 HAVING **之后**才把行收缩为 SELECT 输出键(否则又变回 [];
  顺序错了会双向出错:先投影 → 空结果,不投影 → 泄漏内部聚合列)。

A25 带表前缀的聚合参数恒 0
  修复前:`COUNT(t.n)` → 0、`SUM(t.n)` → null(行键是 n,直接取 row['t.n']
  得 undefined 再被"过滤 NULL"剔除,**且不报错**)。
  修复:新增唯一列引用解析 resolveColumnValue(前缀剥离 → 精确 → 唯一后缀),
  聚合识别统一为 parseAggregateExpression —— 此前"是否聚合"与"如何求值"
  用两条不同的正则。取不到列改为抛 COLUMN_NOT_FOUND,不再静默计 0。

A26 UNION 尾部 ORDER BY/LIMIT 归属错误
  修复前:`A UNION B ORDER BY id DESC` 只排 B;`... LIMIT 3` 返回 4 行
  (parser 把子句挂在右侧 SELECT 上,AST 没有复合查询级字段)。
  修复:SelectUnionStatement 增加 orderBy/limit/offset,parser 把子句**上移**
  (移动而非复制,否则 LIMIT 应用两次),executor 在合并+去重后统一排序/切片。

A27 DISTINCT 作用在投影前
  修复前:`SELECT DISTINCT g AS d FROM t` 返回 4 行 a,a,b,b
  (对 {id,g,n} 原始行去重),而 `SELECT DISTINCT g` 返回 2 行。
  修复:DISTINCT 移到投影后(作用于输出列);ORDER BY 的应用时机随之拆成
  "引用输出列 → 投影后" / "引用非输出列 → 投影前",两者互为因果必须一起改。

A29 maxRowsPerQuery 静默截断写入
  修复前:maxRowsPerQuery=2 时 `INSERT INTO dst SELECT id FROM src`(4 行源)
  只写 2 行并报成功 —— 不是"限制查询规模"而是**静默丢数据**。
  修复:行源不截断(executeSelect 增加 purpose='source'),写路径显式报错。

A30 INSERT 值多于目标列静默丢弃
  修复前:`INSERT INTO t (id,g) VALUES ('9','z','LOST')` 报成功、'LOST' 消失。
  修复:显式列名时解析期拦截(PARSE_ERROR),未给列名时 executor 对照 schema
  拦截(VALIDATION_ERROR)——两种情况都需要,因为前者无需 schema。

A36 派生表别名引用
  修复前:`SELECT d.id FROM (SELECT id, g FROM t) AS d` 返回 `[]`,
  而同义的 `SELECT id FROM (...) AS d` 正确。
  修复:抽出 normalizeUnprefixedReferences(WHERE/ORDER BY/GROUP BY/SELECT
  四类引用统一剥离别名前缀),非 JOIN 单表路径与派生表路径共用同一规则。

连带根治(修复过程中发现的两个更底层问题):

1. **同步抛错穿过 async 边界**:`executor.execute()` 里 `return this.executeXxx(stmt)`
   的同步前导段若抛错(arity/校验),异常成为**同步抛出** ——
   `await expect(db.query(...)).rejects...` 的断言不生效、`.catch()` 永不执行。
   现统一包一层 try/catch,保证任何错误都是 rejected promise。

2. **缺列的行形状不一致**:validateRow 此前"值为 undefined 就不落键",
   于是 `INSERT INTO t (id,g) VALUES ('9','z')` 的行里没有 n 键 →
   `SELECT id,g,n FROM t` 抛 COLUMN_NOT_FOUND: n,而 `SELECT * FROM t` 正常。
   现在缺列且无 default → 显式补 null(SQL 语义),行始终含全部 schema 列;
   ALTER ADD 同步在已有行上物化 null,使"内存视图"与"重启后视图"一致。

验证:全量 83 套件 / 1589 测试通过(含 Aria 5 万行索引竞态、KVStore 持久化);
typecheck(src+tests) 与 lint 零错误。
2026-09-15 00:00:08 +08:00
thzxx 2a109ef933 feat(B-1): 统一行校验 choke point —— 消除三份分叉的校验实现(A12/A17)
背景(PLAN-v0.7.5.md 根因 1):
修复前有**三份**行校验实现,覆盖面各不相同:

  位置                                        类型 required PK非空 maxLength min/max 未知列
  engine/memory.ts(disk/hybrid 共用)          ✓     ✓       ✓      ✗        ✗     静默丢弃
  engine/aria/index.ts → checkFieldType         ✓     ✓       ✓      ✓        ✓     静默丢弃
  table/schema.ts                               ✓     ✓       ✓      ✓        ✓     静默丢弃

后果一(A12):同一份 schema、同一条 INSERT 是否报约束错误取决于引擎选择 ——
`CREATE TABLE t (name STRING(3))` + 插入 'abcdef' 在 Aria 抛错,在
memory/disk/hybrid 静默写入超长值。

后果二(A17):四个引擎对未知列一律静默丢弃。`INSERT INTO t (id, nope) VALUES
('1',2)` 报成功,随后 `SELECT nope` 报 COLUMN_NOT_FOUND —— 同一列名在写路径与
读路径得到**相反结论**。TABLE API 直通路径尤其明显(executor 按 schema 列序
构造行,nope 那个位置根本没有值,所以连"校验 stmt.columns"都拦不住)。

根治方式:
1. 新增 src/table/validation.ts —— 唯一校验定义 `compileValidator(schema)`,
   约束覆盖面取三者并集,并把**规范化**(default 填充、undefined 跳过、
   __proto__ 防污染)与校验放在同一处。
   三种载荷形态刻意分成三个显式入口,不合成带 options 的函数:
     - validateRow(row, knownColumns?)  INSERT 语义(default 生效、缺列合法)
     - validatePartial(row)             UPDATE 语义(只校验出现的列)
     - assertNoUnknownColumns           独立可复用的列名存在性检查
   混成一个函数会让"required 是否生效"取决于调用方参数,重新引入跨路径差异。
2. MemoryEngine / AriaEngine 的私有 validateRow 改为委托;schema.ts 的公开
   validateRow 同样委托(API 不变,实现只剩一份)。
3. 四个引擎新增 validatePayload(table, rows, mode)(IStorageEngine 契约),
   Executor 在**任何副作用之前**调用:多行批量整体判定,错误消息一次列出全部
   未知列与已知列清单。
4. executeInsert 显式校验 stmt.columns 全部存在(A17)。
5. UPDATE 的外键级联写入(applyUpdateCascade)从"直接赋值"改为过
   validatePartial —— 此前 CASCADE 把新主键写进引用列时绕过 maxLength/min/max,
   与 A12 属同一类"校验只在部分写入路径生效"。

连带修正(测试夹具本身不忠实,B-1 使其暴露):
  - tests/engine/aria-cache.test.ts 的 makeRows 无条件返回 {id,name,age},
    部分用例的表只有 {id,name} —— 多余列被静默丢弃所以"通过"。新增 rowsFor()
    按 schema 裁剪,让夹具忠实反映表结构(而不是放宽校验)。
  - tests/v073-fixes.test.ts "schema 外列不持久化" 改为断言写路径即拒绝,
    并保留"合法行落盘后不含额外列"的检查。

验证:
  - 新增 tests/v080-unified-validation.test.ts:8 项 × 4 引擎 + 9 项校验器
    单元契约,共 41 断言;
  - 全量 84 套件 / 1499 测试通过;typecheck(src+tests) 与 lint 零错误。
2026-09-14 23:38:58 +08:00
thzxx 4ab04df882 fix(A15): 三值逻辑求值器统一 —— 消除 WHERE 的第二套语义(静默错值根治)
背景(PLAN-v0.7.5.md 根因 1/7、缺陷 A15):
项目里 `matchWhere`(布尔版,自带 matchField)与三值求值器并存。同一条 SQL 的
语义取决于走哪个函数,实测三类静默错值:
  - `WHERE n = NULL` 命中 NULL 行、`WHERE n != NULL` 返回所有非 NULL 行;
  - `WHERE s NOT LIKE 'x'` 会把 NULL 行判真(布尔取反);
  - `WHERE n NOT BETWEEN 1 AND 2` 恒空集 —— parser 生成的字段级
    `{ n: { $or: [ {$lt:1}, {$gt:2} ] } }` 递归进了 where 子句级求值器,
    子项 `{ $lt: 1 }` 被当成"查询列 `$lt`" → 每行 UNKNOWN。

根治方式(不是打补丁,而是取消第二套实现):
1. where-matcher.ts 重写为**唯一一个递归求值器**,同时理解 where 子句级
   (键是列名/逻辑连接词)与操作符级(键是 `$gt` …),位置由上下文承载而非
   由另一个函数承载;`matchWhere` 退化为"三值结果是否恰为 TRUE"。
   行上下文随求值上下文下传,`$col` 在任意嵌套深度都能解析。
2. parser:`IS NULL` / `IS NOT NULL` 生成 `$isNull` / `$isNotNull` **谓词**
   (此前与 `= NULL` / `!= NULL` 共用 `$eq: null` / `$ne: null`,两者语义无法区分);
   `BETWEEN` 生成真正的范围条件(此前把同一对象同时当操作符对象与操作数);
   `NOT BETWEEN` 展开为 `$or: [{$lt}, {$gt}]`。
3. executor 新增 enginePreFilter:逐行求值谓词(`$col` / `$exists` / CASE 键)
   必须整体移出引擎层 —— 引擎无外层行上下文,会把它们判 UNKNOWN 并把**所有行**
   过滤掉,逐行求值再正确也无行可算。粒度按连接词决定:`$and` 成员可单独移除,
   `$or`/`$not` 成员一移除就改变结果集(漏行/多行),故整条下推放弃。

契约变更(旧测试编码了错误语义,已按 SQL 标准改正并注明理由):
  - a) `{ $eq: null }` 不再命中 NULL 行(`= NULL` 恒 UNKNOWN)→ 用 `$isNull`;
  - b) `IN` 列表含 NULL:`x IN (NULL, 'a')` 只命中 'a'(`null = NULL` 为 UNKNOWN),
       未命中的行仍因 UNKNOWN 不保留。
  - c) 引擎层 `$in: [null, ...]` 与 `$eq: null` 的断言同步修正。

验证:
  - 新增 tests/v080-sql-three-valued.test.ts:26 条 SQL 语义矩阵 × 4 引擎
    (memory/disk/hybrid/aria)+ UPDATE/DELETE 写路径,共 104 断言;
  - 全量 83 套件 / 1458 测试通过(含 Aria 生产负载 10 万行);
  - typecheck(src+tests) 与 lint 零错误。
2026-09-14 23:22:26 +08:00
thzxx 674da6b7b7 fix(A9/A10): 发布订阅接线 + 列对列比较与关联子查询(静默空结果根治)
A9 db.subscribe 对本地写入永不触发
  全库唯一调用 emit 的地方在 BroadcastChannel 收到**其它标签页**消息的分支里,
  于是 README:232「订阅表变更」与 site/docs.html:667-679 的示例
  (event.type: 'insert'|'update'|'delete'、event.row)全部不成立。

  根治方式:新增 src/engine/change-notifier.ts —— IStorageEngine 装饰器,
  把变更通知收敛到**引擎接口**这一个位置(三个写入入口 SQL/Table/Builder 与
  事务内写入都必须经过它),避免在三条路径上各写一份变更描述逻辑。

  事件语义(兑现文档承诺):INSERT 逐行带 row+key;UPDATE/DELETE 写入前快照
  受影响行、成功后逐行发事件并带更新后/删除前的行;CLEAR/DDL 表级事件。
  订阅者返回 Promise 时被 await;订阅者抛错不影响写入结果(只上报 onError)。

  两个实现细节值得记录:
  1. 引擎被装饰后,core 里 `this.engine instanceof HybridEngine` 恒为 false
     → Hybrid 跨标签页重载静默失效。新增 unwrapEngine() 对**内层**引擎做能力探测。
  2. 外部事件(external)绝不能重新广播 —— 否则 A↔B 互相转发形成无限循环
     (实测 8 次以上且不终止)。已分离 emitExternal 路径。

A10 列对列比较与关联 IN 子查询静默空结果
  1) `WHERE t.x = t.y`(唯一可解析的列对列写法)返回 []:
     - 引擎层 matchWhere 无 $col 上下文,把 `{ $col: ... }` 当普通对象比较;
     - executor.filterCorrelated 调用 matchWhere 时**没传** `{ $col: true }`。
     修复:engine 层遇到未解析操作数($col/$subquery)时**放行**而非判假 ——
     引擎的过滤只允许缩小候选集,最终判定始终由带上下文的 executor 完成;
     executor 侧补上 `{ $col: true }`。
     同时修正 MemoryEngine/AriaEngine 的索引下推:非原始值(对象)不走索引,
     否则 String({...}) 得到无意义键、查找为空并短路全表扫描 → 静默空结果。

  2) `WHERE id IN (SELECT user_id FROM o WHERE o.user_id = u.id)` 返回 []:
     子查询执行**不传外层行上下文**,`u.id` 绑定为 null → 子查询空集 → `$in: []`。
     (结构相同的 EXISTS 走另一条分支、结果正确 —— 又一处"同一语义两条路径"。)
     修复:resolveOperatorSubqueries 接收并传递 contextRow;bindColumnRefs 递归
     进入 $subquery 绑定外层引用;新增 lookupOuterValue 先剥外层表名/别名前缀
     再取值(外层行键不带前缀,否则 `u.id` 取 undefined 被 `?? null` 静默成 null)。

ChangeNotifierEngine 能力转发
  装饰器只实现 IStorageEngine 声明的成员,导致:
  - 可选能力缺失时抛原生 Error,破坏 `NOT_SUPPORTED` 错误码契约(14 个用例失败)
    → 新增 requireCapability,统一抛 NOT_SUPPORTED 并保留方法名;
  - 接口外方法(analyzeTable/reindexTable/vacuum)在被包装后静默消失
    → 新增 requireOptionalMethod 显式转发(ANALYZE/REINDEX/VACUUM 恢复可用)。

新增 tests/v080-subscribe.test.ts(5 用例,四引擎 × 三种入口)、
tests/v080-correlated.test.ts(4 用例,含"关联 IN 与等价 EXISTS 结果一致"护栏)。
2026-09-14 22:29:51 +08:00
thzxx c6515440fd test: v042-hardening 适配 LSM.rangeScan 的 async 化(v0.8.0 读取自洽改动的连带修正) 2026-09-14 22:03:56 +08:00
thzxx 765df805eb fix(A1/A2): UPDATE 批内主键碰撞丢行 + ALTER ADD UNIQUE 形同虚设(四引擎根治)
A1 UPDATE 批内新主键碰撞 → 静默丢行
  阶段 1 只用 `table.has(newPk)` 与**语句执行前**的表比对,看不到同一语句内其它行
  即将写入的新主键;阶段 2 逐行写同一个 key 互相覆盖。
  实测 `UPDATE t SET id='X'`(匹配 3 行)返回 affected=3,表中只剩 1 行。
  INSERT 路径在 v0.7.3 已做批内 Set 互查,UPDATE 漏了 —— 典型的"同类修复只打一半"。

  根治:MemoryEngine 与 AriaEngine 的阶段 1 增加批内新主键 Set 互查,
  任一行撞车即整体拒绝(DUPLICATE_KEY),不写入任何一行。
  保守语义说明:这也会拒绝"两行互换主键"(A:x→y, B:y→x,最终状态合法)——
  与既有的"唯一值交换更新保守拒绝"一致,宁可显式报错也不静默丢行。

A2 ALTER ADD COLUMN ... UNIQUE 形同虚设
  只写 schema 不建索引桶(Memory)/索引 LSM(Aria),而唯一性预检完全依赖索引
  (`tableIndexes.get(col)` 缺失即整段跳过)—— 重复值可任意写入,四个引擎全部接受。
  Memory 侧后果更严重:重启时 createTable 依 schema 建桶、回灌第二行触发
  UNIQUE_VIOLATION,而该异常被 KVStoreEngine.open 的 catch 吞掉 → **行静默消失**。

  根治:
  - MemoryEngine.alterTable ADD:index/unique 列建立索引桶并回填;回填前做存量
    唯一性校验,重复则回滚本次 ALTER(删列 + 删桶)并抛 UNIQUE_VIOLATION。
  - AriaEngine.alterTable ADD:复用既有 createIndex(它已实现"回填 + 存量唯一性
    校验 + 失败原子清理",是 v0.6.2/v0.7.3 的成果)—— 不重复实现以免再次漂移。
  - KVStore/Hybrid 通过 Memory 引擎自动获得同等语义。

新增 tests/v080-atomicity.test.ts(4 用例,四引擎参数化)。
2026-09-14 22:02:30 +08:00
thzxx 7c7ecb8b1d test: 补齐 aria-cache 测试的类型标注(getOversizedCount,上一提交遗漏) 2026-09-14 21:53:56 +08:00
thzxx 89243ef6eb fix(A3/A4): SAVEPOINT 语义根治 —— 已回滚的行不再复活、陈旧保存点不再吞写入
A3 已回滚的行在崩溃重启后复活(静默数据错误)
  `ROLLBACK TO <savepoint>` 只改内存快照、**不写 WAL**,而 COMMIT 会把整个 txnId
  标记为已提交,恢复时按"该事务的全部记录"重放 → 被回滚掉的写入被重新应用。
  实测:事务内插入 a、savepoint、插入 b、回滚到 savepoint、提交 →
  实时只剩 a,崩溃重开变成 a+b。

  根治:新增 WALRecordType.SAVEPOINT_ROLLBACK(走既有 data 字段携带
  { replayFromIndex } 边界,二进制格式不变、旧库记录仍可解析)。
  - 写入侧:savepoint() 记录"该事务当时已追加的记录条数";rollbackToSavepoint()
    先写标记再改内存(与 commit/rollback 的"WAL 领先内存"一致)。
  - 恢复侧:按**事务内**下标计算窗口 —— 保留 [0, keepUpTo),丢弃
    [keepUpTo, 最后一个标记),标记之后的记录照常保留。
    注意不能拿全局下标比较:全局数组里混有 txnId=0 的非事务记录(CREATE_TABLE
    等)与其它事务的记录。这个差一错误在实现过程中被测试抓出并修正。
  - 事务内 WAL 记录计数(txnWalRecordCount)在 5 个 appendBatch 站点与 BEGIN
    处维护,事务开始/结束时归零。

A4 跨事务复用的陈旧 savepoint 静默丢弃当前事务的写入
  savepoints 在 commit/rollback 时**从不清空**,且 rollbackToSavepoint 不校验归属。
  实测:上一个事务遗留 savepoint 名 → 新事务 update 后 ROLLBACK TO 该名 + COMMIT,
  写入凭空消失(v=5 被回退成 v=9)。
  根治:事务结束清空 savepoints 与边界表;rollbackToSavepoint 校验
  sp.txnId === currentTxnId,陈旧保存点抛 SAVEPOINT_NOT_FOUND。

新增 tests/v080-savepoint.test.ts(4 个用例):包含"崩溃重放一致性"、
"普通事务不得误伤"、以及"多个保存点回到最早"的语义护栏。
2026-09-14 21:53:46 +08:00
thzxx 074afd3f1e fix(A8 + LSM 读自洽): 行所有权根治 + 读取路径不再依赖 prefetch
A8 行引用泄漏(调用方改查询结果即改写存储)
  实测:rows[0].tag = 'HACKED' 后,tag='HACKED' 与 tag='x' 两条索引查询都返回 0 行 ——
  行与索引失配、该行永久查不出来;嵌套 json 值同样按引用共享。
  Aria 因走反序列化路径反而幸免,又形成跨引擎差异。

  根治:在 IStorageEngine 契约层写入**行所有权约定**(engine/interface.ts)
  —— 读出的行是副本、写入接收的行也是副本;新增 cloneRow/cloneRows
  (优先 structuredClone,退化路径处理 Date/嵌套对象/二进制)。
  Memory/KVStore/Hybrid:find、findStream、getRow 全部返回副本。
  Aria:getAllRows 此前只做 `{ ...value }` 浅拷贝(嵌套 json 仍共享引用),
  改为深拷贝;find/findStream 返回副本。
  实测四种引擎:修改返回值后重读不变、索引两条查询均正确。

LSM 读取自洽(审计 P1-1:缓存未命中 = 静默丢数据)
  此前 loadSSTableReader 缓存未命中返回 null,而所有调用方都是
    const reader = this.loadSSTableReader(meta); if (!reader) continue;
  于是**未命中就静默跳过整个 SSTable**。实测:缓存上限 4KB 而 SSTable 更大时,
  300 行只能查回 59 行,且不报错。
  同时"读路径必须先 prefetch"这个隐式约定,是每次读都要 drainChain + prefetch
  的原因(性能悬崖的另一半)。

  根治:LSM.get / rangeScan / rangeScanLazy 改为 async,未命中即
  `await sstableStore.load()` 回源 + CRC 校验(损坏则自愈清理 meta),
  只有数据确实不存在才返回 null。checkUniqueSync 相应改名 checkUnique 并 async
  (原命名正是因为依赖 prefetch 约定)。引擎侧 12 处调用点补 await。

附带修正的缓存语义:
  - tryCacheSSTable:单个 SSTable 超过缓存上限时标记为常驻(pinned),
    不参与驱逐 —— 驱逐它等价于静默丢数据;内存上限因此是
    cacheLimit + 单个最大 SSTable,已在代码与测试中明确。
  - trimCache 跳过 pinned 条目(此前会把全部缓存一次性清空)。
  - 新增 getCacheSize/getCacheLimit/getOversizedCount/setCacheLimit 访问器
    (测试此前直接读私有字段 cacheSize/cacheLimitBytes —— 那是 TS 错误,
    只因测试不做类型检查才没暴露)。

queryStream async 回调
  此前用 constructor.name === 'AsyncFunction' 判定,对"普通函数返回 Promise"
  完全失效(Promise 被静默丢弃)。现改为双条件识别并走物化路径逐行 await,
  async 回调被真正等待。

测试契约修正:
  - aria-cache:'缓存大小受上限约束' 在极小缓存下是不可成立的契约,改为断言
    真正重要的不变量(数据完整;可装入时受上限约束),并新增"超大 SSTable 常驻"
    用例;'缓存驱逐后全表扫描仍返回完整数据' 保留 300 行断言(此前会失败)。
  - hybrid:磁盘引擎标签断言从 indexeddb(v0.6.0 已移除)改为 opfs。
2026-09-14 21:43:21 +08:00
thzxx 7526951804 fix(A19/A20/A21/A2): 词法器标准化 —— 双引号标识符、未闭合注释报错、去递归、移除方言转义
A19 双引号是分隔标识符(SQL 标准)
  此前 '"' 与 "'" 一起交给 readString,于是 SELECT "name" FROM t 静默产出
  一个名为 'name' 的**常量列**(行数正确、值全错、无报错),且被 lexer.test.ts
  钉死为期望。新增 TokenType.QUOTED_IDENTIFIER;双引号内 "" 表示一个双引号;
  可用于引用保留字列名(SELECT "order" FROM t)。parser 的 expectIdentifier
  显式接受 QUOTED_IDENTIFIER。

A20 未闭合块注释必须报错
  此前 skipBlockComment 循环到 EOF 就返回、不抛错,实测
  db.query("DELETE FROM t WHERE id = '4' /*") **真的删掉了 1 行**;
  SQLite 会报 unterminated comment。任何被截断/拼接的 SQL 都会静默改变语义。

A21 注释跳过改为循环(消除递归爆栈)
  此前 default 分支用 return this.nextToken() 递归,栈深 = 连续注释数,
  两万个连续块注释直接 RangeError(原生错误,调用方无法按 code 分类)。

A2 移除 MySQL 方言的反斜杠转义
  此前只识别反斜杠+单引号:双反斜杠不解转义,以反斜杠结尾的 Windows 路径会
  吞掉闭引号并报出与输入无关的解析错误。更严重的是参数绑定器只翻倍单引号、
  不处理反斜杠 —— 两份词法规则不一致,"参数不改变 SQL 结构"在文本层不成立。
  SQL 标准中反斜杠是普通字符,移除后词法器与绑定器的字符串边界判定完全一致。

更新 2 处把旧行为钉死的测试(lexer.test 双引号=字符串、v033 反斜杠转义)。
2026-09-14 21:08:20 +08:00
thzxx 0dba1abf2a test(P0): v0.8.0 验证基座与工程门禁根治
工作流 C-1 / C-3 前半 + 测试代码类型检查。

【故障注入基座】新增 tests/helpers/storage-harness.ts + faulty-backend.ts
- TransactionalFileStore:忠实 OPFS 提交语义(close 才可见)+ 字节级故障注入
  (failNextWrite/Append/Delete、truncateAppendTo 撕裂写、crashPending 真崩溃)
- 删除旧 opfs-mock:读返回内部引用、keepExistingData:false 不截断、close 空实现
  导致"提交前可见"等真实缺陷无法被测出(31 个测试文件迁移至新 harness)
- 删除 aria-opfs-backend 内的第三份重复 mock(含从未被断言使用的 writeCalls 死代码
  与 entry.content.subarray 恒等分支)
- FaultyBackend:包装任意 IStorageBackend 注入故障;crash() 明确区别于 close()
  (后者是优雅停机,会刷完写队列 —— 这正是此前所有"崩溃恢复"测试的真相)
- 16 条基座自测证明注入真的生效(含 close 不能当崩溃的对照组)

【覆盖率口径】jest.config.cjs
- 移除 '!src/**/index.ts'(该 glob 把 AriaEngine 主实现等 15 个实现文件整体
  排除出统计,与 v0.2.6 曾承认过的问题同源),改为只排除纯类型声明文件并附理由
- 新增 coverageThreshold 门禁(此前完全不存在)
- 真实基线:语句 90.66% / 分支 82.94% / 函数 94.36% / 行 93.43%
- 修正 testMatch 使 tests/helpers 下的测试可被发现

【测试代码类型检查】tsconfig.test.json + npm run typecheck:tests
- 修复 103 个测试代码类型错误(此前 babel 剥离类型 + tsconfig 排除 tests,全部隐藏)
- 新增 tests/helpers/assertions.ts:nonNull/decode/rows/object/engineMethod/expectCode
  以断言收窄替代 as any
- 消除 21 个 lint warning(含 v043-hardening 中定义后从未调用的 mockOPFS 死代码)
- parser.test.ts 12 处 toBeDefined() 空断言升级为结构断言(并新增 AND/OR 优先级用例,
  当前红灯,对应总账第 11 项,将在工作流 A 修复)

【版本契约】新增 tests/version-contract.test.ts
- 校验 src VERSION / package.json / dist 三者一致,替代两处硬编码版本字面量

【CI 门禁】.gitea/workflows/ci.yml
- lint 去掉 continue-on-error(此前永远不让 CI 变红)
- 新增 tests 类型检查、--coverage 覆盖率门禁、dist 与源码同步校验
- 版本 0.7.4 升至 0.8.0
2026-09-14 21:03:06 +08:00
thzxx d4a3f4acd2 fix: v0.7.4 写语句子查询 / 约束硬化 / 真惰性流式 — UPDATE-DELETE WHERE 子查询静默 0 行(四引擎,关联引用显式 NOT_SUPPORTED + EXPLAIN 同步)/ 主键 NULL-undefined 强制拒绝 / DROP INDEX 保留建表 UNIQUE(仅索引来源可解除)/ GROUP BY-DISTINCT-UNION 键类型安全编码 / UPDATE 未知列报错 / queryStream 多语句拒绝 / KVStore 后台错误跨 reopen 清理 + Hybrid begin 补偿 / RB-Tree 删除双黑修复 + LSM 死代码清理 / findStream 迭代器化真惰性(limit 早停 O(1) 内存)/ REINDEX 单次扫描 + 48 回归 2026-08-15 15:08:33 +08:00
thzxx 50468b9b0e fix: v0.7.3 数据正确性与边界窗口收尾 — INSERT 语句级原子(三引擎+Aria PK 批内重复)/ 索引列 IS NULL 恒空 / delete RESTRICT 破坏索引 / queryStream 子查询静默空结果 / ALTER DROP 索引残留 / UNIQUE INDEX 存量校验 / SELECT * 别名投影 / WAL BEGIN/ROLLBACK 事务边界 / aria $in 与级联重复扫描性能 / $and 等值下推 / ANALYZE 索引统计 / React-Vue hooks 生命周期 / 迁移主键兜底 + 58 回归
CI / test (18.x) (push) Successful in 17m43s
CI / test (22.x) (push) Successful in 13m45s
CI / test (20.x) (push) Successful in 15m33s
CI / test (24.x) (push) Successful in 24m46s
CI / e2e (push) Successful in 52s
2026-08-14 22:53:46 +08:00
thzxx 05e6823bf1 fix: v0.7.2 语句级原子性 + 事务 DDL 拒绝 + 约束/绑定硬化 — 6 项修复 + 43 回归 + CI 重型套件串行
CI / test (22.x) (push) Successful in 24m26s
CI / e2e (push) Successful in 10m0s
CI / test (18.x) (push) Successful in 27m14s
CI / test (20.x) (push) Failing after 1h19m9s
CI / test (24.x) (push) Successful in 37m49s
- UPDATE 语句级部分提交(P1,四引擎):两阶段全量预检后执行,批内唯一互查,
  任何一行失败整句不执行(aria 场景 WAL 与内存不再错位)
- 事务内 ALTER/CREATE INDEX/DROP INDEX 残留(P1):Memory/KVStore 显式拒绝
  (对齐 Aria),createTable/dropTable 保持可回滚
- SET NULL 级联绕过 required 约束(P1):预检阶段整体拒绝 FOREIGN_KEY_VIOLATION
- bindParameters 注释误判(P2):行注释/块注释中的 ? 与引号不再参与绑定
- 未闭合字符串静默接受 → lexer 抛 PARSE_ERROR;未知 where 操作符抛 QUERY_ERROR
- UPDATE undefined 覆盖列值 → 语义化为不更新(null 仍置空)
- Hybrid 写穿透非原子(P1):磁盘失败自动重载内存对齐磁盘再抛原错误
- CI:Run tests 拆常规并行 + 重型串行(runInBand),重型测试超时余量提升,
  性能护栏 kv 120→240s / opfs 150→300s(仍拦截悬崖回归)
- 测试 1155 → 1198(74 套件),覆盖率 89.82% 保持
2026-08-13 15:31:16 +08:00
thzxx cbe407eb49 fix: v0.7.1 API 修复与防御统一 — static create / 未 open 防护 / 原型污染 / lint 清零
CI / test (22.x) (push) Successful in 17m24s
CI / e2e (push) Successful in 10m39s
CI / test (18.x) (push) Successful in 19m5s
CI / test (20.x) (push) Successful in 18m4s
CI / test (24.x) (push) Successful in 23m19s
- MetonaSqlark.create 静态工厂(README 示例在 ESM/Node 下此前 TypeError),
  独立 create 函数委托静态实现
- close 未初始化防御(engine undefined 不再崩溃)
- AriaEngine hasTable/getTableNames/getTableSchema 统一 ensureOpen
- 事务回滚失败不掩盖原始错误
- __proto__ 列名防护:Executor 列映射 Object.create(null) + schema 校验拒绝
- lint 清零(移除 5 处未使用导入)

测试 1147 → 1155(73 套件);行覆盖率 89.8%;版本 0.7.1
2026-08-13 11:14:42 +08:00
thzxx 57415975ea feat: v0.7.0 参数化查询 + 事务增量 flush + 复合主键语义硬化 + EXPLAIN 真实索引信息
CI / test (22.x) (push) Successful in 17m29s
CI / test (24.x) (push) Failing after 17m32s
CI / e2e (push) Successful in 9m53s
CI / test (18.x) (push) Successful in 19m17s
CI / test (20.x) (push) Successful in 18m15s
- 参数化查询 db.query(sql, params):词法层 ? 绑定 + SQL 字面量安全编码
  ('' 转义/注入防护);参数计数不匹配 PARAM_ERROR;对象参数显式拒绝
- KVStoreEngine 事务增量 flush:行级变更追踪,commit 仅写改动行
  (1000 行表改 1 行:日志 1 条目 vs 整表 1000 条目);级联影响表漏写修复
  (txFullTables 同步加入 txDirtyTables);移除每次 commit 全量 checkpoint
  (阈值自动 checkpoint + close 统一截断)
- 复合主键显式拒绝:createSchema 校验期 SCHEMA_ERROR + ALTER ADD 主键列防护
  (此前静默取第一个主键,其余标记失效)
- EXPLAIN usingIndex 真实命中信息:pk / index:col / none

测试 1126 → 1147(72 套件);行覆盖率 89.8%;版本 0.7.0
2026-08-13 10:57:26 +08:00
thzxx f97c5a6001 fix(P2): v0.6.3 原子性/一致性/资源治理 — 8 项修复 + 12 回归
CI / test (18.x) (push) Successful in 19m13s
CI / test (20.x) (push) Successful in 18m8s
CI / test (22.x) (push) Successful in 17m18s
CI / test (24.x) (push) Successful in 22m57s
CI / e2e (push) Successful in 9m53s
- KVStore 混合写单记录原子:新增 writeBatch(put+delete 同一条日志记录),
  KVStoreEngine 全部混合写路径统一(兑现真原子宣称,崩溃无新旧行并存)
- WAL full 模式写入失败抛错(此前 console.warn 吞错 → 崩溃即丢且无感知)
- MemoryEngine SET NULL 级联索引残留:复用 removeIndexEntries(消除虚假 UNIQUE_VIOLATION)
- delete 级联两阶段:先全量 RESTRICT 预检(沿 CASCADE 链递归)再执行,无部分级联
  (Memory/Aria 对齐)
- BufferPool 驱逐同步清理 pages Map(EvictionManager onRemove 回调,内存预算真实生效)
- MVCC commit 清理已提交版本(版本链仅作事务内 undo,消除行数据双份常驻)
- LSM.flush 重复入链修复(入链即置空 immutable)+ frozenMemtables 可见性时序
- rollbackToSavepoint 重建受影响表二级索引(消除过期索引条目)

测试 1114 → 1126(71 套件);行覆盖率 89.7%;版本 0.6.3
2026-08-13 10:30:39 +08:00
thzxx ef1934a38c 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
2026-08-13 09:51:26 +08:00
thzxx a91ac368e2 ci: 放宽 10 万行性能护栏(kv 60s→120s / opfs 90s→150s)— CI debian runner 慢 2~3 倍且 maxWorkers=2 并行重型测试,84s 为健康性能(修复前悬崖 353s);护栏仍能拦截悬崖回归
CI / test (18.x) (push) Successful in 19m27s
CI / test (20.x) (push) Successful in 18m7s
CI / test (22.x) (push) Successful in 17m14s
CI / test (24.x) (push) Successful in 23m6s
CI / e2e (push) Successful in 9m58s
2026-08-11 09:02:35 +08:00
thzxx 95a3e418fd chore: 发布 v0.6.1 npm 包到 Gitea registry(package.json version 0.6.0→0.6.1,版本断言测试同步)
CI / test (18.x) (push) Successful in 18m59s
CI / test (20.x) (push) Successful in 17m47s
CI / e2e (push) Successful in 9m55s
CI / test (22.x) (push) Successful in 17m12s
CI / test (24.x) (push) Failing after 16m42s
2026-08-10 22:07:32 +08:00
thzxx 9c109b4619 chore: 移除调试残留 tests/zz-dbg.test.ts
CI / test (20.x) (push) Successful in 17m51s
CI / test (22.x) (push) Successful in 16m50s
CI / test (18.x) (push) Successful in 19m19s
CI / test (24.x) (push) Failing after 16m42s
CI / e2e (push) Successful in 9m55s
2026-08-10 21:30:56 +08:00
thzxx 5c6011d487 fix(P0): 生产矩阵审计暴露 2 个崩溃恢复丢数据 bug — ① FileManager 页面 id 崩溃回退(allocatePageIds 后 saveMeta 前中断 → nextPageId 回退 → 恢复期页面复用被 compaction 误删,kv 2万行+加密崩溃丢75%):init 以现存最大页面 id+1 为准;② LSM.flush 剩余数据与 compaction 并发写 meta(产物 saveMeta 被覆盖成孤儿 → 优雅关闭重开丢75%):剩余落盘挂链串行。新增 13 组合矩阵审计(后端×特性×功能全量验收)
CI / test (20.x) (push) Canceled after 0s
CI / test (22.x) (push) Canceled after 0s
CI / test (24.x) (push) Canceled after 0s
CI / e2e (push) Canceled after 0s
CI / test (18.x) (push) Canceled after 12m46s
2026-08-10 21:30:49 +08:00
thzxx d83910832e perf(P1): 批量插入性能悬崖 — insert 循环内逐行 prefetchKeys(每行 await drainChain 排空后台链),compaction 在链上数秒时每行阻塞数秒 → kv 后端 10 万行插入 353s;改为批级预加载本批 PK 一次,实测 353s→12.5s(28 倍)/ opfs 25s;新增 kv/opfs 双后端 10 万行回归(性能护栏+索引完整+崩溃恢复),aria-cache 测试同步适配显式 flush
CI / test (18.x) (push) Successful in 18m51s
CI / test (20.x) (push) Successful in 17m42s
CI / test (22.x) (push) Successful in 16m58s
CI / test (24.x) (push) Failing after 14m38s
CI / e2e (push) Successful in 10m36s
2026-08-10 20:14:57 +08:00
thzxx 34225a86b3 fix(P0): SSTable rangeScan 尾块漏读 — 索引块记录块尾 key 但二分按块首语义定位,endKey 落在块尾时下一块被排除导致二级索引查询丢数据(5万行丢106~771条);endBlockIdx 多扫一块 + 4 个 sstable 边界回归 + 重建二级索引大数据量回归(含崩溃恢复)。附带:checkpoint 同步 flush 二级索引 LSM(P1)、kv 后端页面化 + SharedMemoryBackend chunk 化、生产负载验证测试
CI / test (20.x) (push) Successful in 24m55s
CI / test (22.x) (push) Successful in 16m19s
CI / test (24.x) (push) Successful in 20m55s
CI / e2e (push) Successful in 9m54s
CI / test (18.x) (push) Successful in 26m38s
2026-08-10 18:18:50 +08:00
thzxx 25bab0f9aa feat: v0.6.1 — AriaEngine 可选自研 KVStore 后端(storageBackend: 'kv')+ KVStore APPEND 日志类型 + 10 个 aria+kv 集成测试 + 文档全量同步
CI / test (20.x) (push) Successful in 10m55s
CI / test (22.x) (push) Successful in 10m49s
CI / e2e (push) Successful in 9m54s
CI / test (18.x) (push) Successful in 10m58s
CI / test (24.x) (push) Successful in 10m41s
2026-08-10 14:52:38 +08:00
thzxx 8a78f27f7d fix: v0.6.1 生产可用性深度审查 — MemoryEngine 级联环无限递归(P0)/ KVStore 多表事务与级联原子化 / 未open防护统一 / 27 个异常场景测试 + aria级联回归
CI / test (18.x) (push) Successful in 10m59s
CI / test (20.x) (push) Successful in 10m59s
CI / test (22.x) (push) Successful in 10m49s
CI / test (24.x) (push) Successful in 10m47s
CI / e2e (push) Successful in 10m4s
2026-08-10 14:29:40 +08:00
thzxx a9e1a281d3 fix: v0.6.0 复查修正 — KVStore 快照损坏水位 bug(metaSeq 误跳日志)+ 快照损坏测试盲区修复(此前篡改未生效)+ metaSeq 回归测试 + KVStoreEngine 真实浏览器 e2e(3 用例)+ 版本/配置文档校准
CI / test (20.x) (push) Successful in 10m51s
CI / test (18.x) (push) Successful in 10m59s
CI / test (22.x) (push) Successful in 10m47s
CI / test (24.x) (push) Successful in 10m41s
CI / e2e (push) Successful in 9m52s
2026-08-10 14:11:44 +08:00
thzxx 24b3ca1079 release: v0.6.0 — 完全移除 IndexedDB,自研 KVStore 事务存储引擎(多key原子写/快照日志恢复/CRC自愈)+ KVStoreEngine + 旧库迁移工具 + 10万级压力验证 + 崩溃注入e2e
CI / test (20.x) (push) Successful in 10m53s
CI / test (22.x) (push) Successful in 10m47s
CI / test (24.x) (push) Successful in 10m42s
CI / e2e (push) Successful in 10m27s
CI / test (18.x) (push) Successful in 11m1s
2026-08-10 13:56:04 +08:00
thzxx 334067d89e release: v0.5.1 — 存储后端生产级硬化(CRC-32/全库加密/WAL分片/页面化存储/多标签页锁/e2e)+ 深度审查修复(假实现接线/死代码清理)
CI / test (18.x) (push) Successful in 10m10s
CI / test (20.x) (push) Successful in 10m10s
CI / test (22.x) (push) Successful in 10m6s
CI / e2e (push) Successful in 9m51s
CI / test (24.x) (push) Successful in 10m28s
2026-08-10 12:07:00 +08:00
thzxx cff98b0903 release: v0.4.4 — SSTable 编码修复(UTF-8 字节估算 + u32 长度字段 + v1/v2 双格式兼容),大内容不再崩溃
CI / test (18.x) (push) Successful in 10m3s
CI / test (20.x) (push) Successful in 10m4s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m56s
2026-08-09 21:34:28 +08:00
thzxx d269bdfb75 release: v0.4.3 — 关闭时序与后台任务加固(close 排空、失败不吞错、compaction 竞态修复)+ 提交先 WAL
CI / test (18.x) (push) Successful in 10m6s
CI / test (20.x) (push) Successful in 10m11s
CI / test (22.x) (push) Successful in 10m4s
CI / test (24.x) (push) Successful in 10m0s
2026-08-09 19:48:06 +08:00
thzxx 22b0b1fad4 release: v0.4.2 — 生产就绪与崩溃自愈 + 问题清单修复 + 版本迭代
CI / test (18.x) (push) Successful in 10m7s
CI / test (20.x) (push) Successful in 10m6s
CI / test (22.x) (push) Successful in 10m2s
CI / test (24.x) (push) Successful in 10m0s
2026-08-09 19:15:37 +08:00
thzxx a1e4f5071c release: v0.4.1 — Aria 级联/ALTER/clearAll + 流式查询/派生表 + 正确性加固
CI / test (20.x) (push) Successful in 10m4s
CI / test (22.x) (push) Successful in 10m8s
CI / test (24.x) (push) Successful in 9m55s
CI / test (18.x) (push) Successful in 10m9s
新增:
- AriaEngine 外键级联(CASCADE/SET NULL/RESTRICT)+ clearAll() 重置 API
- 引擎级 alterTable:Aria DROP COLUMN 重写存储行 + schema 持久化
- 流式查询 queryStream / findStream(LSM 惰性扫描不物化)
- FROM 派生表 / 多列 ON 哈希连接 / COUNT(DISTINCT) / NULLS FIRST/LAST
- 普通列别名 + ORDER BY 别名 + 无表查询 + 字符串常量列
- 演示页引擎切换器(Memory/Aria)+ 预设自动重置

修复:
- Aria WAL DROP_TABLE 崩溃恢复(删表复活)+ 恢复后 WAL 截断
- Memory update/delete 索引维护(unique 约束绕过)
- 关联 EXISTS 绑定失效 / HAVING 标量子查询 / INSERT SELECT 位置错位
- 裸布尔列条件(WHERE done / CASE WHEN done)
- Aria $in 重复行 / JOIN 主表 WHERE 下推 / DROP INDEX 报错
- ORDER BY/GROUP BY/SELECT 表前缀列 + SQL '' 标准转义

质量:894 测试 · 47 套件 · 81.5% 覆盖率
2026-08-08 13:36:34 +08:00
thzxx fda3f1ad34 fix: CI Node 18/20 下 aria-crypto 失败 — SubtleCrypto 跨 realm ArrayBuffer 兼容
CI / test (18.x) (push) Successful in 9m58s
CI / test (20.x) (push) Successful in 9m58s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m54s
- crypto.ts encryptPage/decryptPage 改传 TypedArray 视图(ArrayBuffer.isView 检查跨 realm 可靠)
- jest.setup.js structuredClone polyfill 用跨 realm toString 标签检查
  (修复 fake-indexeddb 存储 ArrayBuffer 被 JSON 破坏成 {} 的问题)
- 新增 SSTable 加密真实路径测试(加密落盘→重载解密, 8 个测试)
- aria/v025 固定 db 名改随机(fake-indexeddb 真实持久化后防表残留冲突)
- Node 18/20/22/24 全矩阵 837 测试通过
2026-08-08 11:07:35 +08:00
thzxx d544501e1c release: v0.3.2 — 质量加固 + SQL扩展 + 表达式 + 并发同步
CI / test (18.x) (push) Failing after 5m11s
CI / test (20.x) (push) Failing after 5m8s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m56s
v0.2.6 质量加固:
- 修复 AriaEngine 二级索引 SSTable 互相覆盖(命名空间隔离)
- 修复 LSM 多版本读取顺序错误 + MergeIterator 取最新来源
- 重写 LZ4 压缩器(往返一致性 + 缓冲区溢出)
- sstableCache LRU 上限 + 预加载兜底(BufferPool 配置生效)
- 修复 React/Vue 集成 import type 运行时 bug + exports 子路径
- 新增 38 个测试(LZ4往返/Crypto/集成), 删除伪测试

v0.3.0 SQL 功能扩展:
- 多语句 parseAll + 事务语句 BEGIN/COMMIT/ROLLBACK
- INSERT INTO ... SELECT + UNION/UNION ALL + EXISTS 关联子查询
- CREATE/DROP INDEX 五引擎实现 + 别名 WHERE 修复
- benchmark 页面 + 36 个新测试

v0.3.1 表达式与性能:
- CASE WHEN 表达式(SELECT 列/WHERE/聚合)
- JOIN + 关联子查询逐行绑定
- WAL 批量组提交(写放大 O(N)→O(1))
- 修复 pending frozen 可见性 + flush 缓存竞争

v0.3.2 并发:
- CASE WHEN 用于 WHERE/聚合 + JOIN 哈希连接
- 多标签页同步(multiTabSync + BroadcastChannel)
- IndexedDB schema 持久化(reopen 后表结构恢复)
- 修复 where-matcher 顶层 $not
- 修复 CJS 产物 .js 被 ESM 解析(exports 空) — .cjs 后缀 + exports 修正
- 836 测试 / 44 套件 / 81.0% 覆盖率
2026-08-08 10:41:30 +08:00
thzxx eb79b2198e release: v0.2.5 — 质量加固 + Bug修复 + 性能优化 + SQL扩展
CI / test (18.x) (push) Successful in 10m4s
CI / test (20.x) (push) Successful in 10m0s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m58s
2026-07-29 21:50:53 +08:00
thzxx 4c26882caa release: v0.2.4 — 701 tests, 32 suites, 零死代码, 零空壳, 全模块接入
CI / test (18.x) (push) Successful in 10m0s
CI / test (20.x) (push) Successful in 10m0s
CI / test (22.x) (push) Successful in 10m0s
CI / test (24.x) (push) Successful in 9m54s
2026-07-27 22:18:08 +08:00
thzxx d33f4ab3b0 test: OPFSEngine 12项mock测试 + Schema约束5项测试 → 543 passed
CI / test (18.x) (push) Successful in 9m58s
CI / test (20.x) (push) Successful in 9m58s
CI / test (22.x) (push) Successful in 10m18s
CI / test (24.x) (push) Successful in 10m2s
2026-07-27 21:34:12 +08:00
thzxx 4a3feac9ea release: v0.2.3 AriaEngine 引擎加固 — RB-Tree fixDelete/LSM SSTable缓存预热/LZ4格式修复
CI / test (18.x) (push) Successful in 9m58s
CI / test (20.x) (push) Successful in 9m56s
CI / test (22.x) (push) Successful in 9m58s
CI / test (24.x) (push) Successful in 9m52s
2026-07-27 21:22:29 +08:00
thzxx e6efa39d48 release: v0.2.1 生产加固 — WAL CRC/约束激活/Hybrid提交顺序/RESTRICT外键/浏览器兼容表/debug模式/onError回调
CI / test (20.x) (push) Successful in 9m58s
CI / test (18.x) (push) Successful in 10m0s
CI / test (22.x) (push) Successful in 10m0s
CI / test (24.x) (push) Successful in 9m56s
2026-07-27 20:47:30 +08:00
thzxx 620cd11521 fix: 修复 CI 卡死 + LZ4/SSTable/Checkpoint 多项 bug — 526 测试全通过
CI / test (18.x) (push) Successful in 10m1s
CI / test (20.x) (push) Successful in 10m6s
CI / test (22.x) (push) Successful in 10m2s
CI / test (24.x) (push) Successful in 10m6s
2026-07-27 20:28:23 +08:00
thzxx bc69d8f500 fix: 修复测试无法自然退出 — forceExit + 减少延迟 + 拆分 coverage
CI / test (22.x) (push) Canceled after 0s
CI / test (24.x) (push) Canceled after 0s
CI / test (18.x) (push) Canceled after 1h32m41s
CI / test (20.x) (push) Canceled after 0s
- jest.config.cjs: forceExit:true + testTimeout:15000

- package.json: npm test 默认不再 --coverage

- tests/utils.test.ts: debounce 延迟 50->20, 100->50
2026-07-27 18:12:06 +08:00
thzxx f84673e519 feat: v0.2.0 AriaEngine 自研存储引擎
CI / test (20.x) (push) Canceled after 0s
CI / test (22.x) (push) Canceled after 0s
CI / test (24.x) (push) Canceled after 0s
CI / test (18.x) (push) Canceled after 1h26m17s
- 新增 AriaEngine: LSM-Tree 页面式存储引擎,19 个模块,~3500 行 TS
  - page/: Slotted Page 格式 (header/slot/tuple/format) + CRC32
  - buffer/: Buffer Pool (LRU 缓存 + 驱逐策略)
  - index/: LSM-Tree (MemTable 红黑树 + SSTable + Bloom Filter + Merge Iterator)
  - wal/: WAL 日志 (二进制格式) + Checkpoint 管理
  - transaction/: MVCC 版本链 + 快照隔离
  - store/: IndexedDB / Memory 双后端抽象
  - compression/: LZ4 页面压缩

- 完整持久化: Schema 自动保存、SSTable 元数据管理、WAL 恢复
- 事务感知 CRUD: insert/update/delete 在事务中缓冲到 snapshot
- mode: 'aria' 激活自研引擎

- 新增 7 个测试文件,测试数 318 → 524,套件 20 → 27
  - aria-page.test.ts (32 tests): Page 格式单元测试
  - aria-index.test.ts (26 tests): Bloom Filter + MemTable
  - aria-sstable.test.ts (9 tests): SSTable Builder + Reader
  - aria-buffer.test.ts (25 tests): LRU + Eviction + Buffer Pool
  - aria-wal-mvcc.test.ts (22 tests): WAL 编解码 + MVCC 事务
  - aria-compress.test.ts (11 tests): LZ4 + Merge Iterator
  - aria.test.ts (80 tests): AriaEngine 集成 + 边界测试

- Bug 修复: LRUList size 跟踪、WAL 缓冲区越界、ColumnEncoding 导入
- 全面更新 README.md + site/ 站点文件 (index/docs/demo)
2026-07-27 16:40:29 +08:00
thzxx 1f8e11bf72 feat: SQL 语法支持 BETWEEN AND、DROP TABLE IF EXISTS
CI / test (18.x) (push) Successful in 9m56s
CI / test (20.x) (push) Successful in 9m54s
CI / test (22.x) (push) Successful in 9m50s
CI / test (24.x) (push) Successful in 9m49s
2026-07-26 17:55:45 +08:00
thzxx b21cbfd544 test: v0.1.14 硬固化测试(幂等init/flush原子性/versionchange)+ site版本号修复
CI / test (18.x) (push) Successful in 9m56s
CI / test (20.x) (push) Successful in 9m53s
CI / test (22.x) (push) Successful in 9m51s
CI / test (24.x) (push) Successful in 9m47s
2026-07-26 17:33:42 +08:00
thzxx 71e238a5cc test: v0.1.13 新增42项测试覆盖(事务回滚/子查询/外键级联/连接池)
CI / test (18.x) (push) Successful in 9m52s
CI / test (20.x) (push) Successful in 9m50s
CI / test (22.x) (push) Successful in 9m51s
CI / test (24.x) (push) Successful in 9m49s
2026-07-26 16:40:11 +08:00
thzxx e2a590c5b1 feat: metona-sqlark v0.1.12 — 前端TypeScript关系型数据库
- 4种存储引擎:Memory / IndexedDB / OPFS / Hybrid
- 完整SQL支持:SELECT/INSERT/UPDATE/DELETE/JOIN/GROUP BY/HAVING/DISTINCT
- Query Builder链式API + TypeScript泛型支持
- 聚合函数:COUNT/SUM/AVG/MIN/MAX
- 事务、插件系统(14 hooks)、发布订阅、数据迁移、导入导出
- React/Vue框架集成
- 264个测试用例,93.46%覆盖率
- 零运行时依赖
2026-07-26 15:00:01 +08:00