From fe672d2f612e4ba3b329271725545b574cc4df42 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 28 Dec 2010 10:17:33 +0100 Subject: [PATCH] DDC-617 - Throw error if selecting identification variables without picking at least one root entity alias. --- lib/Doctrine/ORM/Query/Parser.php | 56 ++++-- .../ORM/Query/LanguageRecognitionTest.php | 186 +++++++++--------- .../ORM/Query/SelectSqlGenerationTest.php | 2 +- 3 files changed, 140 insertions(+), 104 deletions(-) diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index 26dfb0535..0c22c9fbf 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -277,20 +277,8 @@ class Parser { $AST = $this->getAST(); - // Fix order of identification variables. - // They have to appear in the select clause in the same order as the - // declarations (from ... x join ... y join ... z ...) appear in the query - // as the hydration process relies on that order for proper operation. - if ( count($this->_identVariableExpressions) > 1) { - foreach ($this->_queryComponents as $dqlAlias => $qComp) { - if (isset($this->_identVariableExpressions[$dqlAlias])) { - $expr = $this->_identVariableExpressions[$dqlAlias]; - $key = array_search($expr, $AST->selectClause->selectExpressions); - unset($AST->selectClause->selectExpressions[$key]); - $AST->selectClause->selectExpressions[] = $expr; - } - } - } + $this->fixIdentificationVariableOrder($AST); + $this->assertSelectEntityRootAliasRequirement(); if (($customWalkers = $this->_query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) !== false) { $this->_customTreeWalkers = $customWalkers; @@ -332,6 +320,46 @@ class Parser return $this->_parserResult; } + + private function assertSelectEntityRootAliasRequirement() + { + if ( count($this->_identVariableExpressions) > 0) { + $foundRootEntity = false; + foreach ($this->_identVariableExpressions AS $dqlAlias => $expr) { + if (isset($this->_queryComponents[$dqlAlias]) && $this->_queryComponents[$dqlAlias]['parent'] === null) { + $foundRootEntity = true; + } + } + + if (!$foundRootEntity) { + $this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.'); + } + } + } + + /** + * Fix order of identification variables. + * + * They have to appear in the select clause in the same order as the + * declarations (from ... x join ... y join ... z ...) appear in the query + * as the hydration process relies on that order for proper operation. + * + * @param AST\SelectStatement|AST\DeleteStatement|AST\UpdateStatement $AST + * @return void + */ + private function fixIdentificationVariableOrder($AST) + { + if ( count($this->_identVariableExpressions) > 1) { + foreach ($this->_queryComponents as $dqlAlias => $qComp) { + if (isset($this->_identVariableExpressions[$dqlAlias])) { + $expr = $this->_identVariableExpressions[$dqlAlias]; + $key = array_search($expr, $AST->selectClause->selectExpressions); + unset($AST->selectClause->selectExpressions[$key]); + $AST->selectClause->selectExpressions[] = $expr; + } + } + } + } /** * Generates a new syntax error. diff --git a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php b/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php index aab94c9dc..0ebe1aafe 100644 --- a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php +++ b/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php @@ -15,7 +15,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase $this->_em = $this->_getTestEntityManager(); } - public function assertValidDql($dql, $debug = false) + public function assertValidDQL($dql, $debug = false) { try { $parserResult = $this->parseDql($dql); @@ -28,7 +28,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase } } - public function assertInvalidDql($dql, $debug = false) + public function assertInvalidDQL($dql, $debug = false) { try { $parserResult = $this->parseDql($dql); @@ -62,311 +62,311 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase public function testEmptyQueryString() { - $this->assertInvalidDql(''); + $this->assertInvalidDQL(''); } public function testPlainFromClauseWithAlias() { - $this->assertValidDql('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testSelectSingleComponentWithAsterisk() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testSelectSingleComponentWithMultipleColumns() { - $this->assertValidDql('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testSelectMultipleComponentsUsingMultipleFrom() { - $this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user'); + $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user'); } public function testSelectMultipleComponentsWithAsterisk() { - $this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p'); } public function testSelectDistinctIsSupported() { - $this->assertValidDql('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testAggregateFunctionInSelect() { - $this->assertValidDql('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testDuplicatedAliasInAggregateFunction() { - $this->assertInvalidDql('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertInvalidDQL('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testAggregateFunctionWithDistinctInSelect() { - $this->assertValidDql('SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testFunctionalExpressionsSupportedInWherePart() { - $this->assertValidDql("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'"); + $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'"); } public function testArithmeticExpressionsSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000'); } public function testInExpressionSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)'); } public function testInExpressionWithoutSpacesSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1,2,3)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1,2,3)'); } public function testNotInExpressionSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)'); } public function testInExpressionWithSingleValuedAssociationPathExpression() { - $this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)"); + $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)"); } public function testInvalidInExpressionWithCollectionValuedAssociationPathExpression() { - $this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IN (?1, ?2)"); + $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IN (?1, ?2)"); } public function testInstanceOfExpressionSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee'); } public function testInstanceOfExpressionWithInputParamSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1'); } public function testNotInstanceOfExpressionSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u NOT INSTANCE OF ?1'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u NOT INSTANCE OF ?1'); } public function testExistsExpressionSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)'); } public function testNotExistsExpressionSupportedInWherePart() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)'); } public function testAggregateFunctionInHavingClause() { - $this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING COUNT(p.phonenumber) > 2'); - $this->assertValidDql("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING MAX(u.name) = 'romanb'"); + $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING COUNT(p.phonenumber) > 2'); + $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING MAX(u.name) = 'romanb'"); } public function testLeftJoin() { - $this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p'); } public function testJoin() { - $this->assertValidDql('SELECT u,p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u,p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p'); } public function testInnerJoin() { - $this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p'); } public function testMultipleLeftJoin() { - $this->assertValidDql('SELECT u, a, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a LEFT JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u, a, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a LEFT JOIN u.phonenumbers p'); } public function testMultipleInnerJoin() { - $this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INNER JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INNER JOIN u.phonenumbers p'); } public function testMixingOfJoins() { - $this->assertValidDql('SELECT u.name, a.topic, p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a LEFT JOIN u.phonenumbers p'); + $this->assertValidDQL('SELECT u.name, a.topic, p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a LEFT JOIN u.phonenumbers p'); } public function testOrderBySingleColumn() { - $this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name'); + $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name'); } public function testOrderBySingleColumnAscending() { - $this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name ASC'); + $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name ASC'); } public function testOrderBySingleColumnDescending() { - $this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name DESC'); + $this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name DESC'); } public function testOrderByMultipleColumns() { - $this->assertValidDql('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username DESC, u.name DESC'); + $this->assertValidDQL('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username DESC, u.name DESC'); } public function testSubselectInInExpression() { - $this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = 'zYne')"); + $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = 'zYne')"); } public function testSubselectInSelectPart() { - $this->assertValidDql("SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); + $this->assertValidDQL("SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); } public function testArithmeticExpressionInSelectPart() { - $this->assertValidDql("SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u"); + $this->assertValidDQL("SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u"); } public function testArithmeticExpressionInSubselectPart() { - $this->assertValidDql("SELECT (SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); + $this->assertValidDQL("SELECT (SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); } public function testArithmeticExpressionWithParenthesisInSubselectPart() { - $this->assertValidDql("SELECT (SELECT (SUM(u.id) / COUNT(u.id)) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); + $this->assertValidDQL("SELECT (SELECT (SUM(u.id) / COUNT(u.id)) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); } public function testDuplicateAliasInSubselectPart() { - $this->assertInvalidDql("SELECT (SELECT SUM(u.id) / COUNT(u.id) AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u2) foo FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); + $this->assertInvalidDQL("SELECT (SELECT SUM(u.id) / COUNT(u.id) AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u2) foo FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'"); } public function testPositionalInputParameter() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1'); } public function testNamedInputParameter() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id'); } public function testJoinConditionOverrideNotSupported() { - $this->assertInvalidDql("SELECT u.name, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p ON p.phonenumber = '123 123'"); + $this->assertInvalidDQL("SELECT u.name, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p ON p.phonenumber = '123 123'"); } public function testIndexByClauseWithOneComponent() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id'); } public function testIndexBySupportsJoins() { - $this->assertValidDql('SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a INDEX BY a.id'); // INDEX BY is now referring to articles + $this->assertValidDQL('SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a INDEX BY a.id'); // INDEX BY is now referring to articles } public function testIndexBySupportsJoins2() { - $this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p INDEX BY p.phonenumber'); + $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p INDEX BY p.phonenumber'); } public function testBetweenExpressionSupported() { - $this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name BETWEEN 'jepso' AND 'zYne'"); + $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name BETWEEN 'jepso' AND 'zYne'"); } public function testNotBetweenExpressionSupported() { - $this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT BETWEEN 'jepso' AND 'zYne'"); + $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT BETWEEN 'jepso' AND 'zYne'"); } public function testLikeExpression() { - $this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z%'"); + $this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z%'"); } public function testNotLikeExpression() { - $this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT LIKE 'z%'"); + $this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT LIKE 'z%'"); } public function testLikeExpressionWithCustomEscapeCharacter() { - $this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'"); + $this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'"); } public function testFieldComparisonWithoutAlias() { - $this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE id = 1"); + $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE id = 1"); } public function testDuplicatedAliasDeclaration() { - $this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles u WHERE u.id = 1"); + $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles u WHERE u.id = 1"); } public function testImplicitJoinInWhereOnSingleValuedAssociationPathExpression() { // This should be allowed because avatar is a single-value association. // SQL: SELECT ... FROM forum_user fu INNER JOIN forum_avatar fa ON fu.avatar_id = fa.id WHERE fa.id = ? - $this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a WHERE a.id = ?1"); + $this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a WHERE a.id = ?1"); } public function testImplicitJoinInWhereOnCollectionValuedPathExpression() { // This should be forbidden, because articles is a collection - $this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a WHERE a.title = ?"); + $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a WHERE a.title = ?"); } public function testInvalidSyntaxIsRejected() { - $this->assertInvalidDql("FOOBAR CmsUser"); - $this->assertInvalidDql("DELETE FROM Doctrine\Tests\Models\CMS\CmsUser.articles"); - $this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles.comments"); + $this->assertInvalidDQL("FOOBAR CmsUser"); + $this->assertInvalidDQL("DELETE FROM Doctrine\Tests\Models\CMS\CmsUser.articles"); + $this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles.comments"); // Currently UNDEFINED OFFSET error - $this->assertInvalidDql("SELECT c FROM CmsUser.articles.comments c"); + $this->assertInvalidDQL("SELECT c FROM CmsUser.articles.comments c"); } public function testUpdateWorksWithOneField() { - $this->assertValidDql("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone'"); + $this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone'"); } public function testUpdateWorksWithMultipleFields() { - $this->assertValidDql("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone', u.username = 'some'"); + $this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone', u.username = 'some'"); } public function testUpdateSupportsConditions() { - $this->assertValidDql("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone' WHERE u.id = 5"); + $this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone' WHERE u.id = 5"); } public function testDeleteAll() { - $this->assertValidDql('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testDeleteWithCondition() { - $this->assertValidDql('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = 3'); + $this->assertValidDQL('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = 3'); } /** @@ -375,94 +375,94 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase */ public function testImplicitJoinWithCartesianProductAndConditionInWhere() { - $this->assertValidDql("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.name = a.topic"); + $this->assertValidDQL("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.name = a.topic"); } public function testAllExpressionWithCorrelatedSubquery() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); } public function testCustomJoinsAndWithKeywordSupported() { - $this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p WITH p.phonenumber = 123 WHERE u.id = 1'); + $this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p WITH p.phonenumber = 123 WHERE u.id = 1'); } public function testAnyExpressionWithCorrelatedSubquery() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ANY (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ANY (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); } public function testSomeExpressionWithCorrelatedSubquery() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); } public function testArithmeticExpressionWithoutParenthesisInWhereClause() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) + 1 > 10'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) + 1 > 10'); } public function testMemberOfExpression() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers'); - //$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE 'Joe' MEMBER OF u.nicknames"); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers'); + //$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE 'Joe' MEMBER OF u.nicknames"); } public function testSizeFunction() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1'); } public function testEmptyCollectionComparisonExpression() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY'); } public function testSingleValuedAssociationFieldInWhere() { - $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1'); - $this->assertValidDql('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1'); + $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1'); + $this->assertValidDQL('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1'); } public function testBooleanLiteralInWhere() { - $this->assertValidDql('SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true'); + $this->assertValidDQL('SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true'); } public function testSubqueryInSelectExpression() { - $this->assertValidDql('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u'); } public function testUsageOfQComponentOutsideSubquery() { - $this->assertInvalidDql('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u WHERE p.user = ?1'); + $this->assertInvalidDQL('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u WHERE p.user = ?1'); } public function testUnknownAbstractSchemaName() { - $this->assertInvalidDql('SELECT u FROM UnknownClassName u'); + $this->assertInvalidDQL('SELECT u FROM UnknownClassName u'); } public function testCorrectPartialObjectLoad() { - $this->assertValidDql('SELECT PARTIAL u.{id,name} FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT PARTIAL u.{id,name} FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testIncorrectPartialObjectLoadBecauseOfMissingIdentifier() { - $this->assertInvalidDql('SELECT PARTIAL u.{name} FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertInvalidDQL('SELECT PARTIAL u.{name} FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testScalarExpressionInSelect() { - $this->assertValidDql('SELECT u, 42 + u.id AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT u, 42 + u.id AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'); } public function testInputParameterInSelect() { - $this->assertValidDql('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'); + $this->assertValidDQL('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'); } /** @@ -470,7 +470,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase */ public function testDQLKeywordInJoinIsAllowed() { - $this->assertValidDql('SELECT u FROM ' . __NAMESPACE__ . '\DQLKeywordsModelUser u JOIN u.group g'); + $this->assertValidDQL('SELECT u FROM ' . __NAMESPACE__ . '\DQLKeywordsModelUser u JOIN u.group g'); } /** @@ -478,15 +478,23 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase */ public function testDQLKeywordInConditionIsAllowed() { - $this->assertValidDql('SELECT g FROM ' . __NAMESPACE__ . '\DQLKeywordsModelGroup g WHERE g.from=0'); + $this->assertValidDQL('SELECT g FROM ' . __NAMESPACE__ . '\DQLKeywordsModelGroup g WHERE g.from=0'); } /* The exception is currently thrown in the SQLWalker, not earlier. public function testInverseSideSingleValuedAssociationPathNotAllowed() { - $this->assertInvalidDql('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1'); + $this->assertInvalidDQL('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1'); } */ + + /** + * @group DDC-617 + */ + public function testSelectOnlyNonRootEntityAlias() + { + $this->assertInvalidDQL('SELECT g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g'); + } } /** @Entity */ diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 94c41c50d..ecc32fe56 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -325,7 +325,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase public function testSupportsMultipleJoins() { $this->assertSqlGeneration( - 'SELECT u.id, a.id, p, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c', + 'SELECT u.id, a.id, p.phonenumber, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c', 'SELECT c0_.id AS id0, c1_.id AS id1, c2_.phonenumber AS phonenumber2, c3_.id AS id3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id INNER JOIN cms_phonenumbers c2_ ON c0_.id = c2_.user_id INNER JOIN cms_comments c3_ ON c1_.id = c3_.article_id' ); }