@@ -1354,7 +1354,7 @@ reference_kind TEXT CHECK (reference_kind IN (" + referenceKindCheck + @")),
13541354 line INTEGER,
13551355 column_number INTEGER,
13561356 context TEXT,
1357- reference_line_id INTEGER REFERENCES reference_lines(id),
1357+ reference_line_id INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL ,
13581358 container_kind TEXT CHECK (container_kind IS NULL OR container_kind IN (" + symbolKindCheck + @")),
13591359 container_name TEXT
13601360 )" ) ;
@@ -1403,7 +1403,7 @@ value TEXT
14031403 EnsureColumn (
14041404 "symbol_references" ,
14051405 "reference_line_id" ,
1406- rebuildsSymbolReferences ? "INTEGER" : "INTEGER REFERENCES reference_lines(id)" ) ;
1406+ rebuildsSymbolReferences ? "INTEGER" : "INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL " ) ;
14071407 // #86: Unicode-aware folded name columns for `--exact` name matching across all
14081408 // `--exact` command variants. Populated by the writer via NameFold.Fold; NULL on
14091409 // legacy rows until a full reindex, in which case the reader falls back to the
@@ -1415,6 +1415,7 @@ value TEXT
14151415 EnsureColumn ( "symbol_references" , "is_self_reference" , "INTEGER NOT NULL DEFAULT 0" ) ;
14161416 EnsureColumn ( "symbol_references" , "is_mutual_recursion" , "INTEGER NOT NULL DEFAULT 0" ) ;
14171417 EnforceRequiredFileIdConstraints ( ) ;
1418+ EnforceReferenceLineSetNullConstraint ( ) ;
14181419 EnsureReferenceLinesContextKey ( ) ;
14191420
14201421 // Indexes / インデックス
@@ -1513,6 +1514,7 @@ CREATE TRIGGER IF NOT EXISTS fts_chunks_au AFTER UPDATE ON chunks BEGIN
15131514
15141515 private void EnforceRequiredFileIdConstraints ( )
15151516 {
1517+ var symbolKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . SymbolKinds ) ;
15161518 Execute ( "PRAGMA foreign_keys=OFF" ) ;
15171519 var legacyAlterTable = ExecuteScalar ( "PRAGMA legacy_alter_table" ) ;
15181520 Execute ( "PRAGMA legacy_alter_table=ON" ) ;
@@ -1534,11 +1536,11 @@ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
15341536 "id, file_id, chunk_index, start_line, end_line, content" ) ;
15351537 RebuildTableWithRequiredFileId (
15361538 "symbols" ,
1537- """
1539+ $ """
15381540 CREATE TABLE symbols (
15391541 id INTEGER PRIMARY KEY AUTOINCREMENT,
15401542 file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
1541- kind TEXT,
1543+ kind TEXT CHECK (kind IN ( { symbolKindCheck } )) ,
15421544 sub_kind TEXT,
15431545 name TEXT,
15441546 line INTEGER,
@@ -1548,7 +1550,7 @@ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
15481550 body_start_line INTEGER,
15491551 body_end_line INTEGER,
15501552 signature TEXT,
1551- container_kind TEXT,
1553+ container_kind TEXT CHECK (container_kind IS NULL OR container_kind IN ( { symbolKindCheck } )) ,
15521554 container_name TEXT,
15531555 container_qualified_name TEXT,
15541556 family_key TEXT,
@@ -1588,6 +1590,8 @@ private void RebuildReferenceLineTablesWithRequiredFileId()
15881590 return ;
15891591 }
15901592
1593+ var symbolKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . SymbolKinds ) ;
1594+ var referenceKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . ReferenceKinds ) ;
15911595 const string referenceLinesCreateSql =
15921596 """
15931597 CREATE TABLE reference_lines (
@@ -1599,18 +1603,18 @@ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
15991603 )
16001604 """ ;
16011605 const string referenceLinesColumns = "id, file_id, line, context" ;
1602- const string symbolReferencesCreateSql =
1603- """
1606+ var symbolReferencesCreateSql =
1607+ $ """
16041608 CREATE TABLE symbol_references (
16051609 id INTEGER PRIMARY KEY AUTOINCREMENT,
16061610 file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
16071611 symbol_name TEXT,
1608- reference_kind TEXT,
1612+ reference_kind TEXT CHECK (reference_kind IN ( { referenceKindCheck } )) ,
16091613 line INTEGER,
16101614 column_number INTEGER,
16111615 context TEXT,
1612- reference_line_id INTEGER REFERENCES reference_lines(id),
1613- container_kind TEXT,
1616+ reference_line_id INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL ,
1617+ container_kind TEXT CHECK (container_kind IS NULL OR container_kind IN ( { symbolKindCheck } )) ,
16141618 container_name TEXT,
16151619 symbol_name_folded TEXT,
16161620 container_name_folded TEXT,
@@ -1636,11 +1640,81 @@ is_mutual_recursion INTEGER NOT NULL DEFAULT 0
16361640 Execute ( $ "DROP TABLE { oldReferenceLines } ") ;
16371641 }
16381642
1643+ private void EnforceReferenceLineSetNullConstraint ( )
1644+ {
1645+ if ( SymbolReferencesReferenceLineDeletesSetNull ( ) )
1646+ return ;
1647+
1648+ var symbolKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . SymbolKinds ) ;
1649+ var referenceKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . ReferenceKinds ) ;
1650+ var symbolReferencesCreateSql =
1651+ $ """
1652+ CREATE TABLE symbol_references (
1653+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1654+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
1655+ symbol_name TEXT,
1656+ reference_kind TEXT CHECK (reference_kind IN ({ referenceKindCheck } )),
1657+ line INTEGER,
1658+ column_number INTEGER,
1659+ context TEXT,
1660+ reference_line_id INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL,
1661+ container_kind TEXT CHECK (container_kind IS NULL OR container_kind IN ({ symbolKindCheck } )),
1662+ container_name TEXT,
1663+ symbol_name_folded TEXT,
1664+ container_name_folded TEXT,
1665+ is_self_reference INTEGER NOT NULL DEFAULT 0,
1666+ is_mutual_recursion INTEGER NOT NULL DEFAULT 0
1667+ )
1668+ """ ;
1669+ const string symbolReferencesColumns = "id, file_id, symbol_name, reference_kind, line, column_number, context, reference_line_id, container_kind, container_name, symbol_name_folded, container_name_folded, is_self_reference, is_mutual_recursion" ;
1670+ const string oldSymbolReferences = "_symbol_references_reference_line_delete" ;
1671+
1672+ Execute ( $ "DROP TABLE IF EXISTS { oldSymbolReferences } ") ;
1673+ Execute ( @"
1674+ UPDATE symbol_references
1675+ SET reference_line_id = NULL
1676+ WHERE reference_line_id IS NOT NULL
1677+ AND NOT EXISTS (
1678+ SELECT 1
1679+ FROM reference_lines
1680+ WHERE reference_lines.id = symbol_references.reference_line_id
1681+ )" ) ;
1682+ Execute ( $ "ALTER TABLE symbol_references RENAME TO { oldSymbolReferences } ") ;
1683+ Execute ( symbolReferencesCreateSql ) ;
1684+ Execute ( $ "INSERT INTO symbol_references ({ symbolReferencesColumns } ) SELECT { symbolReferencesColumns } FROM { oldSymbolReferences } ") ;
1685+ Execute ( $ "DROP TABLE { oldSymbolReferences } ") ;
1686+ }
1687+
1688+ private bool SymbolReferencesReferenceLineDeletesSetNull ( )
1689+ {
1690+ using var cmd = _connection . CreateCommand ( ) ;
1691+ if ( _activeMigrationTransaction != null )
1692+ cmd . Transaction = _activeMigrationTransaction ;
1693+ cmd . CommandText = "PRAGMA foreign_key_list('symbol_references')" ;
1694+
1695+ using var reader = cmd . ExecuteTrackedReader ( ) ;
1696+ while ( reader . TrackedRead ( ) )
1697+ {
1698+ var table = reader . GetString ( 2 ) ;
1699+ var from = reader . GetString ( 3 ) ;
1700+ var onDelete = reader . GetString ( 6 ) ;
1701+ if ( string . Equals ( table , "reference_lines" , StringComparison . OrdinalIgnoreCase )
1702+ && string . Equals ( from , "reference_line_id" , StringComparison . OrdinalIgnoreCase ) )
1703+ {
1704+ return string . Equals ( onDelete , "SET NULL" , StringComparison . OrdinalIgnoreCase ) ;
1705+ }
1706+ }
1707+
1708+ return false ;
1709+ }
1710+
16391711 private void EnsureReferenceLinesContextKey ( )
16401712 {
16411713 if ( ReferenceLinesHasContextUniqueKey ( ) )
16421714 return ;
16431715
1716+ var symbolKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . SymbolKinds ) ;
1717+ var referenceKindCheck = SymbolKindCatalog . ToSqlCheckInList ( SymbolKindCatalog . ReferenceKinds ) ;
16441718 const string referenceLinesCreateSql =
16451719 """
16461720 CREATE TABLE reference_lines (
@@ -1652,18 +1726,18 @@ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
16521726 )
16531727 """ ;
16541728 const string referenceLinesColumns = "id, file_id, line, context" ;
1655- const string symbolReferencesCreateSql =
1656- """
1729+ var symbolReferencesCreateSql =
1730+ $ """
16571731 CREATE TABLE symbol_references (
16581732 id INTEGER PRIMARY KEY AUTOINCREMENT,
16591733 file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
16601734 symbol_name TEXT,
1661- reference_kind TEXT,
1735+ reference_kind TEXT CHECK (reference_kind IN ( { referenceKindCheck } )) ,
16621736 line INTEGER,
16631737 column_number INTEGER,
16641738 context TEXT,
1665- reference_line_id INTEGER REFERENCES reference_lines(id),
1666- container_kind TEXT,
1739+ reference_line_id INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL ,
1740+ container_kind TEXT CHECK (container_kind IS NULL OR container_kind IN ( { symbolKindCheck } )) ,
16671741 container_name TEXT,
16681742 symbol_name_folded TEXT,
16691743 container_name_folded TEXT,
@@ -1969,14 +2043,14 @@ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
19692043 line INTEGER,
19702044 column_number INTEGER,
19712045 context TEXT,
1972- reference_line_id INTEGER REFERENCES reference_lines(id),
2046+ reference_line_id INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL ,
19732047 container_kind TEXT,
19742048 container_name TEXT,
19752049 is_self_reference INTEGER NOT NULL DEFAULT 0,
19762050 is_mutual_recursion INTEGER NOT NULL DEFAULT 0
19772051 )" ) ) ;
19782052 yield return ( "EnsureColumn symbol_references.reference_line_id" ,
1979- ( ) => EnsureColumn ( "symbol_references" , "reference_line_id" , "INTEGER REFERENCES reference_lines(id)" ) ) ;
2053+ ( ) => EnsureColumn ( "symbol_references" , "reference_line_id" , "INTEGER REFERENCES reference_lines(id) ON DELETE SET NULL " ) ) ;
19802054 yield return ( "EnsureColumn symbol_references.is_self_reference" ,
19812055 ( ) => EnsureColumn ( "symbol_references" , "is_self_reference" , "INTEGER NOT NULL DEFAULT 0" ) ) ;
19822056 yield return ( "EnsureColumn symbol_references.is_mutual_recursion" ,
0 commit comments