mirror of
https://github.com/discourse/discourse.git
synced 2026-03-04 01:15:08 +08:00
## Problem `Migration::ColumnDropper.mark_readonly` could incorrectly detect a default value from a non-public schema table. The query checking for column defaults did not filter by `table_schema`: ```sql SELECT column_default IS NOT NULL FROM information_schema.columns WHERE table_name = :table_name AND column_name = :column_name ``` When multiple schemas contain tables with the same name (e.g., from backup/restore operations), this query returns multiple rows. The code uses `.first`, making behavior dependent on PostgreSQL's row ordering. ## Root Cause Don's diagnostic queries on an affected instance confirmed the issue: ```plain table_schema | column_name | column_default --------------+---------------------------+---------------- backup | discourse_rewind_disabled | false ← returned first public | discourse_rewind_disabled | false ``` The `backup` schema (from a previous `pg_dump`) contained a copy of `user_options` with the old default. PostgreSQL returned this row first, causing `mark_readonly` to fail with "You must drop a column's default value before marking it as readonly". ## Fix Just a oneline -> adding `table_schema = 'public'` to the `WHERE` clause to ensure only the `public` schema is considered. ## Why it couldn't be reproduced locally? - Fresh dev databases don't have `backup` schemas - CI environments use clean databases - Row ordering depends on database history (OIDs, backup/restore cycles) Ref - https://meta.discourse.org/t/393049 |
||
|---|---|---|
| .. | ||
| column_dropper_spec.rb | ||
| safe_migrate_spec.rb | ||
| table_dropper_spec.rb | ||