Błąd WYŁĄCZENIA PostgreSQL: Użycie liczby całkowitej typu danych nie ma domyślnej klasy operatora

37

W PostgreSQL 9.2.3 próbuję utworzyć tę uproszczoną tabelę:

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

Ale pojawia się ten błąd:

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.

Dokumenty PostgreSQL używają tego przykładu, który nie działa dla mnie:

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

Ten sam komunikat o błędzie.

I ten , który też mi nie działa:

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

Ten sam komunikat o błędzie.

Jestem w stanie stworzyć to bez problemu:

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

i to:

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

Spędziłem sporo czasu na szukaniu wskazówek, jak wymyślić, jak to zrobić, lub dlaczego nie działa. Jakieś pomysły?

Ian Timothy
źródło
9
+1 Spójrz tutaj, ludzie! Tak to się robi. Pytanie ma wszystko, czego potrzebuje: RDBMS i wersję, przykładowy kod, komunikat o błędzie, jasną definicję problemu, linki, wyświetlanie tego, co próbował OP. Prace. Żadnego hałasu. A to od pierwszego użytkownika! Chapeau. Natychmiast przekonał mnie do bliższego przyjrzenia się.
Erwin Brandstetter
2
Pytanie uzupełniające: dba.stackexchange.com/questions/37391/…
Erwin Brandstetter

Odpowiedzi:

29

Zainstaluj dodatkowy moduł, btree_gistjak wspomniano w instrukcji, w lokalizacji, z którą łączysz się z :

btree_gistRozszerzenia można użyć do zdefiniowania ograniczeń wykluczeń dla zwykłych skalarnych typów danych, które można następnie połączyć z wykluczeniami zakresu w celu uzyskania maksymalnej elastyczności. Na przykład po btree_gistzainstalowaniu następujące ograniczenie odrzuci nakładające się zakresy tylko wtedy, gdy numery sal konferencyjnych są równe:

W nowoczesnym PostgreSQL wystarczy uruchomić (raz na bazę danych):

CREATE EXTENSION btree_gist;

Najpierw musisz zainstalować pakiet „contrib” w systemie operacyjnym. Szczegóły zależą od systemu operacyjnego i używanego repozytorium oprogramowania. W przypadku rodziny Debian jest to zazwyczaj postgresql-contrib-9.2(w przypadku Postgres 9.2). Lub tylko postgresql-contribdla rodziny Red Hat. Rozważ tę pokrewną odpowiedź na SO:

Erwin Brandstetter
źródło
1
To była właściwie jedna z pierwszych rzeczy, których spróbowałem. Było to w znacznie większej skryptu i ten komunikat został pochowany na wyjściu: ERROR: could not open extension control file "/opt/local/share/postgresql92/extension/btree_gist.control": No such file or directory. Zakładałem również, że został już zainstalowany, ponieważ ...EXCLUDE USING gist (startend WITH &&)...działał jak pokazano w moim oryginalnym poście. Dzięki za zrobienie milionowego spojrzenia na to. Teraz zbadaj ten błąd.
Ian Timothy
3
@DenverTimothy: Myślę, że też mogę w tym pomóc. Prawdopodobnie postgresql-contrib-9.2najpierw musisz zainstalować pakiet contrib w systemie operacyjnym. Zależy od twojego systemu operacyjnego. Rozważ tę pokrewną odpowiedź na SO.
Erwin Brandstetter
Warto również zauważyć, że działa on w systemie Mac OS 10.8.2, zainstalowanym wraz z portnarzędziem.
Ian Timothy
@DenverTimothy: Nie używam komputerów Mac, ale główny powinien być taki sam. Zainstaluj pakiet w swoim systemie operacyjnym przed uruchomieniem CREATE EXTENSION.
Erwin Brandstetter
link do wątku listy mailingowej postgres z odpowiedzią
Eugen Konkov
2

jeśli ktoś nie może lub nie chce tego użyć:

CREATE EXTENSION btree_gist;

Tak jak w moim przypadku, ponieważ Django 1.11 ORM nie obsługuje tego indeksu i nie chciałem pisać SQL poza Django. Użyłem czegoś podobnego do:

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

„[]” służy do upewnienia się, że obie granice są włącznie. Testowane z Postgres 9.6 i 10.5.

Sergios Bagdasar
źródło