From bc4df66dde701dbd6ccd6f7772a3db01ba2abd2a Mon Sep 17 00:00:00 2001 From: Andreas Hilmer Date: Mon, 11 Sep 2023 15:23:42 +0200 Subject: [PATCH 1/3] [115] Add table with long name to test setup --- spec/lib/query_spec.rb | 8 ++++++++ spec/support/database_helpers.rb | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/spec/lib/query_spec.rb b/spec/lib/query_spec.rb index 743acdf..88c820e 100644 --- a/spec/lib/query_spec.rb +++ b/spec/lib/query_spec.rb @@ -321,6 +321,14 @@ "constraint_validated" => "t", "definition" => "FOREIGN KEY (book_id) REFERENCES books(user_id)", }, + { + "table_on" => "this_is_a_table_with_a_very_long_name", + "table_from" => "-", + "constraint_type" => "p", + "constraint_name" => "this_is_a_table_with_a_very_long_name_pkey", + "constraint_validated" => "t", + "definition" => "PRIMARY KEY (id)", + }, ] expect(described_class.get_all_constraints_for(client)).to eq(result) diff --git a/spec/support/database_helpers.rb b/spec/support/database_helpers.rb index 480f750..db03c92 100644 --- a/spec/support/database_helpers.rb +++ b/spec/support/database_helpers.rb @@ -80,6 +80,11 @@ def new_dummy_table_sql "createdOn" TIMESTAMP NOT NULL, last_login TIMESTAMP ); + + CREATE TABLE IF NOT EXISTS #{schema}.this_is_a_table_with_a_very_long_name ( + id serial PRIMARY KEY, + "createdOn" TIMESTAMP NOT NULL + ); ALTER ROLE jamesbond SET statement_timeout = '60s'; ALTER ROLE jamesbond SET lock_timeout = '60s'; From ae2e75a08738b0aa0ffd5810e98510323738125a Mon Sep 17 00:00:00 2001 From: Andreas Hilmer Date: Mon, 11 Sep 2023 15:30:33 +0200 Subject: [PATCH 2/3] [115] Add failing test --- lib/pg_online_schema_change/query.rb | 12 ++++++++++++ spec/lib/orchestrate_spec.rb | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/pg_online_schema_change/query.rb b/lib/pg_online_schema_change/query.rb index 4947124..006a932 100644 --- a/lib/pg_online_schema_change/query.rb +++ b/lib/pg_online_schema_change/query.rb @@ -134,6 +134,18 @@ def get_indexes_for(client, table) indexes end + # fetches the sequence name of a table and column combination + def get_sequence_name(client, table, column) + query = <<~SQL + SELECT pg_get_serial_sequence('#{table}', '#{column}'); + SQL + + run(client.connection, query) { |result| result.map { |row| + row["pg_get_serial_sequence"] + } + }.first + end + def get_triggers_for(client, table) query = <<~SQL SELECT pg_get_triggerdef(oid) as tdef FROM pg_trigger diff --git a/spec/lib/orchestrate_spec.rb b/spec/lib/orchestrate_spec.rb index 59dd5b8..3689160 100644 --- a/spec/lib/orchestrate_spec.rb +++ b/spec/lib/orchestrate_spec.rb @@ -180,6 +180,29 @@ assertions: [{ count: 1, data: [{ "reloptions" => "{autovacuum_enabled=false}" }] }], ) end + + describe "when table has a long name" do + let(:client) do + options = + client_options.to_h.merge(alter_statement: "ALTER TABLE this_is_a_table_with_a_very_long_name ADD COLUMN \"user_id\" int;") + client_options = Struct.new(*options.keys).new(*options.values) + PgOnlineSchemaChange::Client.new(client_options) + end + + before do + allow(PgOnlineSchemaChange::Client).to receive(:new).and_return(client) + described_class.setup!(client_options) + setup_tables(client) + end + + it "successfully" do + described_class.setup_audit_table! + + sequence_name = PgOnlineSchemaChange::Query.get_sequence_name(client, described_class.audit_table, described_class.audit_table_pk) + expect(described_class.audit_table_pk_sequence).to eq(sequence_name) + end + end + end describe ".setup_trigger!" do From 4ecb0df2967c936b93328f509cbd60dd9ecb69f7 Mon Sep 17 00:00:00 2001 From: Andreas Hilmer Date: Mon, 11 Sep 2023 15:14:58 +0200 Subject: [PATCH 3/3] [115] Dynamically fetch the audit table sequence name --- lib/pg_online_schema_change/orchestrate.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pg_online_schema_change/orchestrate.rb b/lib/pg_online_schema_change/orchestrate.rb index 1c83b7e..790f75f 100644 --- a/lib/pg_online_schema_change/orchestrate.rb +++ b/lib/pg_online_schema_change/orchestrate.rb @@ -35,7 +35,6 @@ def setup_store Store.set(:operation_type_column, "operation_type_#{pgosc_identifier}") Store.set(:trigger_time_column, "trigger_time_#{pgosc_identifier}") Store.set(:audit_table_pk, "at_#{pgosc_identifier}_id") - Store.set(:audit_table_pk_sequence, "#{audit_table}_#{audit_table_pk}_seq") Store.set(:shadow_table, "pgosc_st_#{client.table.downcase}_#{pgosc_identifier}") Store.set(:primary_table_storage_parameters, Query.storage_parameters_for(client, client.table_name, true) || "") @@ -109,6 +108,8 @@ def setup_audit_table! SQL Query.run(client.connection, sql) + + Store.set(:audit_table_pk_sequence, Query.get_sequence_name(client, audit_table, audit_table_pk)) end def setup_trigger!