From 4841a068be7a26f9d9f6366563eead19a7fffd40 Mon Sep 17 00:00:00 2001 From: Rajesh Sharma Date: Tue, 19 Feb 2013 20:31:52 +0545 Subject: [PATCH] [DDC-2304] accept more than 2 parameters in CONCAT function - Tested and parser validates at least 2 parameters given - test added for CONCAT function and indentation fixed - calling getConcatExpression using call_user_func_array as number of arguments is not known removing dependency to patch DBAL - maintaining backward compatibility --- .../Query/AST/Functions/ConcatFunction.php | 32 ++++++++++---- .../ORM/Query/SelectSqlGenerationTest.php | 43 +++++++++++++++++++ 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php index 2d4b7b8d1..421fe9ae7 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php @@ -22,7 +22,7 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\Lexer; /** - * "CONCAT" "(" StringPrimary "," StringPrimary ")" + * "CONCAT" "(" StringPrimary "," StringPrimary {"," StringPrimary }* ")" * * * @link www.doctrine-project.org @@ -35,18 +35,25 @@ use Doctrine\ORM\Query\Lexer; class ConcatFunction extends FunctionNode { public $firstStringPrimary; + public $secondStringPrimary; - + + public $concatExpressions = array(); + /** * @override */ public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { $platform = $sqlWalker->getConnection()->getDatabasePlatform(); - return $platform->getConcatExpression( - $sqlWalker->walkStringPrimary($this->firstStringPrimary), - $sqlWalker->walkStringPrimary($this->secondStringPrimary) - ); + + $args = array(); + + foreach ($this->concatExpressions as $expression) { + $args[] = $sqlWalker->walkStringPrimary($expression); + } + + return call_user_func_array(array($platform,'getConcatExpression'), $args); } /** @@ -56,10 +63,19 @@ class ConcatFunction extends FunctionNode { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); - + $this->firstStringPrimary = $parser->StringPrimary(); + $this->concatExpressions[] = $this->firstStringPrimary; + $parser->match(Lexer::T_COMMA); - $this->secondStringPrimary = $parser->StringPrimary(); + + $this->secondStringPrimary = $parser->StringPrimary(); + $this->concatExpressions[] = $this->secondStringPrimary; + + while ($parser->getLexer()->isNextToken(Lexer::T_COMMA)) { + $parser->match(Lexer::T_COMMA); + $this->concatExpressions[] = $parser->StringPrimary(); + } $parser->match(Lexer::T_CLOSE_PARENTHESIS); } diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index d5cfa77c4..fccacbdab 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -1887,6 +1887,49 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase 'SELECT CASE WHEN LENGTH(c0_.name) > ? THEN SUBSTRING(c0_.name FROM 0 FOR ?) ELSE TRIM(c0_.name) END AS sclr0 FROM cms_users c0_' ); } + + /** + * @group DDC-2268 + */ + + public function testSupportsMoreThanTwoParametersInConcatFunction() + { + $connMock = $this->_em->getConnection(); + $orgPlatform = $connMock->getDatabasePlatform(); + + $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform); + $this->assertSqlGeneration( + "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1", + "SELECT c0_.id AS id0 FROM cms_users c0_ WHERE CONCAT(c0_.name, c0_.status, 's') = ?" + ); + $this->assertSqlGeneration( + "SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1", + "SELECT CONCAT(c0_.id, c0_.name, c0_.status) AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?" + ); + + $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform); + $this->assertSqlGeneration( + "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1", + "SELECT c0_.id AS id0 FROM cms_users c0_ WHERE c0_.name || c0_.status || 's' = ?" + ); + $this->assertSqlGeneration( + "SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1", + "SELECT c0_.id || c0_.name || c0_.status AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?" + ); + + + $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\SQLServerPlatform()); + $this->assertSqlGeneration( + "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1", + "SELECT c0_.id AS id0 FROM cms_users c0_ WITH (NOLOCK) WHERE (c0_.name + c0_.status + 's') = ?" + ); + $this->assertSqlGeneration( + "SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1", + "SELECT (c0_.id + c0_.name + c0_.status) AS sclr0 FROM cms_users c0_ WITH (NOLOCK) WHERE c0_.id = ?" + ); + + $connMock->setDatabasePlatform($orgPlatform); + } } class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode