mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Prepared statements shouldn't share a cache with unprepared statements
When prepared statements are enabled, the statement cache caches the SQL directly, including the bind parameters. If a similar query is run later with prepared statements disabled, we need to use a separate cache instead of trying to share the same one. Fixes #24351
This commit is contained in:
parent
7b82e1c77b
commit
3af40b71f3
2 changed files with 16 additions and 3 deletions
|
@ -136,7 +136,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def initialize_find_by_cache # :nodoc:
|
||||
@find_by_statement_cache = {}.extend(Mutex_m)
|
||||
@find_by_statement_cache = { true => {}.extend(Mutex_m), false => {}.extend(Mutex_m) }
|
||||
end
|
||||
|
||||
def inherited(child_class) # :nodoc:
|
||||
|
@ -280,8 +280,9 @@ module ActiveRecord
|
|||
private
|
||||
|
||||
def cached_find_by_statement(key, &block) # :nodoc:
|
||||
@find_by_statement_cache[key] || @find_by_statement_cache.synchronize {
|
||||
@find_by_statement_cache[key] ||= StatementCache.create(connection, &block)
|
||||
cache = @find_by_statement_cache[connection.prepared_statements]
|
||||
cache[key] || cache.synchronize {
|
||||
cache[key] ||= StatementCache.create(connection, &block)
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -94,5 +94,17 @@ module ActiveRecord
|
|||
additional_books = cache.execute([], Book, Book.connection)
|
||||
assert first_books != additional_books
|
||||
end
|
||||
|
||||
def test_unprepared_statements_dont_share_a_cache_with_prepared_statements
|
||||
Book.create(name: "my book")
|
||||
Book.create(name: "my other book")
|
||||
|
||||
book = Book.find_by(name: "my book")
|
||||
other_book = Book.connection.unprepared_statement do
|
||||
Book.find_by(name: "my other book")
|
||||
end
|
||||
|
||||
refute_equal book, other_book
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue