diff --git a/src/pl/plpython/expected/plpython_trigger.out b/src/pl/plpython/expected/plpython_trigger.out index 4148963..0e02200 100644 --- a/src/pl/plpython/expected/plpython_trigger.out +++ b/src/pl/plpython/expected/plpython_trigger.out @@ -503,3 +503,22 @@ SELECT * FROM b; 1234 (1 row) +-- check that SQL run in trigger code can see transition tables +CREATE TABLE transition_table_test (id int, name text); +INSERT INTO transition_table_test VALUES (1, 'a'); +CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plpythonu AS +$$ + rv = plpy.execute("SELECT * FROM old_table") + assert(rv.nrows() == 1) + plpy.info("old: " + str(rv[0]["id"]) + " -> " + rv[0]["name"]) + rv = plpy.execute("SELECT * FROM new_table") + assert(rv.nrows() == 1) + plpy.info("new: " + str(rv[0]["id"]) + " -> " + rv[0]["name"]) + return None +$$; +CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f(); +UPDATE transition_table_test SET name = 'b'; +INFO: old: 1 -> a +INFO: new: 1 -> b diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c index 697a0e1..83c1979 100644 --- a/src/pl/plpython/plpy_exec.c +++ b/src/pl/plpython/plpy_exec.c @@ -345,6 +345,41 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc) PG_TRY(); { + int rc; + + if (tdata->tg_newtable) + { + Enr enr = palloc(sizeof(EnrData)); + + enr->md.name = tdata->tg_trigger->tgnewtable; + enr->md.tupdesc = tdata->tg_relation->rd_att; + enr->md.enrtuples = tuplestore_tuple_count(tdata->tg_newtable); + enr->reldata = tdata->tg_newtable; + rc = SPI_register_relation(enr); + + if (rc != SPI_OK_REL_REGISTER) + elog(ERROR, + "could not register relation \"%s\": %s", + tdata->tg_trigger->tgnewtable, + SPI_result_code_string(rc)); + } + if (tdata->tg_oldtable) + { + Enr enr = palloc(sizeof(EnrData)); + + enr->md.name = tdata->tg_trigger->tgoldtable; + enr->md.tupdesc = tdata->tg_relation->rd_att; + enr->md.enrtuples = tuplestore_tuple_count(tdata->tg_oldtable); + enr->reldata = tdata->tg_oldtable; + rc = SPI_register_relation(enr); + + if (rc != SPI_OK_REL_REGISTER) + elog(ERROR, + "could not register relation \"%s\": %s", + tdata->tg_trigger->tgoldtable, + SPI_result_code_string(rc)); + } + plargs = PLy_trigger_build_args(fcinfo, proc, &rv); plrv = PLy_procedure_call(proc, "TD", plargs); diff --git a/src/pl/plpython/sql/plpython_trigger.sql b/src/pl/plpython/sql/plpython_trigger.sql index a054fe7..0847faf 100644 --- a/src/pl/plpython/sql/plpython_trigger.sql +++ b/src/pl/plpython/sql/plpython_trigger.sql @@ -406,3 +406,24 @@ SELECT * FROM a; DROP TABLE a; INSERT INTO b DEFAULT VALUES; SELECT * FROM b; + +-- check that SQL run in trigger code can see transition tables + +CREATE TABLE transition_table_test (id int, name text); +INSERT INTO transition_table_test VALUES (1, 'a'); + +CREATE FUNCTION transition_table_test_f() RETURNS trigger LANGUAGE plpythonu AS +$$ + rv = plpy.execute("SELECT * FROM old_table") + assert(rv.nrows() == 1) + plpy.info("old: " + str(rv[0]["id"]) + " -> " + rv[0]["name"]) + rv = plpy.execute("SELECT * FROM new_table") + assert(rv.nrows() == 1) + plpy.info("new: " + str(rv[0]["id"]) + " -> " + rv[0]["name"]) + return None +$$; + +CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f(); +UPDATE transition_table_test SET name = 'b';