aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorKevin Grittner <kgrittn@postgresql.org>2017-04-04 18:36:39 -0500
committerKevin Grittner <kgrittn@postgresql.org>2017-04-04 18:36:39 -0500
commit5ebeb579b9b281dba5f8415b2fbda86fdae7b366 (patch)
tree66aac432d4acc7300f2b395e4c8282f75d53ef0a /src/backend
parent9a3215026bd6955e88bd8c20542cfe6acffdb1c8 (diff)
downloadpostgresql-5ebeb579b9b281dba5f8415b2fbda86fdae7b366.tar.gz
postgresql-5ebeb579b9b281dba5f8415b2fbda86fdae7b366.zip
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)
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/executor/spi.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 2f07a444b4d..3a89ccd913f 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -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;
+}