diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 61d9044816..ba8563af22 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -2463,12 +2463,19 @@ reform_and_rewrite_tuple(HeapTuple tuple, TupleDesc newTupDesc = RelationGetDescr(NewHeap); HeapTuple copiedTuple; int i; + Datum tup_values[MaxTupleAttributeNumber]; + bool values_free[MaxTupleAttributeNumber]; + + memset(tup_values, 0, newTupDesc->natts * sizeof(Datum)); + memset(values_free, 0, newTupDesc->natts * sizeof(bool)); heap_deform_tuple(tuple, oldTupDesc, values, isnull); /* Be sure to null out any dropped columns */ for (i = 0; i < newTupDesc->natts; i++) { + tup_values[i] = values[i]; + if (TupleDescAttr(newTupDesc, i)->attisdropped) isnull[i] = true; @@ -2507,15 +2514,25 @@ reform_and_rewrite_tuple(HeapTuple tuple, /* if compression method doesn't match then detoast the value */ if (TupleDescAttr(newTupDesc, i)->attcompression != cmethod) - values[i] = PointerGetDatum(detoast_attr(new_value)); + { + tup_values[i] = PointerGetDatum(detoast_attr(new_value)); + values_free[i] = true; + } } } - copiedTuple = heap_form_tuple(newTupDesc, values, isnull); + copiedTuple = heap_form_tuple(newTupDesc, tup_values, isnull); /* The heap rewrite module does the rest */ rewrite_heap_tuple(rwstate, tuple, copiedTuple); + /* Free any detoasted value allocated if recompressed */ + for (i = 0; i < newTupDesc->natts; i++) + { + if (values_free[i]) + pfree(DatumGetPointer(tup_values[i])); + } + heap_freetuple(copiedTuple); }