Thread: BUG #16177: pg_event_trigger_ddl_commands() returns empty set for ddl_command_start and "drop table"
BUG #16177: pg_event_trigger_ddl_commands() returns empty set for ddl_command_start and "drop table"
From
PG Bug reporting form
Date:
The following bug has been logged on the website: Bug reference: 16177 Logged by: Andrei Pozolotin Email address: andrei.pozolotin@gmail.com PostgreSQL version: 11.6 Operating system: linux Description: 1. use case is to delete rows with oid references to the table before "drop table" 2. one way to do that is with event_trigger, see code snippet below 3. the problem is that: pg_event_trigger_ddl_commands() returns empty set for ddl_command_start and "drop table" 4. this issue was already mentioned before: https://postgrespro.com/list/thread-id/2394772 5. sample code: CREATE OR REPLACE FUNCTION pglogical_assign_repset() RETURNS event_trigger AS $$ DECLARE obj record; BEGIN RAISE NOTICE 'pglogical assign: % %', tg_event, tg_tag; FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP IF obj.object_type = 'table' THEN IF obj.schema_name = 'public' THEN IF tg_tag IN ('CREATE TABLE') THEN PERFORM pglogical.replication_set_add_table('default', obj.objid); END IF; IF tg_tag IN ('DROP TABLE') THEN PERFORM pglogical.replication_set_remove_table('default', obj.objid); END IF; END IF; END IF; END LOOP; END; $$ LANGUAGE plpgsql; --- DROP EVENT TRIGGER IF EXISTS pglogical_assign_repset_create; CREATE EVENT TRIGGER pglogical_assign_repset_create ON ddl_command_end WHEN TAG IN ('CREATE TABLE') EXECUTE FUNCTION pglogical_assign_repset(); --- DROP EVENT TRIGGER IF EXISTS pglogical_assign_repset_delete; CREATE EVENT TRIGGER pglogical_assign_repset_delete ON ddl_command_start WHEN TAG IN ('DROP TABLE') EXECUTE FUNCTION pglogical_assign_repset(); ---
Re: BUG #16177: pg_event_trigger_ddl_commands() returns empty setfor ddl_command_start and "drop table"
From
Alvaro Herrera
Date:
On 2019-Dec-22, PG Bug reporting form wrote: > 1. use case is to delete rows with oid references to the table before "drop > table" I think you could achieve that with an event trigger on event sql_drop. IIRC that event trigger is run for the objects before the drops are actually executed. ddl_command_start is pretty useless, because it doesn't have much info abot the command being run; I'm sure that pg_event_trigger_ddl_commands() would always return empty there. The function would return non-empty only during ddl_command_end, but that's no useful to you because the drops will already have run. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: BUG #16177: pg_event_trigger_ddl_commands() returns empty set forddl_command_start and "drop table"
From
Andrei Pozolotin
Date:
Alvaro, hi: 1. thank you for the idea, I have just tried that 2. I could not make it work, since "sql_drop" event happens **after** the "drop table" has already being attempted and failed due to table oid dependencies 3. you may find it curious that I was in fact trying to improve on the following trigger function: https://github.com/2ndQuadrant/pglogical#automatic-assignment-of-replication-sets-for-new-tables to make it work for "drop table" as well 4. my current workaround is to move trigger logic for "create table"/"drop table" outside of postgre into the app layer, essentially doing via execute() intercept: * replicate_ddl_command("create table; replication_set_add_table();") * replicate_ddl_command("replication_set_remove_table(); drop table;") 5. nonetheless, can you suggest any other way to make "event_trigger" work for this scenario: https://github.com/2ndQuadrant/pglogical#automatic-assignment-of-replication-sets-for-new-tables ? Thanks, Andrei. On 2019-12-23 08:36, Alvaro Herrera wrote: > On 2019-Dec-22, PG Bug reporting form wrote: > >> 1. use case is to delete rows with oid references to the table before >> "drop >> table" > > I think you could achieve that with an event trigger on event sql_drop. > IIRC that event trigger is run for the objects before the drops are > actually executed. > > ddl_command_start is pretty useless, because it doesn't have much info > abot the command being run; I'm sure that > pg_event_trigger_ddl_commands() would always return empty there. > The function would return non-empty only during ddl_command_end, but > that's no useful to you because the drops will already have run.
Re: BUG #16177: pg_event_trigger_ddl_commands() returns empty setfor ddl_command_start and "drop table"
From
Alvaro Herrera
Date:
Hello, On 2019-Dec-23, Andrei Pozolotin wrote: > 1. thank you for the idea, I have just tried that > > 2. I could not make it work, since "sql_drop" event > happens **after** the "drop table" has already being attempted > and failed due to table oid dependencies Well, that's really disappointing, but now that you say it, I remember that yes we had to save all table info prior to firing the trigger because it (the trigger) would run after the drop. I think there was a restriction that forced us to do things that way, but TBH I don't remember clearly. > 3. you may find it curious that I was in fact trying to improve on the > following trigger function: > https://github.com/2ndQuadrant/pglogical#automatic-assignment-of-replication-sets-for-new-tables > to make it work for "drop table" as well That makes sense. > 4. my current workaround is to move trigger logic for "create table"/"drop > table" > outside of postgre into the app layer, essentially doing via execute() > intercept: > * replicate_ddl_command("create table; replication_set_add_table();") > * replicate_ddl_command("replication_set_remove_table(); drop table;") That seems a decent workaround, if suboptimal. > 5. nonetheless, can you suggest any other way to make "event_trigger" work > for this scenario: > https://github.com/2ndQuadrant/pglogical#automatic-assignment-of-replication-sets-for-new-tables > ? I wonder if it's possible for pglogical to register pg_depend entries to the replication set, so that the repset membership is dropped alongside the table. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Re: BUG #16177: pg_event_trigger_ddl_commands() returns empty set forddl_command_start and "drop table"
From
Andrei Pozolotin
Date:
Alvaro: great, I posted your idea with pglogical: https://github.com/2ndQuadrant/pglogical/issues/234 Andrei. On 2019-12-24 10:18, Alvaro Herrera wrote: > I wonder if it's possible for pglogical to register pg_depend entries > to > the replication set, so that the repset membership is dropped alongside > the table.