*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.145 2005/01/27 23:23:55 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.146 2005/02/09 23:17:26 neilc Exp $
*
*-------------------------------------------------------------------------
*/
TupleTableSlot *newslot;
HeapScanDesc scan;
HeapTuple tuple;
+ MemoryContext oldCxt;
+ List *dropped_attrs = NIL;
+ ListCell *lc;
econtext = GetPerTupleExprContext(estate);
memset(values, 0, i * sizeof(Datum));
memset(nulls, 'n', i * sizeof(char));
+ /*
+ * Any attributes that are dropped according to the new tuple
+ * descriptor can be set to NULL. We precompute the list of
+ * dropped attributes to avoid needing to do so in the
+ * per-tuple loop.
+ */
+ for (i = 0; i < newTupDesc->natts; i++)
+ {
+ if (newTupDesc->attrs[i]->attisdropped)
+ dropped_attrs = lappend_int(dropped_attrs, i);
+ }
+
/*
* Scan through the rows, generating a new row if needed and then
* checking all the constraints.
*/
scan = heap_beginscan(oldrel, SnapshotNow, 0, NULL);
+ /*
+ * Switch to per-tuple memory context and reset it for each
+ * tuple produced, so we don't leak memory.
+ */
+ oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
+
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
if (newrel)
{
- /*
- * Extract data from old tuple. We can force to null any
- * columns that are deleted according to the new tuple.
- */
- int natts = newTupDesc->natts;
-
+ /* Extract data from old tuple */
heap_deformtuple(tuple, oldTupDesc, values, nulls);
- for (i = 0; i < natts; i++)
- {
- if (newTupDesc->attrs[i]->attisdropped)
- nulls[i] = 'n';
- }
+ /* Set dropped attributes to null in new tuple */
+ foreach (lc, dropped_attrs)
+ nulls[lfirst_int(lc)] = 'n';
/*
* Process supplied expressions to replace selected
nulls[ex->attnum - 1] = ' ';
}
+ /*
+ * Form the new tuple. Note that we don't explicitly
+ * pfree it, since the per-tuple memory context will
+ * be reset shortly.
+ */
tuple = heap_formtuple(newTupDesc, values, nulls);
}
/* Write the tuple out to the new relation */
if (newrel)
- {
simple_heap_insert(newrel, tuple);
- heap_freetuple(tuple);
- }
-
ResetExprContext(econtext);
CHECK_FOR_INTERRUPTS();
}
+ MemoryContextSwitchTo(oldCxt);
heap_endscan(scan);
}