- 10 5月, 2020 6 次提交
-
-
由 Ryuta Kamizono 提交于
Before IN clause optimization 70ddb8a7, Active Record had generated an SQL with binds when `prepared_statements: true`: ```ruby # prepared_statements: true # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id` IN (?, ?, ?) # # prepared_statements: false # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id` IN (1, 2, 3) # Author.where(id: [1, 2, 3]).to_a ``` But now, binds in IN clause is substituted regardless of whether `prepared_statements: true` or not: ```ruby # prepared_statements: true # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id`IN (1,2,3) # # prepared_statements: false # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id`IN (1,2,3) # Author.where(id: [1, 2, 3]).to_a ``` I suppose that is considered as a regression for the context: > While I would prefer that we fix/avoid the too-many-parameters problem, but I don't like the idea of globally ditching bind params for this edge case... we're getting to the point where I'd almost consider anything that doesn't use a bind to be a bug. https://github.com/rails/rails/pull/33844#issuecomment-421000003 This makes binds consider whether `prepared_statements: true` or not (i.e. restore the original behavior as before), but still gain that optimization when need the substitute binds (`prepared_statements: false`, `relation.to_sql`). Even when `prepared_statements: true`, it still much faster than before by optimized (bind node less) binds generation. ```ruby class Post < ActiveRecord::Base end ids = (1..1000).each.map do |n| Post.create!.id end puts "prepared_statements: #{Post.connection.prepared_statements.inspect}" Benchmark.ips do |x| x.report("where with ids") do Post.where(id: ids).to_a end end ``` * Before (200058b0) `prepared_statements: true`: ``` Warming up -------------------------------------- where with ids 6.000 i/100ms Calculating ------------------------------------- where with ids 63.806 (± 7.8%) i/s - 318.000 in 5.015903s ``` `prepared_statements: false`: ``` Warming up -------------------------------------- where with ids 7.000 i/100ms Calculating ------------------------------------- where with ids 73.550 (± 8.2%) i/s - 371.000 in 5.085672s ``` * Now with this change `prepared_statements: true`: ``` Warming up -------------------------------------- where with ids 9.000 i/100ms Calculating ------------------------------------- where with ids 91.992 (± 7.6%) i/s - 459.000 in 5.020817s ``` `prepared_statements: false`: ``` Warming up -------------------------------------- where with ids 10.000 i/100ms Calculating ------------------------------------- where with ids 104.335 (± 8.6%) i/s - 520.000 in 5.026425s ```
-
由 Ryuta Kamizono 提交于
Follow up of #34122. Relation method call is relying on method_missing, but if `Kernel` has the same named method (e.g. `open`, etc), it will invoke Kernel's method since method_missing is not happened. To prevent that, eager generate relation methods if a method is the same name on `Kernel`. Fixes #39195.
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
`singleton_class` is in Ruby 1.9.2, and there is no use singleton class eval in the files.
-
由 Ryuta Kamizono 提交于
Current SQL generation code is hard to maintenance, I've found a bug that create index comment in bulk change table when I'm refactoring that.
-
由 Ryuta Kamizono 提交于
I've found the bug when I'm refactoring index creation code in #39203.
-
- 09 5月, 2020 2 次提交
-
-
由 Ryuta Kamizono 提交于
We fixed `generate_relation_method` to address kwargs warnings at #38038, but I missed generated named scopes also need the same fix. Test case has picked from #39196. Co-authored-by: NJohn Hawthorn <john@hawthorn.email>
-
由 Ryuta Kamizono 提交于
We now always use `arel_attribute` for attribute alias resolution.
-
- 08 5月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
Fixes #39170. #39170 is a regression caused by 362348b5 to maintain kwargs flag to address kwargs warnings.
-
- 07 5月, 2020 5 次提交
-
-
由 Ryuta Kamizono 提交于
Actually that result is odd and hard to predictable result to me, but we should not change the public behavior without deprecation cycle. I had not intended to break any apps, so I've restored the behavior. Fixes #39171.
-
由 Ryuta Kamizono 提交于
It is possible to unscope only the column in the specified table. ```ruby posts = Post.joins(:comments).group(:"posts.hidden") posts = posts.where("posts.hidden": false, "comments.hidden": false) posts.count # => { false => 10 } # unscope both hidden columns posts.unscope(where: :hidden).count # => { false => 11, true => 1 } # unscope only comments.hidden column posts.unscope(where: :"comments.hidden").count # => { false => 11 } ``` Co-authored-by: NSlava Korolev <korolvs@gmail.com>
-
由 Ryuta Kamizono 提交于
-
由 Jonathan Hefner 提交于
Follow-up to #39147 and #39168. By adding a new purpose-specific format, we avoid potential pitfalls from concatenating format strings. We also save a String allocation per Time attribute per inspect. The new format also includes a time zone offset for more introspective inspection.
-
由 Adam Hess 提交于
DATE_FORMATS can be either a format string or a lambda we don't want to attempt to concat them with a string if we are in the lambda case
-
- 06 5月, 2020 5 次提交
-
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
This removes an optimization that `attr.in(range_object)` acts as `attr.between(range_object` which is deprecated over 5 years ago. `attr.in` will generate exactly IN clause even if a range object is passed. Use `attr.between` instead if BETWEEN clause is what want to get. Ref https://github.com/rails/arel/pull/333.
-
由 Ryuta Kamizono 提交于
Some apps would expect that type cast is not evaluated at relation build time consistently. Context: https://github.com/kamipo/rails/commit/b571c4f3f2811b5d3dc8b005707cf8c353abdf03#r31015008 https://github.com/rails/rails/pull/34303 And also this removes extra grouping on IN clause behaved as before.
-
由 Bogdan Gusiev 提交于
Fixes #39073
-
由 eileencodes 提交于
This reverts commit 9817d74f, reversing changes made to d326b029. Just making this easier to merge our PR in. Otherwise there's tons of conflicts and our PR is faster.
-
- 05 5月, 2020 6 次提交
-
-
由 Ryuta Kamizono 提交于
Some commits adds `**` to address kwargs warnings in Ruby 2.7, but `save` and `save!` are originally doesn't take positional arguments, so maintain both `*` and `**` is redundant. https://github.com/rails/rails/commit/6d68bb5f695414b1801c1c3952ef955a5b0b6c6a https://github.com/rails/rails/commit/09d7ce79750d08b6b9c64fd038eee285d0cbfd44 https://github.com/rails/rails/commit/51a7422c9f10cc75a3ef6bf9177324fc771d7ba4
-
由 Ryuta Kamizono 提交于
In the past, we sometimes hit missing `Symbol#start_with?` and `Symbol#end_with?`. https://github.com/rails/rails/commit/63256bc5d7dd77b2cce82df46c53249dab2dc2a8 https://github.com/rails/rails/commit/a8e812964d711fa03843e76ae50f5ff81cdc9e00 So I proposed `Symbol#start_with?` and `Symbol#end_with?` to allow duck typing that methods for String and Symbol, then now it is available in Ruby 2.7. https://bugs.ruby-lang.org/issues/16348 Using `String#starts_with?` and `String#ends_with?` could not be gained that conveniency, so it is preferable to not use these in the future.
-
由 Ryuta Kamizono 提交于
```ruby steve = Person.find_by(name: "Steve") david = Author.find_by(name: "David") relation = Essay.where(writer: steve) # Before relation.rewhere(writer: david).to_a # => [] # After relation.rewhere(writer: david).to_a # => [david] ``` For now `rewhere` only works for truly column names, doesn't work for alias attributes, nested conditions, associations. To fix that, need to build new where clause first, and then get attribute names from new where clause.
-
由 hotatekaoru 提交于
To change a NOT NULL constraint `reversible`. When changing a NOT NULL constraint, we use `ActiveRecord::ConnectionAdapters::SchemaStatements#change` method that is not reversible, so `up` and `down` methods were required. Actually, we can use `change_column_null` method if only one constraint changed, but if we want to change multiple constarints with ALTER QUERY, `up` and `down` methods were required.
-
由 akinomaeni 提交于
before ``` p Knot.create => #<Knot id: 1, created_at: "2016-05-05 01:29:47"> ``` after ``` p Knot.create => #<Knot id: 1, created_at: "2016-05-05 01:29:47.116928000"> ```
- 04 5月, 2020 1 次提交
-
-
由 Ryuta Kamizono 提交于
-
- 03 5月, 2020 4 次提交
-
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
-
由 Eugene Kenny 提交于
Since 901d62c5, associations can only be autosaved once: after a record has been saved, `@new_record_before_save` will always be false. This assumes that records only transition to being persisted once, but there are two cases where it happens multiple times: when the transaction that saved the record is rolled back, and when the persisted record is later duplicated.
-
- 02 5月, 2020 5 次提交
-
-
由 Ryuta Kamizono 提交于
I supposed all aggregation functions will return numeric result in #39039, but that assumption was incorrect for `minimum` and `maximum`, if an aggregated column is non numeric type. I've restored type casting aggregated result for `minimum` and `maximum`. Fixes #39110.
-
由 Ryuta Kamizono 提交于
The type information for type casting is entirely separated to type object, so if anyone does passing a column to `type_cast` in Rails 6, they are likely doing something wrong. See the comment for more details: https://github.com/rails/rails/blob/28d815b89487ce4001a3f6f0ab684e6f9c017ed0/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb#L33-L42 This also deprecates passing legacy binds (an array of `[column, value]` which is 4.2 style format) to query methods on connection. That legacy format was kept for backward compatibility, instead of that, I've supported casted binds format (an array of casted values), it is easier to construct binds than existing two binds format.
-
由 Ryuta Kamizono 提交于
-
由 eileencodes 提交于
A coworker at GitHub found a few months back that if we used `santitize_sql` over `where` when we knew the values going into `where` it was a lot faster than `where`. This PR adds a new Arel node type called `HomogenousIn` that will be used when Rails knows the values are all homogenous and can therefore pick a faster codepath. This new codepath skips some of the required processing by `where` to make `wheres` with homogenous arrays faster without requiring the application author to know when to use which query type. Using our benchmark code: ```ruby ids = (1..1000).each.map do |n| Post.create!.id end Benchmark.ips do |x| x.report("where with ids") do Post.where(id: ids).to_a end x.report("where with sanitize") do Post.where(ActiveRecord::Base.sanitize_sql(["id IN (?)", ids])).to_a end x.compare! end ``` Before this PR comparing where with a list of IDs to santitize sql: ``` Warming up -------------------------------------- where with ids 11.000 i/100ms where with sanitize 17.000 i/100ms Calculating ------------------------------------- where with ids 115.733 (± 4.3%) i/s - 583.000 in 5.045828s where with sanitize 174.231 (± 4.0%) i/s - 884.000 in 5.081495s Comparison: where with sanitize: 174.2 i/s where with ids: 115.7 i/s - 1.51x slower ``` After this PR comparing where with a list of IDs to santitize sql: ``` Warming up -------------------------------------- where with ids 16.000 i/100ms where with sanitize 19.000 i/100ms Calculating ------------------------------------- where with ids 158.293 (± 6.3%) i/s - 800.000 in 5.072208s where with sanitize 169.141 (± 3.5%) i/s - 855.000 in 5.060878s Comparison: where with sanitize: 169.1 i/s where with ids: 158.3 i/s - same-ish: difference falls within error ``` Co-authored-by: NAaron Patterson <aaron.patterson@gmail.com>
-
由 eileencodes 提交于
-
- 01 5月, 2020 5 次提交
-
-
由 Ryuta Kamizono 提交于
I've found the internal `without_transaction_enrollment` callbacks which have not been newly used over five years, when I tried to work reverting #9068 (https://github.com/rails/rails/pull/36049#issuecomment-487318060). I think that we will never make that callbacks public, since the mechanism of `without_transaction_enrollment` is too implementation specific, at least before #9068, records in a transaction had enrolled all into the transaction. That callbacks was introduced at #18936 to make `touch_later` #19324, but I think that the internal callbacks is overkill to just make the `touch_later` only, and invoking the extra callbacks also have a little overhead even if we haven't used that. So I think we can remove the internal callbacks for now, until we will come up with a good use for that callbacks.
-
由 Jean Boussier 提交于
-
由 Ryuta Kamizono 提交于
`column_types` is empty except PostgreSQL adapter, and `attribute_types.each_key { |k| column_types.delete k }` is also empty even if PostgreSQL adapter almost all case, so that code is quite useless. This improves performance for `find_by_sql` to avoid that useless loop as much as possible. ```ruby ActiveRecord::Schema.define do create_table :active_storage_blobs do |t| t.string :key, null: false t.string :filename, null: false t.string :content_type t.text :metadata t.string :service_name, null: false t.bigint :byte_size, null: false t.string :checksum, null: false t.datetime :created_at, null: false t.index [ :key ], unique: true end end class ActiveStorageBlob < ActiveRecord::Base end Benchmark.ips do |x| x.report("find_by") { ActiveStorageBlob.find_by(id: 1) } end ``` Before: ``` Warming up -------------------------------------- find_by 1.256k i/100ms Calculating ------------------------------------- find_by 12.595k (± 3.4%) i/s - 64.056k in 5.091599s ``` After: ``` Warming up -------------------------------------- find_by 1.341k i/100ms Calculating ------------------------------------- find_by 13.170k (± 3.5%) i/s - 67.050k in 5.097439s ``` To avoid column types loop for PostgreSQL adapter, this skips returning additional column types if a column has already been type casted by pg decoders. Fortunately this fixes #36186 partly for common types.
-
由 Ryuta Kamizono 提交于
-
由 Ryuta Kamizono 提交于
Relying on the `Arel::Table.engine` is convenient if an app have only a single kind of database, but if not so, the global state is not always the same with the current connection.
-