In postgres how do I add index to existing table? - postgresql

In postgres how do I add index to existing table?
I tried following but it's not working:
CREATE INDEX my_index ON my_table USING btree(a_column);
and then this:
CREATE INDEX my_index ON my_table USING btree(a_column);
But neither works.
I am using ant to do a db migration. And when I do ant db-migrate-apply-postgresql I keep getting the error
[echo] ERROR: relation "my_index" already exists

Well, this error message:
ERROR: relation "my_index" already exists
is pretty clear, isn't it.
You are trying to create an index with the name of an existing index or table.
You need to use a different name.

Related

Upsert with "on conflict do update" with partial index in jOOQ

I have a partial index on table MY_TABLE that is defined like:
CREATE UNIQUE INDEX my_index
ON MY_TABLE(CUSTOMER_ID, OWNER_ID)
WHERE CLOSED_ON IS NULL;
Then, I'm attempting an upsert using jOOQ
final var insert = using(configuration)
.insertInto(MY_TABLE,
MY_TABLE.CUSTOMER_ID,
MY_TABLE.OWNER_ID,
MY_TABLE.UPDATED_ON);
customers.forEach(custId -> insert.values(custId, reprId, today));
insert.onConflict(MY_TABLE.CUSTOMER_ID, MY_TABLE.OWNER_ID)
.where(MY_TABLE.CLOSED_ON.isNull())
.doUpdate()
.set(MY_TABLE.UPDATED_ON, today)
.execute();
But the above code is throwing this error:
org.jooq.exception.DataAccessException: SQL [...];
ERROR: invalid reference to FROM-clause entry for table "my_table"
Hint: There is an entry for table "my_table", but it cannot be referenced from this part of the query.
Looking at the generated SQL I see jOOQ is adding the schema and table name to the where part of the on conflict, which Postgres doesn't like:
... on conflict ("customer_id", "owner_id") where "my_schema"."my_table"."closed_on" is null do update set ...
Is there a way to tell jOOQ not to add the schema and table name?
This is a workaround I'm using, but I wonder if there is a better way:
.where(condition("closed_on IS NULL"))
We found a bug report in jOOQ's issues page that asks exactly this question:
https://github.com/jOOQ/jOOQ/issues/11732
Which mentions this workaround:
.where(field(COURSE_ENROLL.DELETED_TS.getUnqualifiedName()).isNull())
So I can do that instead of what I did with the literal string in my case.
This is also mentioned to be a bug that was fixed 3 weeks ago :)
Thanks.
EDIT:
There is already a fix for this in jOOQ 3.14.9

Why wont postgres let me drop an index? [duplicate]

I hope to remove index in table, but it occurs not remove index.
CREATE INDEX idx_name ON schema_name.table_name(column1, column2);
And, remove index
DROP INDEX idx_name;
but, it fail.
error message is
ERROR: index "idx_name" does not exist
How I do it?
You need to specify schema if it isn't in your search path.
DROP INDEX schema_name.idx_name;
To clarify:
The name of the index to be created. No schema name can be included here; the index is always created in
the same schema as its parent table

Postgres: Error constraint "fk" of relation "tbl" does not exist (with Yii - PHP)

I searched for this problem. But my postgres user has enough grant and I do not think I have misspelling error. However I am newbie.
I have this error message:
21:38:03 set search_path='public'
21:38:03 ALTER TABLE public.tbl_user DROP CONSTRAINT "fk-user-access-user-id"
21:38:03 ERROR: constraint "fk-user-access-user-id" of relation "tbl_user" does not exist
I use the PhpStorm. I just open the database view, expanded the tbl_user table, right click and select "drop". And I got this error in the console.
So the above SQL command generated by the PhpStorm.
Then I tried with these commands manually on Ubuntu:
ALTER TABLE tbl_user DROP CONSTRAINT "fk-user-access-user-id"
ALTER TABLE "tbl_user" DROP CONSTRAINT "fk-user-access-user-id"
But I get the same error.
In the PhpStorm I see this definition:
"fk-user-access-user-id" FOREIGN KEY (access_id) REFERENCES tbl_access (id)
The tbl_access table exists with the primary id key.
I do not understand this error message, because the "fk-user-access-user-id" foreign key is at the tbl_user and so for me the 'relation "tbl_user" does not exist' strange. I do not understand.
I tried to find similar problem on StackOverflow, but I gave up after 20x question reading.
By the way, the postgres code was generated by the Yii framework.
$this->addColumn('{{%user}}', 'access_id', $this->integer()->notNull()->defaultValue(1)->after('status'));
$this->addForeignKey('fk-user-access-user-id', '{{%user}}', 'access_id', '{{%access}}', 'id');
first row mean add access_id column to the user table.
second row: create foreign key with 'fk-user...' name on tbl_user table's access_id column references to tbl_access table's id column.
So I used this PHP code to generate this SQL commands. I prefer this way because for me the migration files are very useful.
Most likely the definition and actual implementation in your underlying DB has changed from what the app has recorded. Depending on what the history is, either a change in the app for that foreign key relationship was not migrated to persist the change at the database level, or someone has executed some operation directly at the DB level to remove the relationship. You will need to sync up the app layer to the DB at this point I would think.

How to rename a PostgreSQL table by prefixing an underscore?

I have a database which relies on a PostgreSQL system and I am maintaining it so I want to change tables and overall scheme. For this I thought of renaming the older tables so they have an underscore as a prefix. But this is not working:
DROP TABLE IF EXISTS _my_table; -- table does not exists, this does nothing
ALTER TABLE my_table
RENAME TO _my_table;
The result of the query is the following:
NOTICE: table "_my_table" does not exist, skipping ERROR:
type "_my_table" already exists
********** Error **********
ERROR: type "_my_table" already exists SQL state: 42710
The '_my_table' table is a fake name, but this error is reproduced by actually creating a '_my_table' table and running the same script above.
I am using pgAdmin III to access the database tables and making use of it's 'rename' operation results in the same error.
The postgresql documentation for the alter table method does not tell me explicitly about this particular problem: http://www.postgresql.org/docs/9.3/static/sql-altertable.html
Do I really need to use a prefix like 'backup' instead of '_' ? Or would it be possible to rename it, my only interest is to maintain the information in the table whilst having the minimal changes to the table name.
You cannot simply put an underscore in front of the existing table name because every table has an associated type that is... a leading underscore before the table name. You can verify this in the pg_catalog.pg_type table. Having a table name start with an underscore is not the problem, but the internal procedure is that a new table is created physically from the old table and only when the old table is no longer in use by other processes will the old table, and its associated type, be deleted. Hence the error referencing the type (and not the relation).
So if you really want to keep the old name with an underscore, you should first ALTER TABLE to some temp name and then ALTER TABLE to the underscore + original name. Or simply use another prefix...
ERROR: type "_my_table" already exists
Both tables and types are stored in the internal table pg_class. A unique name is required, that's why you get this error message.

How to force drop index relation in postgresql?

In PostgreSQL 9.2 / PostGIS 2.0.2 I had an index on a spatial column, created with
CREATE INDEX tiger_data_sld_the_geom_gist ON tiger_data.sld USING gist(the_geom);
Subsequently dropped the index with
DROP INDEX tiger_data_sld_the_geom_gist;
But now, when I try to recreate, I get this error:
# CREATE INDEX tiger_data_sld_the_geom_gist ON tiger_data.sld USING gist(the_geom);
ERROR: relation "tiger_data_sld_the_geom_gist" already exists
Dropping again doesn't work. It says that the index doesn't exist:
# DROP INDEX tiger_data_sld_the_geom_gist;
ERROR: index "tiger_data_sld_the_geom_gist" does not exist
I haven't found the relation "tiger_data_sld_the_geom_gist" in any list of database objects, have tried DROP TABLE, and searched around for solutions.
What is this mystery relation "tiger_data_sld_the_geom_gist", and how do I remove it so that I can create the index?
Edit:
Also have tried restarting the server, and dumping / dropping / reloading the table (dropped with CASCADE).
Unless you are setting the search_path GUC to (or at least including) the tiger_data schema, you need to add the schema to the index name to issue the DROP INDEX (I'd use it in any case for safety):
DROP INDEX tiger_data.tiger_data_sld_the_geom_gist;
That's because the index always go to the same schema of the table it belongs to. If the above doesn't solve your problem, you can check if this relation name exists and on each schema it is in with the following:
SELECT r.relname, r.relkind, n.nspname
FROM pg_class r INNER JOIN pg_namespace n ON r.relnamespace = n.oid
WHERE r.relname = 'tiger_data_sld_the_geom_gist';
It will return the kind (i for indexes, r for tables, S for sequences and v for views) of any relation that has the name tiger_data_sld_the_geom_gist and name of the schema it belongs to.
Though not particularly efficient, this appears to have done the trick:
Dump the table with pg_dump.
Drop the table.
Dump the database with pg_dump.
Drop the database.
Recreate the database and reload from dump files.