• S
    Do not cache prepared statements that are unlikely to have cache hits · cbcdecd2
    Sean Griffin 提交于
    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.
    cbcdecd2
sqlite3_adapter.rb 19.9 KB