diff options
| author | Tom Lane | 2018-10-08 20:16:36 +0000 |
|---|---|---|
| committer | Tom Lane | 2018-10-08 20:16:36 +0000 |
| commit | 82ff0cc91d9840d1c56ca1beed58bedfde3da9a3 (patch) | |
| tree | 005702660dc609455ece3fb423e9f74c15d43edb /src/backend | |
| parent | 6eb3eb577d76b3f58a98f78232af9e86624ce5eb (diff) | |
Advance transaction timestamp for intra-procedure transactions.
Per discussion, this behavior seems less astonishing than not doing so.
Peter Eisentraut and Tom Lane
Discussion: https://postgr.es/m/20180920234040.GC29981@momjian.us
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/access/transam/xact.c | 22 | ||||
| -rw-r--r-- | src/backend/executor/spi.c | 13 |
2 files changed, 27 insertions, 8 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index e3f668bf6ab..59e021f887a 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -1887,20 +1887,26 @@ StartTransaction(void) TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); /* - * set transaction_timestamp() (a/k/a now()). We want this to be the same - * as the first command's statement_timestamp(), so don't do a fresh - * GetCurrentTimestamp() call (which'd be expensive anyway). In a - * parallel worker, this should already have been provided by a call to + * set transaction_timestamp() (a/k/a now()). Normally, we want this to + * be the same as the first command's statement_timestamp(), so don't do a + * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But + * for transactions started inside procedures (i.e., nonatomic SPI + * contexts), we do need to advance the timestamp. Also, in a parallel + * worker, the timestamp should already have been provided by a call to * SetParallelStartTimestamps(). - * - * Also, mark xactStopTimestamp as unset. */ if (!IsParallelWorker()) - xactStartTimestamp = stmtStartTimestamp; + { + if (!SPI_inside_nonatomic_context()) + xactStartTimestamp = stmtStartTimestamp; + else + xactStartTimestamp = GetCurrentTimestamp(); + } else Assert(xactStartTimestamp != 0); - xactStopTimestamp = 0; pgstat_report_xact_timestamp(xactStartTimestamp); + /* Mark xactStopTimestamp as unset. */ + xactStopTimestamp = 0; /* * initialize current transaction state fields diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 11ca800e4cd..fb36e762f28 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -423,6 +423,19 @@ AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid) } } +/* + * Are we executing inside a procedure (that is, a nonatomic SPI context)? + */ +bool +SPI_inside_nonatomic_context(void) +{ + if (_SPI_current == NULL) + return false; /* not in any SPI context at all */ + if (_SPI_current->atomic) + return false; /* it's atomic (ie function not procedure) */ + return true; +} + /* Parse, plan, and execute a query string */ int |
