delta-relations-plpython.patch
application/octet-stream
Filename: delta-relations-plpython.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/pl/plpython/expected/plpython_trigger.out | 19 | 0 |
| src/pl/plpython/plpy_exec.c | 35 | 0 |
| src/pl/plpython/sql/plpython_trigger.sql | 21 | 0 |
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';