1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

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
This commit is contained in:
Tom Lane
2018-10-08 16:16:36 -04:00
parent 8569ef63f4
commit 1145c26b74
5 changed files with 91 additions and 8 deletions

View File

@ -1906,20 +1906,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

View File

@ -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