From 88c1578ca6748bec0929736d475e9882e1dc4b82 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 7 Dec 2023 11:23:53 +0000 Subject: Add latest changes from gitlab-org/gitlab@16-6-stable-ee --- ...i_pipelines_pipeline_id_bigint_for_self_host.rb | 19 ++++- ...elines_pipeline_id_bigint_for_self_host_spec.rb | 89 ++++++++++++++++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 spec/migrations/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host_spec.rb diff --git a/db/post_migrate/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host.rb b/db/post_migrate/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host.rb index a960258ff3d..a422811415b 100644 --- a/db/post_migrate/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host.rb +++ b/db/post_migrate/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host.rb @@ -10,11 +10,13 @@ class SwapColumnsForCiPipelinesPipelineIdBigintForSelfHost < Gitlab::Database::M TRIGGER_FUNCTION_NAME = :trigger_1bd97da9c1a4 COLUMN_NAME = :auto_canceled_by_id BIGINT_COLUMN_NAME = :auto_canceled_by_id_convert_to_bigint - FK_NAME = :fk_262d4c2d19 - BIGINT_FK_NAME = :fk_67e4288f3a INDEX_NAME = :index_ci_pipelines_on_auto_canceled_by_id BIGINT_INDEX_NAME = :index_ci_pipelines_on_auto_canceled_by_id_bigint + class PgForeignKeys < MigrationRecord + self.table_name = :postgres_foreign_keys + end + def up return if column_type_of?(:bigint) @@ -45,10 +47,21 @@ class SwapColumnsForCiPipelinesPipelineIdBigintForSelfHost < Gitlab::Database::M reset_trigger_function(TRIGGER_FUNCTION_NAME) # Swap fkey constraint - swap_foreign_keys(TABLE_NAME, FK_NAME, BIGINT_FK_NAME) + swap_foreign_keys( + TABLE_NAME, + foreign_key_name_for(TABLE_NAME, COLUMN_NAME), + foreign_key_name_for(TABLE_NAME, BIGINT_COLUMN_NAME) + ) # Swap index swap_indexes(TABLE_NAME, INDEX_NAME, BIGINT_INDEX_NAME) end end + + def foreign_key_name_for(source, column) + PgForeignKeys + .where(constrained_table_name: source) + .where(constrained_columns: [column]) + .first&.name || raise("Required foreign key for #{source} #{column} is missing.") + end end diff --git a/spec/migrations/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host_spec.rb b/spec/migrations/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host_spec.rb new file mode 100644 index 00000000000..f7afee950b7 --- /dev/null +++ b/spec/migrations/20231025025733_swap_columns_for_ci_pipelines_pipeline_id_bigint_for_self_host_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe SwapColumnsForCiPipelinesPipelineIdBigintForSelfHost, feature_category: :continuous_integration do + let(:connection) { active_record_base.connection } + + before do + connection.execute('ALTER TABLE ci_pipelines ALTER COLUMN auto_canceled_by_id TYPE integer') + connection.execute('ALTER TABLE ci_pipelines ALTER COLUMN auto_canceled_by_id_convert_to_bigint TYPE bigint') + end + + it_behaves_like( + 'swap conversion columns', + table_name: :ci_pipelines, + from: :auto_canceled_by_id, + to: :auto_canceled_by_id_convert_to_bigint + ) + + context 'when foreign key names are different' do + before do + if connection.foreign_key_exists?(:ci_pipelines, name: :fk_262d4c2d19) + connection.execute( + 'ALTER TABLE "ci_pipelines" RENAME CONSTRAINT "fk_262d4c2d19" TO "fk_4_auto_canceled_by_id"' + ) + end + + if connection.foreign_key_exists?(:ci_pipelines, name: :fk_67e4288f3a) + connection.execute( + 'ALTER TABLE "ci_pipelines" RENAME CONSTRAINT "fk_67e4288f3a" TO "fk_4_auto_canceled_by_id_convert_to_bigint"' + ) + end + end + + after do + if connection.foreign_key_exists?(:ci_pipelines, name: :fk_4_auto_canceled_by_id) + connection.execute( + 'ALTER TABLE "ci_pipelines" RENAME CONSTRAINT "fk_4_auto_canceled_by_id" TO "fk_262d4c2d19"' + ) + end + + if connection.foreign_key_exists?(:ci_pipelines, name: :fk_4_auto_canceled_by_id_convert_to_bigint) + connection.execute( + 'ALTER TABLE "ci_pipelines" RENAME CONSTRAINT "fk_4_auto_canceled_by_id_convert_to_bigint" TO "fk_67e4288f3a"' + ) + end + end + + it 'swaps the foreign key properly' do + disable_migrations_output do + recorder = ActiveRecord::QueryRecorder.new { migrate! } + expect(recorder.log).to include( + /RENAME CONSTRAINT "fk_4_auto_canceled_by_id_convert_to_bigint" TO "temp_name_for_renaming"/ + ) + expect(recorder.log).to include( + /RENAME CONSTRAINT "fk_4_auto_canceled_by_id" TO "fk_4_auto_canceled_by_id_convert_to_bigint"/ + ) + expect(recorder.log).to include(/RENAME CONSTRAINT "temp_name_for_renaming" TO "fk_4_auto_canceled_by_id"/) + end + end + end + + context 'when foreign key is missing' do + before do + if connection.foreign_key_exists?(:ci_pipelines, name: :fk_262d4c2d19) + connection.remove_foreign_key(:ci_pipelines, name: :fk_262d4c2d19) + end + + if connection.foreign_key_exists?(:ci_pipelines, name: :fk_4_auto_canceled_by_id) + connection.remove_foreign_key(:ci_pipelines, name: :fk_4_auto_canceled_by_id) + end + end + + after do + # Need to add the foreign key back or it will fail the other tests + connection.add_foreign_key( + :ci_pipelines, :ci_pipelines, + name: :fk_262d4c2d19, column: :auto_canceled_by_id, on_delete: :nullify + ) + end + + it 'raises error' do + disable_migrations_output do + expect { migrate! }.to raise_error(/Required foreign key for .* is missing./) + end + end + end +end -- cgit v1.2.3