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