aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/merger.rb
Commit message (Collapse)AuthorAgeFilesLines
* Fix merging left_joins to maintain its own `join_type` contextRyuta Kamizono2019-04-271-2/+6
| | | | | | | | | | | | | | | This fixes a regression for #35864. Usually, stashed joins (mainly eager loading) are performed as LEFT JOINs. But the case of merging joins/left_joins of different class, that (stashed) joins are performed as the same `join_type` as the parent context for now. Since #35864, both (joins/left_joins) stashed joins might be contained in `joins_values`, so each stashed joins should maintain its own `join_type` context. Fixes #36103.
* Stash `left_joins` into `joins` to deduplicate redundant LEFT JOINRyuta Kamizono2019-04-051-16/+7
| | | | | | | | | | | | | | | | | | | | | | | | | Originally the `JoinDependency` has the deduplication for eager loading (LEFT JOIN). This re-uses that deduplication for `left_joins`. And also, This makes left join order into part of joins, i.e.: Before: ``` association joins -> stash joins (eager loading, etc) -> string joins -> left joins ``` After: ``` association joins -> stash joins (eager loading, left joins, etc) -> string joins ``` Now string joins are able to refer left joins. Fixes #34325. Fixes #34332. Fixes #34536.
* Bugfix ActiveRecord::Relation#merge special case of from clauseBogdan Gusiev2018-09-281-3/+6
| | | | | When one relation is merged into another that has a different base class merging `from_clause` causes invalid SQL to be generated
* Fix merging relation that order including `?`Ryuta Kamizono2018-08-211-2/+2
| | | | | | | | | | | | | | | The `Relation::Merger` has a problem that order values would be merged as nested array. That was caused an issue #33664 since if array value is passed to `order` and first element in the array includes `?`, the array is regarded as a prepared statement and bind variables. https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html#method-i-sanitize_sql_for_order Just merging that as splat args like other values would fix the issue. Fixes #33664.
* Use `construct_join_dependency` in all placesRyuta Kamizono2018-07-031-6/+2
|
* Ensure to calculate column aliases after all table aliases are constructedRyuta Kamizono2018-06-191-6/+2
| | | | | | | | | | | | | | | | | Currently, column aliases which is used for eager loading are calculated before constructing all table aliases in FROM clause. `JoinDependency#join_constraints` constructs table aliases for `joins` first, and then always re-constructs table aliases for eager loading. If both `joins` and eager loading are given a same table association, the re-construction would cause the discrepancy between column aliases and table aliases. To avoid the discrepancy, the column aliases should be calculated after all table aliases are constructed. Fixes #30603.
* Avoid passing unnecessary arguments to relationDaniel Colson2018-01-241-1/+5
| | | | | | | | | | | | Most of the time the table and predicate_builder passed to Relation.new are exactly the arel_table and predicate builder of the given klass. This uses klass.arel_table and klass.predicate_builder as the defaults, so we don't have to pass them in most cases. This does change the signaure of both Relation and AssocationRelation. Are we ok with that?
* Fix relation merger issue with `left_outer_joins`Mehmet Emin INAC2018-01-151-1/+25
|
* Relation merging should keep joining orderRyuta Kamizono2017-11-111-10/+8
| | | | | | | `joins_values.partition` will break joins values order. It should be kept as user intended order. Fixes #15488.
* Decouple building `AliasTracker` from `JoinDependency`Ryuta Kamizono2017-10-081-1/+1
| | | | | This is preparation to respect parent relation's alias tracking for fixing #30681.
* `Relation::Merger` should not fill `values` with empty valuesRyuta Kamizono2017-07-251-10/+12
| | | | | | | | | Currently `Relation#merge` will almost fill `values` with empty values (e.g. `other.order_values` is always true, it should be `other.order_values.any?`). This means that `Relation#merge` always changes `values` even if actually `values` is nothing changed. This behavior will makes `Relation#empty_scope?` fragile. So `Relation#merge` should avoid unnecessary changes.
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* Fix `JoinDependency` with using a custom tableRyuta Kamizono2017-07-181-3/+4
| | | | | | | | | | | | | | | Without this fix, `JoinDependency` doesn't use a custom table alias: ``` % ARCONN=sqlite3 be ruby -w -Itest test/cases/relations_test.rb -n test_using_a_custom_table_with_joins_affects_the_wheres Using sqlite3 Run options: -n test_using_a_custom_table_with_joins_affects_the_wheres --seed 14531 E Error:RelationTest#test_using_a_custom_table_with_joins_affects_the_wheres: ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: posts.author_id: SELECT "omg_posts".* FROM "posts" "omg_posts" INNER JOIN "authors" ON "authors"."id" = "posts"."author_id" WHERE "omg_posts"."title" = ? LIMIT ? ```
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* Remove over meta programming in AR::RelationBogdan Gusiev2016-08-231-8/+4
| | | | | | | | | | Introduced low level methods #set_value and #get_value for setting query attributes: relation.set_value(:where, {id: 1}) relation.get_value(:includes) Used those internally when working with relation's attributes at the abstract level
* normalizes indentation and whitespace across the projectXavier Noria2016-08-061-61/+61
|
* applies new string literal convention in activerecord/libXavier Noria2016-08-061-1/+1
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Properly include the `from` clause when merging relationsSean Griffin2016-01-141-0/+3
| | | | | | | | | | The code that set the from clause was removed in bdc5141652770fd227455681cde1f9899f55b0b9. I did not give any reason for doing so. My assumption was that I intended to change it to use the clause objects, but forgot. We appeared to not have test coverage for this case. Fixes #22996
* Don't allocate a bunch of strings in `Relation::Merger`Sean Griffin2015-09-021-4/+8
| | | | | | Since the strings are dynamically computed from a constant, the actual strings we're creating are a known set. We can compute them ahead of time, and reduce the number of allocations in that method.
* Fix regression caused by a01d164bRafael Mendonça França2015-07-071-2/+2
| | | | | | | | | When preload is used in a default scope the preload_values were returning nested arrays and causing the preloader to fail because it doesn't know how to deal with nested arrays. So before calling preload! we need to splat the arguments. This is not needed to includes because it flatten its arguments.
* Fix the shadowing warning for `reflection`Roque Pinel2015-05-281-2/+2
|
* Properly append preload / includes args on MergerWashington Luiz2015-05-281-1/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Couldn't find other way to get the association name from a given class other than looping through `reflect_on_all_associations` reflections .. Noticed this one while looking at this example: ```ruby class Product < ActiveRecord::Base has_many :variants has_many :translations end class Translation < ActiveRecord::Base belongs_to :product end class Variant < ActiveRecord::Base belongs_to :product end class BugTest < Minitest::Test def test_merge_stuff product = Product.create! name: 'huhu' variant = Variant.create! product_id: product.id Translation.create! locale: 'en', product_id: product.id product_relation = Product.all .preload(:translations) .joins(:translations) .merge(Translation.where(locale: 'en')) .where(name: 'huhu') assert_equal variant, Variant.joins(:product).merge(product_relation).first end end ```
* Remove redundant require 'set' linesMehmet Emin İNAÇ2015-05-151-1/+0
|
* Move the `from` bind logic to a `FromClause` classSean Griffin2015-01-261-4/+2
| | | | | | | Contrary to my previous commit message, it wasn't overkill, and led to much cleaner code. [Sean Griffin & anthonynavarre]
* Remove `Relation#bind_values=`Sean Griffin2015-01-261-3/+4
| | | | | | | | | | 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.
* `Relation#Merger` can merge all clause methodsSean Griffin2015-01-251-3/+11
| | | | This will make it easy to add `having_clause` and `join_clause` later.
* Move where merging logic over to `WhereClause`Sean Griffin2015-01-251-39/+2
| | | | | | 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`
* Don't duplicate `Relation::VALUE_METHODS` in `Relation::Merger`Sean Griffin2015-01-241-2/+1
|
* Inject the `PredicateBuilder` into the `Relation` instanceSean Griffin2014-12-261-1/+1
| | | | | | | Construction of relations can be a hotspot, we don't want to create one of these in the constructor. This also allows us to do more expensive things in the predicate builder's constructor, since it's created once per AR::Base subclass
* Remove the unused second argument to `substitute_at`Sean Griffin2014-11-171-12/+0
| | | | Oh hey, we got to remove some code because of that!
* Remove unneccessary default values from relation mergerSean Griffin2014-10-281-2/+2
| | | | The value methods will default to an empty array for us automatically
* Call value methods when merging relations, rather than accessing keysSean Griffin2014-10-281-14/+14
| | | | | | | | The change to accessing keys directly was originally added to allow `merge` to take a hash. The implementation of `HashMerger` no longer requires us to be doing so. Accessing the values directly makes it impossible to change internal storage details, even if shim methods are added temporarily
* [ci skip] Make merge method nodocAnshul Sharma2014-10-201-8/+1
|
* [ci skip] merge docsAnshul Sharma2014-10-201-0/+7
|
* Make filter_binds filter out symbols that are equal to stringsNat Budin2014-05-141-1/+1
| | | | | | | | | | | | | ActiveRecord::Relation::Merger's filter_binds method does not filter out bind variables when one of the attribute nodes has a string name, but the other has a symbol name, even when those names are actually equal. This can result in there being more bind variables than placeholders in the generated SQL. This is particularly an issue for PostgreSQL, where this is treated as an error. This patch changes the filter_binds method to make it convert both attribute names to strings before comparing.
* select! renamed to avoid name collision Array#select!Earl J St Sauver2014-04-211-1/+9
| | | | | | | | Fixes #14752 Select mimics the block interface of arrays, but does not mock the block interface for select!. This change moves the api to be a private method, _select!.
* Build the reverse_order on its proper method.Lauro Caetano2014-04-071-1/+0
| | | | | | | | | | | | | | | | | | The reverse_order method was using a flag to control if the order should be reversed or not. Instead of using this variable just build the reverse order inside its proper method. This implementation was leading to an unexpected behavior when using reverse_order and then applying reorder(nil). Example: Before Post.order(:name).reverse_order.reorder(nil) # => SELECT "posts".* FROM "posts" ORDER BY "posts"."id" DESC After Post.order(:name).reverse_order.reorder(nil) # => SELECT "posts".* FROM "posts"
* stuff the join dependency object in the "anything goes" hash.Aaron Patterson2013-10-101-1/+1
|
* Relation#merge should not lose readonly(false) flag.thedarkone2013-09-111-1/+5
| | | | The original code ignores the `false` value because `false.blank? # => true`.
* Don't create fibers just to iterateNicholas Jakobsen2013-08-301-3/+3
|
* add a specific factory method rather than using newAaron Patterson2013-07-231-1/+1
|
* reorder bind parameters when merging relationsAaron Patterson2013-07-151-2/+18
|
* Typo fix [skip ci]Ankit Gupta2013-07-121-1/+1
|
* Simplify/fix implementation of default scopesJon Leighton2013-06-281-4/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The previous implementation was necessary in order to support stuff like: class Post < ActiveRecord::Base default_scope where(published: true) scope :ordered, order("created_at") end If we didn't evaluate the default scope at the last possible moment before sending the SQL to the database, it would become impossible to do: Post.unscoped.ordered This is because the default scope would already be bound up in the "ordered" scope, and therefore wouldn't be removed by the "Post.unscoped" part. In 4.0, we have deprecated all "eager" forms of scopes. So now you must write: class Post < ActiveRecord::Base default_scope { where(published: true) } scope :ordered, -> { order("created_at") } end This prevents the default scope getting bound up inside the "ordered" scope, which means we can now have a simpler/better/more natural implementation of default scoping. A knock on effect is that some things that didn't work properly now do. For example it was previously impossible to use #except to remove a part of the default scope, since the default scope was evaluated after the call to #except.
* avoid creating a set if no where values are removedAaron Patterson2013-05-211-0/+2
|
* remove bind values for where clauses that were removedAaron Patterson2013-05-211-9/+8
|
* push partitioning up so bind elimination can get the removed wheresAaron Patterson2013-05-211-5/+3
|
* push partion logic down and initialization logic upAaron Patterson2013-05-211-15/+11
|
* partition the where values so we can access the removed onesAaron Patterson2013-05-201-1/+6
|