Skip to content

6.0.0.rc1: ActiveRecord builds a query using INNER JOIN instead of LEFT OUTER JOIN #36103

@sinsoku

Description

@sinsoku

Steps to reproduce

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # gem "rails", '5.2.3'
  gem "rails", '6.0.0.rc1'
  # gem "rails", github: 'rails/rails'
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :user, force: true do |t|
  end

  create_table :posts, force: true do |t|
    t.integer :user_id
  end

  create_table :comments, force: true do |t|
    t.integer :post_id
  end
end

class User < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments

  scope :no_comments, lambda {
    left_joins(:comments).where(comments: { id: nil })
  }
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

class BugTest < Minitest::Test
  def test_sql
    expected = 'SELECT "users".* FROM "users" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE "comments"."id" IS NULL'
    assert_equal expected, User.all.merge(Post.no_comments).to_sql

    # This assertion is successful on 5.2.3, but it is failed on 6.0.0.rc1.
    #
    # Failure:
    # BugTest#test_sql [ar_merge.rb:57]:
    # --- expected
    # +++ actual
    # @@ -1 +1 @@
    # -"SELECT \"users\".* FROM \"users\" LEFT OUTER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\" WHERE \"comments\".\"id\" IS NULL"
    # +"SELECT \"users\".* FROM \"users\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\" WHERE \"comments\".\"id\" IS NULL"
  end
end

Expected behavior

I expected the same behavior as v5.2.3.

Actual behavior

ActiveRecord builds a query using INNER JOIN instead of LEFT OUTER JOIN.

System configuration

Rails version: 6.0.0.rc1

Ruby version: ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-darwin17]

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions