提交 8d7554e9 编写于 作者: R Ryuta Kamizono

Fix tests failure with `prepared_statements: false`

Some tests does not work for unprepared statements.
Add `if ActiveRecord::Base.connection.prepared_statements` and fix a
regex for fix tests failure with `prepared_statements: false`.
上级 e4ad3b26
......@@ -11,7 +11,8 @@ def setup
##
# PostgreSQL does not support null bytes in strings
unless current_adapter?(:PostgreSQLAdapter)
unless current_adapter?(:PostgreSQLAdapter) ||
(current_adapter?(:SQLite3Adapter) && !ActiveRecord::Base.connection.prepared_statements)
def test_update_prepared_statement
b = Book.create(name: "my \x00 book")
b.reload
......
......@@ -57,9 +57,11 @@ def test_schema_dumping
assert_match %r{t\.bit_varying\s+"a_bit_varying",\s+limit: 4,\s+default: "0011"$}, output
end
def test_assigning_invalid_hex_string_raises_exception
assert_raises(ActiveRecord::StatementInvalid) { PostgresqlBitString.create! a_bit: "FF" }
assert_raises(ActiveRecord::StatementInvalid) { PostgresqlBitString.create! a_bit_varying: "FF" }
if ActiveRecord::Base.connection.prepared_statements
def test_assigning_invalid_hex_string_raises_exception
assert_raises(ActiveRecord::StatementInvalid) { PostgresqlBitString.create! a_bit: "FF" }
assert_raises(ActiveRecord::StatementInvalid) { PostgresqlBitString.create! a_bit_varying: "F" }
end
end
def test_roundtrip
......
......@@ -125,14 +125,16 @@ def test_schema_names_logs_name
assert_equal 'SCHEMA', @subscriber.logged[0][1]
end
def test_statement_key_is_logged
bind = Relation::QueryAttribute.new(nil, 1, Type::Value.new)
@connection.exec_query('SELECT $1::integer', 'SQL', [bind], prepare: true)
name = @subscriber.payloads.last[:statement_name]
assert name
res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)")
plan = res.column_types['QUERY PLAN'].deserialize res.rows.first.first
assert_operator plan.length, :>, 0
if ActiveRecord::Base.connection.prepared_statements
def test_statement_key_is_logged
bind = Relation::QueryAttribute.new(nil, 1, Type::Value.new)
@connection.exec_query('SELECT $1::integer', 'SQL', [bind], prepare: true)
name = @subscriber.payloads.last[:statement_name]
assert name
res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)")
plan = res.column_types['QUERY PLAN'].deserialize res.rows.first.first
assert_operator plan.length, :>, 0
end
end
# Must have PostgreSQL >= 9.2, or with_manual_interventions set to
......
......@@ -7,14 +7,14 @@ class PostgreSQLExplainTest < ActiveRecord::PostgreSQLTestCase
def test_explain_for_one_query
explain = Developer.where(:id => 1).explain
assert_match %(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = $1), explain
assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = \$?1), explain
assert_match %(QUERY PLAN), explain
end
def test_explain_with_eager_loading
explain = Developer.where(:id => 1).includes(:audit_logs).explain
assert_match %(QUERY PLAN), explain
assert_match %(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = $1), explain
assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = \$?1), explain
assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" = 1), explain
end
end
......@@ -5,6 +5,7 @@
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapterTest < ActiveRecord::PostgreSQLTestCase
self.use_transactional_tests = false
include DdlHelper
include ConnectionHelper
......@@ -239,30 +240,6 @@ def test_pk_and_sequence_for_with_collision_pg_class_oid
@connection.drop_table 'ex2', if_exists: true
end
def test_exec_insert_number
with_example_table do
insert(@connection, 'number' => 10)
result = @connection.exec_query('SELECT number FROM ex WHERE number = 10')
assert_equal 1, result.rows.length
assert_equal 10, result.rows.last.last
end
end
def test_exec_insert_string
with_example_table do
str = 'いただきます!'
insert(@connection, 'number' => 10, 'data' => str)
result = @connection.exec_query('SELECT number, data FROM ex WHERE number = 10')
value = result.rows.last.last
assert_equal str, value
end
end
def test_table_alias_length
assert_nothing_raised do
@connection.table_alias_length
......@@ -286,33 +263,35 @@ def test_exec_no_binds
end
end
def test_exec_with_binds
with_example_table do
string = @connection.quote('foo')
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [bind_param(1)])
if ActiveRecord::Base.connection.prepared_statements
def test_exec_with_binds
with_example_table do
string = @connection.quote('foo')
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
bind = Relation::QueryAttribute.new("id", 1, Type::Value.new)
result = @connection.exec_query('SELECT id, data FROM ex WHERE id = $1', nil, [bind])
assert_equal [[1, 'foo']], result.rows
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
assert_equal [[1, 'foo']], result.rows
end
end
end
def test_exec_typecasts_bind_vals
with_example_table do
string = @connection.quote('foo')
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
def test_exec_typecasts_bind_vals
with_example_table do
string = @connection.quote('foo')
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
bind = ActiveRecord::Relation::QueryAttribute.new("id", "1-fuu", ActiveRecord::Type::Integer.new)
result = @connection.exec_query(
'SELECT id, data FROM ex WHERE id = $1', nil, [bind])
bind = Relation::QueryAttribute.new("id", "1-fuu", Type::Integer.new)
result = @connection.exec_query('SELECT id, data FROM ex WHERE id = $1', nil, [bind])
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
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
end
......@@ -438,19 +417,6 @@ def test_unparsed_defaults_are_at_least_set_when_saving
end
private
def insert(ctx, data)
binds = data.map { |name, value|
bind_param(value, name)
}
columns = binds.map(&:name)
bind_subs = columns.length.times.map { |x| "$#{x + 1}" }
sql = "INSERT INTO ex (#{columns.join(", ")})
VALUES (#{bind_subs.join(', ')})"
ctx.exec_insert(sql, 'SQL', binds)
end
def with_example_table(definition = 'id serial primary key, number integer, data character varying(255)', &block)
super(@connection, 'ex', definition, &block)
......@@ -459,10 +425,6 @@ def with_example_table(definition = 'id serial primary key, number integer, data
def connection_without_insert_returning
ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false))
end
def bind_param(value, name = nil)
ActiveRecord::Relation::QueryAttribute.new(name, value, ActiveRecord::Type::Value.new)
end
end
end
end
......@@ -55,20 +55,22 @@ def test_setting_auth_clears_stmt_cache
set_session_auth
USERS.each do |u|
set_session_auth u
assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [bind_param(1)]).first['name']
assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
set_session_auth
end
end
end
def test_auth_with_bind
assert_nothing_raised do
set_session_auth
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
assert_equal u, @connection.exec_query("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [bind_param(1)]).first['name']
if ActiveRecord::Base.connection.prepared_statements
def test_auth_with_bind
assert_nothing_raised do
set_session_auth
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", 'SQL', [bind_param(1)])
set_session_auth
end
end
end
end
......
......@@ -172,16 +172,18 @@ def test_raise_wrapped_exception_on_bad_prepare
end
end
def test_schema_change_with_prepared_stmt
altered = false
@connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
@connection.exec_query "alter table developers add column zomg int", 'sql', []
altered = true
@connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
ensure
# We are not using DROP COLUMN IF EXISTS because that syntax is only
# supported by pg 9.X
@connection.exec_query("alter table developers drop column zomg", 'sql', []) if altered
if ActiveRecord::Base.connection.prepared_statements
def test_schema_change_with_prepared_stmt
altered = false
@connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
@connection.exec_query "alter table developers add column zomg int", 'sql', []
altered = true
@connection.exec_query "select * from developers where id = $1", 'sql', [bind_param(1)]
ensure
# We are not using DROP COLUMN IF EXISTS because that syntax is only
# supported by pg 9.X
@connection.exec_query("alter table developers drop column zomg", 'sql', []) if altered
end
end
def test_data_source_exists?
......
......@@ -10,13 +10,13 @@ class ExplainTest < ActiveRecord::SQLite3TestCase
def test_explain_for_one_query
explain = Developer.where(:id => 1).explain
assert_match %(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = ?), explain
assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\?|1)), explain
assert_match(/(SEARCH )?TABLE developers USING (INTEGER )?PRIMARY KEY/, explain)
end
def test_explain_with_eager_loading
explain = Developer.where(:id => 1).includes(:audit_logs).explain
assert_match %(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = ?), explain
assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\?|1)), explain
assert_match(/(SEARCH )?TABLE developers USING (INTEGER )?PRIMARY KEY/, explain)
assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" = 1), explain
assert_match(/(SCAN )?TABLE audit_logs/, explain)
......
......@@ -31,7 +31,8 @@ def setup
ActiveSupport::Notifications.unsubscribe(@subscription)
end
if ActiveRecord::Base.connection.supports_statement_cache?
if ActiveRecord::Base.connection.supports_statement_cache? &&
ActiveRecord::Base.connection.prepared_statements
def test_bind_from_join_in_subquery
subquery = Author.joins(:thinking_posts).where(name: 'David')
scope = Author.from(subquery, 'authors').where(id: 1)
......
......@@ -441,7 +441,7 @@ def test_with_lock_rolls_back_transaction
def test_lock_sending_custom_lock_statement
Person.transaction do
person = Person.find(1)
assert_sql(/LIMIT \$\d FOR SHARE NOWAIT/) do
assert_sql(/LIMIT \$?\d FOR SHARE NOWAIT/) do
person.lock!('FOR SHARE NOWAIT')
end
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册