[英]How to create composite index in Postgres 9
我試過了
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));
在
"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"
他們工作正常
查詢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()
顯示確切的版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.