diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2017-02-13 02:34:52 +0900 |
---|---|---|
committer | Jeremy Daer <jeremydaer@gmail.com> | 2017-02-12 19:52:58 -0700 |
commit | 42ed16a987c91dcb1705a414b5da15c5275e2b16 (patch) | |
tree | 695dd8ef4a8f14939e6971199126353b8d028e7c /activerecord | |
parent | bb45fa05d1681230764af023058af65142c75cff (diff) | |
download | rails-42ed16a987c91dcb1705a414b5da15c5275e2b16.tar.gz rails-42ed16a987c91dcb1705a414b5da15c5275e2b16.tar.bz2 rails-42ed16a987c91dcb1705a414b5da15c5275e2b16.zip |
Schema dumping support for PostgreSQL interval type
Closes #27979
Diffstat (limited to 'activerecord')
8 files changed, 36 insertions, 21 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 4e96f2e002..49d6324a52 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* PostgreSQL: schema dumping support for PostgreSQL interval type. + + *Ryuta Kamizono* + * Deprecate `supports_primary_key?` on connection adapters since it's been long unused and unsupported. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 8de8c05988..e0528c1df6 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -1070,7 +1070,7 @@ module ActiveRecord raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified" end - elsif [:datetime, :time].include?(type) && precision ||= native[:precision] + elsif [:datetime, :time, :interval].include?(type) && precision ||= native[:precision] if (0..6) === precision column_type_sql << "(#{precision})" else diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb index 2d2fede4e8..564e82a4ac 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb @@ -5,8 +5,9 @@ module ActiveRecord class SpecializedString < Type::String # :nodoc: attr_reader :type - def initialize(type) + def initialize(type, **options) @type = type + super(options) end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb index 7491fb716e..372958b9be 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb @@ -88,6 +88,10 @@ module ActiveRecord args.each { |name| column(name, :inet, options) } end + def interval(*args, **options) + args.each { |name| column(name, :interval, options) } + end + def int4range(*args, **options) args.each { |name| column(name, :int4range, options) } end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 203566c91b..89d595eef5 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -109,6 +109,7 @@ module ActiveRecord bit: { name: "bit" }, bit_varying: { name: "bit varying" }, money: { name: "money" }, + interval: { name: "interval" }, } OID = PostgreSQL::OID #:nodoc: @@ -486,8 +487,10 @@ module ActiveRecord m.register_type "polygon", OID::SpecializedString.new(:polygon) m.register_type "circle", OID::SpecializedString.new(:circle) - # FIXME: why are we keeping these types as strings? - m.alias_type "interval", "varchar" + m.register_type "interval" do |_, _, sql_type| + precision = extract_precision(sql_type) + OID::SpecializedString.new(:interval, precision: precision) + end register_class_with_precision m, "time", Type::Time register_class_with_precision m, "timestamp", OID::DateTime diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index eb61782dc7..dc17a715e8 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -28,8 +28,8 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase end def test_data_type_of_time_types - assert_equal :string, @first_time.column_for_attribute(:time_interval).type - assert_equal :string, @first_time.column_for_attribute(:scaled_time_interval).type + assert_equal :interval, @first_time.column_for_attribute(:time_interval).type + assert_equal :interval, @first_time.column_for_attribute(:scaled_time_interval).type end def test_data_type_of_oid_types diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 1aed3e46c3..ea860ef5de 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -261,25 +261,31 @@ class SchemaDumperTest < ActiveRecord::TestCase if current_adapter?(:PostgreSQLAdapter) def test_schema_dump_includes_bigint_default - output = standard_dump + output = dump_table_schema "defaults" assert_match %r{t\.bigint\s+"bigint_default",\s+default: 0}, output end def test_schema_dump_includes_limit_on_array_type - output = standard_dump + output = dump_table_schema "bigint_array" assert_match %r{t\.bigint\s+"big_int_data_points\",\s+array: true}, output end def test_schema_dump_allows_array_of_decimal_defaults - output = standard_dump + output = dump_table_schema "bigint_array" assert_match %r{t\.decimal\s+"decimal_array_default",\s+default: \["1.23", "3.45"\],\s+array: true}, output end def test_schema_dump_expression_indices - index_definition = standard_dump.split(/\n/).grep(/t\.index.*company_expression_index/).first.strip + index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*company_expression_index/).first.strip assert_equal 't.index "lower((name)::text)", name: "company_expression_index", using: :btree', index_definition end + def test_schema_dump_interval_type + output = dump_table_schema "postgresql_times" + assert_match %r{t\.interval\s+"time_interval"$}, output + assert_match %r{t\.interval\s+"scaled_time_interval",\s+precision: 6$}, output + end + if ActiveRecord::Base.connection.supports_extensions? def test_schema_dump_includes_extensions connection = ActiveRecord::Base.connection diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index 15ba2d67ab..a390a76a16 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -23,12 +23,17 @@ ActiveRecord::Schema.define do t.string :char2, limit: 50, default: "a varchar field" t.text :char3, default: "a text field" t.bigint :bigint_default, default: -> { "0::bigint" } - t.text :multiline_default, default: '--- [] + t.text :multiline_default, default: "--- [] -' +" end - %w(postgresql_times postgresql_oids postgresql_timestamp_with_zones + create_table :postgresql_times, force: true do |t| + t.interval :time_interval + t.interval :scaled_time_interval, precision: 6 + end + + %w(postgresql_oids postgresql_timestamp_with_zones postgresql_partitioned_table postgresql_partitioned_table_parent).each do |table_name| drop_table table_name, if_exists: true end @@ -45,14 +50,6 @@ ActiveRecord::Schema.define do end execute <<_SQL - CREATE TABLE postgresql_times ( - id SERIAL PRIMARY KEY, - time_interval INTERVAL, - scaled_time_interval INTERVAL(6) - ); -_SQL - - execute <<_SQL CREATE TABLE postgresql_oids ( id SERIAL PRIMARY KEY, obj_id OID |