CASTING attributes for Ordering on a Doctrine2 DQL Query
You should be able to add your own function to implement this feature.
The class would look something like this:
namespace MyProject\Query;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
class CastAsInteger extends FunctionNode
{
public $stringPrimary;
public function getSql(SqlWalker $sqlWalker)
{
return 'CAST(' . $this->stringPrimary->dispatch($sqlWalker) . ' AS integer)';
}
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringPrimary = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
You'll need to register your function:
$config = $em->getConfiguration();
$config->addCustomNumericFunction('INT', CastAsInteger::class);
Then you can use it:
SELECT e, INT(e.id) AS HIDDEN orderId
FROM Namespace\Bla\MyEntity e
ORDER BY orderId
PS: By adding the HIDDEN
keyword, the alias orderId
won't be in the results (and is only used for ordering).
Based on Jasper N. Brouwer answer, this is a little bit enhanced solution:
<?php
namespace MyProject\Query;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
class Cast extends FunctionNode
{
/** @var \Doctrine\ORM\Query\AST\PathExpression */
protected $first;
/** @var string */
protected $second;
/**
* @param SqlWalker $sqlWalker
*
* @return string
*/
public function getSql(SqlWalker $sqlWalker)
{
return sprintf("CAST(%s AS %s)",
$this->first->dispatch($sqlWalker),
$this->second
);
}
/**
* @param Parser $parser
*
* @return void
*/
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->first = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_AS);
$parser->match(Lexer::T_IDENTIFIER);
$this->second = $parser->getLexer()->token['value'];
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
Now it should be possible to write DQL like this:
SELECT e, CAST(e.id AS integer) AS HIDDEN orderId FROM Namespace\Bla\MyEntity e ORDER BY orderId
Try this one by with out changing the data type
select (entity1 * 1) as display_value, entity1 as return_value
from Table_Name
order by 1 asc;
Think it's better to use some extra functional in such cases ( without trying "to circumvent" theirs). E.g. an excellent solution adding almost all necessary ( not supported from box ) stuff for Doctrine 2
is DoctrineExtensions by beberlei (github). With it it's possible to use directly CAST
-statement like in OP's case:
("Symfony-example") E.g. in your config.xml
add lines:
orm:
..
entity_managers:
....
dql:
....
string_functions:
CAST: DoctrineExtensions\Query\Mysql\Cast
Then U can use it like:
SELECT entity1, CAST(entity1.id AS integer) AS orderId
FROM Namespace\Bla\MyEntity
ORDER BY orderId