diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 964357c4a23f08c7b56ecc1b2b5487cc7508daea..078d63f8f23a1d94c7ad08d2ca4ab9c46868d9e9 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* PostgreSQL support default values for enum types. Fixes #7814. + + *Yves Senn* + * PostgreSQL `default_sequence_name` respects schema. Fixes #7516. *Yves Senn* diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index 09db337a82a6347c8eb4e8126f49cccafc1e5076..b2aeb3a0580804948321aacc5ac7d3cd8e814e60 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -179,7 +179,7 @@ def columns(table_name) # Limit, precision, and scale are all handled by the superclass. column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod| oid = get_oid_type(oid.to_i, fmod.to_i, column_name, type) - default_value = extract_value_from_default(default) + default_value = extract_value_from_default(oid, default) default_function = extract_default_function(default_value, default) new_column(column_name, default_value, oid, type, notnull == 'f', default_function) end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 027169ae3c5da0f224c7cf96308bddbaa8a407b4..23c1a8de2f1bc542748ee93f0829084884694a0a 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -498,7 +498,7 @@ def extract_limit(sql_type) # :nodoc: end # Extracts the value from a PostgreSQL column default definition. - def extract_value_from_default(default) # :nodoc: + def extract_value_from_default(oid, default) # :nodoc: # This is a performance optimization for Ruby 1.9.2 in development. # If the value is nil, we return nil straight away without checking # the regular expressions. If we check each regular expression, @@ -507,6 +507,13 @@ def extract_value_from_default(default) # :nodoc: # makes this method very very slow. return default unless default + # TODO: The default extraction is related to the cast-type. + # we should probably make a type_map lookup and cast the default- + # expression accordingly + if oid.type == :enum && default =~ /\A'(.*)'::/ + return $1 + end + case default when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m $1 diff --git a/activerecord/test/cases/adapters/postgresql/enum_test.rb b/activerecord/test/cases/adapters/postgresql/enum_test.rb index 4146b117f69a7dbf0c6218c3031b195c68344267..b809f1a79c041626c21a94ae84655f9d4fade974 100644 --- a/activerecord/test/cases/adapters/postgresql/enum_test.rb +++ b/activerecord/test/cases/adapters/postgresql/enum_test.rb @@ -39,6 +39,17 @@ def test_column assert_not column.array end + def test_enum_defaults + @connection.add_column 'postgresql_enums', 'good_mood', :mood, default: 'happy' + PostgresqlEnum.reset_column_information + column = PostgresqlEnum.columns_hash["good_mood"] + + assert_equal "happy", column.default + assert_equal "happy", PostgresqlEnum.new.good_mood + ensure + PostgresqlEnum.reset_column_information + end + def test_enum_mapping @connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');" enum = PostgresqlEnum.first