| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
| |
`bound_attributes` is now used universally across the board, removing
the need for the conversion layer. These changes are mostly mechanical,
with the exception of the log subscriber. Additional, we had to
implement `hash` on the attribute objects, so they could be used as a
key for query caching.
|
|\
| |
| | |
[ci skip] fix typo still -> will
|
| | |
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The column is primarily used for type casting, which we're trying to
separate from the idea of a column. Since what we really need is the
combination of a name, type, and value, let's use the object that we
already have to represent that concept, rather than this tuple. No
consumers of the bind values have been changed, only the producers
(outside of tests which care too much about internals). This is
*finally* possible since the bind values are now produced from a
reasonable number of lcoations.
|
| |
| |
| |
| |
| | |
I'm going to be extracting this logic into a clause class, things need
to go through a method and not access the values hash directly.
|
| |
| |
| |
| | |
Attempting to grok this code by refactoring it as I go through it.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The only place it was accessed was in tests. Many of them have another
way that they can test their behavior, that doesn't involve reaching
into internals as far as they did. `AssociationScopeTest` is testing a
situation where the where clause would have one bind param per
predicate, so it can just ignore the predicates entirely. The where
chain test was primarly duplicating the logic tested on `WhereClause`
directly, so I instead just make sure it calls the appropriate method
which is fully tested in isolation.
|
| | |
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The bind values can come from four places. `having`, `where`, `joins`,
and `from` when selecting from a subquery that contains binds. These
need to be kept in a specific order, since the clauses will always
appear in that order. Up until recently, they were not.
Additionally, `joins` actually did keep its bind values in a separate
location (presumably because it's the only case that people noticed was
broken). However, this meant that anything accessing just `bind_values`
was broken (which most places were). This is no longer possible, there
is only a single way to access the bind values, and it includes joins in
the proper location. The setter was removed yesterday, so breaking `+=`
cases is not possible.
I'm still not happy that `joins` is putting it's bind values on the
Arel AST, and I'm planning on refactoring it further, but this removes a
ton of bug cases.
|
| |
| |
| |
| |
| |
| | |
3729103e17e00494c8eae76e8a4ee1ac990d3450
[ci skip]
|
|\ \
| | |
| | | |
Update ActiveRecord::ModelSchema#table_name= 's doc
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Overriding these methods may cause unexpected results since
"table_name=" does more then just setting the "@table_name".
ref: https://github.com/rails/rails/pull/18622#issuecomment-70874358
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Contrary to my previous commit message, it wasn't overkill, and led to
much cleaner code.
[Sean Griffin & anthonynavarre]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The last place that was assigning it was when `from` is called with a
relation to use as a subquery. The implementation was actually
completely broken, and would break if you called `from` more than once,
or if you called it on a relation, which also had its own join clause,
as the bind values would get completely scrambled. The simplest solution
was to just move it into its own array, since creating a `FromClause`
class for this would be overkill.
|
| | | |
|
| | |
| | |
| | |
| | | |
All of its uses have been moved to better places
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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]
|
| | |
| | |
| | |
| | |
| | |
| | | |
PG expects us to not give it nonsenes
[Sean Griffin & anthonynavarre]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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]
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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
|
| | |
| | |
| | |
| | | |
It's under private in Active Model as well.
|
| | |
| | |
| | |
| | |
| | | |
We've now removed all uses of them across the board. All logic lives on
`WhereClause`.
|
| | |
| | |
| | |
| | |
| | |
| | | |
The code assumes that non-single-value methods mean multi value methods.
That is not the case. We need to change the accessor name, and only
assign an array for multi value methods
|
| | | |
|
| | | |
|
| | | |
|
| | |
| | |
| | |
| | |
| | | |
We're still using it in `where_unscoping`, which will require moving
additional logic.
|
| | |
| | |
| | |
| | | |
This will make it easy to add `having_clause` and `join_clause` later.
|
| | | |
|
| | | |
|
| | |
| | |
| | |
| | |
| | | |
Yes, I know, I called it a factory so I'm basically the worst person
ever who loves Java and worships the Gang of Four.
|
| | | |
|
| | |
| | |
| | |
| | | |
Bind values are no longer a thing, so this is unnecessary.
|
| | |
| | |
| | |
| | |
| | |
| | | |
This object being a black box, it knows the details of how to merge
itself with another where clause. This removes all references to where
values or bind values in `Relation::Merger`
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The way that bind values are currently stored on Relation is a mess.
They can come from `having`, `where`, or `join`. I'm almost certain that
`having` is actually broken, and calling `where` followed by `having`
followed by `where` will completely scramble the binds.
Joins don't actually add the bind parameters to the relation itself, but
instead add it onto an accessor on the arel AST which is undocumented,
and unused in Arel itself. This means that the bind values must always
be accessed as `relation.arel.bind_values + relation.bind_values`.
Anything that doesn't is likely broken (and tons of bugs have come up
for exactly that reason)
The result is that everything dealing with `Relation` instances has to
know far too much about the internals. The binds are split, combined,
and re-stored in non-obvious ways that makes it difficult to change
anything about the internal representation of `bind_values`, and is
extremely prone to bugs.
So the goal is to move a lot of logic off of `Relation`, and into
separate objects. This is not the same as what is currently done with
`JoinDependency`, as `Relation` knows far too much about its internals,
and vice versa. Instead these objects need to be black boxes that can
have their implementations swapped easily.
The end result will be two classes, `WhereClause` and `JoinClause`
(`having` will just re-use `WhereClause`), and there will be a single
method to access the bind values of a `Relation` which will be
implemented as
```
join_clause.binds + where_clause.binds + having_clause.binds
```
This is the first step towards that refactoring, with the internal
representation of where changed, and an intermediate representation of
`where_values` and `bind_values` to let the refactoring take small
steps. These will be removed shortly.
|
| | |
| | |
| | |
| | | |
See 4d7a62293e148604045a5f78a9d4312e79e90d13 for the reasoning
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The structure of `values[:where]` is going to change, with an
intermediate definition of `where_values` to aid the refactoring.
Accessing `values[:where]` directly messes with that, signficantly.
The array wrapping is no longer necessary, since `where_values` will
always return an array.
|
| | |
| | |
| | | |
[ci skip]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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`)
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
| | | |
|
|\ \ \
| | | |
| | | |
| | | | |
pretty_print will use #inspect if a subclass redefines it
|
| | | | |
|
| | | | |
|