Permalink
Browse files

Merge pull request #13244 from kommen/pg_enum_type_map

Add Enum type to postgresql adapter's oids to prevent unknown OID warnings
  • Loading branch information...
2 parents 7231a13 + 5c55aaf commit 9ada39f62edad92ef1e754f93b71e452397f53b8 @senny senny committed Mar 4, 2014
@@ -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.
@@ -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
@@ -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']]
@@ -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 9ada39f

Please sign in to comment.