diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2017-07-24 12:28:26 -0400 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2017-07-24 12:28:26 -0400 |
commit | 846832ae54f93a480f37a14a10874767a6330086 (patch) | |
tree | 854264ccdab978f82d27d53a6910f0d53b7836fb /activerecord/lib/active_record | |
parent | a69842447739d2f22657e347bad3b23c64b0c6b8 (diff) | |
download | rails-846832ae54f93a480f37a14a10874767a6330086.tar.gz rails-846832ae54f93a480f37a14a10874767a6330086.tar.bz2 rails-846832ae54f93a480f37a14a10874767a6330086.zip |
Fix test failures when prepared statements are disabled
This also reverts the change to enable prepared statements by default on
MySQL (though I suspect we could enable them and it'd be great). This
change brings back a collector closer to the old `Bind` collector in
Arel. However, this one lives in AR, since this is an AR specific need.
Additionally, we only use it for statement caching, since the new
substitute collector in Arel is higher performance for most cases.
Diffstat (limited to 'activerecord/lib/active_record')
3 files changed, 35 insertions, 14 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 f687d3a7e8..00e54edac0 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -29,8 +29,9 @@ module ActiveRecord sql, binds = visitor.accept(arel.ast, collector).value query = klass.query(sql) else - query = klass.partial_query(arel.ast) - binds = [] + collector = PartialQueryCollector.new + parts, binds = visitor.accept(arel.ast, collector).value + query = klass.partial_query(parts) end [query, binds] end @@ -457,6 +458,28 @@ module ActiveRecord value end end + + class PartialQueryCollector + def initialize + @parts = [] + @binds = [] + end + + def << str + @parts << str + self + end + + def add_bind obj + @binds << obj + @parts << Arel::Nodes::BindParam.new(1) + self + end + + def value + [@parts, @binds] + end + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb index b02368a514..2c2321872d 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -39,7 +39,7 @@ module ActiveRecord def initialize(connection, logger, connection_options, config) super - @prepared_statements = true unless config[:prepared_statements] == false + @prepared_statements = false unless config.key?(:prepared_statements) configure_connection end diff --git a/activerecord/lib/active_record/statement_cache.rb b/activerecord/lib/active_record/statement_cache.rb index db7e0c8a04..64657089b5 100644 --- a/activerecord/lib/active_record/statement_cache.rb +++ b/activerecord/lib/active_record/statement_cache.rb @@ -41,20 +41,18 @@ module ActiveRecord end class PartialQuery < Query # :nodoc: - def initialize(arel) - @arel = arel + def initialize(values) + @values = values + @indexes = values.each_with_index.find_all { |thing, i| + Arel::Nodes::BindParam === thing + }.map(&:last) end def sql_for(binds, connection) - val = @arel.dup - val.grep(Arel::Nodes::BindParam) do |node| - node.value = binds.shift - if binds.empty? - break - end - end - sql, _ = connection.visitor.accept(val, connection.send(:collector)).value - sql + val = @values.dup + casted_binds = binds.map(&:value_for_database) + @indexes.each { |i| val[i] = connection.quote(casted_binds.shift) } + val.join end end |