Fix `unprepared_statement` to work it when nesting

I've been reported a problem by @osyo-manga, preloading queries in
`unprepared_statement` doesn't work as expected in main branch (queries
are executed as prepared statements).

It is caused by #41385, due to `scope.to_sql` in `grouping_key` depends
on `unprepared_statement` which has an issue when nesting.

To fix the issue, don't add/delete object_id in the prepared statements
disabled cache if that is already disabled.
This commit is contained in:
Ryuta Kamizono 2021-02-12 22:25:35 +09:00
parent a82df4c5e0
commit da26910fbc
2 changed files with 19 additions and 2 deletions

View File

@ -160,9 +160,10 @@ module ActiveRecord
end
end
def prepared_statements
def prepared_statements?
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
end
alias :prepared_statements :prepared_statements?
def prepared_statements_disabled_cache # :nodoc:
Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
@ -256,7 +257,7 @@ module ActiveRecord
end
def unprepared_statement
cache = prepared_statements_disabled_cache.add(object_id) if @prepared_statements
cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
yield
ensure
cache&.delete(object_id)

View File

@ -173,6 +173,22 @@ if ActiveRecord::Base.connection.prepared_statements
end
end
def test_nested_unprepared_statements
assert_predicate @connection, :prepared_statements?
@connection.unprepared_statement do
assert_not_predicate @connection, :prepared_statements?
@connection.unprepared_statement do
assert_not_predicate @connection, :prepared_statements?
end
assert_not_predicate @connection, :prepared_statements?
end
assert_predicate @connection, :prepared_statements?
end
private
def assert_bind_params_to_sql
table = Author.quoted_table_name