1. 13 6月, 2019 1 次提交
  2. 27 4月, 2019 1 次提交
    • R
      Fix merging left_joins to maintain its own `join_type` context · 20ede2e2
      Ryuta Kamizono 提交于
      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.
      20ede2e2
  3. 10 4月, 2019 1 次提交
    • D
      Clarify exists check in logs · 2e117c8a
      Dan Fitch 提交于
      The default log messages for Model.exists?, when called from .save
      on an object which uses scoped uniqueness validation like:
      
          class Example < ApplicationRecord
            validates :field, uniqueness: {scope: parent_id}
          end
      
      can result in slightly misleading logs.
      
      An example case:
      
          ↳ app/controllers/example_controller.rb:23
          (0.2ms)  begin transaction
          ↳ app/controllers/example_controller.rb:39
          Example Exists (0.2ms)  SELECT  1 AS one FROM "examples" WHERE "examples"."field" IS NULL AND "examples"."parent_id" = ? LIMIT ?  [["parent_id", 123], ["LIMIT", 1]]
          ↳ app/controllers/example_controller.rb:39
          (0.1ms)  rollback transaction
      
      To me, a Rails newbie, this parsed as the following:
      
      - started the transaction to create a thing
      - found that your object exists already!
      - so we rolled back the transaction
      
      (even though the actual cause of the transaction is something that happens
      after the Exists check.)
      
      All this does is add a question mark to the message, to make it clear in the
      log that this is a check, not a confirmation.
      
      This may be kind of silly, but it may save some future goofs by newbs like me.
      2e117c8a
  4. 05 4月, 2019 1 次提交
    • R
      Stash `left_joins` into `joins` to deduplicate redundant LEFT JOIN · 8f05035b
      Ryuta Kamizono 提交于
      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.
      8f05035b
  5. 07 3月, 2019 1 次提交
  6. 01 3月, 2019 1 次提交
  7. 28 2月, 2019 1 次提交
  8. 08 2月, 2019 1 次提交
    • R
      Fix `relation.exists?` with giving both `distinct` and `offset` · 07dcd99a
      Ryuta Kamizono 提交于
      The `distinct` affects (reduces) rows of the result, so it is important
      part when both `distinct` and `offset` are given.
      
      Replacing SELECT clause to `1 AS one` and removing `distinct` and
      `order` is just optimization for the `exists?`, we should not apply the
      optimization for that case.
      
      Fixes #35191.
      07dcd99a
  9. 18 1月, 2019 1 次提交
    • R
      All of queries should return correct result even if including large number · 31ffbf8d
      Ryuta Kamizono 提交于
      Currently several queries cannot return correct result due to incorrect
      `RangeError` handling.
      
      First example:
      
      ```ruby
      assert_equal true, Topic.where(id: [1, 9223372036854775808]).exists?
      assert_equal true, Topic.where.not(id: 9223372036854775808).exists?
      ```
      
      The first example is obviously to be true, but currently it returns
      false.
      
      Second example:
      
      ```ruby
      assert_equal topics(:first), Topic.where(id: 1..9223372036854775808).find(1)
      ```
      
      The second example also should return the object, but currently it
      raises `RecordNotFound`.
      
      It can be seen from the examples, the queries including large number
      assuming empty result is not always correct.
      
      Therefore, This change handles `RangeError` to generate executable SQL
      instead of raising `RangeError` to users to always return correct
      result. By this change, it is no longer raised `RangeError` to users.
      31ffbf8d
  10. 08 1月, 2019 1 次提交
  11. 27 11月, 2018 1 次提交
    • T
      Make implicit order column configurable · 3b9982a3
      Tekin Suleyman 提交于
      When calling ordered finder methods such as +first+ or +last+ without an
      explicit order clause, ActiveRecord sorts records by primary key. This
      can result in unpredictable and surprising behaviour when the primary
      key is not an auto-incrementing integer, for example when it's a UUID.
      This change makes it possible to override the column used for implicit
      ordering such that +first+ and +last+ will return more predictable
      results. For Example:
      
        class Project < ActiveRecord::Base
          self.implicit_order_column = "created_at"
        end
      3b9982a3
  12. 27 10月, 2018 1 次提交
  13. 23 9月, 2018 1 次提交
    • Y
      Enable `Performance/UnfreezeString` cop · 1b86d901
      yuuji.yaginuma 提交于
      In Ruby 2.3 or later, `String#+@` is available and `+@` is faster than `dup`.
      
      ```ruby
      # frozen_string_literal: true
      
      require "bundler/inline"
      
      gemfile(true) do
        source "https://rubygems.org"
      
        gem "benchmark-ips"
      end
      
      Benchmark.ips do |x|
        x.report('+@') { +"" }
        x.report('dup') { "".dup }
        x.compare!
      end
      ```
      
      ```
      $ ruby -v benchmark.rb
      ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
      Warming up --------------------------------------
                        +@   282.289k i/100ms
                       dup   187.638k i/100ms
      Calculating -------------------------------------
                        +@      6.775M (± 3.6%) i/s -     33.875M in   5.006253s
                       dup      3.320M (± 2.2%) i/s -     16.700M in   5.032125s
      
      Comparison:
                        +@:  6775299.3 i/s
                       dup:  3320400.7 i/s - 2.04x  slower
      
      ```
      1b86d901
  14. 20 9月, 2018 1 次提交
  15. 08 9月, 2018 1 次提交
  16. 01 8月, 2018 1 次提交
  17. 20 7月, 2018 1 次提交
  18. 03 7月, 2018 1 次提交
  19. 19 6月, 2018 1 次提交
    • R
      Ensure to calculate column aliases after all table aliases are constructed · 15e3e9cd
      Ryuta Kamizono 提交于
      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.
      15e3e9cd
  20. 07 6月, 2018 1 次提交
    • R
      Fix GROUP BY queries to apply LIMIT/OFFSET after aggregations · 63e35a13
      Ryuta Kamizono 提交于
      If `eager_loading` is true, `apply_join_dependency` force applies
      LIMIT/OFFSET before JOINs by `limited_ids_for` to keep parent records
      count. But for aggregation queries, LIMIT/OFFSET should be applied after
      aggregations the same as SQL semantics.
      
      And also, we could not replace SELECT list by `limited_ids_for` when a
      query has a GROUP BY clause. It had never been worked since it will
      causes generating invalid SQL for MySQL, PostgreSQL, and probably most
      backends.
      
      ```
      % ARCONN=postgresql be ruby -w -Itest test/cases/calculations_test.rb -n test_group_by_with_limit
      Using postgresql
      Run options: -n test_group_by_with_limit --seed 20925
      
      # Running:
      
      E
      
      Error:
      CalculationsTest#test_group_by_with_limit:
      ActiveRecord::StatementInvalid: PG::GroupingError: ERROR:  column "posts.id" must appear in the GROUP BY clause or be used in an aggregate function
      LINE 1: SELECT  DISTINCT "posts"."id", "posts"."type" AS alias_0 FRO...                         ^
      : SELECT  DISTINCT "posts"."id", "posts"."type" AS alias_0 FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" GROUP BY "posts"."type" ORDER BY "posts"."type" ASC LIMIT $1
      ```
      
      Fixes #8103.
      Closes #27249.
      63e35a13
  21. 04 3月, 2018 1 次提交
  22. 14 1月, 2018 1 次提交
    • R
      Don't pass garbage args to alias tracker · e9c16536
      Ryuta Kamizono 提交于
      This is a complete fix to #30995.
      
      Originally alias tracker will only track table aliases on
      `Arel::Nodes::Join`, other args are ignored.
      
      Since c5ab6e51, parent aliases hash will be passed then it caused the
      regression #30995.
      
      It is enough to pass list of `Arel::Nodes::Join` simply, not need to
      pass garbage args which will be ignored.
      e9c16536
  23. 11 1月, 2018 2 次提交
  24. 10 1月, 2018 1 次提交
  25. 07 1月, 2018 3 次提交
  26. 28 11月, 2017 1 次提交
  27. 26 11月, 2017 1 次提交
  28. 14 11月, 2017 1 次提交
  29. 06 11月, 2017 1 次提交
  30. 09 10月, 2017 3 次提交
  31. 08 10月, 2017 1 次提交
  32. 14 9月, 2017 1 次提交
  33. 25 8月, 2017 1 次提交
  34. 29 7月, 2017 1 次提交
  35. 24 7月, 2017 1 次提交
    • S
      Refactor Active Record to let Arel manage bind params · 213796fb
      Sean Griffin 提交于
      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.
      213796fb