Skip to content

Commit

Permalink
Ensure migration 209 works with NULL fkey values
Browse files Browse the repository at this point in the history
Modify the sub-query on migration 209's backup to not select NULL
items which cause the NOT IN to always be false and consequently
the backup not to run resulting in a violation of the foreign keys.

To test, add an instance with NULL uuid to check the backups still
work correctly and avoid violating the foreign key constraint.
If there are NULL values in a NOT IN () set the result is always
false. Therefore having this instance inserted causes migration 209
to fail unless the IN set sub-query is modified appropriately.

Change-Id: Id0f8c8cb082df8861e85f925b979ddd934a95bfc
Closes-Bug: 1240325
  • Loading branch information
jhesketh committed Oct 16, 2013
1 parent 6affe67 commit 6eda819
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
Expand Up @@ -47,7 +47,8 @@ def upgrade(migrate_engine):
table_dump.create()
for column, ref_table_name, ref_column_name in indexes:
ref_table = load_tables[ref_table_name]
subq = select([getattr(ref_table.c, ref_column_name)])
subq = select([getattr(ref_table.c, ref_column_name)]).where(
getattr(ref_table.c, ref_column_name) != None)
sql = utils.InsertFromSelect(table_dump, table.select().where(
~ getattr(table.c, column).in_(subq)))
sql_del = table.delete().where(
Expand Down
11 changes: 11 additions & 0 deletions nova/tests/db/test_migrations.py
Expand Up @@ -2785,6 +2785,17 @@ def _pre_upgrade_209(self, engine):
change_tables[i].delete().execute()
change_tables[i].insert().values(data[i]).execute()

# NOTE(jhesketh): Add instance with NULL uuid to check the backups
# still work correctly and avoid violating the foreign
# key constraint. If there are NULL values in a NOT IN
# () set the result is always false. Therefore having
# this instance inserted here causes migration 209 to
# fail unless the IN set sub-query is modified
# appropriately. See bug/1240325
db_utils.get_table(engine, 'instances').insert(
{'uuid': None}
).execute()

def _check_209(self, engine, data):
if engine.name == 'sqlite':
return
Expand Down

0 comments on commit 6eda819

Please sign in to comment.