当当前模式不同于函数之一时,属性表示法函数调用会出错。
我创建了一个函数
CREATE FUNCTION pub.FullName(pub.reps)
RETURNS text AS
$func$
select ($1.fname || ' ' || $1.lname)
$func$ LANGUAGE SQL;
我正在尝试使用docs中所述的带有属性符号的函数:
select r.fullname from pub.reps r;
但是收到错误消息:
ERROR: column "fullname" does not exist
带有功能符号的查询工作正常:
select pub.fullname(r.*) from pub.reps r;
数据库已通过备份/还原从PostgreSQL 10迁移。
Select version()
给出:PostgreSQL 11.3, compiled by Visual C++ build 1914, 64-bit
UPD 。发现如果我将pub
模式设置为默认模式,那么select r.fullname from pub.reps r
可以正常工作。
答案 0 :(得分:2)
您自己找到了问题的根源。确切地说:函数pub
的架构必须在当前 search_path
中的任意位置列出 ,而不必是“默认”或“当前”模式(列表中的第一个)。相关:
因此Postgres找不到该功能。在这方面,Postgres 11与Postgres 10并无不同。但是,还有一些值得注意的相关发展。您提到:
数据库已通过备份/还原从PostgreSQL 10迁移。
考虑release notes for Postgres 11中指出的细微变化:
在对函数和列引用进行歧义时考虑语法形式(汤姆巷)
当
x
是表名或组合列时,PostgreSQL具有 传统上将f(x)
和x.f
视为句法形式 等效,允许诸如编写函数然后使用的技巧 好像它是按需计算列。但是,如果两者 解释是可行的,列解释总是 选择,如果用户打算 功能解释。现在,如果有歧义, 选择与句法形式匹配的解释。
因此,如果在表fullname
中有列reps
,并且您显示的函数pub.fullname(pub.reps)
是Postgres 10, ,即使具有功能符号,仍会选择列:
SELECT fullname(r) FROM reps r; -- resolves to column if it exists, ignoring function
db <>小提琴here for Postgres 10
Postgres 11(更合理地)选择功能:
db <>小提琴here for Postgres 11
Postgres 12 (当前为beta)最终实现了真正生成的列。 The release notes:
不过
- 添加对生成的列的支持(Peter Eisentraut)
根据表达式计算生成的列的内容 (包括对同一表中其他列的引用),而不是 由
INSERT
或UPDATE
命令指定。
只有 STORED
生成的列才包含在此版本中。 (更有趣的IMO)VIRTUAL
variant was postponed for a later release。希望获得Postgres 13。
您的表可能如下所示:
CREATE TABLE pub.reps (
reps_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, fname text NOT NULL
, lname text NOT NULL
, fullname text GENERATED ALWAYS AS (fname || ' ' || lname) STORED
);
db <>提琴here
我声明了fname
和lname
列。否则,您的简单串联(NOT NULL
)是一个陷阱。参见: