mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-24 02:44:32 +02:00
extract(): keep all-NULL rows unlinked even with a pre-existing NULL lookup row
Follow-up to the #186 fix: skipping the all-NULL combination in the lookup INSERT is not enough on its own. When extract() reuses a lookup table that already contains an all-NULL row (e.g. one written by an older sqlite-utils version or created manually), the IS-based foreign-key UPDATE would still match that row and link all-NULL source rows to it. The UPDATE now carries a trailing `WHERE NOT (<col> IS NULL AND ...)` so all-NULL source rows are never assigned a foreign key and keep the NULL that the freshly-added column starts with, regardless of the lookup table's existing contents. Adds test_extract_all_null_stays_null_with_preexisting_null_lookup_row. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dad463e9c2
commit
3ab8406b1d
2 changed files with 35 additions and 7 deletions
|
|
@ -2289,12 +2289,15 @@ class Table(Queryable):
|
|||
# Now add the new fk_column
|
||||
self.add_column(magic_lookup_column, int)
|
||||
|
||||
# And populate it
|
||||
# And populate it. The trailing ``WHERE NOT (<all columns NULL>)`` leaves
|
||||
# all-NULL source rows with a NULL foreign key even when the lookup table
|
||||
# already contains an all-NULL row (e.g. a reused or legacy lookup table)
|
||||
# — the IS-based join would otherwise match that row and link to it (#186).
|
||||
self.db.execute(
|
||||
"UPDATE {} SET {} = (SELECT id FROM {} WHERE {where})".format(
|
||||
quote_identifier(self.name),
|
||||
quote_identifier(magic_lookup_column),
|
||||
quote_identifier(table),
|
||||
"UPDATE {table_name} SET {fk} = (SELECT id FROM {lookup} WHERE {where}) WHERE NOT ({all_null})".format(
|
||||
table_name=quote_identifier(self.name),
|
||||
fk=quote_identifier(magic_lookup_column),
|
||||
lookup=quote_identifier(table),
|
||||
where=" AND ".join(
|
||||
"{}.{} IS {}.{}".format(
|
||||
quote_identifier(self.name),
|
||||
|
|
@ -2304,6 +2307,12 @@ class Table(Queryable):
|
|||
)
|
||||
for column in columns
|
||||
),
|
||||
all_null=" AND ".join(
|
||||
"{}.{} IS NULL".format(
|
||||
quote_identifier(self.name), quote_identifier(column)
|
||||
)
|
||||
for column in columns
|
||||
),
|
||||
)
|
||||
)
|
||||
# Figure out the right column order
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue