PostgreSQL EXCLUDE USING-Fehler: Der Datentyp integer hat keine Standardoperatorklasse

37

In PostgreSQL 9.2.3 versuche ich, diese vereinfachte Tabelle zu erstellen:

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

Aber ich bekomme diesen Fehler:

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.

Die PostgreSQL-Dokumente verwenden dieses Beispiel, das für mich nicht funktioniert:

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

Gleiche Fehlermeldung.

Und dieser , der auch bei mir nicht funktioniert:

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

Gleiche Fehlermeldung.

Ich kann das problemlos erstellen:

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

und das:

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

Ich habe ziemlich viel Zeit damit verbracht, nach Hinweisen zu suchen, um herauszufinden, wie dies funktioniert oder warum es nicht funktioniert. Irgendwelche Ideen?

Ian Timothy
quelle
9
+1 Schau mal, Leute! So wird es gemacht. Die Frage hat alles, was sie braucht: das RDBMS und die Version, Beispielcode, Fehlermeldung, eine klare Definition des Problems, Links, eine Anzeige dessen, was das OP versucht hat. Die Werke. Kein Geräusch. Und dies ist von einem Erstanwender! Chapeau. Überzeugte mich sofort, genauer hinzuschauen.
Erwin Brandstetter
2
Folgefrage
Erwin Brandstetter

Antworten:

29

Installieren Sie das Zusatzmodul btree_gistwie im Handbuch beschrieben an dem Speicherort, zu dem Sie eine Verknüpfung hergestellt haben :

Mit der btree_gistErweiterung können Sie Ausschlussbeschränkungen für einfache skalare Datentypen definieren, die dann mit Bereichsausschlüssen kombiniert werden können, um maximale Flexibilität zu erzielen. Beispielsweise btree_gistlehnt die folgende Einschränkung nach der Installation überlappende Bereiche nur ab, wenn die Konferenzraumnummern gleich sind:

In modernen PostgreSQL müssen Sie nur einmal pro Datenbank ausführen:

CREATE EXTENSION btree_gist;

Sie müssen zuerst das "contrib" -Paket in Ihrem Betriebssystem installiert haben. Details hängen von Ihrem Betriebssystem und dem verwendeten Software-Repository ab. Für die Debian-Familie ist dies typisch postgresql-contrib-9.2(für Postgres 9.2). Oder nur postgresql-contribfür die Red Hat-Familie. Betrachten Sie diese verwandte Antwort auf SO:

Erwin Brandstetter
quelle
1
Das war tatsächlich eines der ersten Dinge, die ich ausprobiert habe. Es war in einem viel größeren Skript und diese Fehlermeldung wurde in der Ausgabe begraben ERROR: could not open extension control file "/opt/local/share/postgresql92/extension/btree_gist.control": No such file or directory. Ich ging auch davon aus, dass es bereits installiert war, da das ...EXCLUDE USING gist (startend WITH &&)...wie in meinem ursprünglichen Beitrag gezeigt funktionierte. Vielen Dank, dass Sie sich das millionenfach angesehen haben. Um diesen Fehler zu untersuchen.
Ian Timothy
3
@DenverTimothy: Ich denke, ich kann auch dabei helfen. Sie müssen wahrscheinlich zuerst das Contrib-Paket postgresql-contrib-9.2in Ihrem Betriebssystem installieren . Hängt von Ihrem Betriebssystem ab. Betrachten Sie diese verwandte Antwort auf SO.
Erwin Brandstetter
Es kann auch hilfreich sein, darauf hinzuweisen, dass dies unter Mac OS 10.8.2 ausgeführt wird, das mit dem portTool installiert wurde .
Ian Timothy
@DenverTimothy: Ich verwende keine Macs, aber der Principal sollte derselbe sein. Installieren Sie das Paket in Ihrem Betriebssystem, bevor Sie es ausführen können CREATE EXTENSION.
Erwin Brandstetter
2

wenn jemand dies nicht benutzen kann oder will:

CREATE EXTENSION btree_gist;

Wie in meinem Fall, weil Django 1.11 ORM diesen Index nicht unterstützt und ich SQL nicht außerhalb von Django schreiben wollte. Ich habe etwas Ähnliches benutzt wie:

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

'[]' wird verwendet, um sicherzustellen, dass beide Schranken inklusiv sind. Getestet mit Postgres 9.6 und 10.5.

Sergios Bagdasar
quelle