From 0cc156ce3c1e87d25f44f123776f1aca5fed8f57 Mon Sep 17 00:00:00 2001 From: Brigs Date: Sun, 9 Aug 2026 15:49:18 -0400 Subject: [PATCH] fix: close the connection null_absent_columns opens It opens a connection through open_sqlite_db_readonly to compile the query and returns without closing it. Artifacts call it once per query, so this is one held handle per query for the length of a run rather than a one-off, and it is now wired into 534 call sites here. Measured by counting open file descriptors with gc disabled: 150 calls leaked 150 handles before, 0 after. Behaviour unchanged. Companion to #1778, which fixed the same class in the three does_*_exist_in_db helpers and predates this function. Co-Authored-By: Claude Opus 5 --- scripts/ilapfuncs.py | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/scripts/ilapfuncs.py b/scripts/ilapfuncs.py index cc9af64a4..aa4927eca 100644 --- a/scripts/ilapfuncs.py +++ b/scripts/ilapfuncs.py @@ -1015,21 +1015,26 @@ def null_absent_columns(path, query): return query replaced = [] - for _ in range(50): # a query cannot need more than this - try: - db.execute('EXPLAIN ' + query) - break - except sqlite3.OperationalError as ex: - match = re.match(r'no such column:\s*(\S+)', str(ex)) - if not match: + try: + for _ in range(50): # a query cannot need more than this + try: + db.execute('EXPLAIN ' + query) break - reference = match.group(1) - if reference in replaced: - break # not making progress, leave it alone - replaced.append(reference) - query = _null_out_column(query, reference) - except sqlite3.Error: - break + except sqlite3.OperationalError as ex: + match = re.match(r'no such column:\s*(\S+)', str(ex)) + if not match: + break + reference = match.group(1) + if reference in replaced: + break # not making progress, leave it alone + replaced.append(reference) + query = _null_out_column(query, reference) + except sqlite3.Error: + break + finally: + # Artifacts call this once per query, so an unclosed handle here is one + # leak per query for the whole run rather than a one-off. + db.close() if replaced: logfunc(f'{os.path.basename(path)}: column(s) absent from this version are reported '