2013-07-29 9 views
2

Вот мой стол:PostgreSQL индекс массива int4range с использованием GIN - пользовательский класс оператор

CREATE TABLE 
     mytable 
     (
       id  INT NOT NULL PRIMARY KEY, 
       val  int4range[] 
     ); 

Я хочу, чтобы индексировать столбец VAL:

CREATE INDEX 
    ix_mytable_val 
ON  mytable 
USING GIN (INT4RANGE(val, '[]')); // error, as is GIN(val) 

я придумал следующее:

CREATE OPERATOR CLASS gin_int4range_ops 
DEFAULT FOR TYPE int4range[] USING gin AS 
OPERATOR  1  <(anyrange,anyrange), 
OPERATOR  2  <=(anyrange,anyrange), 
OPERATOR  3  =(anyrange,anyrange), 
OPERATOR  4  >=(anyrange,anyrange), 
OPERATOR  5  >(anyrange,anyrange), 
FUNCTION  1  lower(anyrange), 
FUNCTION  2  upper(anyrange), 
FUNCTION  3  isempty(anyrange), 
FUNCTION  4  lower_inc(anyrange), 
FUNCTION  5  upper_inc(anyrange); 

Но когда я пытаюсь создать индекс, он не работает (ошибка ниже). Однако, если я вызываю создание из блока DO $$, он выполняется.

Если выполняется создание индекса, я получаю сообщение об ошибке INSERT INTO.

"ERROR: cache lookup failed for type 1"

Я также попытался это:

OPERATOR  1  &&(anyrange,anyrange), 
OPERATOR  2  <@(anyrange,anyrange), 
OPERATOR  3  @>(anyrange,anyrange), 
OPERATOR  4  =(anyrange,anyrange), 

Для того, чтобы попытаться решить эту проблему, я перезагрузил PG, машину, и пылесосить DB. Я считаю, что в коде CREATE OPERATOR есть ошибка.

Если я могу индексировать массив пользовательского типа (int, int4range), это было бы еще лучше.

Я провел довольно много времени (полный рабочий день), прорабатывая документацию, форумы и т. Д., Но не могу найти ничего, что действительно помогло бы мне понять, как это решить (т. Е. Создать рабочий пользовательский класс операторов).

ответ

2

Вы должны CREATE OPERATOR CLASS на основе Range Functions and Operators, например:

CREATE OPERATOR CLASS gin_int4range_ops 
    DEFAULT FOR TYPE int4range[] USING gin AS 
     OPERATOR  1  =(anyrange,anyrange), 
     FUNCTION  1  lower(anyrange), 
     FUNCTION  2  upper(anyrange), 
     FUNCTION  3  isempty(anyrange), 
     FUNCTION  4  lower_inc(anyrange), 
     FUNCTION  5  upper_inc(anyrange); 

Теперь вы можете CREATE INDEX:

CREATE INDEX ix_mytable4_vhstore_low 
ON mytable USING gin (val gin_int4range_ops); 

Проверьте также:
Operator Classes and Operator Families
CREATE OPERATOR CLASS

The following query shows all defined operator classes:

SELECT am.amname AS index_method, 
     opc.opcname AS opclass_name 
    FROM pg_am am, pg_opclass opc 
    WHERE opc.opcmethod = am.oid 
    ORDER BY index_method, opclass_name; 

This query shows all defined operator families and all the operators included in each family:

SELECT am.amname AS index_method, 
     opf.opfname AS opfamily_name, 
     amop.amopopr::regoperator AS opfamily_operator 
    FROM pg_am am, pg_opfamily opf, pg_amop amop 
    WHERE opf.opfmethod = am.oid AND 
      amop.amopfamily = opf.oid 
    ORDER BY index_method, opfamily_name, opfamily_operator; 
+0

Спасибо большое! Когда я попытался создать индекс, я получил сообщение «ERROR: cache lookup failed for type 1». Я перезапустил сервер. Есть идеи? – IamIC

+1

Ваш код работает нормально в моем db ... Попытка выяснить. – revoua

+0

Я пробовал все, что мог придумать, но все равно получаю эту ошибку. – IamIC