我试过
create temp table test (kuupaev date, kellaaeg char(5) ) on commit drop;
create index on test ((kuupaev||kellaaeg));
但收到错误
ERROR: functions in index expression must be marked IMMUTABLE
如何在Postgres 9中使用此索引?
在Postgres 8中它起作用了。
更新
命令
create temp table test (kuupaev date, kellaaeg char(5) ) on commit drop;
create index test on test ((kuupaev||kellaaeg));
in
"PostgreSQL 9.3.4, compiled by Visual C++ build 1600, 32-bit"
导致错误
ERROR: functions in index expression must be marked IMMUTABLE
但在
"PostgreSQL 8.4.4, compiled by Visual C++ build 1400, 32-bit"
他们的工作正常
答案 0 :(得分:1)
查询pg_operator
表明相关的运算符实现函数为anytextcat
。
regress=> select l.typname, r.typname, o.oprcode
from pg_operator o
inner join pg_type l on (o.oprleft = l.oid)
inner join pg_type r on (o.oprright = r.oid)
where oprname = '||';
typname | typname | oprcode
-------------+-------------+-----------------
anyarray | anyelement | array_append
anyelement | anyarray | array_prepend
anyarray | anyarray | array_cat
text | text | textcat
varbit | varbit | bitcat
bytea | bytea | byteacat
text | anynonarray | textanycat
anynonarray | text | anytextcat
tsvector | tsvector | tsvector_concat
tsquery | tsquery | tsquery_or
(10 rows)
\df+ anytextcat
显示它是stable
(我正在运行9.4beta2 + git更改,但它与9.2相同)。
查看pg_proc.h
和git blame
的相关行,最后一次提交是cd30728f,但查看git show
表明它不相关。所以我用git blame cd30728f^ -- ./src/include/catalog/pg_proc.h
跳过它。向后工作我发现变化是:
cd30728f - Allow LEAKPROOF functions for better performance of security views. (9.2)
3db6524f - Mark some more I/O-conversion-invoking functions as stable not volatile. (9.2)
8f9fe6ed - Add notion of a "transform function" that can simplify function calls. (9.2)
c82d931d - Fix the volatility marking of textanycat() and anytextcat() (9.0)
其中,只有c82d931d才真正相关。 3db6524f将其从volatile更改为stable,但这对您没有帮助。
git show c82d931d
描述了可能导致此行为更改的提交:
commit c82d931dd180965a9a0c06acc764404f91de8170
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu May 27 16:20:11 2010 +0000
Fix the volatility marking of textanycat() and anytextcat(): they were marked
immutable, but that is wrong in general because the cast from the polymorphic
argument to text could be stable or even volatile. Mark them volatile for
safety. In the typical case where the cast isn't volatile, the planner will
deduce the correct expression volatility after inlining the function, so
performance is not lost. The just-committed fix in CREATE INDEX also ensures
this won't break any indexing cases that ought to be allowed.
Per discussion, I'm not bumping catversion for this change, as it doesn't
seem critical enough to force an initdb on beta testers.
根据:
git branch --contains c82d931d
它是在PostgreSQL 9.0.0版本中引入的。
提交消息表明它假设不会导致索引的任何问题都是安全的,后来的更改不应该有任何区别。
然而,仔细观察,您没有使用text
或varchar
。你正在使用可怕的旧char
类型,它在PostgreSQL中是bpchar
内部。
这里的问题可能是char
存在一种与区域设置相关的微妙行为,或者疏忽导致此更改无法处理char
的情况。我需要更深入地了解这些消息来源,而不是今晚有时间能够确定,坦率地说,我并不关心char(n)
类型。
您应该只使用varchar(5)
。如果您需要空间填充,请考虑使用lpad
。
否则,请将此问题报告给pgsql-bugs - 但请确保显示SELECT version()
的完全版本。