From 26b2783c5d8297188511cef265c67870da62e19c Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 11:08:21 -0500 Subject: [PATCH 01/34] Add patch for primary keys column optimization --- .../schema_statements/primary_keys.rb | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb new file mode 100644 index 00000000000000..e398e1dfdd3e76 --- /dev/null +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module ActiveRecord + module GitlabPatches + module ConnectionAdapters + module Postgresql + module SchemaStatements + # Adds patch for ActiveRecord `primary_keys` methods + # to optimize the query for primary key columns + + # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c + # Issue: https://github.com/rails/rails/issues/55648 + def primary_keys(table_name) + query_values(<<~SQL.squish, "SCHEMA") + SELECT a.attname + FROM pg_index i + JOIN pg_attribute a + ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass + AND i.indisprimary + ORDER BY array_position(i.indkey, a.attnum) + SQL + end + end + end + end + end +end -- GitLab From 95f503f813e6559ec84c30e6a9083a957e0a5a1d Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 11:28:22 -0500 Subject: [PATCH 02/34] Fix comments for patch --- .../postgresql/schema_statements/primary_keys.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index e398e1dfdd3e76..c027c1f908157b 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -5,11 +5,11 @@ module GitlabPatches module ConnectionAdapters module Postgresql module SchemaStatements - # Adds patch for ActiveRecord `primary_keys` methods + # Adds patch for ActiveRecord `primary_keys` method # to optimize the query for primary key columns # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue: https://github.com/rails/rails/issues/55648 + # Issue:https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 def primary_keys(table_name) query_values(<<~SQL.squish, "SCHEMA") SELECT a.attname -- GitLab From 19ce51f4cdd7d87b2001713cefbd6400698fa6f2 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 13:56:37 -0500 Subject: [PATCH 03/34] Fix patch and add tests --- .../lib/active_record/gitlab_patches.rb | 1 + .../schema_statements/primary_keys.rb | 8 +- .../schema_statements/primary_keys_spec.rb | 99 +++++++++++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb index b70de557046476..5f90170577f1a9 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb @@ -5,6 +5,7 @@ require_relative "gitlab_patches/rescue_from" require_relative "gitlab_patches/relation/find_or_create_by" require_relative "gitlab_patches/partitioning" +require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements" module ActiveRecord module GitlabPatches diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index c027c1f908157b..517eba459aa8aa 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -6,10 +6,11 @@ module ConnectionAdapters module Postgresql module SchemaStatements # Adds patch for ActiveRecord `primary_keys` method - # to optimize the query for primary key columns + # to optimize the query for primary key retrieval. # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue:https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 + # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 + def primary_keys(table_name) query_values(<<~SQL.squish, "SCHEMA") SELECT a.attname @@ -26,4 +27,7 @@ def primary_keys(table_name) end end end + + ActiveSupport.on_load(:active_record) do + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb new file mode 100644 index 00000000000000..b266d320f073fe --- /dev/null +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys do + let(:connection) { ActiveRecord::Base.connection } + + describe '#primary_keys' do + context 'with single column primary key' do + it 'returns the primary key column name' do + primary_keys = connection.primary_keys('users') + expect(primary_keys).to eq(['id']) + end + end + + context 'with composite primary key' do + let(:table_name) { :_text_composite_pk_table } + + before do + connection.execute(<<~SQL.squish) + CREATE TABLE #{table_name} ( + organization_Id bigint NOT NULL, + resource_id bigint NOT NULL, + name text, + PRIMARY KEY (organization_id, resource_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns all primary key columns in correct order' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys).to eq(%w[organization_id resource_id]) + end + + it 'preserves the order defined in PRIMARY KEY constraint' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys.first).to eq('organization_id') + expect(primary_keys.second).to eq('resource_id') + end + end + + context 'with reversed composite primary key' do + let(:table_name) { :_test_reversed_pk_table } + + before do + connection.execute(<<~SQL.squish) + CREATE TABLE #{table_name} ( + organization_id bigint NOT NULL, + resource_id bigint NOT NULL, + PRIMARY KEY (resource_id, organization_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns columns in PRIMARY KEY definition order' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys).to eq(%w[resource_id organization_id]) + end + end + + context 'with partitioned table' do + let(:parent_table) { :_test_partitioned_parent } + let(:partition_table) { :_test_partitioned_child } + + before do + connection.execute(<<~SQL.squish) + CREATE TABLE #{parent_table} ( + organization_id bigint NOT NULL, + created_at timestamp NOT NULL, + PRIMARY KEY (organization_id, created_at) + ) PARTITION BY RANGE (created_at); + + CREATE TABLE #{partition_table} PARTITION OF #{parent_table} + FOR VALUES FROM ('2025-01-01') TO ('2025-02-01'); + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{partition_table}") + connection.execute("DROP TABLE IF EXISTS #{parent_table}") + end + + it 'returns primary keys for partitioned table' do + primary_keys = connection.primary_keys(parent_table) + + expect(primary_keys).to eq(%w[organization_id created_at]) + end + end + end +end -- GitLab From fbacd48cba588e966352a676f726934d7cf461fd Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 13:58:50 -0500 Subject: [PATCH 04/34] Fix patch and add tests --- .../postgresql/schema_statements/primary_keys.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 517eba459aa8aa..dc58af68319e7b 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -29,5 +29,6 @@ def primary_keys(table_name) end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) + end end -- GitLab From 36c774eeb2bd1af34cee245d702c413b5b653f0c Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 14:02:55 -0500 Subject: [PATCH 05/34] Fix patch and add tests --- gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb index 5f90170577f1a9..21a496836329a8 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb @@ -5,7 +5,7 @@ require_relative "gitlab_patches/rescue_from" require_relative "gitlab_patches/relation/find_or_create_by" require_relative "gitlab_patches/partitioning" -require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements" +require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys" module ActiveRecord module GitlabPatches -- GitLab From 8248e8e1c843b0540c9469a44a847bb92402110c Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 14:43:05 -0500 Subject: [PATCH 06/34] Fix patch and add tests --- .../postgresql/schema_statements/primary_keys.rb | 4 ++-- .../postgresql/schema_statements/primary_keys_spec.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index dc58af68319e7b..fb5df4282be631 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -3,7 +3,7 @@ module ActiveRecord module GitlabPatches module ConnectionAdapters - module Postgresql + module PostgreSQL module SchemaStatements # Adds patch for ActiveRecord `primary_keys` method # to optimize the query for primary key retrieval. @@ -29,6 +29,6 @@ def primary_keys(table_name) end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) end end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index b266d320f073fe..2e1159e80eb358 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys do +RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys do let(:connection) { ActiveRecord::Base.connection } describe '#primary_keys' do -- GitLab From 4c0ce2523948690c1e572385969992ba1ce6d504 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 14:47:42 -0500 Subject: [PATCH 07/34] Move to outside of module --- .../postgresql/schema_statements/primary_keys.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index fb5df4282be631..2b3ee38aba611b 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -27,8 +27,7 @@ def primary_keys(table_name) end end end - - ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) - end +end +ActiveSupport.on_load(:active_record) do + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) end -- GitLab From 1802ebf0c9b45fea9467368794924442bd18e7a5 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 15:36:54 -0500 Subject: [PATCH 08/34] Get tests to pass --- .../schema_statements/primary_keys.rb | 6 ++++- .../schema_statements/primary_keys_spec.rb | 26 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 2b3ee38aba611b..c9bca151ae84bb 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -29,5 +29,9 @@ def primary_keys(table_name) end end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) + if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) + ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys + ) + end end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index 2e1159e80eb358..a9015702fc33e9 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,12 +1,32 @@ # frozen_string_literal: true -RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys do +RSpec.describe 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', feature_category: :database do let(:connection) { ActiveRecord::Base.connection } + before(:all) do + skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + end + describe '#primary_keys' do context 'with single column primary key' do + let(:table_name) {:_test_pk_table } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id bigserial PRIMARY KEY, + name text + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + it 'returns the primary key column name' do - primary_keys = connection.primary_keys('users') + primary_keys = connection.primary_keys(table_name) + expect(primary_keys).to eq(['id']) end end @@ -17,7 +37,7 @@ before do connection.execute(<<~SQL.squish) CREATE TABLE #{table_name} ( - organization_Id bigint NOT NULL, + organization_id bigint NOT NULL, resource_id bigint NOT NULL, name text, PRIMARY KEY (organization_id, resource_id) -- GitLab From 0653b0e73fba756ebef339ad573728d7e4774378 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 16:14:12 -0500 Subject: [PATCH 09/34] Fix rubocop errors --- .../postgresql/schema_statements/primary_keys_spec.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index a9015702fc33e9..e498cb81f0eff5 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true -RSpec.describe 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', feature_category: :database do +RSpec.describe( + 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', + feature_category: :database + ) do let(:connection) { ActiveRecord::Base.connection } before(:all) do @@ -9,10 +12,10 @@ describe '#primary_keys' do context 'with single column primary key' do - let(:table_name) {:_test_pk_table } + let(:table_name) { :_test_pk_table } before do - connection.execute(<<~SQL) + connection.execute(<<~SQL.squish) CREATE TABLE #{table_name} ( id bigserial PRIMARY KEY, name text -- GitLab From 2eb1683b8ffee62daa6818009f90be0def02c23a Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 14:48:25 -0500 Subject: [PATCH 10/34] Fix rubocop issues --- .../postgresql/schema_statements/primary_keys_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index e498cb81f0eff5..4e3b7c8df4d6e2 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -3,7 +3,7 @@ RSpec.describe( 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', feature_category: :database - ) do +) do let(:connection) { ActiveRecord::Base.connection } before(:all) do -- GitLab From 4ef0185fe13f4fe39871b4fd6b5aa0f5cb92705d Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 15:31:29 -0500 Subject: [PATCH 11/34] Comment out for science --- .../postgresql/schema_statements/primary_keys.rb | 6 +----- .../postgresql/schema_statements/primary_keys_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index c9bca151ae84bb..8602e32e7e575e 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -29,9 +29,5 @@ def primary_keys(table_name) end end ActiveSupport.on_load(:active_record) do - if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) - ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys - ) - end + ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index 4e3b7c8df4d6e2..3a4df6b7e7536c 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -6,9 +6,9 @@ ) do let(:connection) { ActiveRecord::Base.connection } - before(:all) do - skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - end + # before(:all) do + # skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + # end describe '#primary_keys' do context 'with single column primary key' do -- GitLab From d5e22e50652ea632ec674116f06af44ce9deee8b Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 16:31:28 -0500 Subject: [PATCH 12/34] Update patch logic --- .../schema_statements/primary_keys.rb | 46 ++++++++++++------- .../schema_statements/primary_keys_spec.rb | 12 ++--- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 8602e32e7e575e..2773ece21266d3 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -5,23 +5,25 @@ module GitlabPatches module ConnectionAdapters module PostgreSQL module SchemaStatements - # Adds patch for ActiveRecord `primary_keys` method - # to optimize the query for primary key retrieval. + module PrimaryKeys + # Adds patch for ActiveRecord `primary_keys` method + # to optimize the query for primary key retrieval. - # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 + # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c + # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 - def primary_keys(table_name) - query_values(<<~SQL.squish, "SCHEMA") - SELECT a.attname - FROM pg_index i - JOIN pg_attribute a - ON a.attrelid = i.indrelid - AND a.attnum = ANY(i.indkey) - WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass - AND i.indisprimary - ORDER BY array_position(i.indkey, a.attnum) - SQL + def primary_keys(table_name) + query_values(<<~SQL.squish, "SCHEMA") + SELECT a.attname + FROM pg_index i + JOIN pg_attribute a + ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass + AND i.indisprimary + ORDER BY array_position(i.indkey, a.attnum) + SQL + end end end end @@ -29,5 +31,17 @@ def primary_keys(table_name) end end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) + # Load the PostgreSQL adapter first, then prepend + begin + require 'active_record/connection_adapters/postgresql_adapter' + + ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys + ) + rescue LoadError + # PostgreSQL adapter not available (e.g., pg gem not installed) + end end +# ActiveSupport.on_load(:active_record) do +# ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) +# end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index 3a4df6b7e7536c..afb14d8e920299 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,14 +1,12 @@ # frozen_string_literal: true -RSpec.describe( - 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', - feature_category: :database -) do +RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, + feature_category: :database do let(:connection) { ActiveRecord::Base.connection } - # before(:all) do - # skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - # end + before(:all) do + skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + end describe '#primary_keys' do context 'with single column primary key' do -- GitLab From 6fd44ffefce628c64fb337680aa4de5f4e037cc3 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 16:52:44 -0500 Subject: [PATCH 13/34] Disable rubocop for path --- .../postgresql/schema_statements/primary_keys_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index afb14d8e920299..d8d255d1e10187 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable RSpec/FilePath RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, feature_category: :database do let(:connection) { ActiveRecord::Base.connection } @@ -118,3 +119,4 @@ end end end +# rubocop:enable RSpec/FilePath -- GitLab From 46f671b0764accb41e5f8e68f11a1e93e7a01b4f Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 16:57:14 -0500 Subject: [PATCH 14/34] Fix rubocop errors --- .../postgresql/schema_statements/primary_keys.rb | 13 +++++-------- .../schema_statements/primary_keys_spec.rb | 5 +++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 2773ece21266d3..7ecb3c2ce66170 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -32,15 +32,12 @@ def primary_keys(table_name) end ActiveSupport.on_load(:active_record) do # Load the PostgreSQL adapter first, then prepend - begin - require 'active_record/connection_adapters/postgresql_adapter' + require 'active_record/connection_adapters/postgresql_adapter' - ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys - ) - rescue LoadError - # PostgreSQL adapter not available (e.g., pg gem not installed) - end + ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys + ) + rescue LoadError # PostgreSQL adapter not available (e.g., pg gem not installed) end # ActiveSupport.on_load(:active_record) do # ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index d8d255d1e10187..1b39cfc37d9f21 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true # rubocop:disable RSpec/FilePath -RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, - feature_category: :database do +RSpec.describe( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, + feature_category: :database) do let(:connection) { ActiveRecord::Base.connection } before(:all) do -- GitLab From 38c3eb712053f95cde0dbf189f11b3b7528fcf94 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Fri, 12 Dec 2025 17:34:41 -0500 Subject: [PATCH 15/34] Create initializer patch --- .../initializers/0_postgresql_primary_keys.rb | 23 +++++ .../0_postgresql_primary_keys_spec.rb | 98 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 config/initializers/0_postgresql_primary_keys.rb create mode 100644 spec/initializers/0_postgresql_primary_keys_spec.rb diff --git a/config/initializers/0_postgresql_primary_keys.rb b/config/initializers/0_postgresql_primary_keys.rb new file mode 100644 index 00000000000000..169d982d291242 --- /dev/null +++ b/config/initializers/0_postgresql_primary_keys.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# Adds patch for ActiveRecord `primary_keys` method +# to optimize the query for primary key retrieval. + +# Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c +# Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 +# Drop this patch after https://gitlab.com/gitlab-org/gitlab/-/issues/431734 is merged in 18.8 +module PostgreSQLAdapterCustomPrimaryKeys + def primary_keys(table_name) + query_values(<<~SQL.squish, "SCHEMA") + SELECT a.attname + FROM pg_index i + JOIN pg_attribute a + ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass + AND i.indisprimary + ORDER BY array_position(i.indkey, a.attnum) + SQL + end +end +ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(PostgreSQLAdapterCustomPrimaryKeys) diff --git a/spec/initializers/0_postgresql_primary_keys_spec.rb b/spec/initializers/0_postgresql_primary_keys_spec.rb new file mode 100644 index 00000000000000..3f2bf917db2bc8 --- /dev/null +++ b/spec/initializers/0_postgresql_primary_keys_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require 'spec_helper' +RSpec.describe 'PostgreSQL primary keys', feature_category: :database do + let(:connection) { ApplicationRecord.connection } + + describe 'patch application' do + it 'prepends PostgreSQLAdapterCustomPrimaryKeys module' do + expect(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.ancestors) + .to include(PostgreSQLAdapterCustomPrimaryKeys) + end + + it 'patch is applied before the original ActiveRecord method' do + ancestors = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.ancestors + patch_index = ancestors.index(PostgreSQLAdapterCustomPrimaryKeys) + schema_statements_index = ancestors.index(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements) + + expect(patch_index).to be < schema_statements_index + end + end + + describe '#primary_keys' do + context 'with single column primary key' do + let(:table_name) { :_test_single_pk } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id bigserial PRIMARY KEY, + name text + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns the primary key column name' do + expect(connection.primary_keys(table_name)).to eq(['id']) + end + end + + context 'with composite primary key' do + let(:table_name) { :_test_composite_pk } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + organization_id bigint NOT NULL, + resource_id bigint NOT NULL, + name text, + PRIMARY KEY (organization_id, resource_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns all primary key columns in correct order' do + expect(connection.primary_keys(table_name)) + .to eq(%w[organization_id resource_id]) + end + + it 'preserves the order defined in PRIMARY KEY constraint' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys.first).to eq('organization_id') + expect(primary_keys.second).to eq('resource_id') + end + end + + context 'with reversed composite primary key order' do + let(:table_name) { :_test_reversed_pk } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + organization_id bigint NOT NULL, + resource_id bigint NOT NULL, + PRIMARY KEY (resource_id, organization_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns columns in PRIMARY KEY definition order' do + expect(connection.primary_keys(table_name)) + .to eq(%w[resource_id organization_id]) + end + end + end +end -- GitLab From ff290f2fde52c0980f822ac65fd976d8b73aaee9 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Fri, 12 Dec 2025 17:37:44 -0500 Subject: [PATCH 16/34] Delete gem version of patch --- .../lib/active_record/gitlab_patches.rb | 1 - .../schema_statements/primary_keys.rb | 44 ------- .../schema_statements/primary_keys_spec.rb | 123 ------------------ 3 files changed, 168 deletions(-) delete mode 100644 gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb delete mode 100644 gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb index 21a496836329a8..b70de557046476 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb @@ -5,7 +5,6 @@ require_relative "gitlab_patches/rescue_from" require_relative "gitlab_patches/relation/find_or_create_by" require_relative "gitlab_patches/partitioning" -require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys" module ActiveRecord module GitlabPatches diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb deleted file mode 100644 index 7ecb3c2ce66170..00000000000000 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module ActiveRecord - module GitlabPatches - module ConnectionAdapters - module PostgreSQL - module SchemaStatements - module PrimaryKeys - # Adds patch for ActiveRecord `primary_keys` method - # to optimize the query for primary key retrieval. - - # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 - - def primary_keys(table_name) - query_values(<<~SQL.squish, "SCHEMA") - SELECT a.attname - FROM pg_index i - JOIN pg_attribute a - ON a.attrelid = i.indrelid - AND a.attnum = ANY(i.indkey) - WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass - AND i.indisprimary - ORDER BY array_position(i.indkey, a.attnum) - SQL - end - end - end - end - end - end -end -ActiveSupport.on_load(:active_record) do - # Load the PostgreSQL adapter first, then prepend - require 'active_record/connection_adapters/postgresql_adapter' - - ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys - ) - rescue LoadError # PostgreSQL adapter not available (e.g., pg gem not installed) -end -# ActiveSupport.on_load(:active_record) do -# ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) -# end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb deleted file mode 100644 index 1b39cfc37d9f21..00000000000000 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ /dev/null @@ -1,123 +0,0 @@ -# frozen_string_literal: true - -# rubocop:disable RSpec/FilePath -RSpec.describe( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, - feature_category: :database) do - let(:connection) { ActiveRecord::Base.connection } - - before(:all) do - skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - end - - describe '#primary_keys' do - context 'with single column primary key' do - let(:table_name) { :_test_pk_table } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{table_name} ( - id bigserial PRIMARY KEY, - name text - ) - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{table_name}") - end - - it 'returns the primary key column name' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys).to eq(['id']) - end - end - - context 'with composite primary key' do - let(:table_name) { :_text_composite_pk_table } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{table_name} ( - organization_id bigint NOT NULL, - resource_id bigint NOT NULL, - name text, - PRIMARY KEY (organization_id, resource_id) - ) - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{table_name}") - end - - it 'returns all primary key columns in correct order' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys).to eq(%w[organization_id resource_id]) - end - - it 'preserves the order defined in PRIMARY KEY constraint' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys.first).to eq('organization_id') - expect(primary_keys.second).to eq('resource_id') - end - end - - context 'with reversed composite primary key' do - let(:table_name) { :_test_reversed_pk_table } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{table_name} ( - organization_id bigint NOT NULL, - resource_id bigint NOT NULL, - PRIMARY KEY (resource_id, organization_id) - ) - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{table_name}") - end - - it 'returns columns in PRIMARY KEY definition order' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys).to eq(%w[resource_id organization_id]) - end - end - - context 'with partitioned table' do - let(:parent_table) { :_test_partitioned_parent } - let(:partition_table) { :_test_partitioned_child } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{parent_table} ( - organization_id bigint NOT NULL, - created_at timestamp NOT NULL, - PRIMARY KEY (organization_id, created_at) - ) PARTITION BY RANGE (created_at); - - CREATE TABLE #{partition_table} PARTITION OF #{parent_table} - FOR VALUES FROM ('2025-01-01') TO ('2025-02-01'); - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{partition_table}") - connection.execute("DROP TABLE IF EXISTS #{parent_table}") - end - - it 'returns primary keys for partitioned table' do - primary_keys = connection.primary_keys(parent_table) - - expect(primary_keys).to eq(%w[organization_id created_at]) - end - end - end -end -# rubocop:enable RSpec/FilePath -- GitLab From 15aa45a36ecbec0ffb52acc4769d75b564cf89fd Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 11:08:21 -0500 Subject: [PATCH 17/34] Add patch for primary keys column optimization --- .../schema_statements/primary_keys.rb | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb new file mode 100644 index 00000000000000..e398e1dfdd3e76 --- /dev/null +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module ActiveRecord + module GitlabPatches + module ConnectionAdapters + module Postgresql + module SchemaStatements + # Adds patch for ActiveRecord `primary_keys` methods + # to optimize the query for primary key columns + + # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c + # Issue: https://github.com/rails/rails/issues/55648 + def primary_keys(table_name) + query_values(<<~SQL.squish, "SCHEMA") + SELECT a.attname + FROM pg_index i + JOIN pg_attribute a + ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass + AND i.indisprimary + ORDER BY array_position(i.indkey, a.attnum) + SQL + end + end + end + end + end +end -- GitLab From 854a76d7b4eab306a2a362665cce26219df73ad4 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 11:28:22 -0500 Subject: [PATCH 18/34] Fix comments for patch --- .../postgresql/schema_statements/primary_keys.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index e398e1dfdd3e76..c027c1f908157b 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -5,11 +5,11 @@ module GitlabPatches module ConnectionAdapters module Postgresql module SchemaStatements - # Adds patch for ActiveRecord `primary_keys` methods + # Adds patch for ActiveRecord `primary_keys` method # to optimize the query for primary key columns # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue: https://github.com/rails/rails/issues/55648 + # Issue:https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 def primary_keys(table_name) query_values(<<~SQL.squish, "SCHEMA") SELECT a.attname -- GitLab From c66f4cf6bb5e8b39959dbf0bef9137f27b13ffcf Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 13:56:37 -0500 Subject: [PATCH 19/34] Fix patch and add tests --- .../lib/active_record/gitlab_patches.rb | 1 + .../schema_statements/primary_keys.rb | 8 +- .../schema_statements/primary_keys_spec.rb | 99 +++++++++++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb index b70de557046476..5f90170577f1a9 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb @@ -5,6 +5,7 @@ require_relative "gitlab_patches/rescue_from" require_relative "gitlab_patches/relation/find_or_create_by" require_relative "gitlab_patches/partitioning" +require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements" module ActiveRecord module GitlabPatches diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index c027c1f908157b..517eba459aa8aa 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -6,10 +6,11 @@ module ConnectionAdapters module Postgresql module SchemaStatements # Adds patch for ActiveRecord `primary_keys` method - # to optimize the query for primary key columns + # to optimize the query for primary key retrieval. # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue:https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 + # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 + def primary_keys(table_name) query_values(<<~SQL.squish, "SCHEMA") SELECT a.attname @@ -26,4 +27,7 @@ def primary_keys(table_name) end end end + + ActiveSupport.on_load(:active_record) do + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb new file mode 100644 index 00000000000000..b266d320f073fe --- /dev/null +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys do + let(:connection) { ActiveRecord::Base.connection } + + describe '#primary_keys' do + context 'with single column primary key' do + it 'returns the primary key column name' do + primary_keys = connection.primary_keys('users') + expect(primary_keys).to eq(['id']) + end + end + + context 'with composite primary key' do + let(:table_name) { :_text_composite_pk_table } + + before do + connection.execute(<<~SQL.squish) + CREATE TABLE #{table_name} ( + organization_Id bigint NOT NULL, + resource_id bigint NOT NULL, + name text, + PRIMARY KEY (organization_id, resource_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns all primary key columns in correct order' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys).to eq(%w[organization_id resource_id]) + end + + it 'preserves the order defined in PRIMARY KEY constraint' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys.first).to eq('organization_id') + expect(primary_keys.second).to eq('resource_id') + end + end + + context 'with reversed composite primary key' do + let(:table_name) { :_test_reversed_pk_table } + + before do + connection.execute(<<~SQL.squish) + CREATE TABLE #{table_name} ( + organization_id bigint NOT NULL, + resource_id bigint NOT NULL, + PRIMARY KEY (resource_id, organization_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns columns in PRIMARY KEY definition order' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys).to eq(%w[resource_id organization_id]) + end + end + + context 'with partitioned table' do + let(:parent_table) { :_test_partitioned_parent } + let(:partition_table) { :_test_partitioned_child } + + before do + connection.execute(<<~SQL.squish) + CREATE TABLE #{parent_table} ( + organization_id bigint NOT NULL, + created_at timestamp NOT NULL, + PRIMARY KEY (organization_id, created_at) + ) PARTITION BY RANGE (created_at); + + CREATE TABLE #{partition_table} PARTITION OF #{parent_table} + FOR VALUES FROM ('2025-01-01') TO ('2025-02-01'); + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{partition_table}") + connection.execute("DROP TABLE IF EXISTS #{parent_table}") + end + + it 'returns primary keys for partitioned table' do + primary_keys = connection.primary_keys(parent_table) + + expect(primary_keys).to eq(%w[organization_id created_at]) + end + end + end +end -- GitLab From c16d6dc78fc77d7f3d496867c988d782af0382f4 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 13:58:50 -0500 Subject: [PATCH 20/34] Fix patch and add tests --- .../postgresql/schema_statements/primary_keys.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 517eba459aa8aa..dc58af68319e7b 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -29,5 +29,6 @@ def primary_keys(table_name) end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) + end end -- GitLab From 570d353c7070e117857fb65480c5a928e51c2665 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 14:02:55 -0500 Subject: [PATCH 21/34] Fix patch and add tests --- gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb index 5f90170577f1a9..21a496836329a8 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb @@ -5,7 +5,7 @@ require_relative "gitlab_patches/rescue_from" require_relative "gitlab_patches/relation/find_or_create_by" require_relative "gitlab_patches/partitioning" -require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements" +require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys" module ActiveRecord module GitlabPatches -- GitLab From bba5db58a137787bec7c2c44fdb63c3162d4cb4c Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 14:43:05 -0500 Subject: [PATCH 22/34] Fix patch and add tests --- .../postgresql/schema_statements/primary_keys.rb | 4 ++-- .../postgresql/schema_statements/primary_keys_spec.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index dc58af68319e7b..fb5df4282be631 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -3,7 +3,7 @@ module ActiveRecord module GitlabPatches module ConnectionAdapters - module Postgresql + module PostgreSQL module SchemaStatements # Adds patch for ActiveRecord `primary_keys` method # to optimize the query for primary key retrieval. @@ -29,6 +29,6 @@ def primary_keys(table_name) end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys) + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) end end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index b266d320f073fe..2e1159e80eb358 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::Postgresql::SchemaStatements::PrimaryKeys do +RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys do let(:connection) { ActiveRecord::Base.connection } describe '#primary_keys' do -- GitLab From c6a374b7870f79561bdcd3e5744e1fbb37d05a3d Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 14:47:42 -0500 Subject: [PATCH 23/34] Move to outside of module --- .../postgresql/schema_statements/primary_keys.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index fb5df4282be631..2b3ee38aba611b 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -27,8 +27,7 @@ def primary_keys(table_name) end end end - - ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) - end +end +ActiveSupport.on_load(:active_record) do + ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) end -- GitLab From aba81d27918f7fd0fc997fd1b04d4e0639af0d2c Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 15:36:54 -0500 Subject: [PATCH 24/34] Get tests to pass --- .../schema_statements/primary_keys.rb | 6 ++++- .../schema_statements/primary_keys_spec.rb | 26 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 2b3ee38aba611b..c9bca151ae84bb 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -29,5 +29,9 @@ def primary_keys(table_name) end end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::Postgresql::SchemaStatements.prepend(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) + if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) + ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys + ) + end end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index 2e1159e80eb358..a9015702fc33e9 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,12 +1,32 @@ # frozen_string_literal: true -RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys do +RSpec.describe 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', feature_category: :database do let(:connection) { ActiveRecord::Base.connection } + before(:all) do + skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + end + describe '#primary_keys' do context 'with single column primary key' do + let(:table_name) {:_test_pk_table } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id bigserial PRIMARY KEY, + name text + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + it 'returns the primary key column name' do - primary_keys = connection.primary_keys('users') + primary_keys = connection.primary_keys(table_name) + expect(primary_keys).to eq(['id']) end end @@ -17,7 +37,7 @@ before do connection.execute(<<~SQL.squish) CREATE TABLE #{table_name} ( - organization_Id bigint NOT NULL, + organization_id bigint NOT NULL, resource_id bigint NOT NULL, name text, PRIMARY KEY (organization_id, resource_id) -- GitLab From 45180a2425a6c15f085a628f50b01b7ac2d517ac Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 8 Dec 2025 16:14:12 -0500 Subject: [PATCH 25/34] Fix rubocop errors --- .../postgresql/schema_statements/primary_keys_spec.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index a9015702fc33e9..e498cb81f0eff5 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true -RSpec.describe 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', feature_category: :database do +RSpec.describe( + 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', + feature_category: :database + ) do let(:connection) { ActiveRecord::Base.connection } before(:all) do @@ -9,10 +12,10 @@ describe '#primary_keys' do context 'with single column primary key' do - let(:table_name) {:_test_pk_table } + let(:table_name) { :_test_pk_table } before do - connection.execute(<<~SQL) + connection.execute(<<~SQL.squish) CREATE TABLE #{table_name} ( id bigserial PRIMARY KEY, name text -- GitLab From b358400c65af7527189e7189999c54099dd06663 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 14:48:25 -0500 Subject: [PATCH 26/34] Fix rubocop issues --- .../postgresql/schema_statements/primary_keys_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index e498cb81f0eff5..4e3b7c8df4d6e2 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -3,7 +3,7 @@ RSpec.describe( 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', feature_category: :database - ) do +) do let(:connection) { ActiveRecord::Base.connection } before(:all) do -- GitLab From 5de1fb3b1219a64c2caad77cd2b1aa4ea62cce8e Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 15:31:29 -0500 Subject: [PATCH 27/34] Comment out for science --- .../postgresql/schema_statements/primary_keys.rb | 6 +----- .../postgresql/schema_statements/primary_keys_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index c9bca151ae84bb..8602e32e7e575e 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -29,9 +29,5 @@ def primary_keys(table_name) end end ActiveSupport.on_load(:active_record) do - if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) - ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys - ) - end + ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index 4e3b7c8df4d6e2..3a4df6b7e7536c 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -6,9 +6,9 @@ ) do let(:connection) { ActiveRecord::Base.connection } - before(:all) do - skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - end + # before(:all) do + # skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + # end describe '#primary_keys' do context 'with single column primary key' do -- GitLab From 615b9166e52e5685482935f0b4dd0aeb8bfa934a Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 16:31:28 -0500 Subject: [PATCH 28/34] Update patch logic --- .../schema_statements/primary_keys.rb | 46 ++++++++++++------- .../schema_statements/primary_keys_spec.rb | 12 ++--- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 8602e32e7e575e..2773ece21266d3 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -5,23 +5,25 @@ module GitlabPatches module ConnectionAdapters module PostgreSQL module SchemaStatements - # Adds patch for ActiveRecord `primary_keys` method - # to optimize the query for primary key retrieval. + module PrimaryKeys + # Adds patch for ActiveRecord `primary_keys` method + # to optimize the query for primary key retrieval. - # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 + # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c + # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 - def primary_keys(table_name) - query_values(<<~SQL.squish, "SCHEMA") - SELECT a.attname - FROM pg_index i - JOIN pg_attribute a - ON a.attrelid = i.indrelid - AND a.attnum = ANY(i.indkey) - WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass - AND i.indisprimary - ORDER BY array_position(i.indkey, a.attnum) - SQL + def primary_keys(table_name) + query_values(<<~SQL.squish, "SCHEMA") + SELECT a.attname + FROM pg_index i + JOIN pg_attribute a + ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass + AND i.indisprimary + ORDER BY array_position(i.indkey, a.attnum) + SQL + end end end end @@ -29,5 +31,17 @@ def primary_keys(table_name) end end ActiveSupport.on_load(:active_record) do - ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) + # Load the PostgreSQL adapter first, then prepend + begin + require 'active_record/connection_adapters/postgresql_adapter' + + ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys + ) + rescue LoadError + # PostgreSQL adapter not available (e.g., pg gem not installed) + end end +# ActiveSupport.on_load(:active_record) do +# ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) +# end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index 3a4df6b7e7536c..afb14d8e920299 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,14 +1,12 @@ # frozen_string_literal: true -RSpec.describe( - 'ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys', - feature_category: :database -) do +RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, + feature_category: :database do let(:connection) { ActiveRecord::Base.connection } - # before(:all) do - # skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - # end + before(:all) do + skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' + end describe '#primary_keys' do context 'with single column primary key' do -- GitLab From 0bb1a12c6b694a1bd1a2e9f7e1e0c9244289979f Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 16:52:44 -0500 Subject: [PATCH 29/34] Disable rubocop for path --- .../postgresql/schema_statements/primary_keys_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index afb14d8e920299..d8d255d1e10187 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable RSpec/FilePath RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, feature_category: :database do let(:connection) { ActiveRecord::Base.connection } @@ -118,3 +119,4 @@ end end end +# rubocop:enable RSpec/FilePath -- GitLab From 2ef360c00f5ccee514565d00ecda3a36e0900bc6 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Tue, 9 Dec 2025 16:57:14 -0500 Subject: [PATCH 30/34] Fix rubocop errors --- .../postgresql/schema_statements/primary_keys.rb | 13 +++++-------- .../schema_statements/primary_keys_spec.rb | 5 +++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb index 2773ece21266d3..7ecb3c2ce66170 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb @@ -32,15 +32,12 @@ def primary_keys(table_name) end ActiveSupport.on_load(:active_record) do # Load the PostgreSQL adapter first, then prepend - begin - require 'active_record/connection_adapters/postgresql_adapter' + require 'active_record/connection_adapters/postgresql_adapter' - ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys - ) - rescue LoadError - # PostgreSQL adapter not available (e.g., pg gem not installed) - end + ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys + ) + rescue LoadError # PostgreSQL adapter not available (e.g., pg gem not installed) end # ActiveSupport.on_load(:active_record) do # ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb index d8d255d1e10187..1b39cfc37d9f21 100644 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true # rubocop:disable RSpec/FilePath -RSpec.describe ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, - feature_category: :database do +RSpec.describe( + ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, + feature_category: :database) do let(:connection) { ActiveRecord::Base.connection } before(:all) do -- GitLab From 5c83ac6d2a406e8f71604d43942b27d9289de717 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Fri, 12 Dec 2025 17:34:41 -0500 Subject: [PATCH 31/34] Create initializer patch --- .../initializers/0_postgresql_primary_keys.rb | 23 +++++ .../0_postgresql_primary_keys_spec.rb | 98 +++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 config/initializers/0_postgresql_primary_keys.rb create mode 100644 spec/initializers/0_postgresql_primary_keys_spec.rb diff --git a/config/initializers/0_postgresql_primary_keys.rb b/config/initializers/0_postgresql_primary_keys.rb new file mode 100644 index 00000000000000..169d982d291242 --- /dev/null +++ b/config/initializers/0_postgresql_primary_keys.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# Adds patch for ActiveRecord `primary_keys` method +# to optimize the query for primary key retrieval. + +# Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c +# Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 +# Drop this patch after https://gitlab.com/gitlab-org/gitlab/-/issues/431734 is merged in 18.8 +module PostgreSQLAdapterCustomPrimaryKeys + def primary_keys(table_name) + query_values(<<~SQL.squish, "SCHEMA") + SELECT a.attname + FROM pg_index i + JOIN pg_attribute a + ON a.attrelid = i.indrelid + AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass + AND i.indisprimary + ORDER BY array_position(i.indkey, a.attnum) + SQL + end +end +ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(PostgreSQLAdapterCustomPrimaryKeys) diff --git a/spec/initializers/0_postgresql_primary_keys_spec.rb b/spec/initializers/0_postgresql_primary_keys_spec.rb new file mode 100644 index 00000000000000..3f2bf917db2bc8 --- /dev/null +++ b/spec/initializers/0_postgresql_primary_keys_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require 'spec_helper' +RSpec.describe 'PostgreSQL primary keys', feature_category: :database do + let(:connection) { ApplicationRecord.connection } + + describe 'patch application' do + it 'prepends PostgreSQLAdapterCustomPrimaryKeys module' do + expect(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.ancestors) + .to include(PostgreSQLAdapterCustomPrimaryKeys) + end + + it 'patch is applied before the original ActiveRecord method' do + ancestors = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.ancestors + patch_index = ancestors.index(PostgreSQLAdapterCustomPrimaryKeys) + schema_statements_index = ancestors.index(ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements) + + expect(patch_index).to be < schema_statements_index + end + end + + describe '#primary_keys' do + context 'with single column primary key' do + let(:table_name) { :_test_single_pk } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + id bigserial PRIMARY KEY, + name text + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns the primary key column name' do + expect(connection.primary_keys(table_name)).to eq(['id']) + end + end + + context 'with composite primary key' do + let(:table_name) { :_test_composite_pk } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + organization_id bigint NOT NULL, + resource_id bigint NOT NULL, + name text, + PRIMARY KEY (organization_id, resource_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns all primary key columns in correct order' do + expect(connection.primary_keys(table_name)) + .to eq(%w[organization_id resource_id]) + end + + it 'preserves the order defined in PRIMARY KEY constraint' do + primary_keys = connection.primary_keys(table_name) + + expect(primary_keys.first).to eq('organization_id') + expect(primary_keys.second).to eq('resource_id') + end + end + + context 'with reversed composite primary key order' do + let(:table_name) { :_test_reversed_pk } + + before do + connection.execute(<<~SQL) + CREATE TABLE #{table_name} ( + organization_id bigint NOT NULL, + resource_id bigint NOT NULL, + PRIMARY KEY (resource_id, organization_id) + ) + SQL + end + + after do + connection.execute("DROP TABLE IF EXISTS #{table_name}") + end + + it 'returns columns in PRIMARY KEY definition order' do + expect(connection.primary_keys(table_name)) + .to eq(%w[resource_id organization_id]) + end + end + end +end -- GitLab From cfed2a5e8e938d0d2d993cf559435316766a7806 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Fri, 12 Dec 2025 17:37:44 -0500 Subject: [PATCH 32/34] Delete gem version of patch --- .../lib/active_record/gitlab_patches.rb | 1 - .../schema_statements/primary_keys.rb | 44 ------- .../schema_statements/primary_keys_spec.rb | 123 ------------------ 3 files changed, 168 deletions(-) delete mode 100644 gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb delete mode 100644 gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb index 21a496836329a8..b70de557046476 100644 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb +++ b/gems/activerecord-gitlab/lib/active_record/gitlab_patches.rb @@ -5,7 +5,6 @@ require_relative "gitlab_patches/rescue_from" require_relative "gitlab_patches/relation/find_or_create_by" require_relative "gitlab_patches/partitioning" -require_relative "gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys" module ActiveRecord module GitlabPatches diff --git a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb b/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb deleted file mode 100644 index 7ecb3c2ce66170..00000000000000 --- a/gems/activerecord-gitlab/lib/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module ActiveRecord - module GitlabPatches - module ConnectionAdapters - module PostgreSQL - module SchemaStatements - module PrimaryKeys - # Adds patch for ActiveRecord `primary_keys` method - # to optimize the query for primary key retrieval. - - # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c - # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 - - def primary_keys(table_name) - query_values(<<~SQL.squish, "SCHEMA") - SELECT a.attname - FROM pg_index i - JOIN pg_attribute a - ON a.attrelid = i.indrelid - AND a.attnum = ANY(i.indkey) - WHERE i.indrelid = #{quote(quote_table_name(table_name))}::regclass - AND i.indisprimary - ORDER BY array_position(i.indkey, a.attnum) - SQL - end - end - end - end - end - end -end -ActiveSupport.on_load(:active_record) do - # Load the PostgreSQL adapter first, then prepend - require 'active_record/connection_adapters/postgresql_adapter' - - ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys - ) - rescue LoadError # PostgreSQL adapter not available (e.g., pg gem not installed) -end -# ActiveSupport.on_load(:active_record) do -# ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements.prepend(ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys) -# end diff --git a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb b/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb deleted file mode 100644 index 1b39cfc37d9f21..00000000000000 --- a/gems/activerecord-gitlab/spec/active_record/gitlab_patches/connection_adapters/postgresql/schema_statements/primary_keys_spec.rb +++ /dev/null @@ -1,123 +0,0 @@ -# frozen_string_literal: true - -# rubocop:disable RSpec/FilePath -RSpec.describe( - ActiveRecord::GitlabPatches::ConnectionAdapters::PostgreSQL::SchemaStatements::PrimaryKeys, - feature_category: :database) do - let(:connection) { ActiveRecord::Base.connection } - - before(:all) do - skip "PostgreSQL adapter not available" unless ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - end - - describe '#primary_keys' do - context 'with single column primary key' do - let(:table_name) { :_test_pk_table } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{table_name} ( - id bigserial PRIMARY KEY, - name text - ) - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{table_name}") - end - - it 'returns the primary key column name' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys).to eq(['id']) - end - end - - context 'with composite primary key' do - let(:table_name) { :_text_composite_pk_table } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{table_name} ( - organization_id bigint NOT NULL, - resource_id bigint NOT NULL, - name text, - PRIMARY KEY (organization_id, resource_id) - ) - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{table_name}") - end - - it 'returns all primary key columns in correct order' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys).to eq(%w[organization_id resource_id]) - end - - it 'preserves the order defined in PRIMARY KEY constraint' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys.first).to eq('organization_id') - expect(primary_keys.second).to eq('resource_id') - end - end - - context 'with reversed composite primary key' do - let(:table_name) { :_test_reversed_pk_table } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{table_name} ( - organization_id bigint NOT NULL, - resource_id bigint NOT NULL, - PRIMARY KEY (resource_id, organization_id) - ) - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{table_name}") - end - - it 'returns columns in PRIMARY KEY definition order' do - primary_keys = connection.primary_keys(table_name) - - expect(primary_keys).to eq(%w[resource_id organization_id]) - end - end - - context 'with partitioned table' do - let(:parent_table) { :_test_partitioned_parent } - let(:partition_table) { :_test_partitioned_child } - - before do - connection.execute(<<~SQL.squish) - CREATE TABLE #{parent_table} ( - organization_id bigint NOT NULL, - created_at timestamp NOT NULL, - PRIMARY KEY (organization_id, created_at) - ) PARTITION BY RANGE (created_at); - - CREATE TABLE #{partition_table} PARTITION OF #{parent_table} - FOR VALUES FROM ('2025-01-01') TO ('2025-02-01'); - SQL - end - - after do - connection.execute("DROP TABLE IF EXISTS #{partition_table}") - connection.execute("DROP TABLE IF EXISTS #{parent_table}") - end - - it 'returns primary keys for partitioned table' do - primary_keys = connection.primary_keys(parent_table) - - expect(primary_keys).to eq(%w[organization_id created_at]) - end - end - end -end -# rubocop:enable RSpec/FilePath -- GitLab From cf7319718a2fe489d9736e80a957eae18c5cd25b Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 15 Dec 2025 16:10:25 -0500 Subject: [PATCH 33/34] Update patch and test --- config/initializers/0_postgresql_primary_keys.rb | 14 +++++++++++++- .../initializers/0_postgresql_primary_keys_spec.rb | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/config/initializers/0_postgresql_primary_keys.rb b/config/initializers/0_postgresql_primary_keys.rb index 169d982d291242..92dd9a04d94694 100644 --- a/config/initializers/0_postgresql_primary_keys.rb +++ b/config/initializers/0_postgresql_primary_keys.rb @@ -5,8 +5,20 @@ # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 -# Drop this patch after https://gitlab.com/gitlab-org/gitlab/-/issues/431734 is merged in 18.8 module PostgreSQLAdapterCustomPrimaryKeys + if Rails.gem_version >= Gem::Version.new('8.0') + raise <<~ERROR + PostgreSQLAdapterCustomPrimaryKeys patch is no longer needed! + + This patch was a backport of a Rails 7.2 fix for the primary_keys method. + + Please remove this file and its associated test: + - config/initializers/0_postgresql_primary_keys.rb + - spec/initializers/0_postgresql_primary_keys_spec.rb + + ERROR + end + def primary_keys(table_name) query_values(<<~SQL.squish, "SCHEMA") SELECT a.attname diff --git a/spec/initializers/0_postgresql_primary_keys_spec.rb b/spec/initializers/0_postgresql_primary_keys_spec.rb index 3f2bf917db2bc8..625c26ba138eb7 100644 --- a/spec/initializers/0_postgresql_primary_keys_spec.rb +++ b/spec/initializers/0_postgresql_primary_keys_spec.rb @@ -4,6 +4,20 @@ RSpec.describe 'PostgreSQL primary keys', feature_category: :database do let(:connection) { ApplicationRecord.connection } + describe 'Rails version guard' do + it 'raises error if Rails 8.1 or higher is detected' do + allow(Rails).to receive(:gem_version).and_return(Gem::Version.new('8.0')) + + expect do + load Rails.root.join('config/initializers/0_postgresql_primary_keys.rb') + end.to raise_error(RuntimeError, /PostgreSQLAdapterCustomPrimaryKeys patch is no longer needed/) + end + + it 'does not raise error for Rails 7.x' do + expect(Rails.gem_version).to be < Gem::Version.new('8.0') + end + end + describe 'patch application' do it 'prepends PostgreSQLAdapterCustomPrimaryKeys module' do expect(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.ancestors) -- GitLab From ecfc1446141bc897ba81683017a0859694b89941 Mon Sep 17 00:00:00 2001 From: Irina Bronipolsky Date: Mon, 15 Dec 2025 16:38:28 -0500 Subject: [PATCH 34/34] Fix rails version typo --- config/initializers/0_postgresql_primary_keys.rb | 2 +- spec/initializers/0_postgresql_primary_keys_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/initializers/0_postgresql_primary_keys.rb b/config/initializers/0_postgresql_primary_keys.rb index 92dd9a04d94694..817a432478d10d 100644 --- a/config/initializers/0_postgresql_primary_keys.rb +++ b/config/initializers/0_postgresql_primary_keys.rb @@ -6,7 +6,7 @@ # Rails commit: https://github.com/rails/rails/commit/c93d1b09fcc013033af506b10fd60829267be85c # Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/579305 module PostgreSQLAdapterCustomPrimaryKeys - if Rails.gem_version >= Gem::Version.new('8.0') + if Rails.gem_version >= Gem::Version.new('8.1') raise <<~ERROR PostgreSQLAdapterCustomPrimaryKeys patch is no longer needed! diff --git a/spec/initializers/0_postgresql_primary_keys_spec.rb b/spec/initializers/0_postgresql_primary_keys_spec.rb index 625c26ba138eb7..6bf778dcaff008 100644 --- a/spec/initializers/0_postgresql_primary_keys_spec.rb +++ b/spec/initializers/0_postgresql_primary_keys_spec.rb @@ -6,7 +6,7 @@ describe 'Rails version guard' do it 'raises error if Rails 8.1 or higher is detected' do - allow(Rails).to receive(:gem_version).and_return(Gem::Version.new('8.0')) + allow(Rails).to receive(:gem_version).and_return(Gem::Version.new('8.1')) expect do load Rails.root.join('config/initializers/0_postgresql_primary_keys.rb') @@ -14,7 +14,7 @@ end it 'does not raise error for Rails 7.x' do - expect(Rails.gem_version).to be < Gem::Version.new('8.0') + expect(Rails.gem_version).to be < Gem::Version.new('8.1') end end -- GitLab