*** a/src/backend/access/minmax/mmtuple.c
--- b/src/backend/access/minmax/mmtuple.c
***************
*** 93,117 **** MMTuple *
  minmax_form_tuple(TupleDesc idxDsc, TupleDesc diskDsc, DeformedMMTuple *tuple,
  				  Size *size)
  {
! 	Datum		values[diskDsc->natts];
! 	bool		nulls[diskDsc->natts];
  	bool		anynulls = false;
  	MMTuple    *rettuple;
  	int			keyno;
  	uint16		phony_infomask;
! 	bits8		phony_nullbitmap[BITMAPLEN(diskDsc->natts)];
  	Size		len,
  				hoff,
  				data_len;
  
  	/*
  	 * Set up the values/nulls arrays for heap_fill_tuple
  	 */
- 	MemSet(nulls, 0, sizeof(nulls));
  	for (keyno = 0; keyno < idxDsc->natts; keyno++)
  	{
! 		AttrNumber	idxattno = keyno * 2;
  
  		if (tuple->values[keyno].allnulls)
  		{
  			nulls[idxattno] = true;
--- 93,126 ----
  minmax_form_tuple(TupleDesc idxDsc, TupleDesc diskDsc, DeformedMMTuple *tuple,
  				  Size *size)
  {
! 	Datum	   *values;
! 	bool	   *nulls;
  	bool		anynulls = false;
  	MMTuple    *rettuple;
  	int			keyno;
  	uint16		phony_infomask;
! 	bits8	   *phony_nullbitmap;
  	Size		len,
  				hoff,
  				data_len;
  
+ 	Assert(diskDsc->natts > 0);
+ 
+ 	values = palloc(sizeof(Datum) * diskDsc->natts);
+ 	nulls = palloc0(sizeof(bool) * diskDsc->natts);
+ 	phony_nullbitmap = palloc(sizeof(bits8) * BITMAPLEN(diskDsc->natts));
+ 
  	/*
  	 * Set up the values/nulls arrays for heap_fill_tuple
  	 */
  	for (keyno = 0; keyno < idxDsc->natts; keyno++)
  	{
! 		int		idxattno = keyno * 2;
  
+ 		/*
+ 		 * "allnulls" is set when there's no nonnull value in any row in
+ 		 * the column; set the nullable bits for both min and max attrs.
+ 		 */
  		if (tuple->values[keyno].allnulls)
  		{
  			nulls[idxattno] = true;
***************
*** 168,173 **** minmax_form_tuple(TupleDesc idxDsc, TupleDesc diskDsc, DeformedMMTuple *tuple,
--- 177,187 ----
  					&phony_infomask,
  					phony_nullbitmap);
  
+ 	/* done with these */
+ 	pfree(values);
+ 	pfree(nulls);
+ 	pfree(phony_nullbitmap);
+ 
  	/*
  	 * Now fill in the real null bitmasks.	allnulls first.
  	 */
***************
*** 243,251 **** DeformedMMTuple *
  minmax_deform_tuple(TupleDesc tupdesc, MMTuple *tuple)
  {
  	DeformedMMTuple *dtup;
! 	Datum		values[tupdesc->natts * 2];
! 	bool		allnulls[tupdesc->natts];
! 	bool		hasnulls[tupdesc->natts];
  	char	   *tp;
  	bits8	   *nullbits = NULL;
  	int			keyno;
--- 257,265 ----
  minmax_deform_tuple(TupleDesc tupdesc, MMTuple *tuple)
  {
  	DeformedMMTuple *dtup;
! 	Datum	   *values;
! 	bool	   *allnulls;
! 	bool	   *hasnulls;
  	char	   *tp;
  	bits8	   *nullbits = NULL;
  	int			keyno;
***************
*** 253,258 **** minmax_deform_tuple(TupleDesc tupdesc, MMTuple *tuple)
--- 267,276 ----
  	dtup = palloc(offsetof(DeformedMMTuple, values) +
  				  sizeof(MMValues) * tupdesc->natts);
  
+ 	values = palloc(sizeof(Datum) * tupdesc->natts * 2);
+ 	allnulls = palloc(sizeof(bool) * tupdesc->natts);
+ 	hasnulls = palloc(sizeof(bool) * tupdesc->natts);
+ 
  	tp = (char *) tuple + MMTupleDataOffset(tuple);
  
  	if (MMTupleHasNulls(tuple))
***************
*** 277,282 **** minmax_deform_tuple(TupleDesc tupdesc, MMTuple *tuple)
--- 295,304 ----
  		dtup->values[keyno].allnulls = false;
  	}
  
+ 	pfree(values);
+ 	pfree(allnulls);
+ 	pfree(hasnulls);
+ 
  	return dtup;
  }
  
***************
*** 293,298 **** minmax_deform_tuple(TupleDesc tupdesc, MMTuple *tuple)
--- 315,322 ----
   *	values		output values, size 2 * natts (alternates min and max)
   *	allnulls	output "allnulls", size natts
   *	hasnulls	output "hasnulls", size natts
+  *
+  * Output arrays are allocated by caller.
   */
  static inline void
  mm_deconstruct_tuple(char *tp, bits8 *nullbits, bool nulls,
