如何在PostgreSQL中为具有int4range值的hstore类型创建一个运算符

时间:2013-07-25 08:22:27

标签: postgresql operators postgresql-9.2 database-indexes hstore

我有一个带有HSTORE列'ext'的表,其中值是一个int4范围。一个例子:

"p1"=>"[10, 18]", "p2"=>"[24, 32]", "p3"=>"[29, 32]", "p4"=>"[18, 19]"

但是,当我尝试在此创建表达式索引时,我收到错误:

CREATE INDEX ix_test3_p1
ON test3
USING gist
(((ext -> 'p1'::text)::int4range));
  

错误:数据类型文本没有访问方法的默认运算符类   “gist”SQL状态:42704提示:您必须为其指定运算符类   索引或定义数据类型的默认运算符类。

如何为此创建运算符?

注意

每条记录可能都有自己唯一的一组密钥。每个键表示一个属性,值表示值范围。所以并非所有记录都有“p1”。在hstore中考虑这是一个EAV模型。

1 个答案:

答案 0 :(得分:1)

我没有得到那个错误 - 我得到“索引表达式中的函数必须标记为IMMUTABLE”

CREATE TABLE ht (ext hstore);
INSERT INTO ht VALUES ('p1=>"[10,18]"'), ('p1=>"[99,99]"');
CREATE INDEX ht_test_idx ON ht USING GIST ( ((ext->'p1'::text)::int4range) );
ERROR:  functions in index expression must be marked IMMUTABLE

CREATE FUNCTION foo(hstore) RETURNS int4range LANGUAGE SQL AS $$ SELECT ($1->'p1')::int4range; $$ IMMUTABLE;
CREATE INDEX ht_test_idx ON ht USING GIST ( foo(ext) );
SET enable_seq_scan=false;
EXPLAIN SELECT * FROM ht WHERE foo(ext) = '[10,19)';
                              QUERY PLAN                               
-----------------------------------------------------------------------
 Index Scan using ht_test_idx on ht  (cost=0.25..8.52 rows=1 width=32)
   Index Cond: (foo(ext) = '[10,19)'::int4range)

我猜测演员表不是不可变的,因为您可以将范围的默认格式从包含...独占“[...)”更改为其他内容。你可能不会这样做。

显然你会希望你的真实功能能够处理诸如缺少“p1”条目,格式错误的范围等等。