19

I would like to use a GIN index on uuid[] (to have efficient membership tests for arrays of uuids). However when I try it PostgreSQL gives me an error:

mydb=> CREATE TABLE foo (val uuid[]);
CREATE TABLE
mydb=> CREATE INDEX foo_idx ON foo USING GIN(val);
ERROR:  data type uuid[] has no default operator class for access method "gin"
HINT:  You must specify an operator class for the index or define a default operator class for the data type.

How can I add the necessary operator class so that it works?

Note that this is a similar question for the type citext but the provided answer doesn't work.

2 Answers 2

30

Note: this answer is obsolete as this is now part of a standard PostgreSQL, see tbussmann's other answer (which you should upvote).

Original answer:

This can be done using the following operator class:

CREATE OPERATOR CLASS _uuid_ops DEFAULT 
  FOR TYPE _uuid USING gin AS 
  OPERATOR 1 &&(anyarray, anyarray), 
  OPERATOR 2 @>(anyarray, anyarray), 
  OPERATOR 3 <@(anyarray, anyarray), 
  OPERATOR 4 =(anyarray, anyarray), 
  FUNCTION 1 uuid_cmp(uuid, uuid), 
  FUNCTION 2 ginarrayextract(anyarray, internal, internal), 
  FUNCTION 3 ginqueryarrayextract(anyarray, internal, smallint, internal, internal, internal, internal), 
  FUNCTION 4 ginarrayconsistent(internal, smallint, anyarray, integer, internal, internal, internal, internal), 
  STORAGE uuid;

Credits to this for pointing me in the right direction.

The relevant documentation is in Interfacing extensions to indexes, in particular the operator strategy and function numbers for GIN are described there.

Sign up to request clarification or add additional context in comments.

5 Comments

Curious to know: might adding btree_gin have been enough, or was the above required?
No, btree_gin does not include array types.
Just a note, you can't use this on Heroku or any other postgres host, as it requires superuser privs to create an operator class!
I tried using this on PostGres 9.6 but after running it I receive the same error as the OP. I thought maybe the underscore in FOR TYPE _uuid was a typo, but when I create FOR TYPE uuid I get another error when creating the index cache lookup failed for type 3177436692 . Any thoughts on what I might be doing wrong?
What about upgrades? Should we drop this operator class definition if, say, we go from 9.6 to version 10?
13

As of PostgreSQL 10 the custom operator class _uuid_ops is no longer necessary as there is now a general built-in opclass array_ops on anyarry (see: https://www.postgresql.org/docs/current/gin.html#GIN-BUILTIN-OPCLASSES)

2 Comments

Thanks @tbussmann, I referenced your answer in my original one.
Provided link seems to be removed from postgres, it gives page not found error. may be it is postgresql.org/docs/current/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.