Skip to content

Commit c257d25

Browse files
committed
🐛 Fix stale FTS tokens after content update in external content mode #17540
1 parent 63ba3f5 commit c257d25

2 files changed

Lines changed: 32 additions & 39 deletions

File tree

kernel/sql/block.go

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package sql
1919
import (
2020
"bytes"
2121
"database/sql"
22+
"fmt"
2223
"strings"
2324

2425
"github.com/88250/gulu"
@@ -68,11 +69,14 @@ func blockRowIDByBlockID(tx *sql.Tx, id string) (rowID int64, err error) {
6869
return
6970
}
7071
defer rows.Close()
71-
if rows.Next() {
72-
if err = rows.Scan(&rowID); err != nil {
73-
logging.LogErrorf("scan block rowid failed: %s", err)
74-
return
75-
}
72+
if !rows.Next() {
73+
logging.LogErrorf("query block rowid failed: id=%s not found", id)
74+
err = fmt.Errorf("block rowid not found: %s", id)
75+
return
76+
}
77+
if err = rows.Scan(&rowID); err != nil {
78+
logging.LogErrorf("scan block rowid failed: %s", err)
79+
return
7680
}
7781
return
7882
}
@@ -107,18 +111,20 @@ func queryBlockRowIDsTx(tx *sql.Tx, blocks []*Block) (ret map[string]int64, err
107111
return
108112
}
109113

114+
// 下列局部更新索引列的路径(updateRootContent、updateBlockContent、indexNode)须先写 blocks_fts、再写 blocks,
115+
// 以便 FTS 删除旧 token 时仍能从 blocks 读到旧值。
116+
110117
func updateRootContent(tx *sql.Tx, content, updated, ialContent, id string) (err error) {
111-
stmt := "UPDATE blocks SET content = ?, fcontent = ?, updated = ?, ial = ? WHERE id = ?"
112-
if err = execStmtTx(tx, stmt, content, content, updated, ialContent, id); err != nil {
113-
return
114-
}
115-
// external content 模式下按 rowid 定位 FTS 行
116118
var rowID int64
117119
if rowID, err = blockRowIDByBlockID(tx, id); err != nil {
118120
return
119121
}
120-
stmt = "UPDATE blocks_fts SET content = ?, fcontent = ?, updated = ?, ial = ? WHERE rowid = ?"
121-
if err = execStmtTx(tx, stmt, content, content, updated, ialContent, rowID); err != nil {
122+
stmt := "UPDATE blocks_fts SET content = ?, fcontent = ?, ial = ? WHERE rowid = ?"
123+
if err = execStmtTx(tx, stmt, content, content, ialContent, rowID); err != nil {
124+
return
125+
}
126+
stmt = "UPDATE blocks SET content = ?, fcontent = ?, updated = ?, ial = ? WHERE id = ?"
127+
if err = execStmtTx(tx, stmt, content, content, updated, ialContent, id); err != nil {
122128
return
123129
}
124130
removeBlockCache(id)
@@ -127,22 +133,21 @@ func updateRootContent(tx *sql.Tx, content, updated, ialContent, id string) (err
127133
}
128134

129135
func updateBlockContent(tx *sql.Tx, block *Block) (err error) {
130-
stmt := "UPDATE blocks SET content = ? WHERE id = ?"
131-
if err = execStmtTx(tx, stmt, block.Content, block.ID); err != nil {
132-
tx.Rollback()
133-
return
134-
}
135-
// external content 模式下按 rowid 定位 FTS 行
136136
var rowID int64
137137
if rowID, err = blockRowIDByBlockID(tx, block.ID); err != nil {
138138
tx.Rollback()
139139
return
140140
}
141-
stmt = "UPDATE blocks_fts SET content = ? WHERE rowid = ?"
141+
stmt := "UPDATE blocks_fts SET content = ? WHERE rowid = ?"
142142
if err = execStmtTx(tx, stmt, block.Content, rowID); err != nil {
143143
tx.Rollback()
144144
return
145145
}
146+
stmt = "UPDATE blocks SET content = ? WHERE id = ?"
147+
if err = execStmtTx(tx, stmt, block.Content, block.ID); err != nil {
148+
tx.Rollback()
149+
return
150+
}
146151

147152
putBlockCache(block)
148153
return
@@ -166,22 +171,21 @@ func indexNode(tx *sql.Tx, id string) (err error) {
166171

167172
content := NodeStaticContent(node, nil, true, indexAssetPath, true)
168173
content = strings.ReplaceAll(content, editor.Zwsp, "")
169-
stmt := "UPDATE blocks SET content = ? WHERE id = ?"
170-
if err = execStmtTx(tx, stmt, content, id); err != nil {
171-
tx.Rollback()
172-
return
173-
}
174-
// external content 模式下按 rowid 定位 FTS 行
175174
var rowID int64
176175
if rowID, err = blockRowIDByBlockID(tx, id); err != nil {
177176
tx.Rollback()
178177
return
179178
}
180-
stmt = "UPDATE blocks_fts SET content = ? WHERE rowid = ?"
179+
stmt := "UPDATE blocks_fts SET content = ? WHERE rowid = ?"
181180
if err = execStmtTx(tx, stmt, content, rowID); err != nil {
182181
tx.Rollback()
183182
return
184183
}
184+
stmt = "UPDATE blocks SET content = ? WHERE id = ?"
185+
if err = execStmtTx(tx, stmt, content, id); err != nil {
186+
tx.Rollback()
187+
return
188+
}
185189
return
186190
}
187191

kernel/sql/database.go

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,12 +1095,12 @@ func deleteBlocksByIDs(tx *sql.Tx, ids []string) (err error) {
10951095
return
10961096
}
10971097

1098-
stmt = "DELETE FROM blocks WHERE ROWID IN (" + strings.Join(rowIDs, ",") + ")"
1098+
stmt = "DELETE FROM blocks_fts WHERE ROWID IN (" + strings.Join(rowIDs, ",") + ")"
10991099
if err = execStmtTx(tx, stmt); err != nil {
11001100
return
11011101
}
11021102

1103-
stmt = "DELETE FROM blocks_fts WHERE ROWID IN (" + strings.Join(rowIDs, ",") + ")"
1103+
stmt = "DELETE FROM blocks WHERE ROWID IN (" + strings.Join(rowIDs, ",") + ")"
11041104
if err = execStmtTx(tx, stmt); err != nil {
11051105
return
11061106
}
@@ -1322,11 +1322,6 @@ func batchUpdatePath(tx *sql.Tx, tree *parse.Tree, context map[string]any) (err
13221322
if err = execStmtTx(tx, stmt, tree.Box, tree.Path, tree.HPath, tree.ID); err != nil {
13231323
return
13241324
}
1325-
// external content 模式下按 rowid 定位 FTS 行
1326-
stmt = "UPDATE blocks_fts SET box = ?, path = ?, hpath = ? WHERE rowid IN (SELECT rowid FROM blocks WHERE root_id = ?)"
1327-
if err = execStmtTx(tx, stmt, tree.Box, tree.Path, tree.HPath, tree.ID); err != nil {
1328-
return
1329-
}
13301325

13311326
stmt = "UPDATE spans SET box = ?, path = ? WHERE root_id = ?"
13321327
if err = execStmtTx(tx, stmt, tree.Box, tree.Path, tree.ID); err != nil {
@@ -1365,12 +1360,6 @@ func batchUpdateHPath(tx *sql.Tx, tree *parse.Tree, context map[string]any) (err
13651360
return
13661361
}
13671362

1368-
// external content 模式下按 rowid 定位 FTS 行
1369-
stmt = "UPDATE blocks_fts SET hpath = ? WHERE rowid IN (SELECT rowid FROM blocks WHERE root_id = ?)"
1370-
if err = execStmtTx(tx, stmt, tree.HPath, tree.ID); err != nil {
1371-
return
1372-
}
1373-
13741363
ClearCache()
13751364
evtHash := fmt.Sprintf("%x", sha256.Sum256([]byte(tree.ID)))[:7]
13761365
eventbus.Publish(eventbus.EvtSQLUpdateBlocksHPaths, context, 1, evtHash)

0 commit comments

Comments
 (0)