From 3ab6ad23ad16497be818d26fce01a76309c5cba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Wed, 2 May 2012 19:06:43 +0200 Subject: [PATCH] DDC-1802 fixed parsing: FunctionDeclaration "NOT" ("LIKE" | "IN" | "BETWEEN") --- lib/Doctrine/ORM/Query/Parser.php | 21 +++++++++++++------ .../ORM/Query/SelectSqlGenerationTest.php | 20 ++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index 7b9a67135..f8c8d1c4c 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -416,9 +416,10 @@ class Parser /** * Peek beyond the matched closing parenthesis and return the first token after that one. * + * @param boolean $resetPeek Reset peek after finding the closing parenthesis * @return array */ - private function _peekBeyondClosingParenthesis() + private function _peekBeyondClosingParenthesis($resetPeek = true) { $token = $this->_lexer->peek(); $numUnmatched = 1; @@ -440,7 +441,9 @@ class Parser $token = $this->_lexer->peek(); } - $this->_lexer->resetPeek(); + if ($resetPeek) { + $this->_lexer->resetPeek(); + } return $token; } @@ -541,7 +544,7 @@ class Parser foreach ($expr->partialFieldSet as $field) { if (isset($class->fieldMappings[$field])) { - continue; + continue; } $this->semanticalError( @@ -1335,7 +1338,7 @@ class Parser break; case ($glimpse['type'] === Lexer::T_DOT): $expr = $this->SingleValuedPathExpression(); - + break; case ($this->_lexer->peek() && $this->_isMathOperator($this->_peekBeyondClosingParenthesis())): $expr = $this->ScalarExpression(); @@ -2206,7 +2209,13 @@ class Parser if ($peek['value'] == '(') { // Peek beyond the matching closing paranthesis ')' $this->_lexer->peek(); - $token = $this->_peekBeyondClosingParenthesis(); + $token = $this->_peekBeyondClosingParenthesis(false); + + if ($token['type'] === Lexer::T_NOT) { + $token = $this->_lexer->peek(); + } + + $this->_lexer->resetPeek(); } else { // Peek beyond the PathExpression (or InputParameter) $peek = $this->_lexer->peek(); @@ -2658,7 +2667,7 @@ class Parser ? $this->SingleValuedPathExpression() : $this->SimpleArithmeticExpression(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(Lexer::T_CLOSE_PARENTHESIS); return new AST\AggregateExpression($functionName, $pathExp, $isDistinct); } diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index 40bbbaab7..a89190eb9 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -854,6 +854,26 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ); } + /** + * @group DDC-1802 + */ + public function testStringFunctionNotLikeExpression() + { + $this->assertSqlGeneration( + "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) NOT LIKE '%foo OR bar%'", + "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) NOT LIKE '%foo OR bar%'" + ); + + $this->assertSqlGeneration( + "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE UPPER(LOWER(u.name)) NOT LIKE UPPER(LOWER(:str))", + "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(LOWER(c0_.name)) NOT LIKE UPPER(LOWER(?))" + ); + $this->assertSqlGeneration( + "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic NOT LIKE u.name", + "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic NOT LIKE c0_.name)" + ); + } + /** * @group DDC-338 */