Summary
InsertReferences chunks 500 rows per transaction and UPSERTs reference_lines then INSERTs symbol_references. If the second INSERT fails mid-chunk (e.g. file deleted concurrently → FK violation), the reference_lines rows are already committed and orphaned. There's no cascade from symbol_references back to reference_lines, so long-lived repos accumulate unreferenced rows that only --rebuild cleans.
Evidence
src/CodeIndex/Database/DbWriter.cs:428-502 — chunked transaction; reference_lines UPSERT precedes the dependent symbol_references insert.
Impact
- Slow disk-bloat over months on actively-edited repos.
- Mild query slowdown as
reference_lines accumulates rows that no symbol_references row points to.
Proposed direction
- Wrap both inserts in a single nested SAVEPOINT per chunk so a failure rolls both back.
- Or: add a periodic
cdidx db --gc step that finds & deletes reference_lines rows with no incoming symbol_references.
Repro env
- Branch:
main @ 2ee912d (release v1.21.0)
Summary
InsertReferenceschunks 500 rows per transaction and UPSERTsreference_linesthen INSERTssymbol_references. If the second INSERT fails mid-chunk (e.g. file deleted concurrently → FK violation), thereference_linesrows are already committed and orphaned. There's no cascade fromsymbol_referencesback toreference_lines, so long-lived repos accumulate unreferenced rows that only--rebuildcleans.Evidence
src/CodeIndex/Database/DbWriter.cs:428-502— chunked transaction;reference_linesUPSERT precedes the dependentsymbol_referencesinsert.Impact
reference_linesaccumulates rows that nosymbol_referencesrow points to.Proposed direction
cdidx db --gcstep that finds & deletesreference_linesrows with no incomingsymbol_references.Repro env
main@ 2ee912d (release v1.21.0)