1
0
Fork 0
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:
Lars Kanis 2015-03-21 21:51:55 +01:00
parent 348377da4d
commit 1d8d5a74b8
8 changed files with 24 additions and 24 deletions

View file

@ -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) }

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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")