discourse/db/migrate/20260518104900_fixup_id_sequences.rb
David Taylor 4e7578b76e
DEV: Check & resolve sequence issues during db:check_structure_dump (#40118)
As with rows, database sequence values are not persisted in
`structure.sql`. This commit adds a new check which detects any sequence
values introduced by migrations, and throws an error.

Existing issues are fixes up:
1. `enable_bookmarks_with_reminders` was being inserted and removed from
site settings unnecessarily. Removed.

2. user_associated_accounts and data_explorer_queries were having their
sequences updated unnecessarily on empty databases. Updated them to be
conditional.

3. Groups PK had been modified in a couple of different ways. A new
migration normalizes the start & current values to `40`, matching the
current behaviour

4. Badges PK was intended to START_AT 100. However, seed_fu/activerecord
were resetting the sequence to a lower number than that. A before_save
hook on the model already exists to work around that problem. Added a
migration to reset the sequence STARTS AT to 1, to make it clear that it
has no effect and we're relying on the model layer.

5. Flags PK STARTS_AT was already fixed in
`67305dc7bb`. This migration just
normalizes the current value, to fix up any sites which may have been
deployed with the `structure.sql` over the last few days
2026-05-18 15:23:41 +01:00

48 lines
1.8 KiB
Ruby
Vendored

# frozen_string_literal: true
class FixupIdSequences < ActiveRecord::Migration[8.0]
def up
# 20130506020935_add_automatic_to_groups ALTERed start_value to 100, then
# 20130509040248_update_sequence_for_groups setval'd last_value to 40.
# So realistically, 41+ has been the starting point for all sites since then.
# Updating the sequence "START WITH" to reflect reality
execute "ALTER SEQUENCE groups_id_seq START WITH 40"
execute <<~SQL
SELECT setval(
'groups_id_seq',
GREATEST(40, last_value),
CASE WHEN last_value > 40 THEN is_called ELSE false END
) FROM groups_id_seq
SQL
# 20140504174212_increment_reserved_trust_level_badge_ids set start_value
# to 100 to reserve 1-99 for system badges, but that reservation is
# actually enforced by Badge#ensure_not_system at the model layer.
# Revert START WITH to 1 to reflect what the sequence is really doing.
execute "ALTER SEQUENCE badges_id_seq START WITH 1"
execute <<~SQL
SELECT setval(
'badges_id_seq',
GREATEST(1, last_value),
CASE WHEN last_value > 1 THEN is_called ELSE false END
) FROM badges_id_seq
SQL
# 20240423054323_create_flags setval'd last_value to 1001 to reserve
# 1-1000 for system flags, but `setval` isn't captured in structure.sql.
# Sites restored from a structure.sql dumped before 20260518054805 added
# the matching `ALTER … START WITH 1001` would land at last_value=1
# — bump them defensively.
execute <<~SQL
SELECT setval(
'flags_id_seq',
GREATEST(1001, last_value),
CASE WHEN last_value > 1001 THEN is_called ELSE false END
) FROM flags_id_seq
SQL
end
def down
raise ActiveRecord::IrreversibleMigration
end
end