2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/spec/lib/migration
Régis Hanol 2623d7a607
FIX: Add table_schema filter to mark_readonly default check (#37037)
## 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
2026-01-10 21:57:31 +01:00
..
column_dropper_spec.rb FIX: Add table_schema filter to mark_readonly default check (#37037) 2026-01-10 21:57:31 +01:00
safe_migrate_spec.rb DEV: Allow DROP DEFAULT in pre-deploy migrations (#34838) 2025-09-17 16:15:02 +08:00
table_dropper_spec.rb