Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.4] Fix bug related to sub select queries and extra select statements. #19013

Merged
merged 1 commit into from May 1, 2017
Merged

[5.4] Fix bug related to sub select queries and extra select statements. #19013

merged 1 commit into from May 1, 2017

Conversation

ghost
Copy link

@ghost ghost commented Apr 30, 2017

The sub select query must have only one selected column otherwise sql
will throw an error.

If a sub select function (e.g. withCount) is called with a model that
has select queries as a global scope this will cause the error.

The first column is the intended column for the sub select. Any global scope columns will be added after that. To avoid the error the columns array is reduced to just the first column.

This fix only applies to global scopes that use addSelect/selectRaw/withCount. If the select function is used it will replace all the columns and the sub select will return the first column in that select statement.

The sub select query must have only one selected column otherwise sql
will throw an error.

If a sub select function (e.g. withCount) is called with a model that
has select queries as a global scope this will cause the error.
@laurencei
Copy link
Contributor

laurencei commented Apr 30, 2017

Can you show a code example where this occurs? How would I replicate the error?

@ghost
Copy link
Author

ghost commented Apr 30, 2017

I'll give the example that lead me to find the bug.
Three models: User, Thread, Reply.
A user hasMany threads and replies.
A thread hasMany replies.
Lets say whenever you fetch the threads you want the reply count, so you add a global scope:

    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('replyCount', function (Builder $builder) {
            $builder->withCount('replies');
        });
    }

Now lets say you want to retrieve the users with their thread count:

    $users = User::withCount('threads')->get();

That code will then produce the following error:

SQLSTATE[HY000]: General error: 1 sub-select returns 2 columns - expected 1 (SQL: select "users".*, (select count(*), (select count(*) from "replies" where "threads"."id" = "replies"."thread_id") as "replies_count" from "threads" where "users"."id" = "threads"."user_id") as "threads_count" from "users")

I wrote a test which produces the invalid query in the commit.

@tillkruss tillkruss changed the title Fix bug related to sub select queries and extra select statements. [5.4] Fix bug related to sub select queries and extra select statements. May 1, 2017
@taylorotwell taylorotwell merged commit 432816b into laravel:5.4 May 1, 2017
taylorotwell pushed a commit that referenced this pull request Mar 1, 2018
…3357)

A previous pull request #19013, which aimed to solve the issue of multiple select statements causing an SQL error within a withCount function, assumed a sub query would only need one select statement.

This is not the case, so the code that removes excess filters is moved to the withCount method where the sub query does only need one select.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants