diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-02-25 23:40:20 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-02-26 00:30:26 +0900 |
commit | 66b4ddd3353e14b27214e156c949ba41e2ce5ba4 (patch) | |
tree | 10034e7ef5dc6b698689f84ce8f65f91dfcc0f5f /activerecord/lib | |
parent | f4bef91a312954535c37f727c1bdbffaed64c2c1 (diff) | |
download | rails-66b4ddd3353e14b27214e156c949ba41e2ce5ba4.tar.gz rails-66b4ddd3353e14b27214e156c949ba41e2ce5ba4.tar.bz2 rails-66b4ddd3353e14b27214e156c949ba41e2ce5ba4.zip |
Fix prepared statements caching to be enabled even when query caching is enabled
Related cbcdecd, 2a56b2d.
This is a regression caused by cbcdecd.
If query caching is enabled, prepared statement handles are never
re-used, since we missed that a query is preprocessed when query caching
is enabled, but doesn't keep the `preparable` flag.
We should care about that case.
Diffstat (limited to 'activerecord/lib')
3 files changed, 20 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index aa2ecee74a..b5e6d03cf5 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -20,9 +20,22 @@ module ActiveRecord raise "Passing bind parameters with an arel AST is forbidden. " \ "The values must be stored on the AST directly" end - sql, binds = visitor.compile(arel_or_sql_string.ast, collector) - [sql.freeze, binds || []] + + if prepared_statements + sql, binds = visitor.compile(arel_or_sql_string.ast, collector) + + if binds.length > bind_params_length + unprepared_statement do + sql, binds = to_sql_and_binds(arel_or_sql_string) + visitor.preparable = false + end + end + else + sql = visitor.compile(arel_or_sql_string.ast, collector) + end + [sql.freeze, binds] else + visitor.preparable = false if prepared_statements [arel_or_sql_string.dup.freeze, binds] end end @@ -47,13 +60,8 @@ module ActiveRecord arel = arel_from_relation(arel) sql, binds = to_sql_and_binds(arel, binds) - if !prepared_statements || (arel.is_a?(String) && preparable.nil?) - preparable = false - elsif binds.length > bind_params_length - sql, binds = unprepared_statement { to_sql_and_binds(arel) } - preparable = false - else - preparable = visitor.preparable + if preparable.nil? + preparable = prepared_statements ? visitor.preparable : false end if prepared_statements && preparable diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index d950099bab..93b1c4e632 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -97,9 +97,8 @@ module ActiveRecord arel = arel_from_relation(arel) sql, binds = to_sql_and_binds(arel, binds) - if binds.length > bind_params_length - sql, binds = unprepared_statement { to_sql_and_binds(arel) } - preparable = false + if preparable.nil? + preparable = prepared_statements ? visitor.preparable : false end cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) } diff --git a/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb b/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb index 883747b84b..1df4dea2d8 100644 --- a/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +++ b/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb @@ -3,7 +3,7 @@ module ActiveRecord module ConnectionAdapters module DetermineIfPreparableVisitor - attr_reader :preparable + attr_accessor :preparable def accept(*) @preparable = true |