pg_ha_migrations 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7db2dcf4e9c5703c49b53e785ec06df44f3dc94fa190c81fe30e2426ed588d9
4
- data.tar.gz: 6b763dbe8f8126bf26c2682ab69e50ea54df505ba099bf0f981e11a5831dee11
3
+ metadata.gz: 2092871922f1fb41ad0d82a1cda3b1b8ad57bf03b9e9a324d452110926754dba
4
+ data.tar.gz: 9e1e74c22f51cdf6d36333fdd6740ebdd5d5d4e76053a000859e7027b39ac9e5
5
5
  SHA512:
6
- metadata.gz: a92e9ba724c5d8faf39b0314430ea4848e2081926c1f02902e4bffb947cde09ccc2de1c4db74b5cb54ee3fb6b8db3072b88dab2ed10432965fbd612ec3d0c0c2
7
- data.tar.gz: 5bf9858b2f1dc84936dae0128f4ddc43f7ae4961ae2564c5b23afdb9f9f8dbad1b9abe527aabe48bd0afca74e6f8d3a457a412f89ab54ef210dcceeaf5ba60ef
6
+ metadata.gz: 88089a7139e0ec580ff9c32574b4fd890d7bf7203740e6d3ec4821a6d03aed728868602de5347b441a2607951234b157cd19485710591b37e27dda803f4f46c7
7
+ data.tar.gz: a52081ab69232926e4484ac0d551437f61b719e0d1514cba507dcbcaf97c363726f2729037170e452f7d7d153847601604f50f92a837a374afc854e0d37f46d1
@@ -5,7 +5,6 @@ jobs:
5
5
  strategy:
6
6
  matrix:
7
7
  pg:
8
- - 13
9
8
  - 14
10
9
  - 15
11
10
  - 16
@@ -19,12 +18,11 @@ jobs:
19
18
  - rails_7.1
20
19
  - rails_7.2
21
20
  - rails_8.0
21
+ - rails_8.1
22
22
  partman:
23
23
  - 4
24
24
  - 5
25
25
  exclude:
26
- - pg: 13
27
- partman: 5 # Partman 5.x is not available in PGDG for PG 13
28
26
  - pg: 17
29
27
  partman: 4 # Partman 4.x is not available in PGDG for PG 17
30
28
  - pg: 18
data/Appraisals CHANGED
@@ -9,3 +9,7 @@ end
9
9
  appraise "rails-8.0" do
10
10
  gem "rails", "~> 8.0.0"
11
11
  end
12
+
13
+ appraise "rails-8.1" do
14
+ gem "rails", "~> 8.1.0"
15
+ end
data/README.md CHANGED
@@ -63,9 +63,21 @@ We believe the `force: true` option to ActiveRecord's `create_table` method is a
63
63
 
64
64
  ### Rollback
65
65
 
66
- Because we require that ["Rollback strategies do not involve reverting the database schema to its previous version"](https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680#360a), PgHaMigrations does not support ActiveRecord's automatic migration rollback capability.
66
+ Although some schema changes are safe to reverse (e.g., dropping a just-created non-unique index), most possible schema changes are not safe to reverse. A few examples relative to database integrity:
67
+ * Dropping a newly added column may result in data loss.
68
+ * Re-adding a dropped unique index (or any other constraint) may fail because data may now exist that violates the constraint.
69
+ * Dropping a enum value simply isn’t supported by Postgres (and wouldn’t be safe since it might be referenced by rows in the database).
67
70
 
68
- Instead we write all of our migrations with only an `def up` method like:
71
+ These concerns are magnified if we also consider currently running application code (especially across multiple revisions, i.e., during a deploy). For example, the application may expect:
72
+ * Indexes to be present for performant queries.
73
+ * Constraints to hold.
74
+ * Columns to be present.
75
+
76
+ Therefore we require that ["Rollback strategies do not involve reverting the database schema to its previous version"](https://medium.com/paypal-tech/postgresql-at-scale-database-schema-changes-without-downtime-20d3749ed680#360a), and PgHaMigrations does not support ActiveRecord's automatic migration rollback capability.
77
+
78
+ Instead we concentrate on ensuring that operations are safe to apply while both old and new revisions of an application are running. In the rare case where we need to “undo” a schema change, we roll forward, rather than rolling back, by having an engineer write a new schema change and deploying that change.
79
+
80
+ We write all of our migrations with only an `def up` method like:
69
81
 
70
82
  ```
71
83
  def up
@@ -73,7 +85,9 @@ def up
73
85
  end
74
86
  ```
75
87
 
76
- and never use `def change`. We believe that this is the only safe approach in production environments. For development environments we iterate by recreating the database from scratch every time we make a change.
88
+ and never use `def change`.
89
+
90
+ For development environments we iterate by recreating the database from scratch every time we make a change.
77
91
 
78
92
  ### Transactional DDL
79
93
 
@@ -102,7 +116,7 @@ The following functionality is currently unsupported:
102
116
 
103
117
  ### Compatibility Notes
104
118
 
105
- - While some features may work with other versions, this gem is currently tested against PostgreSQL 13+ and Partman 4+
119
+ - While some features may work with other versions, this gem is currently tested against PostgreSQL 14+ and Partman 4+
106
120
 
107
121
  ### Migration Methods
108
122
 
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 8.1.0"
6
+
7
+ gemspec path: "../"
@@ -1,7 +1,7 @@
1
1
  require "active_record/migration/compatibility"
2
2
 
3
3
  module PgHaMigrations::AllowedVersions
4
- ALLOWED_VERSIONS = [4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0].map do |v|
4
+ ALLOWED_VERSIONS = [4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0, 8.1].map do |v|
5
5
  begin
6
6
  ActiveRecord::Migration[v]
7
7
  rescue ArgumentError
@@ -326,6 +326,31 @@ module PgHaMigrations::SafeStatements
326
326
  PgHaMigrations::Index.from_table_and_columns(child_table, columns)
327
327
  end
328
328
 
329
+ # A previous run that was interrupted mid-build can leave an invalid index
330
+ # behind on a child partition. Because CREATE INDEX ... IF NOT EXISTS matches
331
+ # on name only (not validity), that leftover would be skipped and never
332
+ # rebuilt, so the parent index would never become valid and this method
333
+ # would raise below on every re-run. When resuming (if_not_exists), drop any
334
+ # invalid child leftovers first so they get rebuilt. They are unattached at
335
+ # this point (the attach step runs only after every child index is built),
336
+ # so they can be dropped concurrently.
337
+ if if_not_exists && child_indexes.present?
338
+ quoted_child_index_names = child_indexes.map { |child_index| connection.quote(child_index.name) }.join(", ")
339
+
340
+ invalid_child_index_names = connection.select_values(<<~SQL)
341
+ SELECT pg_class.relname
342
+ FROM pg_index
343
+ JOIN pg_class ON pg_class.oid = pg_index.indexrelid
344
+ WHERE NOT pg_index.indisvalid
345
+ AND pg_class.relkind = 'i'
346
+ AND pg_class.relname = ANY (ARRAY[#{quoted_child_index_names}])
347
+ SQL
348
+
349
+ child_indexes.select { |index| invalid_child_index_names.include?(index.name) }.each do |child_index|
350
+ safe_remove_concurrent_index(child_index.table.fully_qualified_name, name: child_index.name)
351
+ end
352
+ end
353
+
329
354
  # CREATE INDEX ON ONLY parent_table
330
355
  unsafe_add_index(
331
356
  parent_table.fully_qualified_name,
@@ -1,3 +1,3 @@
1
1
  module PgHaMigrations
2
- VERSION = "2.2.0"
2
+ VERSION = "2.3.1"
3
3
  end
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency "pry-byebug"
38
38
  spec.add_development_dependency "appraisal", "~> 2.5"
39
39
 
40
- spec.add_dependency "rails", ">= 7.1", "< 8.1"
41
- spec.add_dependency "relation_to_struct", ">= 1.5.1"
40
+ spec.add_dependency "rails", ">= 7.1", "< 8.2"
41
+ spec.add_dependency "relation_to_struct", "~> 1.9"
42
42
  spec.add_dependency "ruby2_keywords"
43
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_ha_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - celeen
@@ -13,7 +13,7 @@ authors:
13
13
  - redneckbeard
14
14
  bindir: exe
15
15
  cert_chain: []
16
- date: 2026-01-08 00:00:00.000000000 Z
16
+ date: 2026-07-31 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: rake
@@ -122,7 +122,7 @@ dependencies:
122
122
  version: '7.1'
123
123
  - - "<"
124
124
  - !ruby/object:Gem::Version
125
- version: '8.1'
125
+ version: '8.2'
126
126
  type: :runtime
127
127
  prerelease: false
128
128
  version_requirements: !ruby/object:Gem::Requirement
@@ -132,21 +132,21 @@ dependencies:
132
132
  version: '7.1'
133
133
  - - "<"
134
134
  - !ruby/object:Gem::Version
135
- version: '8.1'
135
+ version: '8.2'
136
136
  - !ruby/object:Gem::Dependency
137
137
  name: relation_to_struct
138
138
  requirement: !ruby/object:Gem::Requirement
139
139
  requirements:
140
- - - ">="
140
+ - - "~>"
141
141
  - !ruby/object:Gem::Version
142
- version: 1.5.1
142
+ version: '1.9'
143
143
  type: :runtime
144
144
  prerelease: false
145
145
  version_requirements: !ruby/object:Gem::Requirement
146
146
  requirements:
147
- - - ">="
147
+ - - "~>"
148
148
  - !ruby/object:Gem::Version
149
- version: 1.5.1
149
+ version: '1.9'
150
150
  - !ruby/object:Gem::Dependency
151
151
  name: ruby2_keywords
152
152
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +188,7 @@ files:
188
188
  - gemfiles/rails_7.1.gemfile
189
189
  - gemfiles/rails_7.2.gemfile
190
190
  - gemfiles/rails_8.0.gemfile
191
+ - gemfiles/rails_8.1.gemfile
191
192
  - lib/pg_ha_migrations.rb
192
193
  - lib/pg_ha_migrations/allowed_versions.rb
193
194
  - lib/pg_ha_migrations/blocking_database_transactions.rb