aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb5
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb31
-rw-r--r--activerecord/test/cases/adapters/postgresql/connection_test.rb29
-rw-r--r--activerecord/test/cases/adapters/postgresql/range_test.rb706
-rw-r--r--activerecord/test/cases/adapters/postgresql/transaction_test.rb1
-rw-r--r--activerecord/test/cases/view_test.rb6
-rw-r--r--activerecord/test/config.example.yml2
-rw-r--r--guides/source/active_record_postgresql.md2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt2
12 files changed, 385 insertions, 410 deletions
diff --git a/.travis.yml b/.travis.yml
index 3db4e9cd94..666939ddf8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -184,11 +184,6 @@ matrix:
before_install:
- "sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/10/main/postgresql.conf"
- "sudo service postgresql restart 10"
- - rvm: 2.5.1
- env:
- - "GEM=ar:postgresql POSTGRES=9.2"
- addons:
- postgresql: "9.2"
- rvm: jruby-head
jdk: oraclejdk8
env:
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 95f9cf6d14..6186595a56 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Bump minimum PostgreSQL version to 9.3.
+
+ *Yasuo Honda*
+
* Values of enum are frozen, raising an error when attempting to modify them.
*Emmanuel Byrd*
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index bd095fbc73..f73369ceef 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -314,6 +314,11 @@ module ActiveRecord
false
end
+ # Does this adapter support materialized views?
+ def supports_materialized_views?
+ false
+ end
+
# Does this adapter support datetime with precision?
def supports_datetime_with_precision?
false
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 1cef8339f5..1c4e625ead 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -185,7 +185,7 @@ module ActiveRecord
end
def supports_json?
- postgresql_version >= 90200
+ true
end
def supports_comments?
@@ -332,16 +332,16 @@ module ActiveRecord
end
def supports_ranges?
- # Range datatypes weren't introduced until PostgreSQL 9.2
- postgresql_version >= 90200
+ true
end
+ deprecate :supports_ranges?
def supports_materialized_views?
- postgresql_version >= 90300
+ true
end
def supports_foreign_tables?
- postgresql_version >= 90300
+ true
end
def supports_pgcrypto_uuid?
@@ -425,8 +425,8 @@ module ActiveRecord
private
def check_version
- if postgresql_version < 90100
- raise "Your version of PostgreSQL (#{postgresql_version}) is too old. Active Record supports PostgreSQL >= 9.1."
+ if postgresql_version < 90300
+ raise "Your version of PostgreSQL (#{postgresql_version}) is too old. Active Record supports PostgreSQL >= 9.3."
end
end
@@ -589,18 +589,11 @@ module ActiveRecord
def load_additional_types(oids = nil)
initializer = OID::TypeMapInitializer.new(type_map)
- if supports_ranges?
- query = <<~SQL
- SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
- FROM pg_type as t
- LEFT JOIN pg_range as r ON oid = rngtypid
- SQL
- else
- query = <<~SQL
- SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
- FROM pg_type as t
- SQL
- end
+ query = <<~SQL
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
+ FROM pg_type as t
+ LEFT JOIN pg_range as r ON oid = rngtypid
+ SQL
if oids
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb
index f0daea4266..40ab158c05 100644
--- a/activerecord/test/cases/adapters/postgresql/connection_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -146,34 +146,15 @@ module ActiveRecord
end
end
- # Must have PostgreSQL >= 9.2, or with_manual_interventions set to
- # true for this test to run.
- #
- # When prompted, restart the PostgreSQL server with the
- # "-m fast" option or kill the individual connection assuming
- # you know the incantation to do that.
- # To restart PostgreSQL 9.1 on macOS, installed via MacPorts, ...
- # sudo su postgres -c "pg_ctl restart -D /opt/local/var/db/postgresql91/defaultdb/ -m fast"
def test_reconnection_after_actual_disconnection_with_verify
original_connection_pid = @connection.query("select pg_backend_pid()")
# Sanity check.
assert_predicate @connection, :active?
- if @connection.send(:postgresql_version) >= 90200
- secondary_connection = ActiveRecord::Base.connection_pool.checkout
- secondary_connection.query("select pg_terminate_backend(#{original_connection_pid.first.first})")
- ActiveRecord::Base.connection_pool.checkin(secondary_connection)
- elsif ARTest.config["with_manual_interventions"]
- puts "Kill the connection now (e.g. by restarting the PostgreSQL " \
- 'server with the "-m fast" option) and then press enter.'
- $stdin.gets
- else
- # We're not capable of terminating the backend ourselves, and
- # we're not allowed to seek assistance; bail out without
- # actually testing anything.
- return
- end
+ secondary_connection = ActiveRecord::Base.connection_pool.checkout
+ secondary_connection.query("select pg_terminate_backend(#{original_connection_pid.first.first})")
+ ActiveRecord::Base.connection_pool.checkin(secondary_connection)
@connection.verify!
@@ -261,6 +242,10 @@ module ActiveRecord
end
end
+ def test_supports_ranges_is_deprecated
+ assert_deprecated { @connection.supports_ranges? }
+ end
+
private
def with_warning_suppression
diff --git a/activerecord/test/cases/adapters/postgresql/range_test.rb b/activerecord/test/cases/adapters/postgresql/range_test.rb
index 3727fe1edd..478cd5aa76 100644
--- a/activerecord/test/cases/adapters/postgresql/range_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/range_test.rb
@@ -3,418 +3,416 @@
require "cases/helper"
require "support/connection_helper"
-if ActiveRecord::Base.connection.respond_to?(:supports_ranges?) && ActiveRecord::Base.connection.supports_ranges?
- class PostgresqlRange < ActiveRecord::Base
- self.table_name = "postgresql_ranges"
- self.time_zone_aware_types += [:tsrange, :tstzrange]
- end
-
- class PostgresqlRangeTest < ActiveRecord::PostgreSQLTestCase
- self.use_transactional_tests = false
- include ConnectionHelper
- include InTimeZone
-
- def setup
- @connection = PostgresqlRange.connection
- begin
- @connection.transaction do
- @connection.execute <<_SQL
- CREATE TYPE floatrange AS RANGE (
- subtype = float8,
- subtype_diff = float8mi
- );
-_SQL
-
- @connection.create_table("postgresql_ranges") do |t|
- t.daterange :date_range
- t.numrange :num_range
- t.tsrange :ts_range
- t.tstzrange :tstz_range
- t.int4range :int4_range
- t.int8range :int8_range
- end
-
- @connection.add_column "postgresql_ranges", "float_range", "floatrange"
- end
- PostgresqlRange.reset_column_information
- rescue ActiveRecord::StatementInvalid
- skip "do not test on PG without range"
- end
+class PostgresqlRange < ActiveRecord::Base
+ self.table_name = "postgresql_ranges"
+ self.time_zone_aware_types += [:tsrange, :tstzrange]
+end
- insert_range(id: 101,
- date_range: "[''2012-01-02'', ''2012-01-04'']",
- num_range: "[0.1, 0.2]",
- ts_range: "[''2010-01-01 14:30'', ''2011-01-01 14:30'']",
- tstz_range: "[''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']",
- int4_range: "[1, 10]",
- int8_range: "[10, 100]",
- float_range: "[0.5, 0.7]")
-
- insert_range(id: 102,
- date_range: "[''2012-01-02'', ''2012-01-04'')",
- num_range: "[0.1, 0.2)",
- ts_range: "[''2010-01-01 14:30'', ''2011-01-01 14:30'')",
- tstz_range: "[''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'')",
- int4_range: "[1, 10)",
- int8_range: "[10, 100)",
- float_range: "[0.5, 0.7)")
-
- insert_range(id: 103,
- date_range: "[''2012-01-02'',]",
- num_range: "[0.1,]",
- ts_range: "[''2010-01-01 14:30'',]",
- tstz_range: "[''2010-01-01 14:30:00+05'',]",
- int4_range: "[1,]",
- int8_range: "[10,]",
- float_range: "[0.5,]")
-
- insert_range(id: 104,
- date_range: "[,]",
- num_range: "[,]",
- ts_range: "[,]",
- tstz_range: "[,]",
- int4_range: "[,]",
- int8_range: "[,]",
- float_range: "[,]")
-
- insert_range(id: 105,
- date_range: "[''2012-01-02'', ''2012-01-02'')",
- num_range: "[0.1, 0.1)",
- ts_range: "[''2010-01-01 14:30'', ''2010-01-01 14:30'')",
- tstz_range: "[''2010-01-01 14:30:00+05'', ''2010-01-01 06:30:00-03'')",
- int4_range: "[1, 1)",
- int8_range: "[10, 10)",
- float_range: "[0.5, 0.5)")
-
- @new_range = PostgresqlRange.new
- @first_range = PostgresqlRange.find(101)
- @second_range = PostgresqlRange.find(102)
- @third_range = PostgresqlRange.find(103)
- @fourth_range = PostgresqlRange.find(104)
- @empty_range = PostgresqlRange.find(105)
- end
+class PostgresqlRangeTest < ActiveRecord::PostgreSQLTestCase
+ self.use_transactional_tests = false
+ include ConnectionHelper
+ include InTimeZone
- teardown do
- @connection.drop_table "postgresql_ranges", if_exists: true
- @connection.execute "DROP TYPE IF EXISTS floatrange"
- reset_connection
- end
+ def setup
+ @connection = PostgresqlRange.connection
+ begin
+ @connection.transaction do
+ @connection.execute <<~SQL
+ CREATE TYPE floatrange AS RANGE (
+ subtype = float8,
+ subtype_diff = float8mi
+ );
+ SQL
- def test_data_type_of_range_types
- assert_equal :daterange, @first_range.column_for_attribute(:date_range).type
- assert_equal :numrange, @first_range.column_for_attribute(:num_range).type
- assert_equal :tsrange, @first_range.column_for_attribute(:ts_range).type
- assert_equal :tstzrange, @first_range.column_for_attribute(:tstz_range).type
- assert_equal :int4range, @first_range.column_for_attribute(:int4_range).type
- assert_equal :int8range, @first_range.column_for_attribute(:int8_range).type
- end
+ @connection.create_table("postgresql_ranges") do |t|
+ t.daterange :date_range
+ t.numrange :num_range
+ t.tsrange :ts_range
+ t.tstzrange :tstz_range
+ t.int4range :int4_range
+ t.int8range :int8_range
+ end
- def test_int4range_values
- assert_equal 1...11, @first_range.int4_range
- assert_equal 1...10, @second_range.int4_range
- assert_equal 1...Float::INFINITY, @third_range.int4_range
- assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int4_range)
- assert_nil @empty_range.int4_range
- end
+ @connection.add_column "postgresql_ranges", "float_range", "floatrange"
+ end
+ PostgresqlRange.reset_column_information
+ rescue ActiveRecord::StatementInvalid
+ skip "do not test on PG without range"
+ end
+
+ insert_range(id: 101,
+ date_range: "[''2012-01-02'', ''2012-01-04'']",
+ num_range: "[0.1, 0.2]",
+ ts_range: "[''2010-01-01 14:30'', ''2011-01-01 14:30'']",
+ tstz_range: "[''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']",
+ int4_range: "[1, 10]",
+ int8_range: "[10, 100]",
+ float_range: "[0.5, 0.7]")
+
+ insert_range(id: 102,
+ date_range: "[''2012-01-02'', ''2012-01-04'')",
+ num_range: "[0.1, 0.2)",
+ ts_range: "[''2010-01-01 14:30'', ''2011-01-01 14:30'')",
+ tstz_range: "[''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'')",
+ int4_range: "[1, 10)",
+ int8_range: "[10, 100)",
+ float_range: "[0.5, 0.7)")
+
+ insert_range(id: 103,
+ date_range: "[''2012-01-02'',]",
+ num_range: "[0.1,]",
+ ts_range: "[''2010-01-01 14:30'',]",
+ tstz_range: "[''2010-01-01 14:30:00+05'',]",
+ int4_range: "[1,]",
+ int8_range: "[10,]",
+ float_range: "[0.5,]")
+
+ insert_range(id: 104,
+ date_range: "[,]",
+ num_range: "[,]",
+ ts_range: "[,]",
+ tstz_range: "[,]",
+ int4_range: "[,]",
+ int8_range: "[,]",
+ float_range: "[,]")
+
+ insert_range(id: 105,
+ date_range: "[''2012-01-02'', ''2012-01-02'')",
+ num_range: "[0.1, 0.1)",
+ ts_range: "[''2010-01-01 14:30'', ''2010-01-01 14:30'')",
+ tstz_range: "[''2010-01-01 14:30:00+05'', ''2010-01-01 06:30:00-03'')",
+ int4_range: "[1, 1)",
+ int8_range: "[10, 10)",
+ float_range: "[0.5, 0.5)")
+
+ @new_range = PostgresqlRange.new
+ @first_range = PostgresqlRange.find(101)
+ @second_range = PostgresqlRange.find(102)
+ @third_range = PostgresqlRange.find(103)
+ @fourth_range = PostgresqlRange.find(104)
+ @empty_range = PostgresqlRange.find(105)
+ end
- def test_int8range_values
- assert_equal 10...101, @first_range.int8_range
- assert_equal 10...100, @second_range.int8_range
- assert_equal 10...Float::INFINITY, @third_range.int8_range
- assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int8_range)
- assert_nil @empty_range.int8_range
- end
+ teardown do
+ @connection.drop_table "postgresql_ranges", if_exists: true
+ @connection.execute "DROP TYPE IF EXISTS floatrange"
+ reset_connection
+ end
- def test_daterange_values
- assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 5), @first_range.date_range
- assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 4), @second_range.date_range
- assert_equal Date.new(2012, 1, 2)...Float::INFINITY, @third_range.date_range
- assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.date_range)
- assert_nil @empty_range.date_range
- end
+ def test_data_type_of_range_types
+ assert_equal :daterange, @first_range.column_for_attribute(:date_range).type
+ assert_equal :numrange, @first_range.column_for_attribute(:num_range).type
+ assert_equal :tsrange, @first_range.column_for_attribute(:ts_range).type
+ assert_equal :tstzrange, @first_range.column_for_attribute(:tstz_range).type
+ assert_equal :int4range, @first_range.column_for_attribute(:int4_range).type
+ assert_equal :int8range, @first_range.column_for_attribute(:int8_range).type
+ end
- def test_numrange_values
- assert_equal BigDecimal("0.1")..BigDecimal("0.2"), @first_range.num_range
- assert_equal BigDecimal("0.1")...BigDecimal("0.2"), @second_range.num_range
- assert_equal BigDecimal("0.1")...BigDecimal("Infinity"), @third_range.num_range
- assert_equal BigDecimal("-Infinity")...BigDecimal("Infinity"), @fourth_range.num_range
- assert_nil @empty_range.num_range
- end
+ def test_int4range_values
+ assert_equal 1...11, @first_range.int4_range
+ assert_equal 1...10, @second_range.int4_range
+ assert_equal 1...Float::INFINITY, @third_range.int4_range
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int4_range)
+ assert_nil @empty_range.int4_range
+ end
- def test_tsrange_values
- tz = ::ActiveRecord::Base.default_timezone
- assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)..Time.send(tz, 2011, 1, 1, 14, 30, 0), @first_range.ts_range
- assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 1, 1, 14, 30, 0), @second_range.ts_range
- assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.ts_range)
- assert_nil @empty_range.ts_range
- end
+ def test_int8range_values
+ assert_equal 10...101, @first_range.int8_range
+ assert_equal 10...100, @second_range.int8_range
+ assert_equal 10...Float::INFINITY, @third_range.int8_range
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int8_range)
+ assert_nil @empty_range.int8_range
+ end
- def test_tstzrange_values
- assert_equal Time.parse("2010-01-01 09:30:00 UTC")..Time.parse("2011-01-01 17:30:00 UTC"), @first_range.tstz_range
- assert_equal Time.parse("2010-01-01 09:30:00 UTC")...Time.parse("2011-01-01 17:30:00 UTC"), @second_range.tstz_range
- assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range)
- assert_nil @empty_range.tstz_range
- end
+ def test_daterange_values
+ assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 5), @first_range.date_range
+ assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 4), @second_range.date_range
+ assert_equal Date.new(2012, 1, 2)...Float::INFINITY, @third_range.date_range
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.date_range)
+ assert_nil @empty_range.date_range
+ end
- def test_custom_range_values
- assert_equal 0.5..0.7, @first_range.float_range
- assert_equal 0.5...0.7, @second_range.float_range
- assert_equal 0.5...Float::INFINITY, @third_range.float_range
- assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.float_range)
- assert_nil @empty_range.float_range
- end
+ def test_numrange_values
+ assert_equal BigDecimal("0.1")..BigDecimal("0.2"), @first_range.num_range
+ assert_equal BigDecimal("0.1")...BigDecimal("0.2"), @second_range.num_range
+ assert_equal BigDecimal("0.1")...BigDecimal("Infinity"), @third_range.num_range
+ assert_equal BigDecimal("-Infinity")...BigDecimal("Infinity"), @fourth_range.num_range
+ assert_nil @empty_range.num_range
+ end
- def test_timezone_awareness_tzrange
- tz = "Pacific Time (US & Canada)"
+ def test_tsrange_values
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)..Time.send(tz, 2011, 1, 1, 14, 30, 0), @first_range.ts_range
+ assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 1, 1, 14, 30, 0), @second_range.ts_range
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.ts_range)
+ assert_nil @empty_range.ts_range
+ end
- in_time_zone tz do
- PostgresqlRange.reset_column_information
- time_string = Time.current.to_s
- time = Time.zone.parse(time_string)
+ def test_tstzrange_values
+ assert_equal Time.parse("2010-01-01 09:30:00 UTC")..Time.parse("2011-01-01 17:30:00 UTC"), @first_range.tstz_range
+ assert_equal Time.parse("2010-01-01 09:30:00 UTC")...Time.parse("2011-01-01 17:30:00 UTC"), @second_range.tstz_range
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range)
+ assert_nil @empty_range.tstz_range
+ end
- record = PostgresqlRange.new(tstz_range: time_string..time_string)
- assert_equal time..time, record.tstz_range
- assert_equal ActiveSupport::TimeZone[tz], record.tstz_range.begin.time_zone
+ def test_custom_range_values
+ assert_equal 0.5..0.7, @first_range.float_range
+ assert_equal 0.5...0.7, @second_range.float_range
+ assert_equal 0.5...Float::INFINITY, @third_range.float_range
+ assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.float_range)
+ assert_nil @empty_range.float_range
+ end
- record.save!
- record.reload
+ def test_timezone_awareness_tzrange
+ tz = "Pacific Time (US & Canada)"
- assert_equal time..time, record.tstz_range
- assert_equal ActiveSupport::TimeZone[tz], record.tstz_range.begin.time_zone
- end
- end
+ in_time_zone tz do
+ PostgresqlRange.reset_column_information
+ time_string = Time.current.to_s
+ time = Time.zone.parse(time_string)
- def test_create_tstzrange
- tstzrange = Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2011-02-02 14:30:00 CDT")
- round_trip(@new_range, :tstz_range, tstzrange)
- assert_equal @new_range.tstz_range, tstzrange
- assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00 UTC")...Time.parse("2011-02-02 19:30:00 UTC")
- end
+ record = PostgresqlRange.new(tstz_range: time_string..time_string)
+ assert_equal time..time, record.tstz_range
+ assert_equal ActiveSupport::TimeZone[tz], record.tstz_range.begin.time_zone
- def test_update_tstzrange
- assert_equal_round_trip(@first_range, :tstz_range,
- Time.parse("2010-01-01 14:30:00 CDT")...Time.parse("2011-02-02 14:30:00 CET"))
- assert_nil_round_trip(@first_range, :tstz_range,
- Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2010-01-01 13:30:00 +0000"))
- end
+ record.save!
+ record.reload
- def test_create_tsrange
- tz = ::ActiveRecord::Base.default_timezone
- assert_equal_round_trip(@new_range, :ts_range,
- Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0))
+ assert_equal time..time, record.tstz_range
+ assert_equal ActiveSupport::TimeZone[tz], record.tstz_range.begin.time_zone
end
+ end
- def test_update_tsrange
- tz = ::ActiveRecord::Base.default_timezone
- assert_equal_round_trip(@first_range, :ts_range,
- Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0))
- assert_nil_round_trip(@first_range, :ts_range,
- Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2010, 1, 1, 14, 30, 0))
- end
+ def test_create_tstzrange
+ tstzrange = Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2011-02-02 14:30:00 CDT")
+ round_trip(@new_range, :tstz_range, tstzrange)
+ assert_equal @new_range.tstz_range, tstzrange
+ assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00 UTC")...Time.parse("2011-02-02 19:30:00 UTC")
+ end
- def test_timezone_awareness_tsrange
- tz = "Pacific Time (US & Canada)"
+ def test_update_tstzrange
+ assert_equal_round_trip(@first_range, :tstz_range,
+ Time.parse("2010-01-01 14:30:00 CDT")...Time.parse("2011-02-02 14:30:00 CET"))
+ assert_nil_round_trip(@first_range, :tstz_range,
+ Time.parse("2010-01-01 14:30:00 +0100")...Time.parse("2010-01-01 13:30:00 +0000"))
+ end
- in_time_zone tz do
- PostgresqlRange.reset_column_information
- time_string = Time.current.to_s
- time = Time.zone.parse(time_string)
+ def test_create_tsrange
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal_round_trip(@new_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0))
+ end
- record = PostgresqlRange.new(ts_range: time_string..time_string)
- assert_equal time..time, record.ts_range
- assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
+ def test_update_tsrange
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal_round_trip(@first_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0))
+ assert_nil_round_trip(@first_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2010, 1, 1, 14, 30, 0))
+ end
- record.save!
- record.reload
+ def test_timezone_awareness_tsrange
+ tz = "Pacific Time (US & Canada)"
- assert_equal time..time, record.ts_range
- assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
- end
- end
+ in_time_zone tz do
+ PostgresqlRange.reset_column_information
+ time_string = Time.current.to_s
+ time = Time.zone.parse(time_string)
- def test_create_tstzrange_preserve_usec
- tstzrange = Time.parse("2010-01-01 14:30:00.670277 +0100")...Time.parse("2011-02-02 14:30:00.745125 CDT")
- round_trip(@new_range, :tstz_range, tstzrange)
- assert_equal @new_range.tstz_range, tstzrange
- assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00.670277 UTC")...Time.parse("2011-02-02 19:30:00.745125 UTC")
- end
+ record = PostgresqlRange.new(ts_range: time_string..time_string)
+ assert_equal time..time, record.ts_range
+ assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
- def test_update_tstzrange_preserve_usec
- assert_equal_round_trip(@first_range, :tstz_range,
- Time.parse("2010-01-01 14:30:00.245124 CDT")...Time.parse("2011-02-02 14:30:00.451274 CET"))
- assert_nil_round_trip(@first_range, :tstz_range,
- Time.parse("2010-01-01 14:30:00.245124 +0100")...Time.parse("2010-01-01 13:30:00.245124 +0000"))
- end
+ record.save!
+ record.reload
- def test_create_tsrange_preseve_usec
- tz = ::ActiveRecord::Base.default_timezone
- assert_equal_round_trip(@new_range, :ts_range,
- Time.send(tz, 2010, 1, 1, 14, 30, 0, 125435)...Time.send(tz, 2011, 2, 2, 14, 30, 0, 225435))
+ assert_equal time..time, record.ts_range
+ assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
end
+ end
- def test_update_tsrange_preserve_usec
- tz = ::ActiveRecord::Base.default_timezone
- assert_equal_round_trip(@first_range, :ts_range,
- Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432)...Time.send(tz, 2011, 2, 2, 14, 30, 0, 224242))
- assert_nil_round_trip(@first_range, :ts_range,
- Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432)...Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432))
- end
+ def test_create_tstzrange_preserve_usec
+ tstzrange = Time.parse("2010-01-01 14:30:00.670277 +0100")...Time.parse("2011-02-02 14:30:00.745125 CDT")
+ round_trip(@new_range, :tstz_range, tstzrange)
+ assert_equal @new_range.tstz_range, tstzrange
+ assert_equal @new_range.tstz_range, Time.parse("2010-01-01 13:30:00.670277 UTC")...Time.parse("2011-02-02 19:30:00.745125 UTC")
+ end
- def test_timezone_awareness_tsrange_preserve_usec
- tz = "Pacific Time (US & Canada)"
+ def test_update_tstzrange_preserve_usec
+ assert_equal_round_trip(@first_range, :tstz_range,
+ Time.parse("2010-01-01 14:30:00.245124 CDT")...Time.parse("2011-02-02 14:30:00.451274 CET"))
+ assert_nil_round_trip(@first_range, :tstz_range,
+ Time.parse("2010-01-01 14:30:00.245124 +0100")...Time.parse("2010-01-01 13:30:00.245124 +0000"))
+ end
- in_time_zone tz do
- PostgresqlRange.reset_column_information
- time_string = "2017-09-26 07:30:59.132451 -0700"
- time = Time.zone.parse(time_string)
- assert time.usec > 0
+ def test_create_tsrange_preseve_usec
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal_round_trip(@new_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0, 125435)...Time.send(tz, 2011, 2, 2, 14, 30, 0, 225435))
+ end
- record = PostgresqlRange.new(ts_range: time_string..time_string)
- assert_equal time..time, record.ts_range
- assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
- assert_equal time.usec, record.ts_range.begin.usec
+ def test_update_tsrange_preserve_usec
+ tz = ::ActiveRecord::Base.default_timezone
+ assert_equal_round_trip(@first_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432)...Time.send(tz, 2011, 2, 2, 14, 30, 0, 224242))
+ assert_nil_round_trip(@first_range, :ts_range,
+ Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432)...Time.send(tz, 2010, 1, 1, 14, 30, 0, 142432))
+ end
- record.save!
- record.reload
+ def test_timezone_awareness_tsrange_preserve_usec
+ tz = "Pacific Time (US & Canada)"
- assert_equal time..time, record.ts_range
- assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
- assert_equal time.usec, record.ts_range.begin.usec
- end
- end
+ in_time_zone tz do
+ PostgresqlRange.reset_column_information
+ time_string = "2017-09-26 07:30:59.132451 -0700"
+ time = Time.zone.parse(time_string)
+ assert time.usec > 0
- def test_create_numrange
- assert_equal_round_trip(@new_range, :num_range,
- BigDecimal("0.5")...BigDecimal("1"))
- end
+ record = PostgresqlRange.new(ts_range: time_string..time_string)
+ assert_equal time..time, record.ts_range
+ assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
+ assert_equal time.usec, record.ts_range.begin.usec
- def test_update_numrange
- assert_equal_round_trip(@first_range, :num_range,
- BigDecimal("0.5")...BigDecimal("1"))
- assert_nil_round_trip(@first_range, :num_range,
- BigDecimal("0.5")...BigDecimal("0.5"))
- end
+ record.save!
+ record.reload
- def test_create_daterange
- assert_equal_round_trip(@new_range, :date_range,
- Range.new(Date.new(2012, 1, 1), Date.new(2013, 1, 1), true))
+ assert_equal time..time, record.ts_range
+ assert_equal ActiveSupport::TimeZone[tz], record.ts_range.begin.time_zone
+ assert_equal time.usec, record.ts_range.begin.usec
end
+ end
- def test_update_daterange
- assert_equal_round_trip(@first_range, :date_range,
- Date.new(2012, 2, 3)...Date.new(2012, 2, 10))
- assert_nil_round_trip(@first_range, :date_range,
- Date.new(2012, 2, 3)...Date.new(2012, 2, 3))
- end
+ def test_create_numrange
+ assert_equal_round_trip(@new_range, :num_range,
+ BigDecimal("0.5")...BigDecimal("1"))
+ end
- def test_create_int4range
- assert_equal_round_trip(@new_range, :int4_range, Range.new(3, 50, true))
- end
+ def test_update_numrange
+ assert_equal_round_trip(@first_range, :num_range,
+ BigDecimal("0.5")...BigDecimal("1"))
+ assert_nil_round_trip(@first_range, :num_range,
+ BigDecimal("0.5")...BigDecimal("0.5"))
+ end
- def test_update_int4range
- assert_equal_round_trip(@first_range, :int4_range, 6...10)
- assert_nil_round_trip(@first_range, :int4_range, 3...3)
- end
+ def test_create_daterange
+ assert_equal_round_trip(@new_range, :date_range,
+ Range.new(Date.new(2012, 1, 1), Date.new(2013, 1, 1), true))
+ end
- def test_create_int8range
- assert_equal_round_trip(@new_range, :int8_range, Range.new(30, 50, true))
- end
+ def test_update_daterange
+ assert_equal_round_trip(@first_range, :date_range,
+ Date.new(2012, 2, 3)...Date.new(2012, 2, 10))
+ assert_nil_round_trip(@first_range, :date_range,
+ Date.new(2012, 2, 3)...Date.new(2012, 2, 3))
+ end
- def test_update_int8range
- assert_equal_round_trip(@first_range, :int8_range, 60000...10000000)
- assert_nil_round_trip(@first_range, :int8_range, 39999...39999)
- end
+ def test_create_int4range
+ assert_equal_round_trip(@new_range, :int4_range, Range.new(3, 50, true))
+ end
- def test_exclude_beginning_for_subtypes_without_succ_method_is_not_supported
- assert_raises(ArgumentError) { PostgresqlRange.create!(num_range: "(0.1, 0.2]") }
- assert_raises(ArgumentError) { PostgresqlRange.create!(float_range: "(0.5, 0.7]") }
- assert_raises(ArgumentError) { PostgresqlRange.create!(int4_range: "(1, 10]") }
- assert_raises(ArgumentError) { PostgresqlRange.create!(int8_range: "(10, 100]") }
- assert_raises(ArgumentError) { PostgresqlRange.create!(date_range: "(''2012-01-02'', ''2012-01-04'']") }
- assert_raises(ArgumentError) { PostgresqlRange.create!(ts_range: "(''2010-01-01 14:30'', ''2011-01-01 14:30'']") }
- assert_raises(ArgumentError) { PostgresqlRange.create!(tstz_range: "(''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']") }
- end
+ def test_update_int4range
+ assert_equal_round_trip(@first_range, :int4_range, 6...10)
+ assert_nil_round_trip(@first_range, :int4_range, 3...3)
+ end
- def test_where_by_attribute_with_range
- range = 1..100
- record = PostgresqlRange.create!(int4_range: range)
- assert_equal record, PostgresqlRange.where(int4_range: range).take
- end
+ def test_create_int8range
+ assert_equal_round_trip(@new_range, :int8_range, Range.new(30, 50, true))
+ end
- def test_where_by_attribute_with_range_in_array
- range = 1..100
- record = PostgresqlRange.create!(int4_range: range)
- assert_equal record, PostgresqlRange.where(int4_range: [range]).take
- end
+ def test_update_int8range
+ assert_equal_round_trip(@first_range, :int8_range, 60000...10000000)
+ assert_nil_round_trip(@first_range, :int8_range, 39999...39999)
+ end
- def test_update_all_with_ranges
- PostgresqlRange.create!
+ def test_exclude_beginning_for_subtypes_without_succ_method_is_not_supported
+ assert_raises(ArgumentError) { PostgresqlRange.create!(num_range: "(0.1, 0.2]") }
+ assert_raises(ArgumentError) { PostgresqlRange.create!(float_range: "(0.5, 0.7]") }
+ assert_raises(ArgumentError) { PostgresqlRange.create!(int4_range: "(1, 10]") }
+ assert_raises(ArgumentError) { PostgresqlRange.create!(int8_range: "(10, 100]") }
+ assert_raises(ArgumentError) { PostgresqlRange.create!(date_range: "(''2012-01-02'', ''2012-01-04'']") }
+ assert_raises(ArgumentError) { PostgresqlRange.create!(ts_range: "(''2010-01-01 14:30'', ''2011-01-01 14:30'']") }
+ assert_raises(ArgumentError) { PostgresqlRange.create!(tstz_range: "(''2010-01-01 14:30:00+05'', ''2011-01-01 14:30:00-03'']") }
+ end
- PostgresqlRange.update_all(int8_range: 1..100)
+ def test_where_by_attribute_with_range
+ range = 1..100
+ record = PostgresqlRange.create!(int4_range: range)
+ assert_equal record, PostgresqlRange.where(int4_range: range).take
+ end
- assert_equal 1...101, PostgresqlRange.first.int8_range
- end
+ def test_where_by_attribute_with_range_in_array
+ range = 1..100
+ record = PostgresqlRange.create!(int4_range: range)
+ assert_equal record, PostgresqlRange.where(int4_range: [range]).take
+ end
- def test_ranges_correctly_escape_input
- range = "-1,2]'; DROP TABLE postgresql_ranges; --".."a"
- PostgresqlRange.update_all(int8_range: range)
+ def test_update_all_with_ranges
+ PostgresqlRange.create!
- assert_nothing_raised do
- PostgresqlRange.first
- end
- end
+ PostgresqlRange.update_all(int8_range: 1..100)
- def test_infinity_values
- PostgresqlRange.create!(int4_range: 1..Float::INFINITY,
- int8_range: -Float::INFINITY..0,
- float_range: -Float::INFINITY..Float::INFINITY)
+ assert_equal 1...101, PostgresqlRange.first.int8_range
+ end
- record = PostgresqlRange.first
+ def test_ranges_correctly_escape_input
+ range = "-1,2]'; DROP TABLE postgresql_ranges; --".."a"
+ PostgresqlRange.update_all(int8_range: range)
- assert_equal(1...Float::INFINITY, record.int4_range)
- assert_equal(-Float::INFINITY...1, record.int8_range)
- assert_equal(-Float::INFINITY...Float::INFINITY, record.float_range)
+ assert_nothing_raised do
+ PostgresqlRange.first
end
+ end
- private
- def assert_equal_round_trip(range, attribute, value)
- round_trip(range, attribute, value)
- assert_equal value, range.public_send(attribute)
- end
+ def test_infinity_values
+ PostgresqlRange.create!(int4_range: 1..Float::INFINITY,
+ int8_range: -Float::INFINITY..0,
+ float_range: -Float::INFINITY..Float::INFINITY)
- def assert_nil_round_trip(range, attribute, value)
- round_trip(range, attribute, value)
- assert_nil range.public_send(attribute)
- end
-
- def round_trip(range, attribute, value)
- range.public_send "#{attribute}=", value
- assert range.save
- assert range.reload
- end
+ record = PostgresqlRange.first
- def insert_range(values)
- @connection.execute <<~SQL
- INSERT INTO postgresql_ranges (
- id,
- date_range,
- num_range,
- ts_range,
- tstz_range,
- int4_range,
- int8_range,
- float_range
- ) VALUES (
- #{values[:id]},
- '#{values[:date_range]}',
- '#{values[:num_range]}',
- '#{values[:ts_range]}',
- '#{values[:tstz_range]}',
- '#{values[:int4_range]}',
- '#{values[:int8_range]}',
- '#{values[:float_range]}'
- )
- SQL
- end
+ assert_equal(1...Float::INFINITY, record.int4_range)
+ assert_equal(-Float::INFINITY...1, record.int8_range)
+ assert_equal(-Float::INFINITY...Float::INFINITY, record.float_range)
end
+
+ private
+ def assert_equal_round_trip(range, attribute, value)
+ round_trip(range, attribute, value)
+ assert_equal value, range.public_send(attribute)
+ end
+
+ def assert_nil_round_trip(range, attribute, value)
+ round_trip(range, attribute, value)
+ assert_nil range.public_send(attribute)
+ end
+
+ def round_trip(range, attribute, value)
+ range.public_send "#{attribute}=", value
+ assert range.save
+ assert range.reload
+ end
+
+ def insert_range(values)
+ @connection.execute <<~SQL
+ INSERT INTO postgresql_ranges (
+ id,
+ date_range,
+ num_range,
+ ts_range,
+ tstz_range,
+ int4_range,
+ int8_range,
+ float_range
+ ) VALUES (
+ #{values[:id]},
+ '#{values[:date_range]}',
+ '#{values[:num_range]}',
+ '#{values[:ts_range]}',
+ '#{values[:tstz_range]}',
+ '#{values[:int4_range]}',
+ '#{values[:int8_range]}',
+ '#{values[:float_range]}'
+ )
+ SQL
+ end
end
diff --git a/activerecord/test/cases/adapters/postgresql/transaction_test.rb b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
index 984b2f5ea4..919ff3d158 100644
--- a/activerecord/test/cases/adapters/postgresql/transaction_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
@@ -94,7 +94,6 @@ module ActiveRecord
end
test "raises LockWaitTimeout when lock wait timeout exceeded" do
- skip unless ActiveRecord::Base.connection.postgresql_version >= 90300
assert_raises(ActiveRecord::LockWaitTimeout) do
s = Sample.create!(value: 1)
latch1 = Concurrent::CountDownLatch.new
diff --git a/activerecord/test/cases/view_test.rb b/activerecord/test/cases/view_test.rb
index 88e5e4a421..36b9df7ba5 100644
--- a/activerecord/test/cases/view_test.rb
+++ b/activerecord/test/cases/view_test.rb
@@ -156,8 +156,7 @@ if ActiveRecord::Base.connection.supports_views?
end
# sqlite dose not support CREATE, INSERT, and DELETE for VIEW
- if current_adapter?(:Mysql2Adapter, :SQLServerAdapter) ||
- current_adapter?(:PostgreSQLAdapter) && ActiveRecord::Base.connection.postgresql_version >= 90300
+ if current_adapter?(:Mysql2Adapter, :SQLServerAdapter, :PostgreSQLAdapter)
class UpdateableViewTest < ActiveRecord::TestCase
self.use_transactional_tests = false
@@ -207,8 +206,7 @@ if ActiveRecord::Base.connection.supports_views?
end # end of `if current_adapter?(:Mysql2Adapter, :PostgreSQLAdapter, :SQLServerAdapter)`
end # end of `if ActiveRecord::Base.connection.supports_views?`
-if ActiveRecord::Base.connection.respond_to?(:supports_materialized_views?) &&
- ActiveRecord::Base.connection.supports_materialized_views?
+if ActiveRecord::Base.connection.supports_materialized_views?
class MaterializedViewTest < ActiveRecord::PostgreSQLTestCase
include ViewBehavior
diff --git a/activerecord/test/config.example.yml b/activerecord/test/config.example.yml
index 18347cd07d..33962f9e5e 100644
--- a/activerecord/test/config.example.yml
+++ b/activerecord/test/config.example.yml
@@ -1,7 +1,5 @@
default_connection: <%= defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3' %>
-with_manual_interventions: false
-
connections:
jdbcderby:
arunit: activerecord_unittest
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index 16c1567c69..536a7138e9 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -14,7 +14,7 @@ After reading this guide, you will know:
--------------------------------------------------------------------------------
-In order to use the PostgreSQL adapter you need to have at least version 9.1
+In order to use the PostgreSQL adapter you need to have at least version 9.3
installed. Older versions are not supported.
To get started with PostgreSQL have a look at the
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt
index df8a6ad627..2383fe97d3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt
@@ -1,4 +1,4 @@
-# PostgreSQL. Versions 9.1 and up are supported.
+# PostgreSQL. Versions 9.3 and up are supported.
#
# Configure Using Gemfile
# gem 'activerecord-jdbcpostgresql-adapter'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt
index dcd57425e2..2f51030756 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt
@@ -1,4 +1,4 @@
-# PostgreSQL. Versions 9.1 and up are supported.
+# PostgreSQL. Versions 9.3 and up are supported.
#
# Install the pg driver:
# gem install pg