# UNDF: UNDF-2026-000000300 # sqlite-0003 — `sqlite3CreateForeignKey`: O(F×C) column resolution with `sqlite3StrICmp` inside nested loop ## Status PATCHED ## Severity MEDIUM (>50× speedup at F=100 FK cols, C=1000 table cols) ## Location `src/build.c`, function `sqlite3CreateForeignKey()`, lines ~3680-3688 ## Description When resolving FK source column names to column indices during `CREATE TABLE` parsing, SQLite uses a nested loop: ```c for(i=0; inCol; j++){ /* C = total columns in table */ if( sqlite3StrICmp(p->aCol[j].zCnName, pFromCol->a[i].zEName)==0 ){ pFKey->aCol[i].iFrom = j; break; } } if( j>=p->nCol ){ /* error: unknown column */ } } ``` Total cost: O(F × C) with `sqlite3StrICmp` (case-insensitive string compare) for each comparison. `sqlite3ColumnIndex(Table *, const char *)` already exists and uses the pre-built `pTab->aHx[]` hash table for amortized-O(1) case-insensitive column lookup. The table `p` already has `aHx` fully populated at FK parsing time (columns are parsed before REFERENCES clauses in SQL syntax). ## Patch ```c --- a/src/build.c +++ b/src/build.c @@ -3680,14 +3680,17 @@ void sqlite3CreateForeignKey(...){ if( pFromCol==0 ){ pFKey->aCol[0].iFrom = p->nCol-1; }else{ for(i=0; inCol; j++){ - if( sqlite3StrICmp(p->aCol[j].zCnName, pFromCol->a[i].zEName)==0 ){ - pFKey->aCol[i].iFrom = j; - break; - } - } - if( j>=p->nCol ){ + /* CWE-407 fix (sqlite-0003): use hash-based sqlite3ColumnIndex instead + ** of O(p->nCol) sqlite3StrICmp inner loop. */ + int j = sqlite3ColumnIndex(p, pFromCol->a[i].zEName); + if( j<0 ){ sqlite3ErrorMsg(pParse, "unknown column \"%s\" in foreign key definition", pFromCol->a[i].zEName); goto fk_end; + }else{ + pFKey->aCol[i].iFrom = j; } if( IN_RENAME_OBJECT ){ ``` ## Speedup At F=100, C=1000: O(F×C)=100,000 `sqlite3StrICmp` calls → O(F)=100 hash lookups → **1000× speedup**. Typical case (F=5, C=100): O(500) → O(5) → **100× speedup**. The `CREATE TABLE` stage is compilation, not runtime execution. Still matters for schema-intensive workloads (migrations, ORM startup, test suites creating many tables with wide FK column sets). ## Test `defects/sqlite/unit/SqliteTest.java` — `sqlite-0003` section.