java-topology/tools/tickets/defects/sqlite-0001.md
russell@unturf.com db29a08762 undefect. CWE-407 — 92 sites, 42 ecosystems
B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections.
Squash of 94 local commits onto remote master.
2026-03-26 19:48:18 -04:00

1.9 KiB
Raw Permalink Blame History

id repo severity status created
sqlite-0001 sqlite/sqlite MEDIUM PATCHED 2026-03-23

Defect

File: src/trigger.c:792 (checkColumnOverlap) Pattern: sqlite3IdListIndex(pIdList, pEList->a[e].zEName) inside for(e=0; e<pEList->nExpr; e++) Complexity: O(|SET_cols| × |trigger_cols|) per DML trigger check Language: C

Description

checkColumnOverlap determines whether any column in an UPDATE's SET clause (pEList) matches any column listed in a trigger's WHEN-columns list (pIdList). It does this by looping over each column in the SET clause and calling sqlite3IdListIndex() — a linear scan through the IdList — for each one.

sqlite3IdListIndex is a sequential name-comparison loop (O(|pIdList|)). The outer for loop is O(|pEList->nExpr|). Combined: O(|SET_cols| × |trigger_cols|).

This function is called by triggersReallyExist() which runs on every INSERT, UPDATE, and DELETE to determine which triggers fire. For a table with W trigger-watched columns and an UPDATE with S SET columns, each DML statement triggers O(S × W) comparisons. At S=W=50 (wide table with a full-column UPDATE trigger), this is 2,500 string comparisons per DML statement.

Fix

Replace: Linear scan via sqlite3IdListIndex for each SET column With: Build a case-insensitive hash set over pIdList->a[i].zName before the loop; check O(1) per SET column via hash lookup. Data structure: SQLite's sqlite3HashInsert/sqlite3HashFind (already used in the codebase) keyed on column name string.

Work required

  • Patch in defects/sqlite/patch/
  • Unit test — asserts exact comparison counts before/after (in defects/sqlite/unit/)
  • Integration test — UPDATE on table with W=10,20,50 trigger-watched columns (in defects/sqlite/integration/)
  • Benchmark — timing before/after on 10,000 UPDATE statements (in defects/sqlite/bench/)
  • White paper section — whitepaper/vectors/database/sqlite.rst