dibi
dibi copied to clipboard
SqlsrvDriver: offset must have a order by
- bug fix
Limitations in Using OFFSET-FETCH ORDER BY is mandatory to use OFFSET and FETCH clause.
OFFSET clause is mandatory with FETCH. You can never use, ORDER BY … FETCH.
TOP cannot be combined with OFFSET and FETCH in the same query expression.
The OFFSET/FETCH rowcount expression can be any arithmetic, constant, or parameter expression that will return an integer value. The rowcount expression does not support scalar sub-queries.
https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx
I think ORDER BY must be added by programmer, because he knows how to order rows. ORDER BY 1 solves nothing.
But the queries you have in the tests do not pass to MSSQL. "SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY" ends with MSSQL error. Furthermore, FetchSingle() does not pass a simple query, and it does problems with addons like datagrid, etc.
But the queries you have in the tests do not pass to MSSQL. "SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY" ends with MSSQL error.
So tests should be fixed, or not?
Furthermore, FetchSingle() does not pass a simple query, and it does problems with addons like datagrid, etc.
Can you send here example code?
Perhaps we could throw an exception instead from SqlsrvDriver and PdoDriver (the sqlsrv case of applyLimit()) for SQL Server >= 2012, explaining that order must be specified in order to apply the limit? It fails with Incorrect syntax near '0' anyway, so it wouldn't cause a BC break.
I think that would be a good hint for simple cases like:
$dibi->select('*')->from('table')->fetch();
When I read this, I assume it does something like this:
SELECT TOP 1 * FROM [table]
ORDER BY 1 doesn't seem right to me, that might end up in getting an unexpected result, as you are sorting by first column of your query (from SELECT clause), which might be different from the default order (primary key).
If we don't want to force the programmer to order the query, fallback to SELECT TOP 1 ... might be a better option and might actually work without a subquery, since we don't need to offset the result.