Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add Enum type to postgresql adapter's oids to prevent unknown OID war…

…nings.
  • Loading branch information...
commit 5c55aafd38f45ac019573f98438ffdbdc8c580f9 1 parent ffcc617
@kommen kommen authored
View
5 activerecord/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Dynamically register PostgreSQL enum OIDs. This prevents "unknown OID"
+ warnings on enum columns.
+
+ *Dieter Komendera*
+
* `includes` is able to detect the right preloading strategy when string
joins are involved.
View
6 activerecord/lib/active_record/connection_adapters/postgresql/oid.rb
@@ -229,6 +229,12 @@ def infinity(options = {})
end
end
+ class Enum < Type
+ def type_cast(value)
+ value.to_s
+ end
+ end
+
class Hstore < Type
def type_cast_for_write(value)
ConnectionAdapters::PostgreSQLColumn.hstore_to_string value
View
6 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -801,6 +801,12 @@ def initialize_type_map(type_map)
leaves, nodes = nodes.partition { |row| row['typelem'] == '0' }
arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }
+ # populate the enum types
+ enums, leaves = leaves.partition { |row| row['typinput'] == 'enum_in' }
+ enums.each do |row|
+ type_map[row['oid'].to_i] = OID::Enum.new
+ end
+
# populate the base types
leaves.find_all { |row| OID.registered_type? row['typname'] }.each do |row|
type_map[row['oid'].to_i] = OID::NAMES[row['typname']]
View
28 activerecord/test/cases/adapters/postgresql/enum_test.rb
@@ -23,6 +23,8 @@ def setup
t.column :current_mood, :mood
end
end
+ # reload type map after creating the enum type
+ @connection.send(:reload_type_map)
end
def test_enum_mapping
@@ -35,4 +37,30 @@ def test_enum_mapping
assert_equal "happy", enum.reload.current_mood
end
+
+ def test_invalid_enum_update
+ @connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
+ enum = PostgresqlEnum.first
+ enum.current_mood = "angry"
+
+ assert_raise ActiveRecord::StatementInvalid do
+ enum.save
+ end
+ end
+
+ def test_no_oid_warning
+ @connection.execute "INSERT INTO postgresql_enums VALUES (1, 'sad');"
+ stderr_output = capture(:stderr) {
+ enum = PostgresqlEnum.first
+ }
+
+ assert stderr_output.blank?
+ end
+
+ def test_enum_type_cast
+ enum = PostgresqlEnum.new
+ enum.current_mood = :happy
+
+ assert_equal "happy", enum.current_mood
+ end
end

0 comments on commit 5c55aaf

Please sign in to comment.
Something went wrong with that request. Please try again.