pg_online_schema_change 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -38,8 +38,14 @@ module PgOnlineSchemaChange
38
38
  Store.set(:audit_table_pk_sequence, "#{audit_table}_#{audit_table_pk}_seq")
39
39
  Store.set(:shadow_table, "pgosc_st_#{client.table.downcase}_#{pgosc_identifier}")
40
40
 
41
- Store.set(:referential_foreign_key_statements, Query.referential_foreign_keys_to_refresh(client, client.table_name))
42
- Store.set(:self_foreign_key_statements, Query.self_foreign_keys_to_refresh(client, client.table_name))
41
+ Store.set(
42
+ :referential_foreign_key_statements,
43
+ Query.referential_foreign_keys_to_refresh(client, client.table_name),
44
+ )
45
+ Store.set(
46
+ :self_foreign_key_statements,
47
+ Query.self_foreign_keys_to_refresh(client, client.table_name),
48
+ )
43
49
  Store.set(:trigger_statements, Query.get_triggers_for(client, client.table_name))
44
50
  end
45
51
 
@@ -74,9 +80,7 @@ module PgOnlineSchemaChange
74
80
  def setup_signals!
75
81
  reader, writer = IO.pipe
76
82
 
77
- %w[TERM QUIT INT].each do |sig|
78
- trap(sig) { writer.puts sig }
79
- end
83
+ ['TERM', 'QUIT', 'INT'].each { |sig| trap(sig) { writer.puts sig } }
80
84
 
81
85
  reader
82
86
  end
@@ -85,14 +89,14 @@ module PgOnlineSchemaChange
85
89
  reader = setup_signals!
86
90
  signal = reader.gets.chomp
87
91
 
88
- while !reader.closed? && IO.select([reader]) # rubocop:disable Lint/UnreachableLoop
89
- logger.info "Signal #{signal} received, cleaning up"
92
+ while !reader.closed? && reader.wait_readable # rubocop:disable Lint/UnreachableLoop
93
+ logger.info("Signal #{signal} received, cleaning up")
90
94
 
91
95
  client.connection.cancel
92
96
  drop_and_cleanup!
93
97
  reader.close
94
98
 
95
- exit Signal.list[signal]
99
+ exit(Signal.list[signal])
96
100
  end
97
101
  end
98
102
 
@@ -124,13 +128,13 @@ module PgOnlineSchemaChange
124
128
  $$
125
129
  BEGIN
126
130
  IF ( TG_OP = 'INSERT') THEN
127
- INSERT INTO \"#{audit_table}\" select nextval(\'#{audit_table_pk_sequence}\'), 'INSERT', clock_timestamp(), NEW.* ;
131
+ INSERT INTO "#{audit_table}" select nextval('#{audit_table_pk_sequence}'), 'INSERT', clock_timestamp(), NEW.* ;
128
132
  RETURN NEW;
129
133
  ELSIF ( TG_OP = 'UPDATE') THEN
130
- INSERT INTO \"#{audit_table}\" select nextval(\'#{audit_table_pk_sequence}\'), 'UPDATE', clock_timestamp(), NEW.* ;
134
+ INSERT INTO "#{audit_table}" select nextval('#{audit_table_pk_sequence}'), 'UPDATE', clock_timestamp(), NEW.* ;
131
135
  RETURN NEW;
132
136
  ELSIF ( TG_OP = 'DELETE') THEN
133
- INSERT INTO \"#{audit_table}\" select nextval(\'#{audit_table_pk_sequence}\'), 'DELETE', clock_timestamp(), OLD.* ;
137
+ INSERT INTO "#{audit_table}" select nextval('#{audit_table_pk_sequence}'), 'DELETE', clock_timestamp(), OLD.* ;
134
138
  RETURN NEW;
135
139
  END IF;
136
140
  END;
@@ -158,10 +162,18 @@ module PgOnlineSchemaChange
158
162
  Query.run(client.connection, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE", true)
159
163
  logger.info("Setting up shadow table", { shadow_table: shadow_table })
160
164
 
161
- Query.run(client.connection, "SELECT create_table_all('#{client.table_name}', '#{shadow_table}');", true)
165
+ Query.run(
166
+ client.connection,
167
+ "SELECT create_table_all('#{client.table_name}', '#{shadow_table}');",
168
+ true,
169
+ )
162
170
 
163
171
  # update serials
164
- Query.run(client.connection, "SELECT fix_serial_sequence('#{client.table_name}', '#{shadow_table}');", true)
172
+ Query.run(
173
+ client.connection,
174
+ "SELECT fix_serial_sequence('#{client.table_name}', '#{shadow_table}');",
175
+ true,
176
+ )
165
177
  end
166
178
 
167
179
  def disable_vacuum!
@@ -170,8 +182,10 @@ module PgOnlineSchemaChange
170
182
  result = Query.storage_parameters_for(client, client.table_name, true) || ""
171
183
  Store.set(:primary_table_storage_parameters, result)
172
184
 
173
- logger.debug("Disabling vacuum on shadow and audit table",
174
- { shadow_table: shadow_table, audit_table: audit_table })
185
+ logger.debug(
186
+ "Disabling vacuum on shadow and audit table",
187
+ { shadow_table: shadow_table, audit_table: audit_table },
188
+ )
175
189
  sql = <<~SQL
176
190
  ALTER TABLE #{shadow_table} SET (
177
191
  autovacuum_enabled = false, toast.autovacuum_enabled = false
@@ -187,8 +201,10 @@ module PgOnlineSchemaChange
187
201
  def run_alter_statement!
188
202
  # re-uses transaction with serializable
189
203
  statement = Query.alter_statement_for(client, shadow_table)
190
- logger.info("Running alter statement on shadow table",
191
- { shadow_table: shadow_table, parent_table: client.table_name })
204
+ logger.info(
205
+ "Running alter statement on shadow table",
206
+ { shadow_table: shadow_table, parent_table: client.table_name },
207
+ )
192
208
  Query.run(client.connection, statement, true)
193
209
 
194
210
  Store.set(:dropped_columns_list, Query.dropped_columns(client))
@@ -200,10 +216,16 @@ module PgOnlineSchemaChange
200
216
  # Begin the process to copy data into copy table
201
217
  # depending on the size of the table, this can be a time
202
218
  # taking operation.
203
- logger.info("Clearing contents of audit table before copy..", { shadow_table: shadow_table, parent_table: client.table_name })
219
+ logger.info(
220
+ "Clearing contents of audit table before copy..",
221
+ { shadow_table: shadow_table, parent_table: client.table_name },
222
+ )
204
223
  Query.run(client.connection, "DELETE FROM #{audit_table}", true)
205
224
 
206
- logger.info("Copying contents..", { shadow_table: shadow_table, parent_table: client.table_name })
225
+ logger.info(
226
+ "Copying contents..",
227
+ { shadow_table: shadow_table, parent_table: client.table_name },
228
+ )
207
229
  if client.copy_statement
208
230
  query = format(client.copy_statement, shadow_table: shadow_table)
209
231
  return Query.run(client.connection, query, true)
@@ -225,9 +247,6 @@ module PgOnlineSchemaChange
225
247
 
226
248
  def swap!
227
249
  logger.info("Performing swap!")
228
-
229
- storage_params_reset = primary_table_storage_parameters.empty? ? "" : "ALTER TABLE #{client.table_name} SET (#{primary_table_storage_parameters});"
230
-
231
250
  # From here on, all statements are carried out in a single
232
251
  # transaction with access exclusive lock
233
252
 
@@ -235,12 +254,17 @@ module PgOnlineSchemaChange
235
254
 
236
255
  raise AccessExclusiveLockNotAcquired unless opened
237
256
 
238
- Query.run(client.connection, "SET statement_timeout to '#{SWAP_STATEMENT_TIMEOUT}';", opened)
257
+ Query.run(
258
+ client.connection,
259
+ "SET statement_timeout to '#{SWAP_STATEMENT_TIMEOUT}';",
260
+ opened,
261
+ )
239
262
 
240
263
  rows = Replay.rows_to_play(opened)
241
264
  Replay.play!(rows, opened)
242
265
 
243
- query_for_primary_key_refresh = Query.query_for_primary_key_refresh(shadow_table, primary_key, client.table_name, opened)
266
+ query_for_primary_key_refresh =
267
+ Query.query_for_primary_key_refresh(shadow_table, primary_key, client.table_name, opened)
244
268
 
245
269
  sql = <<~SQL
246
270
  #{query_for_primary_key_refresh};
@@ -296,6 +320,17 @@ module PgOnlineSchemaChange
296
320
  def pgosc_identifier
297
321
  @pgosc_identifier ||= SecureRandom.hex(3)
298
322
  end
323
+
324
+ def storage_params_reset
325
+ "ALTER TABLE #{client.table_name} RESET (autovacuum_enabled, toast.autovacuum_enabled);" +
326
+ (
327
+ if primary_table_storage_parameters.empty?
328
+ ""
329
+ else
330
+ "ALTER TABLE #{client.table_name} SET (#{primary_table_storage_parameters});"
331
+ end
332
+ )
333
+ end
299
334
  end
300
335
  end
301
336
  end
@@ -14,21 +14,31 @@ module PgOnlineSchemaChange
14
14
 
15
15
  class << self
16
16
  def alter_statement?(query)
17
- PgQuery.parse(query).tree.stmts.all? do |statement|
18
- statement.stmt.alter_table_stmt.instance_of?(PgQuery::AlterTableStmt) || statement.stmt.rename_stmt.instance_of?(PgQuery::RenameStmt)
19
- end
17
+ PgQuery
18
+ .parse(query)
19
+ .tree
20
+ .stmts
21
+ .all? do |statement|
22
+ statement.stmt.alter_table_stmt.instance_of?(PgQuery::AlterTableStmt) ||
23
+ statement.stmt.rename_stmt.instance_of?(PgQuery::RenameStmt)
24
+ end
20
25
  rescue PgQuery::ParseError
21
26
  false
22
27
  end
23
28
 
24
29
  def same_table?(query)
25
- tables = PgQuery.parse(query).tree.stmts.filter_map do |statement|
26
- if statement.stmt.alter_table_stmt.instance_of?(PgQuery::AlterTableStmt)
27
- statement.stmt.alter_table_stmt.relation.relname
28
- elsif statement.stmt.rename_stmt.instance_of?(PgQuery::RenameStmt)
29
- statement.stmt.rename_stmt.relation.relname
30
- end
31
- end
30
+ tables =
31
+ PgQuery
32
+ .parse(query)
33
+ .tree
34
+ .stmts
35
+ .filter_map do |statement|
36
+ if statement.stmt.alter_table_stmt.instance_of?(PgQuery::AlterTableStmt)
37
+ statement.stmt.alter_table_stmt.relation.relname
38
+ elsif statement.stmt.rename_stmt.instance_of?(PgQuery::RenameStmt)
39
+ statement.stmt.rename_stmt.relation.relname
40
+ end
41
+ end
32
42
 
33
43
  tables.uniq.count == 1
34
44
  rescue PgQuery::ParseError
@@ -36,15 +46,20 @@ module PgOnlineSchemaChange
36
46
  end
37
47
 
38
48
  def table(query)
39
- from_rename_statement = PgQuery.parse(query).tree.stmts.filter_map do |statement|
40
- statement.stmt.rename_stmt&.relation&.relname
41
- end[0]
49
+ from_rename_statement =
50
+ PgQuery
51
+ .parse(query)
52
+ .tree
53
+ .stmts
54
+ .filter_map { |statement| statement.stmt.rename_stmt&.relation&.relname }[
55
+ 0
56
+ ]
42
57
  PgQuery.parse(query).tables[0] || from_rename_statement
43
58
  end
44
59
 
45
60
  def table_name(query, table)
46
61
  table_name = "\"#{table}\""
47
- if table =~ /[A-Z]/ && (query.include? table_name) && table[0] != '"'
62
+ if table =~ /[A-Z]/ && query.include?(table_name) && table[0] != '"'
48
63
  table_name
49
64
  else
50
65
  table
@@ -52,7 +67,9 @@ module PgOnlineSchemaChange
52
67
  end
53
68
 
54
69
  def run(connection, query, reuse_trasaction = false, &block)
55
- connection.cancel if [PG::PQTRANS_INERROR, PG::PQTRANS_UNKNOWN].include?(connection.transaction_status)
70
+ if [PG::PQTRANS_INERROR, PG::PQTRANS_UNKNOWN].include?(connection.transaction_status)
71
+ connection.cancel
72
+ end
56
73
 
57
74
  logger.debug("Running query", { query: query })
58
75
 
@@ -74,18 +91,19 @@ module PgOnlineSchemaChange
74
91
  def table_columns(client, table = nil, reuse_trasaction = false)
75
92
  sql = <<~SQL
76
93
  SELECT attname as column_name, format_type(atttypid, atttypmod) as type, attnum as column_position FROM pg_attribute
77
- WHERE attrelid = \'#{table || client.table_name}\'::regclass AND attnum > 0 AND NOT attisdropped
94
+ WHERE attrelid = '#{table || client.table_name}'::regclass AND attnum > 0 AND NOT attisdropped
78
95
  ORDER BY attnum;
79
96
  SQL
80
97
  mapped_columns = []
81
98
 
82
99
  run(client.connection, sql, reuse_trasaction) do |result|
83
- mapped_columns = result.map do |row|
84
- row["column_name_regular"] = row["column_name"]
85
- row["column_name"] = client.connection.quote_ident(row["column_name"])
86
- row["column_position"] = row["column_position"].to_i
87
- row
88
- end
100
+ mapped_columns =
101
+ result.map do |row|
102
+ row["column_name_regular"] = row["column_name"]
103
+ row["column_name"] = client.connection.quote_ident(row["column_name"])
104
+ row["column_position"] = row["column_position"].to_i
105
+ row
106
+ end
89
107
  end
90
108
 
91
109
  mapped_columns
@@ -95,7 +113,9 @@ module PgOnlineSchemaChange
95
113
  parsed_query = PgQuery.parse(client.alter_statement)
96
114
 
97
115
  parsed_query.tree.stmts.each do |statement|
98
- statement.stmt.alter_table_stmt.relation.relname = shadow_table if statement.stmt.alter_table_stmt
116
+ if statement.stmt.alter_table_stmt
117
+ statement.stmt.alter_table_stmt.relation.relname = shadow_table
118
+ end
99
119
 
100
120
  statement.stmt.rename_stmt.relation.relname = shadow_table if statement.stmt.rename_stmt
101
121
  end
@@ -106,13 +126,11 @@ module PgOnlineSchemaChange
106
126
  query = <<~SQL
107
127
  SELECT indexdef, schemaname
108
128
  FROM pg_indexes
109
- WHERE schemaname = \'#{client.schema}\' AND tablename = \'#{table}\'
129
+ WHERE schemaname = '#{client.schema}' AND tablename = '#{table}'
110
130
  SQL
111
131
 
112
132
  indexes = []
113
- run(client.connection, query) do |result|
114
- indexes = result.map { |row| row["indexdef"] }
115
- end
133
+ run(client.connection, query) { |result| indexes = result.map { |row| row["indexdef"] } }
116
134
 
117
135
  indexes
118
136
  end
@@ -120,13 +138,11 @@ module PgOnlineSchemaChange
120
138
  def get_triggers_for(client, table)
121
139
  query = <<~SQL
122
140
  SELECT pg_get_triggerdef(oid) as tdef FROM pg_trigger
123
- WHERE tgrelid = \'#{client.schema}.#{table}\'::regclass AND tgisinternal = FALSE;
141
+ WHERE tgrelid = '#{client.schema}.#{table}'::regclass AND tgisinternal = FALSE;
124
142
  SQL
125
143
 
126
144
  triggers = []
127
- run(client.connection, query) do |result|
128
- triggers = result.map { |row| "#{row["tdef"]};" }
129
- end
145
+ run(client.connection, query) { |result| triggers = result.map { |row| "#{row["tdef"]};" } }
130
146
 
131
147
  triggers.join(";")
132
148
  end
@@ -144,9 +160,7 @@ module PgOnlineSchemaChange
144
160
  SQL
145
161
 
146
162
  constraints = []
147
- run(client.connection, query) do |result|
148
- constraints = result.map { |row| row }
149
- end
163
+ run(client.connection, query) { |result| constraints = result.map { |row| row } }
150
164
 
151
165
  constraints
152
166
  end
@@ -164,72 +178,93 @@ module PgOnlineSchemaChange
164
178
  end
165
179
 
166
180
  def referential_foreign_keys_to_refresh(client, table)
167
- references = get_all_constraints_for(client).select do |row|
168
- row["table_from"] == table && row["constraint_type"] == "f"
169
- end
181
+ references =
182
+ get_all_constraints_for(client).select do |row|
183
+ row["table_from"] == table && row["constraint_type"] == "f"
184
+ end
170
185
 
171
- references.map do |row|
172
- add_statement = if row["definition"].end_with?("NOT VALID")
173
- "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]};"
174
- else
175
- "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]} NOT VALID;"
176
- end
186
+ references
187
+ .map do |row|
188
+ add_statement =
189
+ if row["definition"].end_with?("NOT VALID")
190
+ "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]};"
191
+ else
192
+ "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]} NOT VALID;"
193
+ end
177
194
 
178
- drop_statement = "ALTER TABLE #{row["table_on"]} DROP CONSTRAINT #{row["constraint_name"]};"
195
+ drop_statement =
196
+ "ALTER TABLE #{row["table_on"]} DROP CONSTRAINT #{row["constraint_name"]};"
179
197
 
180
- "#{drop_statement} #{add_statement}"
181
- end.join
198
+ "#{drop_statement} #{add_statement}"
199
+ end
200
+ .join
182
201
  end
183
202
 
184
203
  def self_foreign_keys_to_refresh(client, table)
185
- references = get_all_constraints_for(client).select do |row|
186
- row["table_on"] == table && row["constraint_type"] == "f"
187
- end
204
+ references =
205
+ get_all_constraints_for(client).select do |row|
206
+ row["table_on"] == table && row["constraint_type"] == "f"
207
+ end
188
208
 
189
- references.map do |row|
190
- add_statement = if row["definition"].end_with?("NOT VALID")
191
- "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]};"
192
- else
193
- "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]} NOT VALID;"
194
- end
195
- add_statement
196
- end.join
209
+ references
210
+ .map do |row|
211
+ add_statement =
212
+ if row["definition"].end_with?("NOT VALID")
213
+ "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]};"
214
+ else
215
+ "ALTER TABLE #{row["table_on"]} ADD CONSTRAINT #{row["constraint_name"]} #{row["definition"]} NOT VALID;"
216
+ end
217
+ add_statement
218
+ end
219
+ .join
197
220
  end
198
221
 
199
222
  def get_foreign_keys_to_validate(client, table)
200
223
  constraints = get_all_constraints_for(client)
201
- referential_foreign_keys = constraints.select do |row|
202
- row["table_from"] == table && row["constraint_type"] == "f"
203
- end
224
+ referential_foreign_keys =
225
+ constraints.select { |row| row["table_from"] == table && row["constraint_type"] == "f" }
204
226
 
205
- self_foreign_keys = constraints.select do |row|
206
- row["table_on"] == table && row["constraint_type"] == "f"
207
- end
227
+ self_foreign_keys =
228
+ constraints.select { |row| row["table_on"] == table && row["constraint_type"] == "f" }
208
229
 
209
- [referential_foreign_keys, self_foreign_keys].flatten.map do |row|
210
- "ALTER TABLE #{row["table_on"]} VALIDATE CONSTRAINT #{row["constraint_name"]};"
211
- end.join
230
+ [referential_foreign_keys, self_foreign_keys].flatten
231
+ .map do |row|
232
+ "ALTER TABLE #{row["table_on"]} VALIDATE CONSTRAINT #{row["constraint_name"]};"
233
+ end
234
+ .join
212
235
  end
213
236
 
214
237
  def dropped_columns(client)
215
- PgQuery.parse(client.alter_statement).tree.stmts.map do |statement|
216
- next if statement.stmt.alter_table_stmt.nil?
217
-
218
- statement.stmt.alter_table_stmt.cmds.map do |cmd|
219
- cmd.alter_table_cmd.name if cmd.alter_table_cmd.subtype == DROPPED_COLUMN_TYPE
238
+ PgQuery
239
+ .parse(client.alter_statement)
240
+ .tree
241
+ .stmts
242
+ .map do |statement|
243
+ next if statement.stmt.alter_table_stmt.nil?
244
+
245
+ statement.stmt.alter_table_stmt.cmds.map do |cmd|
246
+ cmd.alter_table_cmd.name if cmd.alter_table_cmd.subtype == DROPPED_COLUMN_TYPE
247
+ end
220
248
  end
221
- end.flatten.compact
249
+ .flatten
250
+ .compact
222
251
  end
223
252
 
224
253
  def renamed_columns(client)
225
- PgQuery.parse(client.alter_statement).tree.stmts.map do |statement|
226
- next if statement.stmt.rename_stmt.nil?
227
-
228
- {
229
- old_name: statement.stmt.rename_stmt.subname,
230
- new_name: statement.stmt.rename_stmt.newname,
231
- }
232
- end.flatten.compact
254
+ PgQuery
255
+ .parse(client.alter_statement)
256
+ .tree
257
+ .stmts
258
+ .map do |statement|
259
+ next if statement.stmt.rename_stmt.nil?
260
+
261
+ {
262
+ old_name: statement.stmt.rename_stmt.subname,
263
+ new_name: statement.stmt.rename_stmt.newname,
264
+ }
265
+ end
266
+ .flatten
267
+ .compact
233
268
  end
234
269
 
235
270
  def primary_key_for(client, table)
@@ -238,9 +273,9 @@ module PgOnlineSchemaChange
238
273
  pg_attribute.attname as column_name
239
274
  FROM pg_index, pg_class, pg_attribute, pg_namespace
240
275
  WHERE
241
- pg_class.oid = \'#{table}\'::regclass AND
276
+ pg_class.oid = '#{table}'::regclass AND
242
277
  indrelid = pg_class.oid AND
243
- nspname = \'#{client.schema}\' AND
278
+ nspname = '#{client.schema}' AND
244
279
  pg_class.relnamespace = pg_namespace.oid AND
245
280
  pg_attribute.attrelid = pg_class.oid AND
246
281
  pg_attribute.attnum = any(pg_index.indkey)
@@ -248,16 +283,14 @@ module PgOnlineSchemaChange
248
283
  SQL
249
284
 
250
285
  columns = []
251
- run(client.connection, query) do |result|
252
- columns = result.map { |row| row["column_name"] }
253
- end
286
+ run(client.connection, query) { |result| columns = result.map { |row| row["column_name"] } }
254
287
 
255
288
  columns.first
256
289
  end
257
290
 
258
291
  def storage_parameters_for(client, table, reuse_trasaction = false)
259
292
  query = <<~SQL
260
- SELECT array_to_string(reloptions, ',') as params FROM pg_class WHERE relname=\'#{table}\';
293
+ SELECT array_to_string(reloptions, ',') as params FROM pg_class WHERE relname='#{table}';
261
294
  SQL
262
295
 
263
296
  columns = []
@@ -305,16 +338,17 @@ module PgOnlineSchemaChange
305
338
  logger.info("Terminating other backends")
306
339
 
307
340
  query = <<~SQL
308
- SELECT pg_terminate_backend(pid) FROM pg_locks WHERE locktype = 'relation' AND relation = \'#{table}\'::regclass::oid AND pid <> pg_backend_pid()
341
+ SELECT pg_terminate_backend(pid) FROM pg_locks WHERE locktype = 'relation' AND relation = '#{table}'::regclass::oid AND pid <> pg_backend_pid()
309
342
  SQL
310
343
 
311
344
  run(client.connection, query, true)
312
345
  end
313
346
 
314
347
  def copy_data_statement(client, shadow_table, reuse_trasaction = false)
315
- select_columns = table_columns(client, client.table_name, reuse_trasaction).map do |entry|
316
- entry["column_name_regular"]
317
- end
348
+ select_columns =
349
+ table_columns(client, client.table_name, reuse_trasaction).map do |entry|
350
+ entry["column_name_regular"]
351
+ end
318
352
 
319
353
  select_columns -= dropped_columns_list if dropped_columns_list.any?
320
354
 
@@ -332,9 +366,7 @@ module PgOnlineSchemaChange
332
366
  client.connection.quote_ident(insert_into_column)
333
367
  end
334
368
 
335
- select_columns.map! do |select_column|
336
- client.connection.quote_ident(select_column)
337
- end
369
+ select_columns.map! { |select_column| client.connection.quote_ident(select_column) }
338
370
 
339
371
  <<~SQL
340
372
  INSERT INTO #{shadow_table}(#{insert_into_columns.join(", ")})
@@ -345,14 +377,12 @@ module PgOnlineSchemaChange
345
377
 
346
378
  def primary_key_sequence(shadow_table, primary_key, opened)
347
379
  query = <<~SQL
348
- SELECT pg_get_serial_sequence(\'#{shadow_table}\', \'#{primary_key}\') as sequence_name
380
+ SELECT pg_get_serial_sequence('#{shadow_table}', '#{primary_key}') as sequence_name
349
381
  SQL
350
382
 
351
383
  result = run(client.connection, query, opened)
352
384
 
353
- result.map do |row|
354
- row["sequence_name"]
355
- end&.first
385
+ result.map { |row| row["sequence_name"] }&.first
356
386
  end
357
387
 
358
388
  def query_for_primary_key_refresh(shadow_table, primary_key, table, opened)
@@ -361,7 +391,7 @@ module PgOnlineSchemaChange
361
391
  return "" if sequence_name.nil?
362
392
 
363
393
  <<~SQL
364
- SELECT setval((select pg_get_serial_sequence(\'#{shadow_table}\', \'#{primary_key}\')), (SELECT max(#{primary_key}) FROM #{table}));
394
+ SELECT setval((select pg_get_serial_sequence('#{shadow_table}', '#{primary_key}')), (SELECT max(#{primary_key}) FROM #{table}));
365
395
  SQL
366
396
  end
367
397
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
4
-
5
3
  module PgOnlineSchemaChange
6
4
  class Replay
7
5
  extend Helper
@@ -29,7 +27,9 @@ module PgOnlineSchemaChange
29
27
  SQL
30
28
 
31
29
  rows = []
32
- Query.run(client.connection, select_query, reuse_trasaction) { |result| rows = result.map { |row| row } }
30
+ Query.run(client.connection, select_query, reuse_trasaction) do |result|
31
+ rows = result.map { |row| row }
32
+ end
33
33
 
34
34
  rows
35
35
  end
@@ -48,14 +48,10 @@ module PgOnlineSchemaChange
48
48
 
49
49
  # Remove audit table cols, since we will be
50
50
  # re-mapping them for inserts and updates
51
- reserved_columns.each do |col|
52
- new_row.delete(col)
53
- end
51
+ reserved_columns.each { |col| new_row.delete(col) }
54
52
 
55
53
  if dropped_columns_list.any?
56
- dropped_columns_list.each do |dropped_column|
57
- new_row.delete(dropped_column)
58
- end
54
+ dropped_columns_list.each { |dropped_column| new_row.delete(dropped_column) }
59
55
  end
60
56
 
61
57
  if renamed_columns_list.any?
@@ -69,13 +65,9 @@ module PgOnlineSchemaChange
69
65
 
70
66
  # quote indent column to preserve case insensitivity
71
67
  # ensure rows are escaped
72
- new_row = new_row.transform_keys do |column|
73
- client.connection.quote_ident(column)
74
- end
68
+ new_row = new_row.transform_keys { |column| client.connection.quote_ident(column) }
75
69
 
76
- new_row = new_row.transform_values do |value|
77
- client.connection.escape_string(value)
78
- end
70
+ new_row = new_row.transform_values { |value| client.connection.escape_string(value) }
79
71
 
80
72
  case row[operation_type_column]
81
73
  when "INSERT"
@@ -89,21 +81,19 @@ module PgOnlineSchemaChange
89
81
 
90
82
  to_be_deleted_rows << "'#{row[audit_table_pk]}'"
91
83
  when "UPDATE"
92
- set_values = new_row.map do |column, value|
93
- "#{column} = '#{value}'"
94
- end.join(",")
84
+ set_values = new_row.map { |column, value| "#{column} = '#{value}'" }.join(",")
95
85
 
96
86
  sql = <<~SQL
97
87
  UPDATE #{shadow_table}
98
88
  SET #{set_values}
99
- WHERE #{primary_key}=\'#{row[primary_key]}\';
89
+ WHERE #{primary_key}='#{row[primary_key]}';
100
90
  SQL
101
91
  to_be_replayed << sql
102
92
 
103
93
  to_be_deleted_rows << "'#{row[audit_table_pk]}'"
104
94
  when "DELETE"
105
95
  sql = <<~SQL
106
- DELETE FROM #{shadow_table} WHERE #{primary_key}=\'#{row[primary_key]}\';
96
+ DELETE FROM #{shadow_table} WHERE #{primary_key}='#{row[primary_key]}';
107
97
  SQL
108
98
  to_be_replayed << sql
109
99
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgOnlineSchemaChange
4
- VERSION = "0.7.5"
4
+ VERSION = "0.8.0"
5
5
  end