Erro do PostgreSQL EXCLUDE USING: tipo de dados número inteiro não possui classe de operador padrão

37

No PostgreSQL 9.2.3, estou tentando criar esta tabela simplificada:

CREATE TABLE test (
    user_id INTEGER,
    startend TSTZRANGE,
    EXCLUDE USING gist (user_id WITH =, startend WITH &&)
);

Mas eu recebo este erro:

ERROR:  data type integer has no default operator class for access method "gist"
HINT:  You must specify an operator class for the index or define
       a default operator class for the data type.

Os documentos do PostgreSQL usam este exemplo que não funciona para mim:

CREATE TABLE room_reservation (
    room text,
    during tsrange,
    EXCLUDE USING gist (room WITH =, during WITH &&)
);

A mesma mensagem de erro.

E este , que também não funciona para mim:

CREATE TABLE zoo (
    cage   INTEGER,
    animal TEXT,
    EXCLUDE USING gist (cage WITH =, animal WITH <>)
);

A mesma mensagem de erro.

Eu sou capaz de criar isso sem nenhum problema:

CREATE TABLE test (
    user_id INTEGER,
    startend TSTZRANGE,
    EXCLUDE USING gist (startend WITH &&)
);

e isto:

CREATE TABLE test (
    user_id INTEGER,
    startend TSTZRANGE,
    EXCLUDE USING btree (user_id WITH =)
);

Passei um bom tempo pesquisando dicas sobre como fazer isso funcionar ou sobre por que não funciona. Alguma ideia?

Ian Timothy
fonte
9
+1 Olhe aqui, pessoal! É assim que se faz. A pergunta tem tudo o que precisa: o RDBMS e a versão, código de exemplo, mensagem de erro, uma definição clara do problema, links, uma exibição do que o OP tentou. Os trabalhos. Sem barulho E isso é de um usuário iniciante! Chapéu. Me convenceu imediatamente a olhar mais de perto.
Erwin Brandstetter 22/03
2
Pergunta de acompanhamento: dba.stackexchange.com/questions/37391/…
Erwin Brandstetter

Respostas:

29

Instale o módulo adicional, btree_gistconforme mencionado no manual, no local ao qual você vinculou :

Você pode usar a btree_gistextensão para definir restrições de exclusão em tipos de dados escalares simples, que podem ser combinados com exclusões de intervalo para máxima flexibilidade. Por exemplo, após a btree_gistinstalação, a seguinte restrição rejeitará intervalos sobrepostos apenas se os números da sala de reunião forem iguais:

No PostgreSQL moderno, você só precisa executar (uma vez por banco de dados):

CREATE EXTENSION btree_gist;

Você precisa ter o pacote "contrib" instalado no seu sistema operacional primeiro. Os detalhes dependem do seu sistema operacional e do repositório de software usado. Para a família Debian é tipicamente postgresql-contrib-9.2(para o Postgres 9.2). Ou apenas postgresql-contribpara a família Red Hat. Considere esta resposta relacionada no SO:

Erwin Brandstetter
fonte
1
Essa foi realmente uma das primeiras coisas que tentei. Foi em um script muito maior e esta mensagem de erro foi soterrada na saída: ERROR: could not open extension control file "/opt/local/share/postgresql92/extension/btree_gist.control": No such file or directory. Eu também assumi que ele já estava instalado porque ...EXCLUDE USING gist (startend WITH &&)...funcionou como mostrado na minha postagem original. Obrigado por fazer um milionésimo olhar para isso. Agora, pesquise esse erro.
Ian Timothy
3
@ DenverTimothy: Eu acho que posso ajudar com isso também. Você provavelmente precisará instalar o pacote contrib postgresql-contrib-9.2no seu sistema operacional primeiro. Depende do seu sistema operacional. Considere esta resposta relacionada no SO.
Erwin Brandstetter 22/03
Além disso, pode ser útil observar que isso está sendo executado no Mac OS 10.8.2, instalado com a portferramenta.
Ian Timothy
@ DenverTimothy: Eu não estou usando Macs, mas o diretor deve ser o mesmo. Instale o pacote no seu sistema operacional antes de poder executar CREATE EXTENSION.
Erwin Brandstetter 22/03
link para postgres discussão rosca lista com a resposta
Eugen Konkov
2

se alguém não puder ou não quiser usar isso:

CREATE EXTENSION btree_gist;

Como foi no meu caso, porque o Django 1.11 ORM não suporta esse índice e eu não queria escrever SQL fora do Django. Eu usei algo semelhante a:

EXCLUDE USING gist (
    int4range(userid, userid, '[]') WITH =,
    startend WITH && 
)

'[]' é usado para garantir que ambos os limites sejam inclusivos. Testado com Postgres 9.6 e 10.5.

Sergios Bagdasar
fonte