Repository navigation
fix(fts): snapshot FTS aux info in bind data (Fixes ladybugdb/ladybug#1105) - #94
Conversation
…#1105) QueryFTSBindData held a reference into the versioned catalog, which dangles when the prepared plan is reused on a second parameterized execution on the same connection, segfaulting (Refs LadybugDB/ladybug#1082, Refs LadybugDB/ladybug#1088). Store an owned copy of FTSIndexAuxInfo instead.
|
Tested this PR's CI build ( The #1105 crash is fixed:
Remaining gap: the cached parameterized plan is not invalidated when the FTS index is dropped or recreated. Same connection: Q = "CALL QUERY_FTS_INDEX('Doc', 'doc_fts', $q) RETURN node.id AS id ORDER BY id"
c.execute(Q, {"q": "alpha"}) # ['0']
c.execute("CALL DROP_FTS_INDEX('Doc', 'doc_fts')")
c.execute(Q, {"q": "alpha"}) # this PR: still returns ['0'] (index is gone)
c.execute("CALL CREATE_FTS_INDEX('Doc', 'doc_fts', ['text'])")
c.execute(Q, {"q": "alpha"}) # this PR: RuntimeError: unordered_map::atWith the literal form of the same query (
A new |
The prepared-plan cache reuses QueryFTSBindData across executions on the same connection, so the snapshotted aux info / backing-table graph entry / index stats went stale after DROP_FTS_INDEX (stale results) and broke after CREATE_FTS_INDEX (dropped table IDs). Store the queried table/index names and re-resolve them against the catalog on every execution (refreshFromCatalog). A missing index throws the same BinderException as the literal path, and a recreated index refreshes the snapshot. The cached physical plan also reuses the shared graph, so rebuild it when the backing table IDs changed.
Second parameterized CALL QUERY_FTS_INDEX on the same connection segfaults (LadybugDB/ladybug#1105, follow-up to LadybugDB/ladybug#1082 / LadybugDB/ladybug#1088).
Root cause: QueryFTSBindData held a const IndexCatalogEntry reference into the versioned catalog. Bind data outlives the bind transaction via the prepared-plan cache, so the 2nd execution dereferences a dangling entry.
Fix: store an owned FTSIndexAuxInfo value copy; read config from auxInfo in getQueryTerms/bindFunc/writer.
Minimal local testing per policy - CI owns build + e2e (extension rebuild + 4-mode repro from the issue).