1. 07 5月, 2020 2 次提交
    • J
      Add DATE_FORMATS[:inspect] · 2b38bf68
      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.
      2b38bf68
    • A
      Don't attempt to add a string to a lambda · 38121340
      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
      38121340
  2. 06 5月, 2020 6 次提交
  3. 05 5月, 2020 6 次提交
  4. 04 5月, 2020 2 次提交
  5. 03 5月, 2020 2 次提交
  6. 02 5月, 2020 4 次提交
  7. 01 5月, 2020 5 次提交
    • R
      Remove internal `without_transaction_enrollment` callbacks · 75873d8f
      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.
      75873d8f
    • R
      Avoid quite useless loop in `find_by_sql` · 71e45582
      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.
      71e45582
    • R
      Replace `result_as_array` by type mapping · 348e142b
      Ryuta Kamizono 提交于
      348e142b
    • R
    • R
      Should not rely on the global `Arel::Table.engine` in the framework · bc99e401
      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.
      bc99e401
  8. 30 4月, 2020 1 次提交
    • R
      Deprecate `allowed_index_name_length` in `DatabaseLimits` · ab2d859e
      Ryuta Kamizono 提交于
      `allowed_index_name_length` was used for internal temporary operations
      in SQLite3, since index name in SQLite3 must be globally unique and
      SQLite3 doesn't have ALTER TABLE feature (so it is emulated by creating
      temporary table with prefix).
      
      `allowed_index_name_length` was to reserve the margin for the prefix,
      but actually SQLite3 doesn't have a limitation for identifier name
      length, so the margin has removed at 36901e6e.
      
      Now `allowed_index_name_length` is no longer relied on by any adapter,
      so I'd like to remove the internal specific method which is no longer
      used.
      ab2d859e
  9. 29 4月, 2020 1 次提交
    • R
      PERF: Improve performance of where when using an array of values · c3a2b54b
      Ryuta Kamizono 提交于
      This is a smaller alternative of performance improvement, without
      refactoring type casting mechanism #39009.
      
      This is relatively a smaller change (but about 40% faster than before),
      so I think this could be easier reviewed without discuss about
      refactoring type casting mechanism.
      
      This just makes `attribute.in(values)` less allocation from an array of
      casted nodes to one casted array node.
      
      ```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:
      
      ```
      Warming up --------------------------------------
            where with ids     7.000  i/100ms
       where with sanitize    13.000  i/100ms
      
      Calculating -------------------------------------
            where with ids     70.661  (± 5.7%) i/s -    357.000  in   5.072771s
       where with sanitize    130.993  (± 7.6%) i/s -    663.000  in   5.096085s
      
      Comparison:
       where with sanitize:      131.0 i/s
            where with ids:       70.7 i/s - 1.85x  slower
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
            where with ids    10.000  i/100ms
       where with sanitize    13.000  i/100ms
      
      Calculating -------------------------------------
            where with ids     98.174  (± 7.1%) i/s -    490.000  in   5.012851s
       where with sanitize    132.289  (± 8.3%) i/s -    663.000  in   5.052728s
      
      Comparison:
       where with sanitize:      132.3 i/s
            where with ids:       98.2 i/s - 1.35x  slower
      ```
      c3a2b54b
  10. 28 4月, 2020 1 次提交
  11. 27 4月, 2020 2 次提交
    • R
      Fix typo · 60ff1194
      Ryuta Kamizono 提交于
      60ff1194
    • R
      Deprecate `in_clause_length` in `DatabaseLimits` · c0ca7625
      Ryuta Kamizono 提交于
      `in_clause_length` was added at c5a284f8 to address to Oracle IN clause
      length limitation.
      
      Now `in_clause_length` is entirely integrated in Arel visitor since
      #35838 and #36074.
      
      Since Oracle visitors are the only code that rely on `in_clause_length`.
      so I'd like to remove that from Rails code base, like has removed Oracle
      visitors (#38946).
      c0ca7625
  12. 26 4月, 2020 1 次提交
    • R
      More concise Arel `Or` ast and make `Or` visitor non recursive · 7d3bff1f
      Ryuta Kamizono 提交于
      Before this, 1000 `Or` nodes will raise "stack level too deep" due to
      visiting too deep Arel ast.
      
      This makes more concise Arel `Or` ast and `Or` visitor non recursive if
      `Or` nodes are adjoined, as a result, "stack level too deep" is no
      longer raised.
      
      ```ruby
      class Post < ActiveRecord::Base
      end
      
      posts = (0..500).map { |i| Post.where(id: i) }
      
      Benchmark.ips do |x|
        x.report("inject scopes") { posts.inject(&:or).to_sql }
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
            where with ids     9.000  i/100ms
      Calculating -------------------------------------
            where with ids     96.126  (± 2.1%) i/s -    486.000  in   5.058960s
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
             inject scopes    10.000  i/100ms
      Calculating -------------------------------------
             inject scopes    101.714  (± 2.9%) i/s -    510.000  in   5.018880s
      ```
      
      Fixes #39032.
      7d3bff1f
  13. 25 4月, 2020 5 次提交
  14. 24 4月, 2020 1 次提交
  15. 23 4月, 2020 1 次提交