From 6ccf7a7ac704242a5adef43695e4f35c2f9542c0 Mon Sep 17 00:00:00 2001 From: Stefan Klug Date: Tue, 18 Sep 2012 11:57:39 +0200 Subject: [PATCH] fixed Parser which incorrectly treated ((( as function --- lib/Doctrine/ORM/Query/Parser.php | 64 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php index 0b9bb5bd3..3fccca1d1 100644 --- a/lib/Doctrine/ORM/Query/Parser.php +++ b/lib/Doctrine/ORM/Query/Parser.php @@ -507,13 +507,14 @@ class Parser */ private function isFunction() { - $peek = $this->lexer->peek(); - $nextpeek = $this->lexer->peek(); + $lookaheadType = $this->lexer->lookahead['type']; + $peek = $this->lexer->peek(); + $nextpeek = $this->lexer->peek(); $this->lexer->resetPeek(); // We deny the COUNT(SELECT * FROM User u) here. COUNT won't be considered a function - return ($peek['type'] === Lexer::T_OPEN_PARENTHESIS && $nextpeek['type'] !== Lexer::T_SELECT); + return ($lookaheadType >= Lexer::T_IDENTIFIER && $peek['type'] === Lexer::T_OPEN_PARENTHESIS && $nextpeek['type'] !== Lexer::T_SELECT); } /** @@ -1786,9 +1787,10 @@ class Parser public function ScalarExpression() { $lookahead = $this->lexer->lookahead['type']; + $peek = $this->lexer->glimpse(); - switch ($lookahead) { - case Lexer::T_IDENTIFIER: + switch (true) { + case ($lookahead === Lexer::T_IDENTIFIER && $peek['type'] === Lexer::T_DOT): $this->lexer->peek(); // lookahead => '.' $this->lexer->peek(); // lookahead => token after '.' $peek = $this->lexer->peek(); // lookahead => token after the token after the '.' @@ -1800,47 +1802,55 @@ class Parser return $this->StateFieldPathExpression(); - case Lexer::T_INTEGER: - case Lexer::T_FLOAT: + case ($lookahead === Lexer::T_INTEGER): + case ($lookahead === Lexer::T_FLOAT): return $this->SimpleArithmeticExpression(); - case Lexer::T_STRING: + case ($lookahead === Lexer::T_STRING): return $this->StringPrimary(); - case Lexer::T_TRUE: - case Lexer::T_FALSE: + case ($lookahead === Lexer::T_TRUE): + case ($lookahead === Lexer::T_FALSE): $this->match($lookahead); return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token['value']); - case Lexer::T_INPUT_PARAMETER: + case ($lookahead === Lexer::T_INPUT_PARAMETER): return $this->InputParameter(); - case Lexer::T_CASE: - case Lexer::T_COALESCE: - case Lexer::T_NULLIF: + case ($lookahead === Lexer::T_CASE): + case ($lookahead === Lexer::T_COALESCE): + case ($lookahead === Lexer::T_NULLIF): // Since NULLIF and COALESCE can be identified as a function, // we need to check if before check for FunctionDeclaration return $this->CaseExpression(); - default: - if ( ! ($this->isFunction() || $this->isAggregateFunction($lookahead))) { - $this->syntaxError(); - } - - // We may be in an ArithmeticExpression (find the matching ")" and inspect for Math operator) + case ($this->isFunction()): $this->lexer->peek(); // "(" - $peek = $this->peekBeyondClosingParenthesis(); - if ($this->isMathOperator($peek)) { - return $this->SimpleArithmeticExpression(); + switch (true) { + case ($this->isMathOperator($this->peekBeyondClosingParenthesis())): + // SUM(u.id) + COUNT(u.id) + return $this->SimpleArithmeticExpression(); + break; + + case ($this->isAggregateFunction($this->lexer->lookahead['type'])): + return $this->AggregateExpression(); + break; + + default: + // IDENTITY(u) + return $this->FunctionDeclaration(); + break; } - if ($this->isAggregateFunction($this->lexer->lookahead['type'])) { - return $this->AggregateExpression(); - } + break; - return $this->FunctionDeclaration(); + case ($lookahead === Lexer::T_OPEN_PARENTHESIS): + return $this->SimpleArithmeticExpression(); + + default: + $this->syntaxError(); } }