-
Notifications
You must be signed in to change notification settings - Fork 77
Description
This is a bug.
Prerequisites
- Are you running the latest version?
- Are you reporting to the correct repository?
- Did you check the documentation?
- Did you perform a cursory search?
Description
This is a bug coming from this: https://stackoverflow.com/questions/13580826/postgresql-repeating-rows-from-limit-offset
Basically, whenever a table column is sorted by, using the table header sort action, if there are more rows with the same value on this column, and this set of data exceeds the page limit(ex Status column has Active value set for 100 users, but we only see 10 users per page - we will have 10 pages with Active users), it can be possible to see the same record from page one, on page two as well, because all rows that are returned have the same value for the non-unique column (ex: Status). In that case the database is free to return the rows in any order it wants.
On PostgreSQL I've tested and it is indeed generating a random order for the records with the same ordered-by-non-unique-column, and I can see record ID 197 on page 1,3,4...
On MySQL, I see that this is not happening, at least not on laravel-enso.com, on Company table, with Status column. In the link attached someone explained that maybe MySQL uses a cluster index ordering after the order set by query on Status, so that's why it might not behave the same.
With this context set, a possible solution for us, for PostgreSQL, is to to override the following class/method (and bind it):
vendor/laravel-enso/tables/src/Services/Data/Sorts/Sort.php
public function handle(): void
{
$sort = new CustomSort($this->config, $this->query);
if ($sort->applies()) {
$sort->handle();
//INJECT HERE AN ADDITIONAL ALWAYS-ON SORTING ON "ID" HAVING THE SAME TYPE (ASC/DESC) AS EXISTING SORT
} elseif (! $this->query->getQuery()->orders) {
$this->query->orderBy($this->config->template()->get('defaultSort'));
}
}So that in the end, no matter what the user is sorting by (ex: Status), we will add an additional sorting step, in order to avoid the repeating record issue:
Before:
... ORDER BY Table.Status ...After:
... ORDER BY Table.Status, Table.Id ...