【问题标题】:PostgreSQL ERROR: function to_tsvector(character varying, unknown) does not existPostgreSQL 错误:函数 to_tsvector(字符变化,未知)不存在
【发布时间】:2013-01-09 12:34:50
【问题描述】:

这个 psql 会话 sn-p 应该是不言自明的:

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

【问题讨论】:

  • 您使用的是哪个 Postgres 版本?
  • language 列的数据类型是什么?如果您使用的是 9.1,为什么还要使用 8.3 的手册?

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


【解决方案1】:

使用显式类型转换:

SELECT language, to_tsvector(language<b>::regconfig</b>, 'hello world') FROM languages;

或将languages.language 列更改为输入regconfigSee @Swav's answer.

为什么?

Postgres 允许function overloading。函数签名由它们的(可选schema-qualified)name加上(列表)输入参数类型定义。 to_tsvector() 的 2 参数形式需要 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

【讨论】:

    【解决方案2】:

    Erwin Brandstetter 答案的替代方法

    您可以将语言列定义为 regconfig 类型,这将使​​您的查询不那么冗长,即:

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

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

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

    会很好用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 2014-06-30
      • 1970-01-01
      • 2014-07-02
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多