8000 Paginator OrderBy fix take 2 by billschaller · Pull Request #1337 · doctrine/orm · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Paginator OrderBy fix take 2 #1337

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

Merged
merged 6 commits into from
Mar 24, 2015

Conversation

billschaller
Copy link
Member

This PR fixes issues created in #1220, reported in #1267. The original PR was reverted in #1283.

The issue was that in queries ordered by joined association columns, the joined column aliases did not exist in the outer query created in LimitSubqueryOutputWalker.

This PR adds functionality to LimitSubqueryOutputWalker which finds any such columns referenced in the OrderBy clause, and adds them to the SelectStatement prior to SQL generation.

@doctrinebot
Copy link

Hello,

thank you for creating this pull request. I have automatically opened an issue
on our Jira Bug Tracker for you. See the issue link:

http://www.doctrine-project.org/jira/browse/DDC-3623

We use Jira to track the state of pull requests and the versions they got
included in.

$selects = [];
if (preg_match_all('/PathExpression\([^\)]+"identificationVariable": \'([^\']*)\'[^\)]+"field": \'([^\']*)\'[^\)]+\)/i', $orderByDump, $matches, PREG_SET_ORDER)) {
foreach($matches as $match) {
$idVar = $match[1];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use named subpatterns if possible

*/
public function preserveSqlOrdering(SelectStatement $AST, array $sqlIdentifier, $innerSql, $sql)
public function preserveSqlOrdering(array $sqlIdentifier, $innerSql, $sql, $orderByClause)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm this is public API. Can we really change method signature and return type here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be private.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making it private on merge.

// Remove order by clause from the inner query
// It will be re-appended in the outer select generated by this method
$orderByClause = $AST->orderByClause;
$AST->orderByClause = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite sure if this does any harm to non SQL Server platforms which actually support ORDER BY clauses in subqueries. This might change results, no? So an option could be to throw an exception for SQL Server or just ignore the ORDER BY as done here. Please correct me if I'm wrong here...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

essentially an order by clause in a subquery without a limit applied is meaningless - there may be scenarios where ordering by in a subquery can be implemented by a DBA to help with joins on subordinate keys, but the ORM doesn't do that.

@raziel057
Copy link
Contributor

Is this ticket related to this one? #1151

@billschaller
Copy link
Member Author

@guilhermeblanco fixed capitalization

@billschaller
Copy link
Member Author

@raziel057 I believe this should fix #1151

@raziel057
Copy link
Contributor

@zeroedin-bill Ok thanks. I can check if the bug is fixed as soon as the PR is merged.

*
* @return string
*
* @throws \RuntimeException
*/
public function walkSelectStatement(SelectStatement $AST)
public function walkSelectStatement(SelectStatement $AST, $addMissingItemsFromOrderByToSelect = true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you adding an extra argument compared to the walker API ? this looks wrong to me (and it can cause issues later).

The logic needing to be shared between 2 cases should be extracted to a separate method and the case of addMissingItemsFromOrderByToSelect should use another method than walkSelectStatement for the case it needs a separate logic

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this is because the walker clones itself and then calls walkSelectStatement on the clone. The method that does the cloning and that nonsense is called from walkSelectStatement. Not sure how better to structure that call chain so as to avoid recursion and still allow the functionality.

I'm open to suggestions...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stof would it make sense to move the body of walkSelectStatement to a separate method, say doWalkSelectStatement(SelectStatement $AST, $addMissingItemsFromOrderByToSelect) and then have the main walkSelectStatement method just call that? Not sure that obfuscation would help anything but it does resolve the function signature weirdness.

Ocramius added a commit that referenced this pull request Mar 24, 2015
…sues' into hotfix/#1342-paginator-functional-test-integration
8000
@Ocramius Ocramius merged commit 4c84f54 into doctrine:master Mar 24, 2015
Ocramius added a commit that referenced this pull request Mar 24, 2015
…sues' into hotfix/#1342-paginator-functional-test-integration
@Ocramius Ocramius self-assigned this Mar 24, 2015
@mrkrstphr
Copy link
Contributor

This broke the same the thing we reported in #1267. Getting pretty much the same error:

Doctrine\DBAL\Exception\DriverException: An exception occurred while executing 'SELECT DISTINCT id_0, n0_.created FROM (SELECT n0_.id AS id_0, n0_.subject AS subject_1, n0_.short_content AS short_content_2, n0_.long_content AS long_content_3, n0_.created AS created_4, n0_.modified AS modified_5, n1_.expiration AS expiration_6, n0_.notification_type AS notification_type_7 FROM notification_alerts n1_ INNER JOIN notifications n0_ ON n1_.id = n0_.id) dctrn_result ORDER BY n0_.created DESC':

SQLSTATE[HY000]: General error: 1 no such column: n0_.created

@billschaller
Copy link
Member Author

@mrkrstphr please make a failing functional test.

@mrkrstphr
Copy link
Contributor

I'll work on putting one together later today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants
0