From 45c9316d7dc5562cf9fee664267cfe9edbce7f7e Mon Sep 17 00:00:00 2001 From: Ted Johansson Date: Mon, 14 Oct 2024 13:55:35 +0800 Subject: [PATCH] DEV: Fix problem check tracker unique index not respecting NULLs (#29169) By default, when checking uniqueness on a tuple for the purposes of enforcing a unique index, PostgreSQL considers NULLs to be distinct values. Because of this we could incorrectly have multiple entries with { identifier: "rails_env", target: nil } created due to race conditions. This would then cause errors at runtime. --- ...ue_constraint_on_problem_check_trackers.rb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 db/migrate/20241011054348_fix_unique_constraint_on_problem_check_trackers.rb diff --git a/db/migrate/20241011054348_fix_unique_constraint_on_problem_check_trackers.rb b/db/migrate/20241011054348_fix_unique_constraint_on_problem_check_trackers.rb new file mode 100644 index 00000000000..c032c7cda2b --- /dev/null +++ b/db/migrate/20241011054348_fix_unique_constraint_on_problem_check_trackers.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class FixUniqueConstraintOnProblemCheckTrackers < ActiveRecord::Migration[7.1] + def up + remove_index :problem_check_trackers, %i[identifier target], if_exists: true + + # Remove any existing duplicates that might have slipped by to prevent + # the creation of the new unique index from failing. + # + execute(<<~SQL) + DELETE FROM problem_check_trackers + WHERE id IN( + SELECT pct1.id + FROM problem_check_trackers pct1 + JOIN problem_check_trackers pct2 + ON pct1.identifier = pct2.identifier + AND pct1.target IS NULL + AND pct2.target IS NULL + WHERE pct1.id > pct2.id + ) + SQL + + add_index :problem_check_trackers, %i[identifier target], unique: true, nulls_not_distinct: true + end + + def down + remove_index :problem_check_trackers, %i[identifier target], if_exists: true + add_index :problem_check_trackers, %i[identifier target], unique: true + end +end