Skip to content

[12.x] Fix: Make Paginated Queries Consistent Across Pages#55176

Merged
taylorotwell merged 2 commits into
laravel:12.xfrom
tomchkk:fix/query-failure-in-paged-queries
Mar 27, 2025
Merged

[12.x] Fix: Make Paginated Queries Consistent Across Pages#55176
taylorotwell merged 2 commits into
laravel:12.xfrom
tomchkk:fix/query-failure-in-paged-queries

Conversation

@tomchkk

@tomchkk tomchkk commented Mar 26, 2025

Copy link
Copy Markdown
Contributor

Problem

When using Illuminate\Database\Query\Builder methods orderedChunkById and orderedLazyById without specifying $column and $alias property values, where the query includes a join on another table, the query for the first page may work as expected while the query for subsequent pages may throw Illuminate\Database\QueryException with the following message:

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous...

The cause of this issue is that the query for the first page doesn't include a where clause for the id column, but the subsequent queries do. So it may not be clear that the column is ambiguous until at least the query for the second page is run.

-- page 1 passes
select * from users join profiles on profiles.user_id = users.id order by id asc limit 15
-- page 2 fails due to ambiguity in where clause
select * from users join profiles on profiles.user_id = users.id where id > 15 order by id asc limit 15

Impact

In non-production environments, since it's common to encounter a smaller dataset, use of these methods without the mentioned properties may work without a problem. However, when releasing a feature into an environment with a large enough dataset to cause the paged query to run more than once, suddenly a working, tested change may fail.

Solution

The PR modifies the forPageBeforeId and forPageAfterId methods in Illuminate\Database\Query\Builder to always include a where clause on the given $column property; specifically, if property $lastId evaluates to null, the clause $this->whereNotNull($column) is added.

-- page 1 fails due to ambiguity in where clause
select * from users join profiles on profiles.user_id = users.id where id is not null order by id asc limit 15
-- page 2 fails due to ambiguity in where clause
select * from users join profiles on profiles.user_id = users.id where id > 15 order by id asc limit 15

Benefits

The benefit of always including a where clause on the given column name is that any ambiguity in the query is immediately evident, even when used on a small dataset.

@taylorotwell taylorotwell merged commit 16ad066 into laravel:12.x Mar 27, 2025
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.

2 participants