postgres: alter publication with IF EXISTS - postgresql

I have a SQL ALTER statement to update an existing publication to add a table.
ALTER PUBLICATION publication_p1 ADD TABLE schema.tablename;
I want to add this line to an automated database versioning script. However I want to see if the publication would be added IF the table wasn't a member AND if the publication existed. So something like:
ALTER PUBLICATION IF EXISTS publication_p1 ADD TABLE IF NOT EXISTS schema.tablename;
I tried my idea, and obviously didn't work. Looking at the postgres documentation IF EXISTS is not supported.
Is there a way of applying something similar in POSTGRES?
Thanks

Related

Redshift: Truncating Table Created by another user

I'm trying to truncate a table in redshift but it's throwing the following error -
SQL Error [500310] [42501]: Amazon Invalid operation: must
be owner of relation table;
I have already granted all the privileges on the table to the user. As checked through the online documentation for redshift, I can't grant the truncate table access explicitly like the way it's enabled now in PostgreSQL. Is there a way or a best practice to handle this scenario?
As you say only the table owner or a superuser can truncate a table. There are several options.
Change the table to be owned by the user that needs to truncate but this may not meet other constraints
Alter table to current user, truncate, and alter it back to the previous user (requires DROP permission)
Drop and recreate the table but this may break dependencies
Make a table LIKE the original, perform an ALTER TABLE APPEND to this new table, and then drop the new table (some restrictions like no identity columns)

Rename column on iSeries DB2

I would like to rename a column in DB2 on the iSeries platform. The link below is related, however, I do not have a primary key or constraint defined on the columns I would like to rename. In addition, I'm not certain that they are on the iSeries as well.
Rename column in DB2
However, I decided to give it a go with the following statement:
ALTER TABLE MYLIB.MYFILE RENAME COLUMN COL0001 TO COL0002;
Post execution, I am given the following warning:
Additionally, I do not see a RENAME COLUMN in the docs:
https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/db2/rbafzatabl.htm
Is this something that is not possible on V7R1 DB2?
There is no RENAME COLUMN clause in the ALTER TABLE statement in DB2 for IBM i.
You may probably achieve the same with the following:
ALTER TABLE MYLIB.MYFILE ADD COLUMN COL0002 ...;
UPDATE MYLIB.MYFILE SET COL0002 = COL0001;
ALTER TABLE MYLIB.MYFILE DROP COLUMN COL0001;

PSQL was inferring schema, but how?

We're in the process of upgrading our software from PostgreSQL 9.2 to 9.6 and we've run into an odd issue.
Our installation runs an SQL script to create the database. This is done using psql -f. This worked fine under 9.2 but seems to have issues with not creating objects in 9.6. I've been looking into this and found something odd in the SQL script. Most of the tables are created using statements that look like this:
--
-- Name: crawler_run; Type: TABLE; Schema: analytics; Owner: postgres; Tablespace:
--
CREATE TABLE IF NOT EXISTS crawler_run (
... columns, etc.
);
--
ALTER TABLE analytics.crawler_run OWNER TO postgres;
Note that there is no schema in the create table statement. But the tables were being created in the correct schema and the subsequent alter table statement was not failing.
My best guess is that the preceding comment has something to do with it, but I've not been able to find any documentation to support that.
So how was this working?
Tables are created in the first schema of the user/role search_path, which is either set permanently or just for the current session.
Look for a statement like:
SET search_path = analytics
In your case it was analytics and now it is probably back to the default public.

How to Check if a Foreign Key Exists on a Specific Table in PostgreSQL

I have a foreign key named user__fk__store_id that was supposed to be created on the user table.
However, I made a mistake and instead have it created on another table I have named client.
My servers have an automated process that reads from a JSON file I created with what new tables to create, remove, etc... Every time a server needs to be upgraded with new stuff, it will run through this JSON file and run the queries it needs to.
In this case, in the json file, I'm trying to have it drop the existing incorrect foreign key constraint that was created on the client table, and recreate it correctly on the user table. So technically, it should be running these 2 queries back to back:
ALTER TABLE client DROP CONSTRAINT user__fk__store_id;
ALTER TABLE user ADD CONSTRAINT user__fk__store_id;
The problem I'm having is I can't figure out the query to run in order to see if the user__fk__store_id exists on the client table. I only know how to check if the constraint exists on any table in the database with the following:
SELECT COUNT(1) FROM pg_constraint WHERE conname='user__fk__store_id';
This would be a problem because this means every time I run my upgrade script on my servers, it will always think the constraint of that name already exists, but when it attempts to run the drop query it will error out because it can't find that constraint in the client table.
Is there a query I can run to check not just if the constraint exists, but also if it exists in a specific table?
I found the answer to my own question, I can just run the following query:
SELECT COUNT(1) FROM information_schema.table_constraints WHERE constraint_name='user__fk__store_id' AND table_name='client';
Above answer works fine, but following returns true/false and also checks for schema
SELECT EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE table_schema='schema_name' AND table_name='MyTable' AND
constraint_name='myTable_fkName_fkey');

Create TABLE in many Postgres schemas with a single command

I have two schemas in my Postgres BOOK database, MSPRESS and ORELLY.
I want to create the same table in two schemas:
CREATE TABLE MSPRRESS.BOOK(title TEXT, author TEXT);
CREATE TABLE ORELLY.BOOK(title TEXT, author TEXT);
Now, I want to create the same table in all my schemas with a single command.
To accomplish this, I thought about event triggers available in Postgres 9.3 (http://www.postgresql.org/docs/9.3/static/event-triggers.html). Intercepting CREATE TABLE command by my event trigger, I thought to determine name of table and schema in which it is created and just repeat the same command for all available schemas. Sadly, event trigger procedure does not get name of table being created.
Is there a way to 'real-time' synchronization of Postgres schema?
Currently only TG_EVENT and TG_TAG is available from an event trigger, but this feature will likely be expanded. In the meantime, you can query information_schema for differences and try to add every table, where its missing; but don't forget that this synchronization will also trigger several event triggers, so you should do it carefully.
But if you just want to build several schemas with the same structure (without further synchronization), you could just write schema-less queries to build them & run it on every schema one-by-one, after changing search path with SET search_path / SET SCHEMA.