将问号转换为参数的自定义 Doctrine DQL 函数
Custom Doctrine DQL function with Question Mark being converted into parameter
我正在使用 Symfony 2.6 和 Doctrine 2.5,我正在尝试制作自定义 DQL 函数来实现“?” Postgres 运算符(用于确定具有特定键的元素是否存在于 Postgres 的 jsonb 字段中)http://www.postgresql.org/docs/9.4/static/functions-json.html
这是代码(从https://github.com/boldtrn/JsonbBundle的DQL代码复制而来,我只是改了问号)
class HasElement extends FunctionNode
{
public $leftHandSide = null;
public $rightHandSide = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->leftHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->rightHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return '(' .
$this->leftHandSide->dispatch($sqlWalker) . " ? " .
$this->rightHandSide->dispatch($sqlWalker) .
')';
}
}
但是在创建查询时问号被认为是参数占位符,我收到语法错误并且在设置参数之前在查询中它被替换为 $2。
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near ""
LINE 1: ...id = r1_.id WHERE r0_.file_id = AND (r0_.attrs )
查询应该是“(r0_attrs ? $1)”
有没有什么方法可以在 DQL 中使用问号而不将其视为参数?我尝试转义并替换为 unicode 序列,但没有用
编辑: 虽然这个问题的答案与这个被标记为重复的答案相同(使用函数而不是别名运算符),但错误是不同的. Doctrine 的解析出现在 PDO 参数分配之前,如果不是这样的话我会得到这个错误:
PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'
除此之外,只是大致流程相同,具体答案不同(需要使用不同的函数)
我一直在寻找 solution/alternative,我发现 ?
是函数 jsonb_exists(column_name, key)
的别名,我将在我的自定义 DQL 函数中使用它。
同样的事情也适用于 ?|
和 ?&
所以 class 变成了这个
class JsonbExistence extends FunctionNode
{
public $leftHandSide = null;
public $rightHandSide = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->leftHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->rightHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
// We use a workaround to allow this statement in a WHERE. Doctrine relies on the existence of an ComparisonOperator
return 'jsonb_exists(' .
$this->leftHandSide->dispatch($sqlWalker) .', '.
$this->rightHandSide->dispatch($sqlWalker) .
')';
}
}
这不是 doctrine/symfony 问题,而是与 PDO 相关。
你可以查看这个How to prevent PDO from interpreting a question mark as a placeholder?
这主要是尝试使用相同的运算符,但使用 PHP PDO 库。
我正在使用 Symfony 2.6 和 Doctrine 2.5,我正在尝试制作自定义 DQL 函数来实现“?” Postgres 运算符(用于确定具有特定键的元素是否存在于 Postgres 的 jsonb 字段中)http://www.postgresql.org/docs/9.4/static/functions-json.html
这是代码(从https://github.com/boldtrn/JsonbBundle的DQL代码复制而来,我只是改了问号)
class HasElement extends FunctionNode
{
public $leftHandSide = null;
public $rightHandSide = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->leftHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->rightHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return '(' .
$this->leftHandSide->dispatch($sqlWalker) . " ? " .
$this->rightHandSide->dispatch($sqlWalker) .
')';
}
}
但是在创建查询时问号被认为是参数占位符,我收到语法错误并且在设置参数之前在查询中它被替换为 $2。
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near ""
LINE 1: ...id = r1_.id WHERE r0_.file_id = AND (r0_.attrs )
查询应该是“(r0_attrs ? $1)”
有没有什么方法可以在 DQL 中使用问号而不将其视为参数?我尝试转义并替换为 unicode 序列,但没有用
编辑: 虽然这个问题的答案与这个被标记为重复的答案相同(使用函数而不是别名运算符),但错误是不同的. Doctrine 的解析出现在 PDO 参数分配之前,如果不是这样的话我会得到这个错误:
PDOException: SQLSTATE[HY093]: Invalid parameter number: no parameters were bound: SELECT * FROM tbl WHERE hst ? 'foo'
除此之外,只是大致流程相同,具体答案不同(需要使用不同的函数)
我一直在寻找 solution/alternative,我发现 ?
是函数 jsonb_exists(column_name, key)
的别名,我将在我的自定义 DQL 函数中使用它。
同样的事情也适用于 ?|
和 ?&
所以 class 变成了这个
class JsonbExistence extends FunctionNode
{
public $leftHandSide = null;
public $rightHandSide = null;
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->leftHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_COMMA);
$this->rightHandSide = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
// We use a workaround to allow this statement in a WHERE. Doctrine relies on the existence of an ComparisonOperator
return 'jsonb_exists(' .
$this->leftHandSide->dispatch($sqlWalker) .', '.
$this->rightHandSide->dispatch($sqlWalker) .
')';
}
}
这不是 doctrine/symfony 问题,而是与 PDO 相关。
你可以查看这个How to prevent PDO from interpreting a question mark as a placeholder?
这主要是尝试使用相同的运算符,但使用 PHP PDO 库。