mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Follow-on cleanup for the transition table patch.
Commit 59702716
added transition table support to PL/pgsql so that
SQL queries in trigger functions could access those transient
tables. In order to provide the same level of support for PL/perl,
PL/python and PL/tcl, refactor the relevant code into a new
function SPI_register_trigger_data. Call the new function in the
trigger handler of all four PLs, and document it as a public SPI
function so that authors of out-of-tree PLs can do the same.
Also get rid of a second QueryEnvironment object that was
maintained by PL/pgsql. That was previously used to deal with
cursors, but the same approach wasn't appropriate for PLs that are
less tangled up with core code. Instead, have SPI_cursor_open
install the connection's current QueryEnvironment, as already
happens for SPI_execute_plan.
While in the docs, remove the note that transition tables were only
supported in C and PL/pgSQL triggers, and correct some ommissions.
Thomas Munro with some work by Kevin Grittner (mostly docs)
This commit is contained in:
@ -503,3 +503,24 @@ 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
|
||||
DROP TABLE transition_table_test;
|
||||
DROP FUNCTION transition_table_test_f();
|
||||
|
@ -345,6 +345,11 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
int rc PG_USED_FOR_ASSERTS_ONLY;
|
||||
|
||||
rc = SPI_register_trigger_data(tdata);
|
||||
Assert(rc >= 0);
|
||||
|
||||
plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
|
||||
plrv = PLy_procedure_call(proc, "TD", plargs);
|
||||
|
||||
|
@ -406,3 +406,27 @@ 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';
|
||||
|
||||
DROP TABLE transition_table_test;
|
||||
DROP FUNCTION transition_table_test_f();
|
||||
|
Reference in New Issue
Block a user