Unable to CREATE TRIGGER in Postgres - postgresql

The database simply hangs and never provides an error or response. I've tried this in pgadmin and pgsql.
The trigger is to refresh a materialized view. My trigger function for the refresh has inserted successfully, but I cannot create the trigger.
Trigger function:
CREATE OR REPLACE FUNCTION trig_refresh_inprogress() RETURNS trigger
AS
$$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY inprogress;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Example trigger:
CREATE TRIGGER trig_01_refresh_inprogress
AFTER TRUNCATE OR INSERT OR UPDATE OR DELETE
ON customer FOR EACH STATEMENT
EXECUTE PROCEDURE trig_refresh_inprogress();
I have verified that I have trigger privileges on the customer table and executive privileges on the function.

Related

How to create a trigger in postgresql

I need to create a trigger in postgres where, when I add a record to table A, it automatically inserts its primary key value (which is auto incremented) into table B, the primary key of table A is the foreign key in table B.
I have tried doing it through pgadmin but it does not allow me to save. Could someone help out please.
First create the following trigger function.
CREATE OR REPLACE FUNCTION auto_insert() RETURNS TRIGGER AS
$BODY$
BEGIN
INSERT INTO
B(a_id)
VALUES(new.id);
RETURN new;
END;
$BODY$
language plpgsql;
And then attach the trigger function to table A.
CREATE TRIGGER auto_inserter
AFTER INSERT ON A
FOR EACH ROW
EXECUTE PROCEDURE auto_insert();

PostgreSQL: How to automatically set table owner when creating new table

In PostgreSQL, table owner is automatically set to user who created the table when creating new table. In this situation, the other users can not dropped the table.
So I want to automatically change table owner for newly created tables to specific role. By using this approach, anyone who has this role can drop the tables which table owner is the same role.
To achieve this goal, I used the same approach as described in this blog. https://blog.hagander.net/setting-owner-at-create-table-237/
I am currently using this function. This function should be triggered when new table is created in a schema analytics_custom and change table owner to analytics_custom_readwrite.
But it looks like the functions is not working as expected. Table owner of newly created table is an user who created the table.
Am I missing something? Any problem with this function?
CREATE OR REPLACE FUNCTION analytics_custom.trg_create_set_owner()
RETURNS event_trigger
LANGUAGE plpgsql
AS $function$
DECLARE
obj record;
BEGIN
FOR obj IN
SELECT *
FROM pg_event_trigger_ddl_commands()
WHERE schema_name='analytics_custom' AND command_tag='CREATE TABLE'
LOOP
if obj.object_identity ~ 'analytics_custom.*'
THEN
EXECUTE format('ALTER TABLE %s OWNER TO analytics_custom_readwrite', obj.object_identity);
end if;
END LOOP;
END;
$function$
;
CREATE EVENT TRIGGER analytics_custom_trg_create_set_owner
ON ddl_command_end
WHEN tag IN ('CREATE TABLE')
EXECUTE PROCEDURE analytics_custom.trg_create_set_owner();

Trigger to update Materialised view after an insert on another materialised view Postgresql

I am trying to trigger a refresh for a materialised view after an Insert,update or delete on another materialised view. I am trying to use a triggered function to achieve this. Script is as follows;
CREATE FUNCTION aza_ods_version1.populate_fact_churn_m()
RETURNS TRIGGER AS $$
BEGIN
REFRESH MATERIALIZED VIEW aza_ods_version1.fact_churn_monthly;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER refresh_fact_churn_monthly
AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE
ON aza_ods_version1.fact_transactions
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE aza_ods_version1.populate_fact_churn_m();
On attempting to create the trigger, I get this error;
ERROR: "fact_transactions" is not a table or view
SQL state: 42809
I think its because fact_transactions is a materialized view and not a view or table.
Is there a way i can achieve what i am trying to??
You can't.
The documentation for CREATE TRIGGER doesn't mention materialized views:
table_name The name (optionally schema-qualified) of the table, view, or foreign table the trigger is for.
You cannot put a trigger on a materialized view, you will need to put the trigger on each table references in the query that generated the materialized. Further for TRUNCATE you will need to create a separate trigger:
In addition, triggers may be defined to fire for TRUNCATE, though only
FOR EACH STATEMENT.

Trigger data changed of replicated table - postgres

I have 2 DB , 1st is master db and 2nd is replica db (just some tables of master DB). I try to add the trigger on replica table to catching when it is replicated from master db tables.
I using the trigger for catching insert, delete and update action but it seem not work. that trigger only work for some table that change from sql statement. Not work for replica tables.
Is there any way to catching the replica tables changes? I using go lang and follow guide of this post
https://coussej.github.io/2015/09/15/Listening-to-generic-JSON-notifications-from-PostgreSQL-in-Go/
i did these step :
-- create function
CREATE OR REPLACE FUNCTION notify_event() RETURNS TRIGGER AS $$
DECLARE
data json;
notification json;
BEGIN
IF (TG_OP = 'DELETE') THEN
data = row_to_json(OLD);
ELSE
data = row_to_json(NEW);
END IF;
notification = json_build_object(
'table',TG_TABLE_NAME,
'action', TG_OP,
'data', data);
PERFORM pg_notify('events',notification::text);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- create trigger
CREATE TRIGGER user_warehouse_notify_event
AFTER INSERT OR UPDATE OR DELETE ON users_warehouse_rel
FOR EACH ROW EXECUTE PROCEDURE notify_event();
-- enable replica trigger
ALTER TABLE users_warehouse_rel ENABLE REPLICA TRIGGER user_warehouse_notify_event
it's still not work
When logical replication applies its changes, session_replication_role is set to replica so that normal triggers are not triggered.
To change that for your trigger, use
ALTER TABLE atable ENABLE ALWAYS TRIGGER trigger_name;
Think twice before using this – badly defined triggers can break replication.

postgresql trigger not working

i have a table "demand_details"
on update or delete i want to store values of each row in another table "demand_details_log"
my functions is as follows
CREATE OR REPLACE FUNCTION water_blogb() RETURNS trigger AS
$BODY$
BEGIN
IF (TG_OP='UPDATE') THEN
INSERT INTO demand_details_log VALUES ('U',now(),OLD.*);
RETURN NEW;
END IF;
IF (TG_OP='DELETE') THEN
INSERT INTO demand_details_log VALUES ('D',now(),OLD.*);
RETURN OLD;
END IF;
END;
$BODY$ LANGUAGE plpgsql
my trigger is as follows
CREATE TRIGGER water_btrg_b
AFTER UPDATE OR DELETE
ON demand_details
FOR EACH ROW
EXECUTE PROCEDURE water_blogb();
MY problem is the same trigger and functions works well on other table (by changing table,trigger and function name) but not working with demand table. I tried with "RAISE NOTICE 'working...'" in both in other table trigger gets fired but in demand table its not fired at all.
As you found, triggers are not inherited. This leads to some difficulties in managing triggers in inherited table structures. You may want to read up on some of the issues involved at http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-3-table.html and http://ledgersmbdev.blogspot.com/2012/08/or-modelling-32-setsubset-modelling.html.
Now those do not address table partitioning directly which may be what you are trying to do here. I would recommend that you build in some additional tests that you can run to check and make sure that triggers are properly installed on all subtables. I would suggest taking a look at How to find inherited tables programatically in PostgreSQL? and also the pg_trigger table so that you can build a report of child tables which do not share the triggers of their parents.