Postgres GIN Index Not Creating Through Liquibase Scripts - postgresql

I am trying to create a GIN index through liquibase scripts.
CREATE INDEX IF NOT EXISTS index_name ON schema_name.table_name USING gin (column1, lower(column2) COLLATE pg_catalog."default" gin_trgm_ops)
Each time migration for the liquibae changeset fails with the following exception:
liquibase.exception.DatabaseException: ERROR: operator class "gin_trgm_ops" does not exist for access method "gin"
The problem is that this query works when run directly from pgAdmin query tool. There seems to be some issue when running this query from liquibase scripts.
I had to create the following extensions before creating the index from pgAdmin query tool. I am creating these extensions in the liquibase script too.
CREATE EXTENSION IF NOT EXISTS pg_trgm with schema public;
CREATE EXTENSION IF NOT EXISTS btree_gin with schema public;
Following is the part of my liquibase script that is creating the extensions and indexes. Btree index creating queries work well with the liquibase scripts. It fails with the above exception when trying to create GIN index.
CREATE EXTENSION IF NOT EXISTS pg_trgm with schema public;
CREATE EXTENSION IF NOT EXISTS btree_gin with schema public;
The following works:
CREATE INDEX IF NOT EXISTS index_name ON table_name USING btree (col1,col2 COLLATE pg_catalog."default")
CREATE INDEX IF NOT EXISTS index_name ON table_name USING btree (col1, col2 COLLATE pg_catalog."default")
But this fails:
CREATE INDEX IF NOT EXISTS index_name ON table_name USING gin (col1, lower(col2) COLLATE pg_catalog."default" gin_trgm_ops)

Wondering if liquibase is running the script, is not running with the public schema in the search path, resulting in an inability to find the gin_trgm_ops operator class you're using to create the index. The error message would certainly indicate this.
Either add it to the search path explicitly and try again (it should work), or create the extension in the pg_catalog schema so that its available implicitly. See here: https://www.postgresql.org/docs/9.1/ddl-schemas.html (section 5.7.5).
You can do this by running the following in place of your existing pg_trgm create extension command.
CREATE EXTENSION IF NOT EXISTS pg_trgm with schema pg_catalog;
This followed by your other commands should do the trick.

Following worked for me instead of using createIndex statement in changeSet I used custom sql statement like
<changeSet author="me" id="26">
<sql>CREATE INDEX my_table_hours_idx ON my_table USING GIN(hours)</sql>
</changeSet>

Related

Can't drop an index in postgres Heroku - receive ERROR: index "ix_public_jobs_next_run_time" does not exist

I have a table in Heroku Postgres (Hobby tier) with a "jobs" table. I am using PGAdmin to view and work with the database.
If I view the dependents tab for the "jobs" table, I can see that an index exists "public.ix_public_jobs_next_run_time".
From the query tool, I run the query "DROP INDEX public.ix_public_jobs_next_run_time;" and get the following error:
ERROR: index "ix_public_jobs_next_run_time" does not exist
SQL state: 42704
Why can't I drop this index?
Background: I am using SQLAlchemy ORM to db upgrade my postgres database to modify some tables. The db upgrade command fails when it tries to drop the index. I used the steps above to recreate this error.
Perhaps you set a search_path that does not include public. Then you have to name the schema explicitly:
DROP INDEX public.ix_public_jobs_next_run_time;
Another option is of course that you connected to the wrong database when you tried to drop the index.

Do I have to create extension on every connect to database?

I want to use uuid_generate_v4 in PostgreSQL. I am currently using version 11, but plan to upgrade to 12.
When I try to call the function I get this error after every connect:
test=# SELECT uuid_generate_V4();
ERROR: function uuid_generate_v4() does not exist
LINE 1: SELECT uuid_generate_V4();
And I have to rerun:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
Minimum "working" example
CREATE DATABASE test;
\connect test;
SELECT uuid_generate_V4(); -- Fails makes sense
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
SELECT uuid_generate_V4(); -- Works
\connect postgres --- Close connection to test
\connect test;
SELECT uuid_generate_V4(); -- Fails makes no sense
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
SELECT uuid_generate_V4(); -- Works
Do I really need to add/create the extension at every connect or am I doing something wrong?
I have the same problem with other extensions as well, but uuid is the most crucial to get working.

PostgreSql hstore extension with public prefix issue

I've struggled with my PostgreSql and hstore extension, so in my sql dump file hstore fields are created with this script:
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;
CREATE TABLE public.identity_devices (
...
metadata public.hstore
);
So I'm getting an error
structure.sql:2058: ERROR: type "public.hstore" does not exist
But in case I use
metadata hstore
everything works fine.
Also, have to note that this happens only on our CI where we're running as user runner but owner of public schema is postgres.
If needs some more data, please let me know and I will provide.
Regards,
You can check if and where the extension is already installed using the command \dx hstore
As we're using Postgres9.3 we have to install hstore manually, on our CI they use Postgres9.6 which automatically add hstore on Db creation.
Also, it puts hstore in namespace pg_catalog which turned out was the main reason why hstore wasn't visible by public.hstore.
So what I had to do is to do one step after creating db on CI, which drop particular extension and creates new one in correct schema.
Anyway, the problem wasn't so hard as it was tricky and weird.

PostgreSQL to Oracle - Can i change OWNER in Oracle?

I am trying to edit PostgreSQL schema script and make it executable in Oracle (Oracle Express). In PostgreSQL were under the each CREAT TABLE these commands:
ALTER TABLE table_name OWNER TO user;
For example table_name is appuser and user is projectX.
The table is successfully created, but there is an error: ORA-01735: invalid ALTER TABLE option
I have also created another user in my scheme (projectX), but the error is still there. So I am confused. Does this command ALTER TABLE table_name OWNER TO user; even exists in Oracle database?

Can't access data from pg_index using Foreign Data Wrapper in postgreSQL 9.3

I implement Foreign data wrapper in postgreSQL 9.3 in another postgreSQL DATABASE as below:
CREATE SERVER app_db
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (dbname 'postgres', host 'localhost');
CREATE USER MAPPING for postgres
SERVER app_db
OPTIONS (user 'postgres', password 'XXXX');
CREATE FOREIGN TABLE location_local
(
id integer,
name character varying
)
SERVER app_db OPTIONS (table_name 'location')
SELECT * FROM location_local;
This all works fine as location table is in public schema. but I also want to access data from pg_catalog. When I follow the same procedure to access the data than it gives me error.
ERROR: relation "public.pg_catalog.pg_index" does not exist
is there any way to access data from catalog using FDW or any other way?
You could try the schema_name option in the foreign table definition:
CREATE FOREIGN TABLE foreign_index (
-- ...
)
SERVER app_db
OPTIONS (
schema_name 'pg_catalog',
table_name 'pg_index'
);
But that might won't work, because pg_catalog is not really a schema, but a system-catalog. If that is the case, you can still use the dblink module to run queries at a foreign database.