How to use uuid with postgresql gist in EXCLUDE constraint - postgresql

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 &&)|)

Related

postgresql: btree_gist does not exist

I need to use btree_gist in order to index three fields: a postgis geometry, a date and bigint.
I have postgresql-contrib installed, and I'm able to create the extension without any problem using: CREATE EXTENSION btree_gist; the extension is visible in the extensions list in pgAdmin, but it is not installed according to the command \dx in psql.
Obviously trying to create an index with btree_gist results in an error stating that btree_gist does not exist.
I'm running pqsl 9.5.4.
Is there something that I'm missing?
According to manuels
https://www.postgresql.org/docs/9.5/static/btree-gist.html
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, inet, and cidr.
PostGIS geometries not included here and also Postgis geometries has own index type GIST
And there is a similar question here
Postgres GIST vs Btree index

PostgreSQL query with function gen_random_uuid() not working on Windows

I have the following query for creating a table,
CREATE TABLE IF NOT EXISTS company (
id uuid CONSTRAINT companyid PRIMARY KEY DEFAULT gen_random_uuid(),
name varchar(128) NOT NULL,
db_uri varchar(255) NOT NULL,
c_uri varchar(255) NOT NULL,
date_c timestamp DEFAULT now(),
date_m timestamp DEFAULT now()
) WITH (fillfactor=90);
I am getting the following error when I run it through pgAdminIII.
ERROR: function gen_random_uuid() does not exist
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
********** Error **********
ERROR: function gen_random_uuid() does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
I have created an extension pgcrypto as that contains gen_random_uuid() function definition but that also did not help.
I ran the same scripts on a MAC and it all worked fine.
I am using PostgreSQL 9.3.
The issue was with Version of PostgreSQL.
It is in PostgreSQL 9.4 up that, pgcrypto has the gen_random_uuid() function.
Got the new version installed and it was all good!
http://www.postgresql.org/docs/9.3/static/pgcrypto.html
http://www.postgresql.org/docs/9.4/static/pgcrypto.html

How to correctly associate an id generator sequence with a table

I'm using Grails 3.0.7 and Postgres 9.2. I'm very new to Postgres, so this may be a dumb question. How do I correctly associate an id generator sequence with a table? I read somewhere that if you create a table with an id column that has a serial datatype, then it will automatically create a sequence for that table.
However, the column seems to be created with a type of bigint. How do I get Grails to create the column with a bigserial datatype, and will this even solve my problem? What if I want one sequence per table? I'm just not sure how to go about setting this up because I've never really used Postgres in the past.
You can define a generator in a domain class like this:
static mapping = {
id generator:'sequence', params:[sequence:'domain_sq']
}
If the sequence is already present in the database then you'll need to name it in the params.
There are other properties also available as outlined in the documentation, for example:
static mapping = {
id column: 'book_id', type: 'integer'
}
In Postgres 10 or later consider an IDENTITY column instead. See:
Auto increment table column
However, the column seems to be created with a type of bigint. How do
I get Grails to create the column with a bigserial datatype, and will
this even solve my problem?
That's expected behavior. Define the column as bigserial, that's all you have to do. The Postgres pseudo data types smallserial, serial and bigserial create a smallint, int or bigint column respectively, and attach a dedicated sequence. The manual:
The data types smallserial, serial and bigserial are not true types,
but merely a notational convenience for creating unique identifier
columns (similar to the AUTO_INCREMENT property supported by some
other databases). In the current implementation, specifying:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
Big quote, I couldn't describe it any better than the manual.
Related:
Get table and column "owning" a sequence
Safely rename tables using serial primary key columns

PostgreSQL bigserial & nextval

I've got a PgSQL 9.4.3 server setup and previously I was only using the public schema and for example I created a table like this:
CREATE TABLE ma_accessed_by_members_tracking (
reference bigserial NOT NULL,
ma_reference bigint NOT NULL,
membership_reference bigint NOT NULL,
date_accessed timestamp without time zone,
points_awarded bigint NOT NULL
);
Using the Windows Program PgAdmin III I can see it created the proper information and sequence.
However I've recently added another schema called "test" to the same database and created the exact same table, just like before.
However this time I see:
CREATE TABLE test.ma_accessed_by_members_tracking
(
reference bigint NOT NULL DEFAULT nextval('ma_accessed_by_members_tracking_reference_seq'::regclass),
ma_reference bigint NOT NULL,
membership_reference bigint NOT NULL,
date_accessed timestamp without time zone,
points_awarded bigint NOT NULL
);
My question / curiosity is why in a public schema the reference shows bigserial but in the test schema reference shows bigint with a nextval?
Both work as expected. I just do not understand why the difference in schema's would show different table creations. I realize that bigint and bigserial allow the same volume of ints to be used.
Merely A Notational Convenience
According to the documentation on Serial Types, smallserial, serial, and bigserial are not true data types. Rather, they are a notation to create at once both sequence and column with default value pointing to that sequence.
I created test table on schema public. The command psql \d shows bigint column type. Maybe it's PgAdmin behavior ?
Update
I checked PgAdmin source code. In function pgColumn::GetDefinition() it scans table pg_depend for auto dependency and when found it - replaces bigint with bigserial to simulate original table create code.
When you create a serial column in the standard way:
CREATE TABLE new_table (
new_id serial);
Postgres creates a sequence with commands:
CREATE SEQUENCE new_table_new_id_seq ...
ALTER SEQUENCE new_table_new_id_seq OWNED BY new_table.new_id;
From documentation: The OWNED BY option causes the sequence to be associated with a specific table column, such that if that column (or its whole table) is dropped, the sequence will be automatically dropped as well.
Standard name of a sequence is built from table name, column name and suffix _seq.
If a serial column was created in such a way, PgAdmin shows its type as serial.
If a sequence has non-standard name or is not associated with a column, PgAdmin shows nextval() as default value.

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;