-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
fixed PostgreSQL and Oracle pagination issues #1325
Conversation
Pagination with ordering on 1:m and m:m relations, was not working properly because of selecting the ordered fields in main select statement with distinction (e.g. SELECT DISTINCT e0_.id, p1_.name from ... ) in this case we've received less rows than we've required in query. So I've modified the subquery generation part. In case of PostgreSQL and Oracle added the row_number in the subquery over order by statement, then the main select is grouped by id and selected min of row number, also ordering by rownumber asc, because they are on right order already (e.g. select e0_.id, min(rownum) as rownum from ..... order by rownum). In case of MySQL, the subselect result with ids are in right order so there is no need to select that fields(this fixes the same issue too) In other cases I haven't tested because of that leaved the same.
Hello, thank you for creating this pull request. I have automatically opened an issue http://www.doctrine-project.org/jira/browse/DDC-3606 We use Jira to track the state of pull requests and the versions they got |
* which are participated in order by statement, arent selected in | ||
* main select statement. | ||
*/ | ||
if($this->platform->getName() == 'mysql'){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cs, missing spaces if (
, ) {
@TomasVotruba please let me know, should I have to modify the tests for CI? Thanks. |
} | ||
$globalOrderByStmt = SqlWalker::walkOrderByClause($AST->orderByClause); | ||
|
||
$innerRowNumberSelectPart = ' ROW_NUMBER() OVER(%s) as ROWNUM'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AS
should be kept capital, to be consistent in the tests.
@vaheshadunts Not sure. The output should remain the same. E. g. you can solve |
@vaheshadunts: Have you seen the comments in the issue linked in code. The same affects mssql >= 2008, mariadb >= 5.5, and probably mysql 5.6 |
@TomasVotruba Thank you for advices, anyway I've modified the tests as my queries should be generated. |
@mrhov thanks for your comment, so are you suggesting to override my code on the versions that you've listed ? |
Well I don't know the fix for those versions as I'm using a postgresql for the past few years exclusively. I'm just bringing this to your attention. There were a couple of bug fixes regarding the code around pagination in the past couple of months. So I'm advising you to be careful. |
@deeky666 I think that before merging any new bugfix about the pagination, we should introduce a functional testsuite for the pagination, i.e. running the paginated queries against the DB and asserting the result instead of only doing assertions on the generated SQL. This is the only way we can know that the pagination works properly. |
); | ||
|
||
// http://www.doctrine-project.org/jira/browse/DDC-1958 | ||
if ($this->platform->getName() == 'postgresql' || $this->platform->getName() == 'oracle') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use instanceof
here
Absolutely in line with what @stof suggested. |
@Ocramius thank you for your comments, If you want to see the before/after differences on a small data I can demo it for you, please let me know. |
Consider reviewing #1337 before thinking of working further on this. |
…into hotfix/doctrine#1342-paginator-functional-test-integration
Hi @Ocramius , I've tested the PR #1337 , works fine, but it doesn't solve the issues which I have listed and solved in this PR, anyway if you if you don't mind, I'll merge the #1337 and this PR, and will made a new PR soon. Please let me know your opinion about this. Thanks. P.S. please let me know If you have a some notices about code stylistics. |
@vaheshadunts open a new PR: I'll gladly review. |
ok @Ocramius , I'll do it ASAP |
@Ocramius after #1337 issues are more than before. Also I agree with #1337 and with #1220 that LimitSubqueryOutputWalker should not duplicate orderBy clauses, BUT we couldn't get a correct result with DISTINCT {array_merge(sqlIdentifier, sqlOrderColumns)} clause, please let me know if you're agree with this. Also in SQL we are not able to do ordering without selecting them. Unfortunately in the postgreSQL and Oracle, the subquery order result doesn't affect on the main query (thats how born the idea, to select a row number, like we did in MSSQL). At the other side we don't need to duplicate the ordered fields, thats why I've decided to MOVE that fields into subquery, and do not order them (that solved the SELECT DISTINCTION problem, using order by rownumber expression with grouping id of the entity from 'FROM' clause). Whats the problem
If we'll continue with #1337 we will not be able to use row_number and group manipulations to solve this issue. Now please pay attention to the #1325's generated query
Please let me know Excuse me for such a long comment, I'm ready to discuss with you. Thanks a lot !! DEMOS: NOTE: Please pay attention to count that printed out in demo, that's the result of count(Paginator instance); |
@vaheshadunts - that could work... is there any way you could add a testcase to https://github.com/doctrine/doctrine2/blob/master/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php? I think I can probably get this fixed this afternoon. |
@vaheshadunts @Ocramius I tried to make a failing testcase here: https://github.com/zeroedin-bill/doctrine2/tree/DDC-3606-testcase and was not able to reproduce the problem... Am I missing something? |
@zeroedin-bill sorry for late answer, I was away, as it was night in out country. So to fail tests we need to have 2 departments in one company which names are next to each other with alphabetical order, in that case the test fails. In your testcase you're doing assertions on count and names, but count of paginator working correct (CountOutputWalker class works fine), and with names. that will be ok too, I think we need to do assertion after iteration $i === 0, what do you think ? Please have a look at my comments in https://github.com/zeroedin-bill/doctrine2/blob/DDC-3606-testcase/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php |
@vaheshadunts - There's an assertion on the count of $companies, which will be an array with 9 items - after iteration, $i must be 0 or the test fails, so the extra assertion wouldn't matter. I can look at this more tonight - Do you think you could convert your example into a self-contained testcase? That might be the easiest way. |
@vaheshadunts if there are still cases where the pagination is broken, please start by adding more cases in the pagination functional tests to show these issues (and prevent regressions breaking them again in the future). |
@zeroedin-bill please have a look at my demo examples. the count works correct as the Paginator implements Countable interface, and count is set by CountOutputWalker, so count($paginator) is correct, thats why I want to assert $i === 0, please have a look this demo http://dev.progarithm.com:8000/paging/pgsql/web/ . Pay attention on first result, output is one family but count is 2.. Sure I can build a testcase, but please try with my notes on your testcase, I think it should work.. P.S. please tell me your timezone. |
@vaheshadunts I tried your notes on my testcase - Didn't work... have to go catch a plane now... Please build your example as a testcase - thanks! |
sure @zeroedin-bill |
@zeroedin-bill https://github.com/vaheshadunts/doctrine2/tree/pagination-order-tests Thanks |
Pagination with ordering on 1:m and m:m relations, was not working
properly because of selecting the ordered fields in main select
statement with distinction (e.g. SELECT DISTINCT e0_.id, p1_.name from
... ) in this case we've received less rows than we've required in
query. So I've modified the subquery generation part.
In case of PostgreSQL and Oracle added the row_number in the subquery
over order by statement, then the main select is grouped by id and
selected min of row number, also ordering by rownumber asc, because they
are on right order already (e.g. select e0_.id, min(rownum) as rownum
from ..... order by rownum).
In case of MySQL, the subselect result with ids are in right order so
there is no need to select that fields(this fixes the same issue too)
In other cases I haven't tested because of that leaved the same.