Skip to content

Commit 98e4cf2

Browse files
committed
Bump required PostgreSQL version to 10.0
Rails main currently claims support for PostgreSQL 9.3+. However, to ensure forward compatibility with PostgreSQL 18 and future releases, we need to establish a more sustainable baseline. * Changes in this commit: - Bump minimum required PostgreSQL version from 9.3 to 10.0 - Deprecate `supports_pgcrypto_uuid?` (no longer needed since PostgreSQL 10+ includes pgcrypto by default) * Reasons for choosing PostgreSQL 10.0 baseline: - The pg gem v1.6 raises its minimum required PostgreSQL version to 10 via ged/ruby-pg#606 - PostgreSQL 9.3 reached end-of-life in November 2018, and PostgreSQL 9.6 reached end-of-life in November 2021 - While Ruby on Rails has not historically dropped database support solely based on EOL status, PostgreSQL 9.3 (released in 2013) is now over a decade old and maintaining compatibility becomes increasingly challenging Discussed at https://discuss.rubyonrails.org/t/proposal-bump-the-minimum-supported-postgresql-version-from-9-3-to-10/89422
1 parent 2b4feed commit 98e4cf2

File tree

10 files changed

+43
-56
lines changed

10 files changed

+43
-56
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Bump the minimum PostgreSQL version to 10.0.
2+
3+
*Yasuo Honda*
4+
15
* Fix PostgreSQL schema dumping to handle schema-qualified table names in foreign_key references that span different schemas.
26

37
# before

activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,7 @@ def select_max_column_value_sql(table, column)
503503

504504
def select_min_column_value_sql(sequence)
505505
quoted_sequence = @adapter.quote_table_name(sequence)
506-
if @adapter.database_version >= 10_00_00
507-
"SELECT seqmin FROM pg_sequence WHERE seqrelid = #{@adapter.quote(quoted_sequence)}::regclass"
508-
else
509-
"SELECT min_value FROM #{quoted_sequence}"
510-
end
506+
"SELECT seqmin FROM pg_sequence WHERE seqrelid = #{@adapter.quote(quoted_sequence)}::regclass"
511507
end
512508

513509
def reset_sequence_sql(sequence, max_value, min_value)

activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def supports_insert_returning?
284284
end
285285

286286
def supports_insert_on_conflict?
287-
database_version >= 9_05_00 # >= 9.5
287+
true
288288
end
289289
alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
290290
alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
@@ -295,15 +295,15 @@ def supports_virtual_columns?
295295
end
296296

297297
def supports_identity_columns? # :nodoc:
298-
database_version >= 10_00_00 # >= 10.0
298+
true
299299
end
300300

301301
def supports_nulls_not_distinct?
302302
database_version >= 15_00_00 # >= 15.0
303303
end
304304

305305
def supports_native_partitioning? # :nodoc:
306-
database_version >= 10_00_00 # >= 10.0
306+
true
307307
end
308308

309309
if PG::Connection.method_defined?(:close_prepared) # pg 1.6.0 & libpq 17
@@ -471,8 +471,9 @@ def supports_foreign_tables?
471471
end
472472

473473
def supports_pgcrypto_uuid?
474-
database_version >= 9_04_00 # >= 9.4
474+
true
475475
end
476+
deprecate :supports_pgcrypto_uuid?, deprecator: ActiveRecord.deprecator
476477

477478
def supports_optimizer_hints?
478479
unless defined?(@has_pg_hint_plan)
@@ -706,8 +707,8 @@ def build_insert_sql(insert) # :nodoc:
706707
end
707708

708709
def check_version # :nodoc:
709-
if database_version < 9_03_00 # < 9.3
710-
raise "Your version of PostgreSQL (#{database_version}) is too old. Active Record supports PostgreSQL >= 9.3."
710+
if database_version < 10_00_00 # < 10.0
711+
raise "Your version of PostgreSQL (#{database_version}) is too old. Active Record supports PostgreSQL >= 10.0."
711712
end
712713
end
713714

activerecord/test/cases/adapters/postgresql/connection_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ def test_release_non_existent_advisory_lock
232232
end
233233
end
234234

235+
def test_supports_supports_pgcrypto_uuid_is_deprecated
236+
assert_deprecated(ActiveRecord.deprecator) do
237+
@connection.supports_pgcrypto_uuid?
238+
end
239+
end
240+
235241
private
236242
def cause_server_side_disconnect
237243
unless @connection.instance_variable_get(:@raw_connection).transaction_status == ::PG::PQTRANS_INTRANS

activerecord/test/cases/adapters/postgresql/geometric_test.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,6 @@ class PostgreSQLGeometricLineTest < ActiveRecord::PostgreSQLTestCase
254254
class PostgresqlLine < ActiveRecord::Base; end
255255

256256
setup do
257-
unless ActiveRecord::Base.lease_connection.database_version >= 90400
258-
skip("line type is not fully implemented")
259-
end
260257
@connection = ActiveRecord::Base.lease_connection
261258
@connection.create_table("postgresql_lines") do |t|
262259
t.line :a_line

activerecord/test/cases/adapters/postgresql/uuid_test.rb

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ def connection
1111
def drop_table(name)
1212
connection.drop_table name, if_exists: true
1313
end
14-
15-
def uuid_function
16-
connection.supports_pgcrypto_uuid? ? "gen_random_uuid()" : "uuid_generate_v4()"
17-
end
18-
19-
def uuid_default
20-
connection.supports_pgcrypto_uuid? ? {} : { default: uuid_function }
21-
end
2214
end
2315

2416
class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
@@ -31,7 +23,7 @@ class UUIDType < ActiveRecord::Base
3123

3224
setup do
3325
enable_extension!("uuid-ossp", connection)
34-
enable_extension!("pgcrypto", connection) if connection.supports_pgcrypto_uuid?
26+
enable_extension!("pgcrypto", connection)
3527

3628
connection.create_table "uuid_data_type" do |t|
3729
t.uuid "guid"
@@ -43,14 +35,11 @@ class UUIDType < ActiveRecord::Base
4335
drop_table "uuid_data_type"
4436
end
4537

46-
if ActiveRecord::Base.lease_connection.respond_to?(:supports_pgcrypto_uuid?) &&
47-
ActiveRecord::Base.lease_connection.supports_pgcrypto_uuid?
48-
def test_uuid_column_default
49-
connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "gen_random_uuid()"
50-
UUIDType.reset_column_information
51-
column = UUIDType.columns_hash["thingy"]
52-
assert_equal "gen_random_uuid()", column.default_function
53-
end
38+
def test_uuid_column_default
39+
connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "gen_random_uuid()"
40+
UUIDType.reset_column_information
41+
column = UUIDType.columns_hash["thingy"]
42+
assert_equal "gen_random_uuid()", column.default_function
5443
end
5544

5645
def test_change_column_default
@@ -228,7 +217,7 @@ class UUID < ActiveRecord::Base
228217
# to test dumping tables which columns have defaults with custom functions
229218
connection.execute <<~SQL
230219
CREATE OR REPLACE FUNCTION my_uuid_generator() RETURNS uuid
231-
AS $$ SELECT * FROM #{uuid_function} $$
220+
AS $$ SELECT * FROM gen_random_uuid() $$
232221
LANGUAGE SQL VOLATILE;
233222
SQL
234223

@@ -238,7 +227,7 @@ class UUID < ActiveRecord::Base
238227
t.uuid "other_uuid_2", default: "my_uuid_generator()"
239228
end
240229

241-
connection.create_table("pg_uuids_3", id: :uuid, **uuid_default) do |t|
230+
connection.create_table("pg_uuids_3", id: :uuid) do |t|
242231
t.string "name"
243232
end
244233
end
@@ -286,11 +275,7 @@ def test_schema_dumper_for_uuid_primary_key_with_custom_default
286275

287276
def test_schema_dumper_for_uuid_primary_key_default
288277
schema = dump_table_schema "pg_uuids_3"
289-
if connection.supports_pgcrypto_uuid?
290-
assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "gen_random_uuid\(\)" }/, schema)
291-
else
292-
assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema)
293-
end
278+
assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "gen_random_uuid\(\)" }/, schema)
294279
end
295280

296281
def test_schema_dumper_for_uuid_primary_key_default_in_legacy_migration
@@ -384,10 +369,10 @@ class UuidComment < ActiveRecord::Base
384369

385370
setup do
386371
connection.transaction do
387-
connection.create_table("pg_uuid_posts", id: :uuid, **uuid_default) do |t|
372+
connection.create_table("pg_uuid_posts", id: :uuid) do |t|
388373
t.string "title"
389374
end
390-
connection.create_table("pg_uuid_comments", id: :uuid, **uuid_default) do |t|
375+
connection.create_table("pg_uuid_comments", id: :uuid) do |t|
391376
t.references :uuid_post, type: :uuid
392377
t.string "content"
393378
end
@@ -443,14 +428,14 @@ class UuidComment < ActiveRecord::Base
443428

444429
setup do
445430
connection.transaction do
446-
connection.create_table("pg_uuid_forums", id: :uuid, **uuid_default) do |t|
431+
connection.create_table("pg_uuid_forums", id: :uuid) do |t|
447432
t.string "name"
448433
end
449-
connection.create_table("pg_uuid_posts", id: :uuid, **uuid_default) do |t|
434+
connection.create_table("pg_uuid_posts", id: :uuid) do |t|
450435
t.references :uuid_forum, type: :uuid
451436
t.string "title"
452437
end
453-
connection.create_table("pg_uuid_comments", id: :uuid, **uuid_default) do |t|
438+
connection.create_table("pg_uuid_comments", id: :uuid) do |t|
454439
t.references :uuid_post, type: :uuid
455440
t.string "content"
456441
end

activerecord/test/schema/postgresql_specific_schema.rb

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
ActiveRecord::Schema.define do
44
ActiveRecord::TestCase.enable_extension!("uuid-ossp", connection)
5-
ActiveRecord::TestCase.enable_extension!("pgcrypto", connection) if supports_pgcrypto_uuid?
5+
ActiveRecord::TestCase.enable_extension!("pgcrypto", connection)
66

7-
uuid_default = supports_pgcrypto_uuid? ? {} : { default: "uuid_generate_v4()" }
8-
9-
create_table :chat_messages, id: :uuid, force: true, **uuid_default do |t|
7+
create_table :chat_messages, id: :uuid, force: true do |t|
108
t.text :content
119
end
1210

@@ -15,11 +13,11 @@
1513
t.text :content
1614
end
1715

18-
create_table :uuid_parents, id: :uuid, force: true, **uuid_default do |t|
16+
create_table :uuid_parents, id: :uuid, force: true do |t|
1917
t.string :name
2018
end
2119

22-
create_table :uuid_children, id: :uuid, force: true, **uuid_default do |t|
20+
create_table :uuid_children, id: :uuid, force: true do |t|
2321
t.string :name
2422
t.uuid :uuid_parent_id
2523
end
@@ -139,23 +137,23 @@
139137
end
140138

141139
create_table :uuid_comments, force: true, id: false do |t|
142-
t.uuid :uuid, primary_key: true, **uuid_default
140+
t.uuid :uuid, primary_key: true
143141
t.string :content
144142
end
145143

146144
create_table :uuid_entries, force: true, id: false do |t|
147-
t.uuid :uuid, primary_key: true, **uuid_default
145+
t.uuid :uuid, primary_key: true
148146
t.string :entryable_type, null: false
149147
t.uuid :entryable_uuid, null: false
150148
end
151149

152150
create_table :uuid_items, force: true, id: false do |t|
153-
t.uuid :uuid, primary_key: true, **uuid_default
151+
t.uuid :uuid, primary_key: true
154152
t.string :title
155153
end
156154

157155
create_table :uuid_messages, force: true, id: false do |t|
158-
t.uuid :uuid, primary_key: true, **uuid_default
156+
t.uuid :uuid, primary_key: true
159157
t.string :subject
160158
end
161159

guides/source/active_record_postgresql.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ After reading this guide, you will know:
1818

1919
--------------------------------------------------------------------------------
2020

21-
In order to use the PostgreSQL adapter you need to have at least version 9.3
21+
In order to use the PostgreSQL adapter you need to have at least version 10.0
2222
installed. Older versions are not supported.
2323

2424
To get started with PostgreSQL have a look at the

guides/source/command_line.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ The main difference is the content of the `config/database.yml` file. With the
181181
PostgreSQL option, it looks like this:
182182
183183
```yaml
184-
# PostgreSQL. Versions 9.3 and up are supported.
184+
# PostgreSQL. Versions 10.0 and up are supported.
185185
#
186186
# Install the pg driver:
187187
# gem install pg

railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# PostgreSQL. Versions 9.3 and up are supported.
1+
# PostgreSQL. Versions 10.0 and up are supported.
22
#
33
# Install the pg driver:
44
# gem install pg

0 commit comments

Comments
 (0)