Equivalent to exclusion constraint composed of integer and range - postgresql

I need to have something equivalent to this exclusion constraint
drop table if exists t;
create table t (
i int,
tsr tstzrange,
exclude using gist (i with =, tsr with &&)
);
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.
I guess the problem is obvious from the error message. How to do it?

You need to install the additional module btree_gist to make it work. The module installs the missing operator class.
Details in this related answer:
Exclusion constraint on a bitstring column with bitwise AND operator
More at this answer on dba.SE:
PostgreSQL EXCLUDE USING error: Data type integer has no default operator class

Related

How to define operator class for composite type in PostgreSQL?

I have a composite type. And I want to define exclusion constraint on it, that would also be combined with range exclusions, but getting the following error.
create type example_t as (
x uuid,
y text
);
create table example (
id example_t not null,
time tstzrange not null,
exclude using gist (id with =, time with &&)
);
ERROR: data type example_t 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. SQL state: 42704
How can I define the operator class for 'example_t' composite type?
It is complicated to define a new GiST operator class. You'd have to define support functions and matching strategies. See the documentation for an example how that is done using C functions.
But I think it would be much simpler not to include the column of type example_t in the exclusion constraint, but the individual elements id.x and id.y. That way you can probably get along with the operator classes defined in the btree_gist contrib module.

How to use uuid with postgresql gist in EXCLUDE constraint

I'm getting error while I use Exclude constraint using gist
ALTER TABLE tbl_product ADD EXCLUDE USING gist (base_id WITH =, lifetime WITH &&);
ERROR: data type uuid 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.
Note:
base_id datatype is uuid,
lifetime datatype is period
I am using PostgreSQL 9.4. I have to use 9.4 only as I don't have any other option since I am unable to install temporal extension in 9.5, 9.6 and 10 are gives an error.
You'll need the btree_gist extension for that:
btree_gist provides GiST index operator classes that implement B-tree equivalent behavior for the data types int2, int4, int8, float4, float8, numeric, timestamp with time zone, timestamp without time zone, time with time zone, time without time zone, date, interval, oid, money, char, varchar, text, bytea, bit, varbit, macaddr, macaddr8, inet, cidr, uuid, and all enum types.
Unfortunately support for uuid was only added in v10.
With v10, you should be able to use
base_id gist_uuid_ops WITH =
in your exclusion constraint.
With 9.4, you could cast the column to a different type first:
(base_id::text) gist_text_ops WITH =
The accepted answer is correct, btree_gist is needed, however the suggested solution does not work (at least not in v12 in 2021). If you've been getting errors like in original question you should do the following:
CREATE EXTENSION IF NOT EXISTS btree_gist;
ALTER TABLE tbl_product ADD EXCLUDE USING gist (base_id WITH =, lifetime WITH &&);
As a bonus, I've been using it in Elixir & Ecto 3.5 and here's how to do this in Ecto migration:
execute "CREATE EXTENSION IF NOT EXISTS btree_gist"
create constraint(:tbl_product, "constraint_name", exclude: ~s|gist ("base_id" WITH =, lifetime WITH &&)|)

What is the purpose of defining an operator class when defining index in postgres?

For example
CREATE INDEX my_index_name
ON public.my_table USING btree
(my_column int8_ops)
TABLESPACE pg_default;
vs
CREATE INDEX my_index_name
ON public.my_table USING btree
(my_column)
TABLESPACE pg_default;
What is the difference?
As much as I dislike quoting verbatim, I think what is written in the manual describes it most correctly and succintly, and I doubt I could do better:
The operator class identifies the operators to be used by the index
for that column. For example, a B-tree index on the type int4 would
use the int4_ops class; this operator class includes comparison
functions for values of type int4. In practice the default operator
class for the column's data type is usually sufficient. The main
reason for having operator classes is that for some data types, there
could be more than one meaningful index behavior. For example, we
might want to sort a complex-number data type either by absolute value
or by real part. We could do this by defining two operator classes for
the data type and then selecting the proper class when making an
index. The operator class determines the basic sort ordering (which
can then be modified by adding sort options COLLATE, ASC/DESC and/or
NULLS FIRST/NULLS LAST).
As for your example, if my_column is defined as type int8, then specifying the operator class as int8_ops is moot, as that would be the default operator for that type.

Using postgresql gin or gist index with bigint column

i am trying to create gin index on bigint column and getting an error (PostgreSQL 9.1.9 / Debian 7).
CREATE TABLE test (id bigint CONSTRAINT test_pkey PRIMARY KEY, field bigint);
CREATE INDEX idx_test_field ON test using GIN(field);
ERROR: data type bigint 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.
Is there no default support for int8 gin,gist indexes ?
There's generally no reason to create a GiST or GIN index on a primitive type.
If you do require this - say, if you want a composite index that includes both some primitive types and some more complex GiST / GIN-only index types - then you will want the btree_gist or btree_gin modules, as appropriate.
CREATE EXTENSION btree_gin;

postgres create an index

I am going from mysql to postgres and I am having a problem creating an index.
CREATE INDEX pointsloc ON table USING gist (point_col);
This is the response I get back:
ERROR: data type point 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.
I have seen I need to specify the operator class for the index, different classes can be used depending upon the type of operators you wish to use on the column. I wish to use the #> or ~ to find if a point is within a polygon.
How do i specify the operator class?? help please has to be a simple thing but I am stumped!
EDIT
Below is a print screen of me trying to add an index to the branch table:
Table "public.branch"
Column | Type | Modifiers
------------------+------------------+-----------------------------------------------------
id | integer | not null default nextval('branch_id_seq'::regclass)
name | character(120) |
center_point_lat | double precision |
center_point_lng | double precision |
center_point | point |
Indexes:
"branch_pkey" PRIMARY KEY, btree (id)
paul=# create index pt_idx on branch using gist (center_point);
ERROR: data type point 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.
Seems to be working fine when I try:
test=# create table test (pt point);
CREATE TABLE
test=# create index pt_idx on test using gist (pt);
CREATE INDEX
Are you sure your point_col actually is of type point? Because, if it's a varchar, than it will indeed miserably fail without the btree_gist contrib - and even then it won't be very useful.