|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.85 2001/03/23 04:49:53 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.86 2001/04/19 04:29:02 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -333,21 +333,32 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
|
333 | 333 |
|
334 | 334 | /*
|
335 | 335 | * If the attribute number is invalid, then we are supposed to return
|
336 |
| - * the entire tuple, we give back a whole slot so that callers know |
337 |
| - * what the tuple looks like. XXX why copy? Couldn't we just give |
338 |
| - * back the existing slot? |
| 336 | + * the entire tuple; we give back a whole slot so that callers know |
| 337 | + * what the tuple looks like. |
| 338 | + * |
| 339 | + * XXX this is a horrid crock: since the pointer to the slot might |
| 340 | + * live longer than the current evaluation context, we are forced to |
| 341 | + * copy the tuple and slot into a long-lived context --- we use |
| 342 | + * TransactionCommandContext which should be safe enough. This |
| 343 | + * represents a serious memory leak if many such tuples are processed |
| 344 | + * in one command, however. We ought to redesign the representation |
| 345 | + * of whole-tuple datums so that this is not necessary. |
| 346 | + * |
| 347 | + * We assume it's OK to point to the existing tupleDescriptor, rather |
| 348 | + * than copy that too. |
339 | 349 | */
|
340 | 350 | if (attnum == InvalidAttrNumber)
|
341 | 351 | {
|
342 |
| - TupleTableSlot *tempSlot = MakeTupleTableSlot(); |
343 |
| - TupleDesc td; |
| 352 | + MemoryContext oldContext; |
| 353 | + TupleTableSlot *tempSlot; |
344 | 354 | HeapTuple tup;
|
345 | 355 |
|
| 356 | + oldContext = MemoryContextSwitchTo(TransactionCommandContext); |
| 357 | + tempSlot = MakeTupleTableSlot(); |
346 | 358 | tup = heap_copytuple(heapTuple);
|
347 |
| - td = CreateTupleDescCopy(tuple_type); |
348 |
| - |
349 |
| - ExecSetSlotDescriptor(tempSlot, td, true); |
350 | 359 | ExecStoreTuple(tup, tempSlot, InvalidBuffer, true);
|
| 360 | + ExecSetSlotDescriptor(tempSlot, tuple_type, false); |
| 361 | + MemoryContextSwitchTo(oldContext); |
351 | 362 | return PointerGetDatum(tempSlot);
|
352 | 363 | }
|
353 | 364 |
|
|
0 commit comments