mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
PostgreSQL, Fix OID based type casts in C for primitive types.
The type map was introduced in aafee23
, but wasn't properly filled.
This mainly adjusts many locations, that expected strings instead of
integers or boolean.
add_pg_decoders is moved after setup of the StatementPool, because
execute_and_clear could potentially make use of it.
This commit is contained in:
parent
348377da4d
commit
1d8d5a74b8
8 changed files with 24 additions and 24 deletions
|
@ -19,7 +19,7 @@ module ActiveRecord
|
|||
enums, nodes = nodes.partition { |row| row['typtype'] == 'e' }
|
||||
domains, nodes = nodes.partition { |row| row['typtype'] == 'd' }
|
||||
arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }
|
||||
composites, nodes = nodes.partition { |row| row['typelem'] != '0' }
|
||||
composites, nodes = nodes.partition { |row| row['typelem'].to_i != 0 }
|
||||
|
||||
mapped.each { |row| register_mapped_type(row) }
|
||||
enums.each { |row| register_enum_type(row) }
|
||||
|
|
|
@ -129,8 +129,8 @@ module ActiveRecord
|
|||
|
||||
result.map do |row|
|
||||
index_name = row[0]
|
||||
unique = row[1] == 't'
|
||||
indkey = row[2].split(" ")
|
||||
unique = row[1]
|
||||
indkey = row[2].split(" ").map(&:to_i)
|
||||
inddef = row[3]
|
||||
oid = row[4]
|
||||
|
||||
|
@ -164,7 +164,7 @@ module ActiveRecord
|
|||
type_metadata = fetch_type_metadata(column_name, type, oid, fmod)
|
||||
default_value = extract_value_from_default(default)
|
||||
default_function = extract_default_function(default_value, default)
|
||||
new_column(column_name, default_value, type_metadata, notnull == 'f', default_function)
|
||||
new_column(column_name, default_value, type_metadata, !notnull, default_function)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -278,8 +278,6 @@ module ActiveRecord
|
|||
@table_alias_length = nil
|
||||
|
||||
connect
|
||||
add_pg_decoders
|
||||
|
||||
@statements = StatementPool.new @connection,
|
||||
self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })
|
||||
|
||||
|
@ -287,6 +285,8 @@ module ActiveRecord
|
|||
raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!"
|
||||
end
|
||||
|
||||
add_pg_decoders
|
||||
|
||||
@type_map = Type::HashLookupTypeMap.new
|
||||
initialize_type_map(type_map)
|
||||
@local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
|
||||
|
@ -798,7 +798,7 @@ module ActiveRecord
|
|||
)
|
||||
end_sql
|
||||
execute_and_clear(sql, "SCHEMA", []) do |result|
|
||||
result.getvalue(0, 0) == 't'
|
||||
result.getvalue(0, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -814,12 +814,12 @@ module ActiveRecord
|
|||
'bool' => PG::TextDecoder::Boolean,
|
||||
}
|
||||
query = <<-SQL
|
||||
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
||||
SELECT t.oid, t.typname
|
||||
FROM pg_type as t
|
||||
SQL
|
||||
coders = execute_and_clear(query, "SCHEMA", []) do |result|
|
||||
result
|
||||
.map { |row| construct_coder(row, coders_by_name['typname']) }
|
||||
.map { |row| construct_coder(row, coders_by_name[row['typname']]) }
|
||||
.compact
|
||||
end
|
||||
|
||||
|
@ -830,7 +830,7 @@ module ActiveRecord
|
|||
|
||||
def construct_coder(row, coder_class)
|
||||
return unless coder_class
|
||||
coder_class.new(oid: row['oid'], name: row['typname'])
|
||||
coder_class.new(oid: row['oid'].to_i, name: row['typname'])
|
||||
end
|
||||
|
||||
ActiveRecord::Type.add_modifier({ array: true }, OID::Array, adapter: :postgresql)
|
||||
|
|
|
@ -31,7 +31,7 @@ class PostgresqlNumberTest < ActiveRecord::TestCase
|
|||
assert_equal 123456.789, first.double
|
||||
assert_equal(-::Float::INFINITY, second.single)
|
||||
assert_equal ::Float::INFINITY, second.double
|
||||
assert_same ::Float::NAN, third.double
|
||||
assert_send [third.double, :nan?]
|
||||
end
|
||||
|
||||
def test_update
|
||||
|
|
|
@ -68,7 +68,7 @@ module ActiveRecord
|
|||
def test_insert_sql_with_proprietary_returning_clause
|
||||
with_example_table do
|
||||
id = @connection.insert_sql("insert into ex (number) values(5150)", nil, "number")
|
||||
assert_equal "5150", id
|
||||
assert_equal 5150, id
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -106,21 +106,21 @@ module ActiveRecord
|
|||
connection = connection_without_insert_returning
|
||||
id = connection.insert_sql("insert into postgresql_partitioned_table_parent (number) VALUES (1)")
|
||||
expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
|
||||
assert_equal expect, id
|
||||
assert_equal expect.to_i, id
|
||||
end
|
||||
|
||||
def test_exec_insert_with_returning_disabled
|
||||
connection = connection_without_insert_returning
|
||||
result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id', 'postgresql_partitioned_table_parent_id_seq')
|
||||
expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
|
||||
assert_equal expect, result.rows.first.first
|
||||
assert_equal expect.to_i, result.rows.first.first
|
||||
end
|
||||
|
||||
def test_exec_insert_with_returning_disabled_and_no_sequence_name_given
|
||||
connection = connection_without_insert_returning
|
||||
result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id')
|
||||
expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
|
||||
assert_equal expect, result.rows.first.first
|
||||
assert_equal expect.to_i, result.rows.first.first
|
||||
end
|
||||
|
||||
def test_sql_for_insert_with_returning_disabled
|
||||
|
@ -238,7 +238,7 @@ module ActiveRecord
|
|||
result = @connection.exec_query('SELECT number FROM ex WHERE number = 10')
|
||||
|
||||
assert_equal 1, result.rows.length
|
||||
assert_equal "10", result.rows.last.last
|
||||
assert_equal 10, result.rows.last.last
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -274,7 +274,7 @@ module ActiveRecord
|
|||
assert_equal 1, result.rows.length
|
||||
assert_equal 2, result.columns.length
|
||||
|
||||
assert_equal [['1', 'foo']], result.rows
|
||||
assert_equal [[1, 'foo']], result.rows
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -288,7 +288,7 @@ module ActiveRecord
|
|||
assert_equal 1, result.rows.length
|
||||
assert_equal 2, result.columns.length
|
||||
|
||||
assert_equal [['1', 'foo']], result.rows
|
||||
assert_equal [[1, 'foo']], result.rows
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -304,7 +304,7 @@ module ActiveRecord
|
|||
assert_equal 1, result.rows.length
|
||||
assert_equal 2, result.columns.length
|
||||
|
||||
assert_equal [['1', 'foo']], result.rows
|
||||
assert_equal [[1, 'foo']], result.rows
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -106,6 +106,6 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase
|
|||
private
|
||||
|
||||
def assert_transaction_is_not_broken
|
||||
assert_equal "1", @connection.select_value("SELECT 1")
|
||||
assert_equal 1, @connection.select_value("SELECT 1")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -384,16 +384,16 @@ class SchemaTest < ActiveRecord::TestCase
|
|||
def test_reset_pk_sequence
|
||||
sequence_name = "#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}"
|
||||
@connection.execute "SELECT setval('#{sequence_name}', 123)"
|
||||
assert_equal "124", @connection.select_value("SELECT nextval('#{sequence_name}')")
|
||||
assert_equal 124, @connection.select_value("SELECT nextval('#{sequence_name}')")
|
||||
@connection.reset_pk_sequence!("#{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME}")
|
||||
assert_equal "1", @connection.select_value("SELECT nextval('#{sequence_name}')")
|
||||
assert_equal 1, @connection.select_value("SELECT nextval('#{sequence_name}')")
|
||||
end
|
||||
|
||||
def test_set_pk_sequence
|
||||
table_name = "#{SCHEMA_NAME}.#{PK_TABLE_NAME}"
|
||||
_, sequence_name = @connection.pk_and_sequence_for table_name
|
||||
@connection.set_pk_sequence! table_name, 123
|
||||
assert_equal "124", @connection.select_value("SELECT nextval('#{sequence_name}')")
|
||||
assert_equal 124, @connection.select_value("SELECT nextval('#{sequence_name}')")
|
||||
@connection.reset_pk_sequence! table_name
|
||||
end
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ class QueryCacheTest < ActiveRecord::TestCase
|
|||
# Oracle adapter returns count() as Fixnum or Float
|
||||
if current_adapter?(:OracleAdapter)
|
||||
assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
|
||||
elsif current_adapter?(:SQLite3Adapter, :Mysql2Adapter)
|
||||
elsif current_adapter?(:SQLite3Adapter, :Mysql2Adapter, :PostgreSQLAdapter)
|
||||
# Future versions of the sqlite3 adapter will return numeric
|
||||
assert_instance_of Fixnum,
|
||||
Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
|
||||
|
|
Loading…
Reference in a new issue