mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +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:
@ -1257,6 +1257,9 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
|
||||
errdetail("Scrollable cursors must be READ ONLY.")));
|
||||
}
|
||||
|
||||
/* Make current query environment available to portal at execution time. */
|
||||
portal->queryEnv = _SPI_current->queryEnv;
|
||||
|
||||
/*
|
||||
* If told to be read-only, or in parallel mode, verify that this query is
|
||||
* in fact read-only. This can't be done earlier because we need to look
|
||||
@ -2716,3 +2719,52 @@ SPI_unregister_relation(const char *name)
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the transient relations from 'tdata' using this SPI connection.
|
||||
* This should be called by PL implementations' trigger handlers after
|
||||
* connecting, in order to make transition tables visible to any queries run
|
||||
* in this connection.
|
||||
*/
|
||||
int
|
||||
SPI_register_trigger_data(TriggerData *tdata)
|
||||
{
|
||||
if (tdata == NULL)
|
||||
return SPI_ERROR_ARGUMENT;
|
||||
|
||||
if (tdata->tg_newtable)
|
||||
{
|
||||
EphemeralNamedRelation enr =
|
||||
palloc(sizeof(EphemeralNamedRelationData));
|
||||
int rc;
|
||||
|
||||
enr->md.name = tdata->tg_trigger->tgnewtable;
|
||||
enr->md.reliddesc = tdata->tg_relation->rd_id;
|
||||
enr->md.tupdesc = NULL;
|
||||
enr->md.enrtype = ENR_NAMED_TUPLESTORE;
|
||||
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)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (tdata->tg_oldtable)
|
||||
{
|
||||
EphemeralNamedRelation enr =
|
||||
palloc(sizeof(EphemeralNamedRelationData));
|
||||
int rc;
|
||||
|
||||
enr->md.name = tdata->tg_trigger->tgoldtable;
|
||||
enr->md.reliddesc = tdata->tg_relation->rd_id;
|
||||
enr->md.tupdesc = NULL;
|
||||
enr->md.enrtype = ENR_NAMED_TUPLESTORE;
|
||||
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)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SPI_OK_TD_REGISTER;
|
||||
}
|
||||
|
Reference in New Issue
Block a user