1. 27 1月, 2015 7 次提交
    • S
      765a3123
    • S
      Remove `Relation#build_where` · 76661dc6
      Sean Griffin 提交于
      All of its uses have been moved to better places
      76661dc6
    • S
      Go through normal `where` logic in `AssociationScope` · 6a7ac40d
      Sean Griffin 提交于
      This removes the need to duplicate much of the logic in `WhereClause`
      and `PredicateBuilder`, simplifies the code, removes the need for the
      connection adapter to be continuously passed around, and removes one
      place that cares about the internal representation of `bind_values`
      
      Part of the larger refactoring to change how binds are represented
      internally
      
      [Sean Griffin & anthonynavarre]
      6a7ac40d
    • S
      Ensure the type caster object given to Arel is always marshallable · 9d4d2e7f
      Sean Griffin 提交于
      The Relation will ultimately end up holding a reference to the arel
      table object, and its associated type caster. If this is a
      `TypeCaster::Connection`, that means it'll hold a reference to the
      connection adapter, which cannot be marshalled. We can work around this
      by just holding onto the class object instead. It's ugly, but I'm hoping
      to remove the need for the connection adapter type caster in the future
      anyway.
      
      [Sean Griffin & anthonynavarre]
      9d4d2e7f
    • S
      Change `having_values` to use the `WhereClause` class · 39f2c3b3
      Sean Griffin 提交于
      This fixed an issue where `having` can only be called after the last
      call to `where`, because it messes with the same `bind_values` array.
      With this change, the two can be called as many times as needed, in any
      order, and the final query will be correct. However, once something
      assigns `bind_values`, that stops. This is because we have to move all
      of the bind values from the having clause over to the where clause since
      we can't differentiate the two, and assignment was likely in the form
      of:
      
      `relation.bind_values += other.bind_values`
      
      This will go away once we remove all places that are assigning
      `bind_values`, which is next on the list.
      
      While this fixes a bug that was present in at least 4.2 (more likely
      present going back as far as 3.0, becoming more likely in 4.1 and later
      as we switched to prepared statements in more cases), I don't think this
      can be easily backported. The internal changes to `Relation` are
      non-trivial, anything that involves modifying the `bind_values` array
      would need to change, and I'm not confident that we have sufficient test
      coverage of all of those locations (when `having` was called with a hash
      that could generate bind values).
      
      [Sean Griffin & anthonynavarre]
      39f2c3b3
    • S
      Improve consistency of counter caches updating in memory · 1152219f
      Sean Griffin 提交于
      When we made sure that the counter gets updated in memory, we only did
      it on the has many side. The has many side only does the update if the
      belongs to cannot. The belongs to side was updated to update the counter
      cache (if it is able). This means that we need to check if the
      belongs_to is able to update in memory on the has_many side.
      
      We also found an inconsistency where the reflection names were used to
      grab the association which should update the counter cache. Since
      reflection names are now strings, this means it was using a different
      instance than the one which would have the inverse instance set.
      
      Fixes #18689
      
      [Sean Griffin & anthonynavarre]
      1152219f
    • S
      Move flattening records added to an association farther out · 025187d9
      Sean Griffin 提交于
      There are many ways that things end up getting passed to `concat`. Not
      all of those entry points called `flatten` on their input. It seems that
      just about every method that is meant to take a single record, or that
      splats its input, is meant to also take an array. `concat` is the
      earliest point that is common to all of the methods which add records to
      the association. Partially fixes #18689
      025187d9
  2. 26 1月, 2015 16 次提交
  3. 25 1月, 2015 5 次提交
    • R
      Fix a typo "devleopment" => "development" · cb18c07f
      Rémy Coutable 提交于
      [ci skip]
      cb18c07f
    • S
      Expand the number of types which can use prepared statements · 3327cd3f
      Sean Griffin 提交于
      This will allow all types which require no additional handling to use
      prepared statements. Specifically, this will allow for `true`, `false`,
      `Date`, `Time`, and any custom PG type to use prepared statements. This
      also revealed another source of nil columns in bind params, and an
      inconsistency in their use.
      
      The specific inconsistency comes from a nested query coming from a
      through association, where one of the inversed associations is not
      bi-directional.
      
      The stop-gap is to simply construct the column at the site it is being
      used. This should simply go away on its own once we use `Attribute` to
      represent them instead, since we already have all of the information we
      need.
      3327cd3f
    • S
      Don't mutate `where_values` · ae8cd56c
      Sean Griffin 提交于
      This is to help facilitate future refactorings, as the internal
      representation is changed. I'm planning on having `where_values` return
      an array that's computed on call, which means that mutation will have no
      affect. This is the only remaining place that was mutating (tested by
      replacing the method with calling `dup`)
      ae8cd56c
    • S
      Don't rely on relation mutability when building through associations · c80487eb
      Sean Griffin 提交于
      Specifically, the issue is relying on `where_unscoping` mutating the
      where values. It does not, however, mutate the bind values, which could
      cause an error under certain circumstances. This was not exposed by the
      tests, since the only place which would have been affected is unscoping
      a boolean, which doesn't go through prepared statements. I had a hard
      time getting better test coverage to demonstrate the issue.
      
      This in turn, caused `merge` to go through proper logic, and try to
      clear out the binds associated with the unscoped relation, which then
      exposed a source of `nil` for the columns, as binds weren't expanding
      `{ "posts.id" => 1 }` to `{ "posts" => { "id" => 1 } }`. This has been
      fixed.
      
      The bulk of `create_binds` needed to be moved to a separate method,
      since the dot notation should not be expanded recursively.
      
      I'm pretty sure this removes a subtle quirk that a ton of code in
      `Relation::Merger` is working around, and I suspect that code can be
      greatly simplified. However, unraveling that rats nest is no small task.
      c80487eb
    • S
      4c0a9922
  4. 24 1月, 2015 5 次提交
  5. 23 1月, 2015 1 次提交
  6. 22 1月, 2015 1 次提交
  7. 21 1月, 2015 3 次提交
    • S
      797f78d0
    • S
      Introduce `ActiveRecord::Base#accessed_fields` · be9b6803
      Sean Griffin 提交于
      This method can be used to see all of the fields on a model which have
      been read. This can be useful during development mode to quickly find
      out which fields need to be selected. For performance critical pages, if
      you are not using all of the fields of a database, an easy performance
      win is only selecting the fields which you need. By calling this method
      at the end of a controller action, it's easy to determine which fields
      need to be selected.
      
      While writing this, I also noticed a place for an easy performance win
      internally which I had been wanting to introduce. You cannot mutate a
      field which you have not read. Therefore, we can skip the calculation of
      in place changes if we have never read from the field. This can
      significantly speed up methods like `#changed?` if any of the fields
      have an expensive mutable type (like `serialize`)
      
      ```
      Calculating -------------------------------------
       #changed? with serialized column (before)
                             391.000  i/100ms
       #changed? with serialized column (after)
                               1.514k i/100ms
      -------------------------------------------------
       #changed? with serialized column (before)
                                4.243k (± 3.7%) i/s -     21.505k
       #changed? with serialized column (after)
                               16.789k (± 3.2%) i/s -     84.784k
      ```
      be9b6803
    • A
      TransactionManager should call rollback records · 2e85224f
      Arthur Neves 提交于
      2e85224f
  8. 20 1月, 2015 2 次提交
    • S
      Fix bind value copying from subqueried relations · 04d1c371
      Sean Griffin 提交于
      With the old implementation, the bind values were created, and then we
      search the attributes for `Relation` objects, and merge them. This
      completely ignores the order that the actual `where` clause will use. If
      all non-relation where parameters are before the relations, it will
      work. However, if we query on both a relation and a value, with the
      value coming second, it breaks. The order of the hash should not affect
      the final query (especially since hashes being ordered is an
      implementation detail)
      04d1c371
    • S
      Move `create_binds` over to the `PredicateBuilder` · 50a8cdf0
      Sean Griffin 提交于
      I'm looking to introduce a `WhereClause` class to handle most of this
      logic, and this method will eventually move over to there. However, this
      intermediate refactoring should make that easier to do.
      50a8cdf0