Kev*_*vin 3 postgresql generated-columns postgresql-14
我正在向表中添加一些列,并且想要一个将它们组合在一起的生成列,我将使用它作为唯一索引。当我尝试添加列时,出现错误ERROR: generation expression is not immutable。
我遵循了这个问题的解决方案,并且专门使用CASE和||进行字符串连接,这应该是immutable.
ALTER TABLE tag
ADD COLUMN prefix VARCHAR(4) NOT NULL,
ADD COLUMN middle BIGINT NOT NULL,
ADD COLUMN postfix VARCHAR(4), -- nullable
-- VARCHAR size is 4 prefix + 19 middle + 4 postfix + 2 delimiter
ADD COLUMN tag_id VARCHAR(29) NOT NULL GENERATED ALWAYS AS
(CASE WHEN postfix IS NULL THEN prefix || '-' || middle
ELSE prefix || '-' || middle || '-' || postfix
END
) STORED;
CREATE UNIQUE INDEX unq_tag_tag_id ON tag(tag_id);
Run Code Online (Sandbox Code Playgroud)
在postgres 邮件列表中,一位贡献者澄清:
整数到文本的强制转换,[...] 不一定是不可变的
但是,他不共享不可变的整数到文本函数。有谁知道是否存在?
Marmite Bomber 的回答给出了解决方案;让我添加一个解释。
\n有两个串联运算符text:
SELECT oid, oprname,\n oprleft::regtype,\n oprright::regtype,\n oprcode\nFROM pg_operator\nWHERE oprname = '||'\n AND oprleft = 'text'::regtype;\n\n oid \xe2\x94\x82 oprname \xe2\x94\x82 oprleft \xe2\x94\x82 oprright \xe2\x94\x82 oprcode \n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n 654 \xe2\x94\x82 || \xe2\x94\x82 text \xe2\x94\x82 text \xe2\x94\x82 textcat\n 2779 \xe2\x94\x82 || \xe2\x94\x82 text \xe2\x94\x82 anynonarray \xe2\x94\x82 textanycat\n(2 rows)\nRun Code Online (Sandbox Code Playgroud)\n第一个运算符text与串联text,第二个运算符text与其他运算符串联。
让我们检查一下这两个函数的波动性:
\nSELECT oid, proname, provolatile\nFROM pg_proc\nWHERE pronamespace = 'pg_catalog'::regnamespace\n AND proname IN ('textcat', 'textanycat');\n\n oid \xe2\x94\x82 proname \xe2\x94\x82 provolatile \n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n 1258 \xe2\x94\x82 textcat \xe2\x94\x82 i\n 2003 \xe2\x94\x82 textanycat \xe2\x94\x82 s\n(2 rows)\nRun Code Online (Sandbox Code Playgroud)\n因此,如果您连接textand bigint,则该操作不是IMMUTABLE,但首先将bigintto转换text为该操作IMMUTABLE。
并不是因为与整数连接,所以该运算符不是不可变的。但anynonarray可以是任何数据类型,例如timestamp with time zone,其字符串表示形式取决于 的当前设置timezone。
| 归档时间: |
|
| 查看次数: |
615 次 |
| 最近记录: |