willbryant/constant_table_saver

Warnings and errors when testing with Rails 5.0.2

Closed this issue · 2 comments

When I add 5.0.2 to the tests' rails versions, I've got these following errors:

  • NoMethodError: undefined method 'substitute_at' for #ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x007fc495340358>. That's because of rails/rails@a557ab0
  • ArgumentError: wrong number of arguments (given 3, expected 1..2) /Users/vincentboucheny/Documents/constant_table_saver/lib/constant_table_saver.rb:53:in 'find_by_sql'. That's because ActiveRecord::StatementCache#execute calls find_by_sql with a new argument: preparable: true.

Thanks @mankalas.

The preparable flag arrived in this commit:

commit cbcdecd2c55fca9613722779231de2d8dd67ad02
Author: Sean Griffin sean@seantheprogrammer.com
Date: Tue Oct 20 14:08:15 2015 -0600

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.

commit 2a56b2d90d4fed8548e3a1e7a7b206454858c872
Author: Sean Griffin sean@seantheprogrammer.com
Date: Thu Feb 11 08:54:58 2016 -0700

Ensure prepared statement caching still occurs with Adequate Record

In Rails 5, we're much more restrictive about when we do or don't cache
a prepared statement. In particular, we never cache when we are sending
an IN statement or a SQL string literal

However, in the case of Adequate Record, we are *always* sending a raw
SQL string, and we *always* want to cache the result.

Fixes #23507

/cc @tgxworld

commit 3f6574efb1757e2eeebb7b960055a07aea93d144
Author: Ryuta Kamizono kamipo@gmail.com
Date: Wed Feb 17 23:18:07 2016 +0900

Add prepared statements support for `Mysql2Adapter`

48db44d implement rails 5.0 support