|
10 | 10 | *
|
11 | 11 | *
|
12 | 12 | * IDENTIFICATION
|
13 |
| - * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.195.4.6 2010/01/24 21:50:06 tgl Exp $ |
| 13 | + * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.195.4.7 2010/07/23 00:43:52 rhaas Exp $ |
14 | 14 | *
|
15 | 15 | *-------------------------------------------------------------------------
|
16 | 16 | */
|
@@ -339,8 +339,35 @@ AssignSubTransactionId(TransactionState s)
|
339 | 339 |
|
340 | 340 | Assert(s->parent != NULL);
|
341 | 341 | Assert(s->state == TRANS_INPROGRESS);
|
| 342 | + |
| 343 | + /* |
| 344 | + * Ensure parent(s) have XIDs, so that a child always has an XID later |
| 345 | + * than its parent. Musn't recurse here, or we might get a stack overflow |
| 346 | + * if we're at the bottom of a huge stack of subtransactions none of which |
| 347 | + * have XIDs yet. |
| 348 | + */ |
342 | 349 | if (!TransactionIdIsValid(s->parent->transactionId))
|
343 |
| - AssignSubTransactionId(s->parent); |
| 350 | + { |
| 351 | + TransactionState p = s->parent; |
| 352 | + TransactionState *parents; |
| 353 | + size_t parentOffset = 0; |
| 354 | + |
| 355 | + parents = palloc(sizeof(TransactionState) * s->nestingLevel); |
| 356 | + while (p != NULL && !TransactionIdIsValid(p->transactionId)) |
| 357 | + { |
| 358 | + parents[parentOffset++] = p; |
| 359 | + p = p->parent; |
| 360 | + } |
| 361 | + |
| 362 | + /* |
| 363 | + * This is technically a recursive call, but the recursion will |
| 364 | + * never be more than one layer deep. |
| 365 | + */ |
| 366 | + while (parentOffset != 0) |
| 367 | + AssignSubTransactionId(parents[--parentOffset]); |
| 368 | + |
| 369 | + pfree(parents); |
| 370 | + } |
344 | 371 |
|
345 | 372 | /*
|
346 | 373 | * Generate a new Xid and record it in PG_PROC and pg_subtrans.
|
|
0 commit comments