我绝望地试图在Symfony2中包含LEVENSHTEIN功能,但是,我仍然收到错误。规格+到目前为止我做了什么:
通过shell执行测试了该函数。完美无缺:
postgres=# SELECT levenshtein('test', 'text');
levenshtein
-------------
1
(1 row)
在DQL中添加了该功能:
<?php
namespace AppBundle\DQL;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
class LevenshteinFunction extends FunctionNode {
public $firstStringExpression = null;
public $secondStringExpression = null;
public function getSql(SqlWalker $sqlWalker) {
return 'LEVENSHTEIN(' . $this->firstStringExpression->dispatch($sqlWalker) . ', ' . $this->secondStringExpression->dispatch($sqlWalker) . ')';
}
public function parse(Parser $parser) {
// levenshtein(str1, str2)
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->firstStringExpression = $parser->StringPrimary();
$parser->match(Lexer::T_COMMA);
$this->secondStringExpression = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
Config.yml
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
dql:
numeric_functions:
LEVENSHTEIN: AppBundle\DQL\LevenshteinFunction
问题:在我的存储库中执行以下代码块时,会出现以下错误:
$this->getEntityManager()->createQuery("SELECT LEVENSHTEIN('test', 'text') FROM AppBundle:User");
return $query->getResult();
SQLSTATE [42883]:未定义的函数:7错误:函数levenshtein(未知,未知)不存在
我错过了什么?为什么DQL / Symfony / PDO / ...没有识别这个功能?任何帮助都非常感谢!
答案 0 :(得分:1)
您的函数类对我来说似乎没问题,但您的配置可能有误。这就是我对CAST
函数所拥有的:
doctrine:
orm:
dql:
string_functions:
CAST: App\MyBundle\Doctrine\DBAL\Functions\Porgres\Cast
您应该注意,您对不同类型的函数有不同的集合,例如string_functions
,numeric_functions
,datetime_functions
。所有这些都列在官方documentation中。
除此之外,清理缓存后,您的代码应该正常工作。
答案 1 :(得分:1)
错误来自Postgres,似乎是一个可见性问题。
当然,必须安装附加模块fuzzystrmatch
。你显然这样做了,或者你的函数调用在psql中也不起作用。
如果它在psql中有效,但在你的应用中却没有,那么只剩下几个可能的解释。显而易见的第一个:
您 是否已连接到同一个数据库? (相同的服务器,相同的端口,相同的数据库?)
您正在与同一位用户联系?可能不 ......
如果与其他用户连接(但无论如何),请检查您是否使用相同的搜索路径。在任一连接中运行并进行比较:
SHOW search_path;
详细信息 - 以及如何设置search_path
:
请注意,扩展程序可以安装到您选择的任何架构中。默认是search_path
中的第一个架构(安装时的“当前架构”,通常为public
,但我不知道您的安装。文档:
如果未指定,则扩展名的控制文件未指定 schema,或者使用当前的默认对象创建模式。
运行此命令以诊断一些事情:
SELECT e.extname AS extension, nsp.nspname AS schema
, r.rolname AS schema_owner, nsp.nspacl AS schema_acl
FROM pg_extension e
JOIN pg_namespace nsp ON nsp.oid = e.extnamespace
JOIN pg_roles r ON r.oid = nsp.nspowner
你会得到类似的东西:
extension | schema | schema_owner | schema_acl ---------------+------------+--------------+------------------------------------- adminpack | pg_catalog | postgres | {postgres=UC/postgres,=U/postgres} plpgsql | pg_catalog | postgres | {postgres=UC/postgres,=U/postgres} fuzzystrmatch | public | postgres | {postgres=UC/postgres,=UC/postgres} tablefunc | public | postgres | {postgres=UC/postgres,=UC/postgres} ...
如果schema_acl
包含=U/postgres
(U
for USAGE
),则public
角色可以访问,即每个人。
相应地设置连接的search_path
或(重新)安装到可见的模式,它应该可以工作。
理论上,拥有角色或超级用户可能已撤消函数本身的EXECUTE
权限...