Skip to content

Commit

Permalink
[DDC-2304] accept more than 2 parameters in CONCAT function
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
broncha authored and beberlei committed Mar 12, 2013
1 parent fc86a31 commit 4841a06
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 8 deletions.
32 changes: 24 additions & 8 deletions lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use Doctrine\ORM\Query\Lexer;

/**
* "CONCAT" "(" StringPrimary "," StringPrimary ")"
* "CONCAT" "(" StringPrimary "," StringPrimary {"," StringPrimary }* ")"
*
*
* @link www.doctrine-project.org
Expand All @@ -35,18 +35,25 @@
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);
}

/**
Expand All @@ -56,10 +63,19 @@ public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$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);
}
Expand Down
43 changes: 43 additions & 0 deletions tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1887,6 +1887,49 @@ public function testCaseThenFunction()
'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
Expand Down

0 comments on commit 4841a06

Please sign in to comment.