Skip to content

Order of JOIN statements not respected when building ActiveRecord query with merge and joins #34328

@abinoda

Description

@abinoda

I'm building a query with ActiveRecord where I do a LEFT OUTER JOIN and then use merge to do an INNER JOIN. When I pass in GithubPr.joins(:github_user) as the argument to merge, the order of the JOIN statements is not as intended, resulting in a broken SQL query.

Steps to reproduce

Here's my query with a .to_sql to print the generated SQL.

GithubPr
        .select('p', 'count(*)')
        .from("generate_series('2018-08-03', '2018-10-26', '1 week') as dates(p)")
        .joins("LEFT OUTER JOIN github_prs on github_prs.created <= p")
        .merge(GithubPr.joins(:github_user))
        .group('p')
        .order('p ASC')
        .to_sql

Expected behavior

The query I would expect would be consistent with the order of the joins I built. I expect the LEFT OUTER JOIN to be first, followed by the INNER JOIN.

SELECT p, count(*)
FROM generate_series('2018-08-03', '2018-10-26', '1 week') as dates(p)
LEFT OUTER JOIN github_prs on github_prs.created <= p
INNER JOIN "github_users" ON "github_users"."id" = "github_prs"."github_user_id"
GROUP BY p
ORDER BY p ASC

Actual behavior

The query that is generated does not respect the order of my joins. Instead, the INNER JOIN comes before the LEFT OUTER JOIN, which does not work/

SELECT p, count(*)
FROM generate_series('2018-08-03', '2018-10-26', '1 week') as dates(p)
INNER JOIN "github_users" ON "github_users"."id" = "github_prs"."github_user_id"
LEFT OUTER JOIN github_prs on github_prs.created <= p
GROUP BY p
ORDER BY p ASC

Weird workaround

I've found a weird workaround where if I pass in a custom join like this:

merge(joins('INNER JOIN github_users on github_users.id = github_prs.github_user_id'))

instead of:

merge(GithubPr.joins(:github_user))

... then the order is correct and the SQL is valid.

System configuration

Rails version: 5.2.1
Ruby version: 2.5.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions