Error de uso exclusivo de PostgreSQL: el tipo de datos entero no tiene clase de operador predeterminada

37

En PostgreSQL 9.2.3 estoy tratando de crear esta tabla simplificada:

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

Pero me sale este error:

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.

Los documentos de PostgreSQL usan este ejemplo que no funciona para mí:

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

Mismo mensaje de error.

Y este , que tampoco funciona para mí:

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

Mismo mensaje de error.

Puedo crear esto sin ningún problema:

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

y esto:

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

He pasado bastante tiempo buscando pistas sobre cómo hacer que esto funcione o sobre por qué no funcionará. ¿Algunas ideas?

Ian Timothy
fuente
99
+1 ¡Mira aquí, gente! Asi es como se hace. La pregunta tiene todo lo que necesita: el RDBMS y la versión, código de ejemplo, mensaje de error, una definición clara del problema, enlaces, una visualización de lo que el OP ha intentado. Los trabajos. Ningun ruido. ¡Y esto es de un usuario primerizo! Chapeau Me convenció de inmediato para echar un vistazo más de cerca.
Erwin Brandstetter
2
Pregunta de seguimiento: dba.stackexchange.com/questions/37391/…
Erwin Brandstetter

Respuestas:

29

Instale el módulo adicional btree_gistcomo se menciona en el manual en la ubicación a la que se vinculó :

Puede usar la btree_gistextensión para definir restricciones de exclusión en tipos de datos escalares simples, que luego se pueden combinar con exclusiones de rango para una máxima flexibilidad. Por ejemplo, después de que btree_gistse instala, la siguiente restricción rechazará los rangos superpuestos solo si los números de la sala de reuniones son iguales:

En PostgreSQL moderno solo necesita ejecutar (una vez por base de datos):

CREATE EXTENSION btree_gist;

Primero debe tener instalado el paquete "contrib" en su sistema operativo. Los detalles dependen de su sistema operativo y del repositorio de software utilizado. Para la familia Debian es típicamente postgresql-contrib-9.2(para Postgres 9.2). O simplemente postgresql-contribpara la familia Red Hat. Considere esta respuesta relacionada en SO:

Erwin Brandstetter
fuente
1
Esa fue en realidad una de las primeras cosas que intenté. Fue en un guión mucho más grande y este mensaje de error quedó enterrada en la salida: ERROR: could not open extension control file "/opt/local/share/postgresql92/extension/btree_gist.control": No such file or directory. También supuse que ya estaba instalado porque ...EXCLUDE USING gist (startend WITH &&)...funcionaba como se muestra en mi publicación original. Gracias por echar un vistazo millonésimo a esto. Ahora para investigar ese error.
Ian Timothy
3
@DenverTimothy: Creo que también puedo ayudar con eso. Probablemente postgresql-contrib-9.2primero necesite instalar el paquete contrib en su sistema operativo. Depende de su sistema operativo. Considere esta respuesta relacionada en SO.
Erwin Brandstetter
Además, puede ser útil tener en cuenta que esto se ejecuta en Mac OS 10.8.2, instalado con la portherramienta.
Ian Timothy
@DenverTimothy: No estoy usando Mac, pero el principal debería ser el mismo. Instale el paquete en su sistema operativo antes de poder ejecutarlo CREATE EXTENSION.
Erwin Brandstetter
2

si alguien no puede o no quiere usar esto:

CREATE EXTENSION btree_gist;

Como fue en mi caso, porque Django 1.11 ORM no admite este índice y no quería escribir SQL fuera de Django. Usé algo similar a:

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

'[]' se usa para asegurarse de que ambos límites sean inclusivos. Probado con Postgres 9.6 y 10.5.

Sergios Bagdasar
fuente