postgresql: btree_gist does not exist - postgresql

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

Related

Postgres: Convert text to timestamptz for index?

I have a column text_ts which is a text field that always holds data representing a timestamptz, just as a text field. I need to create an index on it such as:
CREATE INDEX IF NOT EXISTS text_ts_timestamp_idx ON my_schema.my_table ((text_ts::timestamptz AT TIME ZONE 'UTC'));
However I get the error:
functions in index expression must be marked IMMUTABLE
I have found this: https://dba.stackexchange.com/questions/250627/why-isnt-it-possible-to-cast-to-a-timestamp-in-an-index-in-postgresql which seems to have a recommended way to handle timestamp, but I can't seem to get it to work for timestamptz AT TIME ZONE 'UTC'.
Anyone have any ideas?

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

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;

Implicit Index for table

I am learning Postgresql and db in general. I have a simple query like this and I want to understand what it does
CREATE TABLE adempiere.c_mom(
c_mom_id NUMERIC(10,0) NOT NULL,
isactive character(1) DEFAULT 'Y'::bpchar NOT NULL,
start_date date NOT NULL,
start_time timestamp without time zone NOT NULL,
end_time timestamp without time zone NOT NULL,
CONSTRAINT c_mom_pkey PRIMARY KEY (c_mom_id)
);
So after I execute this I got
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "c_mom_pkey" for table "c_mom"
Now I know that my PK is c_mom_id, but what is the purpose of creating an implicit index it under name c_mom_key?
What does DEFAULT 'Y'::bpchar, or in general what does :: in psql do?
Thank you
The :: notation is a PostgreSQL-specific type cast notation, in this case to type bpchar (blank-padded char).
An index is created to back primary keys to make them efficient. If there wasn't an index to back it, each insert statement would have to scan the whole table just to figure out if that insertion would create a duplicate key or not. Using an index speeds that up (dramatically if the table is large).
This is not PostgreSQL specific. A lot of relational databases will create unique indexes to back primary keys.