PostgreSQL错误:函数to_tsvector(字符变化,未知)不存在

时间:2013-01-25 14:18:03

标签: sql postgresql types casting full-text-search

这个psql会话片段应该是不言自明的:

psql (9.1.7)
Type "help" for help.
=> CREATE TABLE languages(language VARCHAR NOT NULL);
CREATE TABLE
=> INSERT INTO languages VALUES ('english'),('french'),('turkish');
INSERT 0 3
=> SELECT language, to_tsvector('english', 'hello world') FROM languages;
 language|     to_tsvector     
---------+---------------------
 english | 'hello':1 'world':2
 french  | 'hello':1 'world':2
 turkish | 'hello':1 'world':2
(3 rows)

=> SELECT language, to_tsvector(language, 'hello world') FROM languages;
ERROR:  function to_tsvector(character varying, unknown) does not exist
LINE 1: select language, to_tsvector(language, 'hello world')...
                         ^
HINT:  No function matches the given name and argument types.  
You might need to add explicit type casts.

问题是Postgres函数to_tsvector不喜欢varchar字段类型,但此调用应该完全正确according to the documentation

2 个答案:

答案 0 :(得分:7)

使用显式类型转换:

SELECT language, to_tsvector(language::regconfig, 'hello world') FROM languages;

或将列languages.language更改为regconfig类型。 See @Swav's answer.

为什么?

Postgres允许function overloading。功能签名由其(可选架构 - 限定的)名称加上(列表)输入参数类型(s)定义。 to_tsvector()的双参数形式需要类型regconfig作为第一个参数:

SELECT proname, pg_get_function_arguments(oid)
FROM   pg_catalog.pg_proc
WHERE  proname = 'to_tsvector'

   proname   | pg_get_function_arguments
-------------+---------------------------
 to_tsvector | text
 to_tsvector | regconfig, text             -- you are here

如果现有的功能与完全匹配,则Function Type Resolution的规则决定最佳匹配 - 如果有的话。这对于to_tsvector('english', 'hello world')是成功的,'english'无类型字符串文字。但由于参数已键入varchar 而失败,因为从varcharregconfig没有已注册的隐式强制转换。 The manual

  

丢弃输入类型不匹配的候选函数   无法转换(使用隐式转换)来匹配。的未知   为了这个目的,假定文字可以转换为任何东西。

大胆强调我的 regconfig的注册演员:

SELECT castsource::regtype, casttarget::regtype, castcontext
FROM   pg_catalog.pg_cast
WHERE  casttarget = 'regconfig'::regtype;

 castsource | casttarget | castcontext
------------+------------+-------------
 oid        | regconfig  | i
 bigint     | regconfig  | i
 smallint   | regconfig  | i
 integer    | regconfig  | i

Explanation for castcontext

  

castcontext char
  指示可以调用强制转换的上下文   in。e仅表示显式转换(使用CAST::语法)。 a   意味着隐含地分配给目标列,以及   明确。 i在表达式中隐含地表示,以及其他情况。

详细了解三种不同的类型的作业 in the chapter CREATE CAST

答案 1 :(得分:1)

Erwin Brandstetter答案的替代方法

您可以将语言列定义为regconfig类型,这样可以使您的查询更简洁,即:

CREATE TABLE languages(language regconfig NOT NULL DEFAULT 'english'::regconfig)

我将英语设置为默认值,但这不是必需的。之后是原始查询

SELECT language, to_tsvector(language, 'hello world') FROM languages;

会工作得很好。