aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/predicate_builder
Commit message (Collapse)AuthorAgeFilesLines
* Consolidate the duplicated code that building range predicateRyuta Kamizono2019-01-081-21/+2
| | | | | This slightly change the code in the Arel to allow +/-INFINITY as open ended since the Active Record expects that behavior. See 5ecbeda.
* Lazy checking whether or not values in IN clause are boundableRyuta Kamizono2018-10-241-3/+2
| | | | | | | | | | | | | Since #33844, eager loading/preloading with too many and/or too large ids won't be broken by pre-checking whether the value is constructable or not. But the pre-checking caused the type to be evaluated at relation build time instead of at the query execution time, that is breaking an expectation for some apps. I've made the pre-cheking lazy as much as possible, that is no longer happend at relation build time.
* Fallback to unprepared statement only when bind params limit is exceededRyuta Kamizono2018-09-141-2/+2
| | | | | | | | | | | This is a follow up and/or an alternative of #33844. Unlike #33844, this would attempt to construct unprepared statement only when bind params limit (mysql2 65535, pg 65535, sqlite3 249999) is exceeded. I only defined 65535 as the limit, not defined 249999 for sqlite3, since it is an edge case, I'm not excited to add less worth extra code.
* Eager loading/preloading should be worked regardless of large number of recordsRyuta Kamizono2018-09-121-4/+5
| | | | | | | | | | | | | | | | Since 213796f, bind params are used for IN clause if enabled prepared statements. Unfortunately, most adapter modules have a limitation for # of bind params (mysql2 65535, pg 65535, sqlite3 250000). So if eager loading large number of records at once, that query couldn't be sent to the database. Since eager loading/preloading queries are auto-generated by Active Record itself, so it should be worked regardless of large number of records like as before. Fixes #33702.
* Use `Array#extract!` where possiblebogdanvlviv2018-08-141-2/+4
|
* Extract all `base_class.name` as `polymorphic_name`Ryuta Kamizono2018-03-041-5/+7
| | | | | | | This is an alternative of #29722, and follow up of #32048. This does not change the current behavior, but makes it easier to modify all polymorphic names consistently.
* PostgreSQL: Treat infinite values in date like datetime consistentlyRyuta Kamizono2018-02-231-3/+4
| | | | | | | | | | | | | | The values infinity and -infinity are supported by both date and timestamp types. https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE And also, it can not be known whether a value is infinity correctly unless cast a value. I've added `QueryAttribute#infinity?` to handle that case. Closes #27585.
* Use private attr_readerRyuta Kamizono2018-02-234-8/+4
| | | | | Since #32028, Rails 6 requires Ruby 2.3+. No longer needed workaround for Ruby 2.2 "private attribute?" warning.
* Rails 6 requires Ruby 2.3+Jeremy Daer2018-02-172-8/+2
|
* Refactor delegating `join_primary_key` instead of `join_keys` and ↵Ryuta Kamizono2018-01-012-2/+2
| | | | | | | `association_primary_key` in `TableMetadata` Because `join_primary_key` is called by `join_keys` and it is to abstract calling `association_primary_key`.
* Ensure `apply_join_dependency` for subqueries in `from` and `where`Ryuta Kamizono2017-11-101-0/+4
| | | | Fixes #21577.
* Changed join_fk private method to join_foreign_key public methodchopraanmol12017-08-091-1/+1
|
* Currently if relation object are passed to where condition for has one or ↵chopraanmol12017-08-081-2/+2
| | | | | | has many association wrong set of primary key and foreign key are selected. Changed code to use 'join' primary key and foreign key over 'association' primary key and foreign key.
* Remove single element array preprocessRyuta Kamizono2017-07-261-1/+1
| | | | | Since 213796f, array predicate handler supports making binds, so the preprocess is no longer needed.
* Remove unused `queries_predicates`Ryuta Kamizono2017-07-251-12/+0
| | | | Since 213796f, `queries_predicates` is no longer used.
* Refactor Active Record to let Arel manage bind paramsSean Griffin2017-07-244-12/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A common source of bugs and code bloat within Active Record has been the need for us to maintain the list of bind values separately from the AST they're associated with. This makes any sort of AST manipulation incredibly difficult, as any time we want to potentially insert or remove an AST node, we need to traverse the entire tree to find where the associated bind parameters are. With this change, the bind parameters now live on the AST directly. Active Record does not need to know or care about them until the final AST traversal for SQL construction. Rather than returning just the SQL, the Arel collector will now return both the SQL and the bind parameters. At this point the connection adapter will have all the values that it had before. A bit of this code is janky and something I'd like to refactor later. In particular, I don't like how we're handling associations in the predicate builder, the special casing of `StatementCache::Substitute` in `QueryAttribute`, or generally how we're handling bind value replacement in the statement cache when prepared statements are disabled. This also mostly reverts #26378, as it moved all the code into a location that I wanted to delete. /cc @metaskills @yahonda, this change will affect the adapters Fixes #29766. Fixes #29804. Fixes #26541. Close #28539. Close #24769. Close #26468. Close #26202. There are probably other issues/PRs that can be closed because of this commit, but that's all I could find on the first few pages.
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-197-0/+14
|
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-027-7/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-017-0/+7
|
* Don't expose methods and attrs for internal usageRyuta Kamizono2017-05-302-4/+10
|
* Merge pull request #28767 from kamipo/rename_to_association_query_valueAndrew White2017-04-152-0/+0
|\ | | | | Rename `association_query_handler.rb` to `association_query_value.rb`
| * Rename `association_query_handler.rb` to `association_query_value.rb`Ryuta Kamizono2017-04-152-0/+0
| | | | | | | | | | | | Since `AssociationQueryHandler` and `PolymorphicArrayHandler` has removed in #28715, only exists `AssociationQueryValue` and `PolymorphicArrayValue` in these files.
* | Early return in `PredicateBuilder::ArrayHandler`Ryuta Kamizono2017-04-151-4/+3
|/ | | | Partitioning to `values` and `nils` is unneeded before early return.
* `AssociationQueryValue#queries` returns an array for more concise ↵Ryuta Kamizono2017-04-111-1/+1
| | | | association handling
* Convert `PolymorphicArrayValue` to PORO queriesRyuta Kamizono2017-04-092-25/+14
|
* Convert `AssociationQueryValue` to PORO queriesRyuta Kamizono2017-04-091-30/+0
|
* Expose `queries` for `AssociationQueryValue` and `PolymorphicArrayValue`Ryuta Kamizono2017-04-092-21/+25
|
* Avoid to handle polymorphic association for `AssociationQueryHandler`Ryuta Kamizono2017-03-282-29/+21
| | | | It should be handled by `PolymorphicArrayHandler` if polymorphic association.
* Remove deprecated support to passing a class as a value in a queryRafael Mendonça França2016-12-291-29/+0
|
* Merge pull request #26376 from kamipo/remove_polymorphic_base_class_for_arrayRafael França2016-12-291-3/+0
|\ | | | | Remove extracting `polymorphic_base_class` for `Array` in `AssociationQueryValue`
| * Remove extracting `polymorphic_base_class` for `Array` in ↵Ryuta Kamizono2016-09-211-3/+0
| | | | | | | | | | | | `AssociationQueryValue` It is handled by `PolymorphicArrayValue`.
* | Describe what we are protectingAkira Matsuda2016-12-235-0/+10
|/
* Fix broken heredoc indentation caused by rubocop auto-correctRyuta Kamizono2016-09-031-3/+3
| | | | | | All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772. But heredocs was still kept absolute position. This commit aligns heredocs indentation for consistency.
* Revert "Extract `PredicateBuilder::CaseSensitiveHandler`"Sean Griffin2016-08-311-21/+0
| | | | | | | | | This reverts commit 3a1f6fe7b4a70bf0698b0684dd48ac712c6883b6. This commit takes the code in a direction that I am looking to avoid. The predicate builder should be purely concerned with AST construction as it matters to methods like `where`. Things like case sensitivity should continue to be handled elsewhere.
* Extract `PredicateBuilder::CaseSensitiveHandler`Ryuta Kamizono2016-08-161-0/+21
| | | | | | Currently uniqueness validator is coupled with building Arel ASTs. This commit extracts `PredicateBuilder::CaseSensitiveHandler` for decouple the building Arel ASTs.
* normalizes indentation and whitespace across the projectXavier Noria2016-08-065-41/+41
|
* Remove unused `predicate_builder` for `BasicObjectHandler` and `RangeHandler`Ryuta Kamizono2016-07-022-16/+0
|
* Reuse a result of `table.associated_table(column)` in ↵Ryuta Kamizono2016-05-281-2/+3
| | | | `AssociationQueryHandler.value_for`
* Fixed `where` for polymorphic associations when passed an array containing ↵Philippe Huibonhoa2016-02-162-0/+67
| | | | | | | | | | | | | | | | | different types. When passing in an array of different types of objects to `where`, it would only take into account the class of the first object in the array. PriceEstimate.where(estimate_of: [Treasure.find(1), Car.find(2)]) # => SELECT "price_estimates".* FROM "price_estimates" WHERE ("price_estimates"."estimate_of_type" = 'Treasure' AND "price_estimates"."estimate_of_id" IN (1, 2)) This is fixed to properly look for any records matching both type and id: PriceEstimate.where(estimate_of: [Treasure.find(1), Car.find(2)]) # => SELECT "price_estimates".* FROM "price_estimates" WHERE (("price_estimates"."estimate_of_type" = 'Treasure' AND "price_estimates"."estimate_of_id" = 1) OR ("price_estimates"."estimate_of_type" = 'Car' AND "price_estimates"."estimate_of_id" = 2))
* Extract a Relation#arel_attributeMatthew Draper2016-02-041-1/+1
|
* Defer Arel attribute lookup to the model classMatthew Draper2016-02-041-1/+1
| | | | | This still isn't as separated as I'd like, but it at least moves most of the burden of alias mapping in one place.
* Use bind parameters for ranges in where clausesSean Griffin2016-01-211-1/+17
| | | | | | | | | | | | | | This is a similar case to wanting ot use bind params for limit and offset. Right now passing a range grows the amount of prepared statements in an unbounded fashion. We could avoid using prepared statements in that case, similar to what we do with arrays, but there's a known number of variants for ranges. This ends up duplicating some of the logic from Arel for how to handle potentially infinite ranges, and that behavior may be removed from Arel in the future. Fixes #23074
* Reduce calls to stringify_keys.Guo Xiang Tan2015-09-071-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Stackprof output truncated. ``` TOTAL (pct) SAMPLES (pct) FRAME 23 (4.7%) 12 (2.4%) Hash#transform_keys 11 (2.2%) 11 (2.2%) block in Hash#transform_keys 30 (6.1%) 7 (1.4%) Hash#stringify_keys ``` Benchmark Script: ``` begin require 'bundler/inline' rescue LoadError => e $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler' raise e end gemfile(true) do source 'https://rubygems.org' gem 'rails', path: '~/rails' # master against ref "f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06" gem 'arel', github: 'rails/arel', branch: 'master' gem 'rack', github: 'rack/rack', branch: 'master' gem 'sass' gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master' gem 'sprockets', github: 'rails/sprockets', branch: 'master' gem 'pg' gem 'benchmark-ips' end require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench') ActiveRecord::Migration.verbose = false ActiveRecord::Schema.define do create_table :users, force: true do |t| t.string :name, :email t.timestamps null: false end end class User < ActiveRecord::Base; end attributes = { name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", email: "foobar@email.com", } 1000.times { User.create!(attributes) } Benchmark.ips(5, 3) do |x| x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") } x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") } x.compare! end key = if RUBY_VERSION < '2.2' :total_allocated_object else :total_allocated_objects end before = GC.stat[key] User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") after = GC.stat[key] puts "Total Allocated Object: #{after - before}" ``` Before: ``` Calculating ------------------------------------- where with hash 2.796k i/100ms where with string 4.338k i/100ms ------------------------------------------------- where with hash 29.177k (± 1.5%) i/s - 148.188k where with string 47.419k (± 2.8%) i/s - 238.590k Comparison: where with string: 47419.0 i/s where with hash: 29176.6 i/s - 1.63x slower Total Allocated Object: 85 ``` After: ``` Calculating ------------------------------------- where with hash 2.895k i/100ms where with string 4.416k i/100ms ------------------------------------------------- where with hash 30.758k (± 2.0%) i/s - 156.330k where with string 47.708k (± 2.6%) i/s - 238.464k Comparison: where with string: 47707.9 i/s where with hash: 30757.7 i/s - 1.55x slower Total Allocated Object: 84 ```
* Respect custom primary keys for associations in `Relation#where`Sean Griffin2015-02-041-1/+21
| | | | | | | | | | While we query the proper columns, we go through normal handling for converting the value to a primitive which assumes it should use the table's primary key. If the association specifies a different value (and we know that we're working with an association), we should use the custom primary key instead. Fixes #18813.
* Remove unneeded requiresRafael Mendonça França2015-01-041-2/+0
| | | | These requires were added only to change deprecation message
* Rely on the injectable type caster for `arel_table`Sean Griffin2014-12-293-23/+1
| | | | | | | This API will require much less consuming code to change to accomodate the removal of automatic type casting from Arel. As long as the predicates are constructed using the `arel_table` off of an AR subclass, there will be no changes that need to happen.
* Eagerly cast array values passed to the predicate builderSean Griffin2014-12-261-1/+6
| | | | | | | | Part of a larger refactoring to remove type casting from Arel. /cc @mrgilman [Sean Griffin & Melanie Gilman]
* Eagerly cast range values in the predicate builderSean Griffin2014-12-261-0/+24
| | | | | | | | | A custom object is required for this, as you cannot build a range object out of `Arel::Nodes::Quoted` objects. Depends on the changes introduced in https://github.com/rails/arel/commit/cf03bd45e39def057a2f63e42a3391b7d750dece /cc @mrgilman
* Perform casting of single values within the predicate builderSean Griffin2014-12-263-2/+27
| | | | | | | | | | | As part of the larger refactoring to remove type casting from Arel, we need to do the casting of values eagerly. The predicate builder is the closest place that knows about the Active Record class, and can therefore have the type information. /cc @mrgilman [Sean Griffin & Melanie Gilman]
* Remove `klass` and `arel_table` as a dependency of `PredicateBuilder`Sean Griffin2014-12-261-6/+7
| | | | | | | | | | | | | | | This class cares far too much about the internals of other parts of Active Record. This is an attempt to break out a meaningful object which represents the needs of the predicate builder. I'm not fully satisfied with the name, but the general concept is an object which represents a table, the associations to/from that table, and the types associated with it. Many of these exist at the `ActiveRecord::Base` class level, not as properties of the table itself, hence the need for another object. Currently it provides these by holding a reference to the class, but that will likely change in the future. This allows the predicate builder to remain wholy concerned with building predicates. /cc @mrgilman