diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2015-10-20 14:08:15 -0600 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2015-10-20 14:16:22 -0600 |
commit | cbcdecd2c55fca9613722779231de2d8dd67ad02 (patch) | |
tree | 2a7c03913b2206816a09c00994812271db8f14cc /activesupport/test/deprecation_test.rb | |
parent | 72fba7db413561cf293178d5df0708c9380356fb (diff) | |
download | rails-cbcdecd2c55fca9613722779231de2d8dd67ad02.tar.gz rails-cbcdecd2c55fca9613722779231de2d8dd67ad02.tar.bz2 rails-cbcdecd2c55fca9613722779231de2d8dd67ad02.zip |
Do not cache prepared statements that are unlikely to have cache hits
Prior to this commit, Rails makes no differentiation between whether a
query uses bind parameters, and whether or not we cache that query as a
prepared statement. This leads to the cache populating extremely fast in
some cases, with the statements never being reused.
In particular, the two problematic cases are `where(foo: [1, 2, 3])` and
`where("foo = ?", 1)`. In both cases we'll end up quoting the values
rather than using a bind param, causing a cache entry for every value
ever used in that query.
It was noted that we can probably eventually change `where("foo = ?",
1)` to use a bind param, which would resolve that case. Additionally, on
PG we can change our generated query to be `WHERE foo = ANY($1)`, and
pass an array for the bind param. I hope to accomplish both in the
future.
For SQLite and MySQL, we still end up preparing the statements anyway,
we just don't cache it. The statement will be cleaned up after it is
executed. On postgres, we skip the prepare step entirely, as an API is
provided to execute with bind params without preparing the statement.
I'm not 100% happy on the way this ended up being structured. I was
hoping to use a decorator on the visitor, rather than mixing a module
into the object, but the way Arel has it's visitor pattern set up makes
it very difficult to extend without inheritance. I'd like to remove the
duplication from the various places that are extending it, but that'll
require a larger restructuring of that initialization logic. I'm going
to take another look at the structure of it soon.
This changes the signature of one of the adapter's internals, and will
require downstream changes from third party adapters. I'm not too
worried about this, as worst case they can simply add the parameter and
always ignore it, and just keep their previous behavior.
Fixes #21992.
Diffstat (limited to 'activesupport/test/deprecation_test.rb')
0 files changed, 0 insertions, 0 deletions