| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package core
- import (
- "testing"
- "git.ycl.pub/yl32940/TsDB2/DB/core/types"
- )
- // TestScanWithDeleteDuringBatchResolve 扫描回调里逐行删除 (demo/stress_test 第 12 步
- // 的回归): 二级索引扫描物化 pkID 后走批量回表, 回调里的删除会改写主键 B+ 树
- // (叶合并/NextPage 重接)。批量回表必须"分批物化、批后回调" —— 绝不能让用户回调
- // 踩坏正在推进的叶链游标 (旧实现因此 index out of range)。
- func TestScanWithDeleteDuringBatchResolve(t *testing.T) {
- db := fixOpenDB(t)
- tbl := qopNewTable(t, db, "t")
- qopSeed(t, tbl, 1000)
- if err := db.Commit(); err != nil {
- t.Fatalf("commit: %v", err)
- }
- deleted := 0
- err := tbl.Query().Where(Ge("age", int64(0), 0)).ScanWithPKID(func(pkID uint64, _ []types.FieldValue) bool {
- if err := tbl.DeleteRow("pk", qopPKKey(pkID)); err != nil {
- t.Fatalf("删除 %d: %v", pkID, err)
- }
- deleted++
- return true
- })
- if err != nil {
- t.Fatalf("scan+delete: %v", err)
- }
- if deleted != 1000 {
- t.Fatalf("应删 1000 行, 实删 %d", deleted)
- }
- cnt, err := tbl.Query().Count()
- if err != nil || cnt != 0 {
- t.Fatalf("删尽后 count=%d err=%v, 想要 0", cnt, err)
- }
- }
- // TestScanWithUpdateDuringBatchResolve 扫描回调里逐行更新 (改索引列):
- // 更新会改写二级索引与行数据, 正在分批回表的游标必须不受影响, 且每行都被回调到。
- func TestScanWithUpdateDuringBatchResolve(t *testing.T) {
- db := fixOpenDB(t)
- tbl := qopNewTable(t, db, "t")
- qopSeed(t, tbl, 500)
- if err := db.Commit(); err != nil {
- t.Fatalf("commit: %v", err)
- }
- updated := 0
- err := tbl.Query().Where(In("age", []interface{}{int64(7), int64(8), int64(9)}, 0)).
- ScanWithPKID(func(pkID uint64, _ []types.FieldValue) bool {
- if err := tbl.UpdateRowByPK(pkID, []types.FieldValue{
- {FieldName: []byte("age"), Value: int64(99)},
- {FieldName: []byte("score"), Value: int64(1)},
- }); err != nil {
- t.Fatalf("更新 %d: %v", pkID, err)
- }
- updated++
- return true
- })
- if err != nil {
- t.Fatalf("scan+update: %v", err)
- }
- // age ∈ {7,8,9} 且 id<=500: 每值 10 个 → 30 行
- if updated != 30 {
- t.Fatalf("应更新 30 行, 实更新 %d", updated)
- }
- cnt, err := tbl.Query().Where(Eq("age", int64(99), 0)).Count()
- if err != nil || cnt != 30 {
- t.Fatalf("更新后 age=99 的 count=%d err=%v, 想要 30", cnt, err)
- }
- }
|