簡體   English   中英

如何在Postgres 9中創建復合索引

[英]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版本中引入的。

提交消息表明,它應該不會導致索引的任何安全問題,並且后面的更改不應該有任何區別。

但是,仔細觀察,您沒有使用textvarchar 你正在使用可怕的舊char類型,它在PostgreSQL中是內部bpchar

這里的問題要么是存在一個與區域設置相關的char的微妙行為,要么是疏忽導致此更改不處理char的情況。 我需要更深入地了解這些來源,而不是今晚我能夠確定的時間,坦率地說,我真的不關心char(n)類型。

你應該只使用varchar(5) 如果需要空間填充,請考慮使用lpad

否則,請將此問題報告給pgsql-bugs - 但請確保從SELECT version()顯示確切的版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM