diff options
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index adeb57d913..dd3bfa5546 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -565,7 +565,8 @@ module ActiveRecord raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!" end - initialize_type_map + @type_map = OID::TypeMap.new + initialize_type_map(type_map) @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"] @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true end @@ -738,39 +739,56 @@ module ActiveRecord private + def type_map + @type_map + end + def reload_type_map - OID::TYPE_MAP.clear - initialize_type_map + type_map.clear + initialize_type_map(type_map) end - def initialize_type_map + def add_oid(row, records_by_oid, type_map) + return type_map if type_map.key? row['type_elem'].to_i + + if OID.registered_type? row['typname'] + # this composite type is explicitly registered + vector = OID::NAMES[row['typname']] + else + # use the default for composite types + unless type_map.key? row['typelem'].to_i + add_oid records_by_oid[row['typelem']], records_by_oid, type_map + end + + vector = OID::Vector.new row['typdelim'], type_map[row['typelem'].to_i] + end + + type_map[row['oid'].to_i] = vector + type_map + end + + def initialize_type_map(type_map) result = execute('SELECT oid, typname, typelem, typdelim, typinput FROM pg_type', 'SCHEMA') leaves, nodes = result.partition { |row| row['typelem'] == '0' } # populate the leaf nodes leaves.find_all { |row| OID.registered_type? row['typname'] }.each do |row| - OID::TYPE_MAP[row['oid'].to_i] = OID::NAMES[row['typname']] + type_map[row['oid'].to_i] = OID::NAMES[row['typname']] end + records_by_oid = result.group_by { |row| row['oid'] } + arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' } # populate composite types - nodes.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row| - if OID.registered_type? row['typname'] - # this composite type is explicitly registered - vector = OID::NAMES[row['typname']] - else - # use the default for composite types - vector = OID::Vector.new row['typdelim'], OID::TYPE_MAP[row['typelem'].to_i] - end - - OID::TYPE_MAP[row['oid'].to_i] = vector + nodes.each do |row| + add_oid row, records_by_oid, type_map end # populate array types - arrays.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row| - array = OID::Array.new OID::TYPE_MAP[row['typelem'].to_i] - OID::TYPE_MAP[row['oid'].to_i] = array + arrays.find_all { |row| type_map.key? row['typelem'].to_i }.each do |row| + array = OID::Array.new type_map[row['typelem'].to_i] + type_map[row['oid'].to_i] = array end end @@ -951,12 +969,12 @@ module ActiveRecord end def extract_table_ref_from_insert_sql(sql) - sql[/into\s+([^\(]*).*values\s*\(/i] + sql[/into\s+([^\(]*).*values\s*\(/im] $1.strip if $1 end - def create_table_definition(name, temporary, options) - TableDefinition.new native_database_types, name, temporary, options + def create_table_definition(name, temporary, options, as = nil) + TableDefinition.new native_database_types, name, temporary, options, as end def update_table_definition(table_name, base) |