Skip to content

Commit 12d768e

Browse files
committed
Don't use static storage for SaveTransactionCharacteristics().
This is pretty queasy-making on general principles, and the more so once you notice that CommitTransactionCommand() is actually stomping on the values saved by _SPI_commit(). It's okay as long as the active values didn't change during HoldPinnedPortals(); but that's a larger assumption than I think we want to make, especially since the fix is so simple. Discussion: https://postgr.es/m/1533956.1645731245@sss.pgh.pa.us
1 parent 2e51781 commit 12d768e

File tree

3 files changed

+32
-28
lines changed

3 files changed

+32
-28
lines changed

src/backend/access/transam/xact.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,24 +2983,20 @@ StartTransactionCommand(void)
29832983
* GUC system resets the characteristics at transaction end, so for example
29842984
* just skipping the reset in StartTransaction() won't work.)
29852985
*/
2986-
static int save_XactIsoLevel;
2987-
static bool save_XactReadOnly;
2988-
static bool save_XactDeferrable;
2989-
29902986
void
2991-
SaveTransactionCharacteristics(void)
2987+
SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
29922988
{
2993-
save_XactIsoLevel = XactIsoLevel;
2994-
save_XactReadOnly = XactReadOnly;
2995-
save_XactDeferrable = XactDeferrable;
2989+
s->save_XactIsoLevel = XactIsoLevel;
2990+
s->save_XactReadOnly = XactReadOnly;
2991+
s->save_XactDeferrable = XactDeferrable;
29962992
}
29972993

29982994
void
2999-
RestoreTransactionCharacteristics(void)
2995+
RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
30002996
{
3001-
XactIsoLevel = save_XactIsoLevel;
3002-
XactReadOnly = save_XactReadOnly;
3003-
XactDeferrable = save_XactDeferrable;
2997+
XactIsoLevel = s->save_XactIsoLevel;
2998+
XactReadOnly = s->save_XactReadOnly;
2999+
XactDeferrable = s->save_XactDeferrable;
30043000
}
30053001

30063002

@@ -3011,9 +3007,9 @@ void
30113007
CommitTransactionCommand(void)
30123008
{
30133009
TransactionState s = CurrentTransactionState;
3010+
SavedTransactionCharacteristics savetc;
30143011

3015-
if (s->chain)
3016-
SaveTransactionCharacteristics();
3012+
SaveTransactionCharacteristics(&savetc);
30173013

30183014
switch (s->blockState)
30193015
{
@@ -3071,7 +3067,7 @@ CommitTransactionCommand(void)
30713067
StartTransaction();
30723068
s->blockState = TBLOCK_INPROGRESS;
30733069
s->chain = false;
3074-
RestoreTransactionCharacteristics();
3070+
RestoreTransactionCharacteristics(&savetc);
30753071
}
30763072
break;
30773073

@@ -3097,7 +3093,7 @@ CommitTransactionCommand(void)
30973093
StartTransaction();
30983094
s->blockState = TBLOCK_INPROGRESS;
30993095
s->chain = false;
3100-
RestoreTransactionCharacteristics();
3096+
RestoreTransactionCharacteristics(&savetc);
31013097
}
31023098
break;
31033099

@@ -3115,7 +3111,7 @@ CommitTransactionCommand(void)
31153111
StartTransaction();
31163112
s->blockState = TBLOCK_INPROGRESS;
31173113
s->chain = false;
3118-
RestoreTransactionCharacteristics();
3114+
RestoreTransactionCharacteristics(&savetc);
31193115
}
31203116
break;
31213117

@@ -3182,7 +3178,7 @@ CommitTransactionCommand(void)
31823178
StartTransaction();
31833179
s->blockState = TBLOCK_INPROGRESS;
31843180
s->chain = false;
3185-
RestoreTransactionCharacteristics();
3181+
RestoreTransactionCharacteristics(&savetc);
31863182
}
31873183
}
31883184
else if (s->blockState == TBLOCK_PREPARE)

src/backend/executor/spi.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ static void
228228
_SPI_commit(bool chain)
229229
{
230230
MemoryContext oldcontext = CurrentMemoryContext;
231+
SavedTransactionCharacteristics savetc;
231232

232233
/*
233234
* Complain if we are in a context that doesn't permit transaction
@@ -255,9 +256,8 @@ _SPI_commit(bool chain)
255256
(errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION),
256257
errmsg("cannot commit while a subtransaction is active")));
257258

258-
/* XXX this ain't re-entrant enough for my taste */
259259
if (chain)
260-
SaveTransactionCharacteristics();
260+
SaveTransactionCharacteristics(&savetc);
261261

262262
/* Catch any error occurring during the COMMIT */
263263
PG_TRY();
@@ -281,7 +281,7 @@ _SPI_commit(bool chain)
281281
/* Immediately start a new transaction */
282282
StartTransactionCommand();
283283
if (chain)
284-
RestoreTransactionCharacteristics();
284+
RestoreTransactionCharacteristics(&savetc);
285285

286286
MemoryContextSwitchTo(oldcontext);
287287

@@ -305,7 +305,7 @@ _SPI_commit(bool chain)
305305
/* ... and start a new one */
306306
StartTransactionCommand();
307307
if (chain)
308-
RestoreTransactionCharacteristics();
308+
RestoreTransactionCharacteristics(&savetc);
309309

310310
MemoryContextSwitchTo(oldcontext);
311311

@@ -333,6 +333,7 @@ static void
333333
_SPI_rollback(bool chain)
334334
{
335335
MemoryContext oldcontext = CurrentMemoryContext;
336+
SavedTransactionCharacteristics savetc;
336337

337338
/* see under SPI_commit() */
338339
if (_SPI_current->atomic)
@@ -346,9 +347,8 @@ _SPI_rollback(bool chain)
346347
(errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION),
347348
errmsg("cannot roll back while a subtransaction is active")));
348349

349-
/* XXX this ain't re-entrant enough for my taste */
350350
if (chain)
351-
SaveTransactionCharacteristics();
351+
SaveTransactionCharacteristics(&savetc);
352352

353353
/* Catch any error occurring during the ROLLBACK */
354354
PG_TRY();
@@ -373,7 +373,7 @@ _SPI_rollback(bool chain)
373373
/* Immediately start a new transaction */
374374
StartTransactionCommand();
375375
if (chain)
376-
RestoreTransactionCharacteristics();
376+
RestoreTransactionCharacteristics(&savetc);
377377

378378
MemoryContextSwitchTo(oldcontext);
379379

@@ -398,7 +398,7 @@ _SPI_rollback(bool chain)
398398
/* ... and start a new one */
399399
StartTransactionCommand();
400400
if (chain)
401-
RestoreTransactionCharacteristics();
401+
RestoreTransactionCharacteristics(&savetc);
402402

403403
MemoryContextSwitchTo(oldcontext);
404404

src/include/access/xact.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ typedef enum
135135
typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid,
136136
SubTransactionId parentSubid, void *arg);
137137

138+
/* Data structure for Save/RestoreTransactionCharacteristics */
139+
typedef struct SavedTransactionCharacteristics
140+
{
141+
int save_XactIsoLevel;
142+
bool save_XactReadOnly;
143+
bool save_XactDeferrable;
144+
} SavedTransactionCharacteristics;
145+
138146

139147
/* ----------------
140148
* transaction-related XLOG entries
@@ -399,8 +407,8 @@ extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
399407
extern void CommandCounterIncrement(void);
400408
extern void ForceSyncCommit(void);
401409
extern void StartTransactionCommand(void);
402-
extern void SaveTransactionCharacteristics(void);
403-
extern void RestoreTransactionCharacteristics(void);
410+
extern void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s);
411+
extern void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s);
404412
extern void CommitTransactionCommand(void);
405413
extern void AbortCurrentTransaction(void);
406414
extern void BeginTransactionBlock(void);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy