Skip to content

Instantly share code, notes, and snippets.

@galiazzi
Last active May 7, 2024 12:04
Show Gist options
  • Save galiazzi/5e5f04f9753ba4d8a9b972c87dc2a805 to your computer and use it in GitHub Desktop.
Save galiazzi/5e5f04f9753ba4d8a9b972c87dc2a805 to your computer and use it in GitHub Desktop.
Doctrine DQL cast function
<?php
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
{
private $expr1;
private $expr2;
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->expr1 = $parser->ArithmeticExpression();
$parser->match(Lexer::T_COMMA);
$this->expr2 = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(SqlWalker $sqlWalker)
{
$type = trim($this->expr2->dispatch($sqlWalker), "'");
return sprintf(
'cast(%s as %s)',
$this->expr1->dispatch($sqlWalker),
$type
);
}
}
@lyrixx
Copy link

lyrixx commented Sep 28, 2020

For the record, it's better to use

- $this->expr1 = $parser->StringPrimary();
+ $this->expr1 = $parser->ArithmeticExpression();

If you don't do that, doctrine will not replace potential alias in the select clause.

IE: without this patch, such code does not work

$queryBuilder->addSelect(sprintf('JSON_EXTRACT(%s.stats, \'$.analyzedCount\') as HIDDEN %s', $alias, $parameterName));
$queryBuilder->addOrderBy(sprintf('CAST(%s AS \'INT\') ', $parameterName), $direction);

because the parameterName in the cast is not replaced

@galiazzi
Copy link
Author

thanks @lyrixx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment