Skip to content

fix: close the connections the sqlite probes open - #401

Merged
abrignoni merged 1 commit into
mainfrom
fix/close-sqlite-probe-connections
Aug 9, 2026
Merged

fix: close the connections the sqlite probes open#401
abrignoni merged 1 commit into
mainfrom
fix/close-sqlite-probe-connections

Conversation

@abrignoni

Copy link
Copy Markdown
Owner

Follow-up to the connection-leak fix in iLEAPP #1778, which fixed three helpers there. This brings the same fix to this core and covers a fourth function that #1778 predates.

What leaks

Each of does_table_exist_in_db, does_view_exist_in_db and does_column_exist_in_db opens a connection through open_sqlite_db_readonly, returns a bool, and leaves the connection to the garbage collector. null_absent_columns does the same. Artifacts probe the same database repeatedly, so this is one held handle per probe for the length of a run.

does_column_exist_in_db also lacked the if db: guard its two siblings have. When open_sqlite_db_readonly returns None for an unreadable database it raised AttributeError: 'NoneType' object has no attribute 'row_factory' — not a sqlite3.Error, so the local handler missed it and the whole artifact died. One bad file costing an examiner every row.

All four now close in a finally, so the early return True path closes too, and the guard is consistent across the three.

Measured, by counting open file descriptors

Garbage collection disabled so a leak cannot be hidden by collection:

before after
150 null_absent_columns calls +150 open fds +0
450 does_*_exist_in_db calls +450 open fds +0

One leaked handle per call, in both cases, now zero. Behaviour is unchanged: the same query still comes back with the absent column reported as NULL under its own name.

A ResourceWarning-based test was tried first and is not adequate: the warning is raised during garbage collection, where CPython prints "Exception ignored" instead of propagating, so the test reported "no leak" against the unfixed code as well. Descriptor counting was verified to fail on the unfixed version before being trusted.

Levelled across all five cores so they stay identical.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com

does_table_exist_in_db, does_view_exist_in_db, does_column_exist_in_db and
null_absent_columns each open a connection and return without closing it, so a
run holds one handle per probe. All four now close in a finally, which also
covers the early return True path.

does_column_exist_in_db additionally lacked the if db: guard its siblings have,
so an unreadable database raised AttributeError rather than sqlite3.Error and
killed the artifact instead of returning False.

Measured by counting open file descriptors with gc disabled: 150 calls leaked
150 handles before and 0 after; 450 probe calls leaked 450 before and 0 after.

Levelled from iLEAPP PR #1778 plus the null_absent_columns case it predates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@abrignoni
abrignoni merged commit 4b8b493 into main Aug 9, 2026
4 checks passed
@abrignoni
abrignoni deleted the fix/close-sqlite-probe-connections branch August 9, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant