diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 3b95552..44d3b3e 100644
*** a/src/backend/commands/extension.c
--- b/src/backend/commands/extension.c
*************** pg_extension_config_dump(PG_FUNCTION_ARG
*** 2158,2170 ****
  			}
  		}
  
! 		a = array_set(a, 1, &arrayIndex,
! 					  elementDatum,
! 					  false,
! 					  -1 /* varlena array */ ,
! 					  sizeof(Oid) /* OID's typlen */ ,
! 					  true /* OID's typbyval */ ,
! 					  'i' /* OID's typalign */ );
  	}
  	repl_val[Anum_pg_extension_extconfig - 1] = PointerGetDatum(a);
  	repl_repl[Anum_pg_extension_extconfig - 1] = true;
--- 2158,2170 ----
  			}
  		}
  
! 		a = DatumGetArrayTypeP(array_set(PointerGetDatum(a), 1, &arrayIndex,
! 										 elementDatum,
! 										 false,
! 										 -1 /* varlena array */ ,
! 										 sizeof(Oid) /* OID's typlen */ ,
! 										 true /* OID's typbyval */ ,
! 										 'i' /* OID's typalign */ ));
  	}
  	repl_val[Anum_pg_extension_extconfig - 1] = PointerGetDatum(a);
  	repl_repl[Anum_pg_extension_extconfig - 1] = true;
*************** pg_extension_config_dump(PG_FUNCTION_ARG
*** 2196,2208 ****
  			elog(ERROR, "extconfig and extcondition arrays do not match");
  
  		/* Add or replace at same index as in extconfig */
! 		a = array_set(a, 1, &arrayIndex,
! 					  elementDatum,
! 					  false,
! 					  -1 /* varlena array */ ,
! 					  -1 /* TEXT's typlen */ ,
! 					  false /* TEXT's typbyval */ ,
! 					  'i' /* TEXT's typalign */ );
  	}
  	repl_val[Anum_pg_extension_extcondition - 1] = PointerGetDatum(a);
  	repl_repl[Anum_pg_extension_extcondition - 1] = true;
--- 2196,2208 ----
  			elog(ERROR, "extconfig and extcondition arrays do not match");
  
  		/* Add or replace at same index as in extconfig */
! 		a = DatumGetArrayTypeP(array_set(PointerGetDatum(a), 1, &arrayIndex,
! 										 elementDatum,
! 										 false,
! 										 -1 /* varlena array */ ,
! 										 -1 /* TEXT's typlen */ ,
! 										 false /* TEXT's typbyval */ ,
! 										 'i' /* TEXT's typalign */ ));
  	}
  	repl_val[Anum_pg_extension_extcondition - 1] = PointerGetDatum(a);
  	repl_repl[Anum_pg_extension_extcondition - 1] = true;
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 0e7400f..e66d7b5 100644
*** a/src/backend/executor/execQual.c
--- b/src/backend/executor/execQual.c
*************** static Datum ExecEvalCurrentOfExpr(ExprS
*** 252,263 ****
   *
   * NOTE: if we get a NULL result from a subscript expression, we return NULL
   * when it's an array reference, or raise an error when it's an assignment.
-  *
-  * NOTE: we deliberately refrain from applying DatumGetArrayTypeP() here,
-  * even though that might seem natural, because this code needs to support
-  * both varlena arrays and fixed-length array types.  DatumGetArrayTypeP()
-  * only works for the varlena kind.  The routines we call in arrayfuncs.c
-  * have to know the difference (that's what they need refattrlength for).
   *----------
   */
  static Datum
--- 252,257 ----
*************** ExecEvalArrayRef(ArrayRefExprState *asta
*** 267,274 ****
  				 ExprDoneCond *isDone)
  {
  	ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
! 	ArrayType  *array_source;
! 	ArrayType  *resultArray;
  	bool		isAssignment = (arrayRef->refassgnexpr != NULL);
  	bool		eisnull;
  	ListCell   *l;
--- 261,267 ----
  				 ExprDoneCond *isDone)
  {
  	ArrayRef   *arrayRef = (ArrayRef *) astate->xprstate.expr;
! 	Datum		array_source;
  	bool		isAssignment = (arrayRef->refassgnexpr != NULL);
  	bool		eisnull;
  	ListCell   *l;
*************** ExecEvalArrayRef(ArrayRefExprState *asta
*** 278,288 ****
  				lower;
  	int		   *lIndex;
  
! 	array_source = (ArrayType *)
! 		DatumGetPointer(ExecEvalExpr(astate->refexpr,
! 									 econtext,
! 									 isNull,
! 									 isDone));
  
  	/*
  	 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
--- 271,280 ----
  				lower;
  	int		   *lIndex;
  
! 	array_source = ExecEvalExpr(astate->refexpr,
! 								econtext,
! 								isNull,
! 								isDone);
  
  	/*
  	 * If refexpr yields NULL, and it's a fetch, then result is NULL. In the
*************** ExecEvalArrayRef(ArrayRefExprState *asta
*** 400,412 ****
  			}
  			else
  			{
! 				resultArray = array_get_slice(array_source, i,
! 											  upper.indx, lower.indx,
! 											  astate->refattrlength,
! 											  astate->refelemlength,
! 											  astate->refelembyval,
! 											  astate->refelemalign);
! 				econtext->caseValue_datum = PointerGetDatum(resultArray);
  				econtext->caseValue_isNull = false;
  			}
  		}
--- 392,404 ----
  			}
  			else
  			{
! 				econtext->caseValue_datum =
! 					array_get_slice(array_source, i,
! 									upper.indx, lower.indx,
! 									astate->refattrlength,
! 									astate->refelemlength,
! 									astate->refelembyval,
! 									astate->refelemalign);
  				econtext->caseValue_isNull = false;
  			}
  		}
*************** ExecEvalArrayRef(ArrayRefExprState *asta
*** 435,441 ****
  		 */
  		if (astate->refattrlength > 0)	/* fixed-length array? */
  			if (eisnull || *isNull)
! 				return PointerGetDatum(array_source);
  
  		/*
  		 * For assignment to varlena arrays, we handle a NULL original array
--- 427,433 ----
  		 */
  		if (astate->refattrlength > 0)	/* fixed-length array? */
  			if (eisnull || *isNull)
! 				return array_source;
  
  		/*
  		 * For assignment to varlena arrays, we handle a NULL original array
*************** ExecEvalArrayRef(ArrayRefExprState *asta
*** 445,473 ****
  		 */
  		if (*isNull)
  		{
! 			array_source = construct_empty_array(arrayRef->refelemtype);
  			*isNull = false;
  		}
  
  		if (lIndex == NULL)
! 			resultArray = array_set(array_source, i,
! 									upper.indx,
! 									sourceData,
! 									eisnull,
! 									astate->refattrlength,
! 									astate->refelemlength,
! 									astate->refelembyval,
! 									astate->refelemalign);
  		else
! 			resultArray = array_set_slice(array_source, i,
! 										  upper.indx, lower.indx,
! 								   (ArrayType *) DatumGetPointer(sourceData),
! 										  eisnull,
! 										  astate->refattrlength,
! 										  astate->refelemlength,
! 										  astate->refelembyval,
! 										  astate->refelemalign);
! 		return PointerGetDatum(resultArray);
  	}
  
  	if (lIndex == NULL)
--- 437,464 ----
  		 */
  		if (*isNull)
  		{
! 			array_source = PointerGetDatum(construct_empty_array(arrayRef->refelemtype));
  			*isNull = false;
  		}
  
  		if (lIndex == NULL)
! 			return array_set(array_source, i,
! 							 upper.indx,
! 							 sourceData,
! 							 eisnull,
! 							 astate->refattrlength,
! 							 astate->refelemlength,
! 							 astate->refelembyval,
! 							 astate->refelemalign);
  		else
! 			return array_set_slice(array_source, i,
! 								   upper.indx, lower.indx,
! 								   sourceData,
! 								   eisnull,
! 								   astate->refattrlength,
! 								   astate->refelemlength,
! 								   astate->refelembyval,
! 								   astate->refelemalign);
  	}
  
  	if (lIndex == NULL)
*************** ExecEvalArrayRef(ArrayRefExprState *asta
*** 478,492 ****
  						 astate->refelemalign,
  						 isNull);
  	else
! 	{
! 		resultArray = array_get_slice(array_source, i,
! 									  upper.indx, lower.indx,
! 									  astate->refattrlength,
! 									  astate->refelemlength,
! 									  astate->refelembyval,
! 									  astate->refelemalign);
! 		return PointerGetDatum(resultArray);
! 	}
  }
  
  /*
--- 469,480 ----
  						 astate->refelemalign,
  						 isNull);
  	else
! 		return array_get_slice(array_source, i,
! 							   upper.indx, lower.indx,
! 							   astate->refattrlength,
! 							   astate->refelemlength,
! 							   astate->refelembyval,
! 							   astate->refelemalign);
  }
  
  /*
diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c
index 600646e..72285ef 100644
*** a/src/backend/utils/adt/array_userfuncs.c
--- b/src/backend/utils/adt/array_userfuncs.c
*************** array_push(PG_FUNCTION_ARGS)
*** 146,153 ****
  	typbyval = my_extra->typbyval;
  	typalign = my_extra->typalign;
  
! 	result = array_set(v, 1, &indx, newelem, isNull,
! 					   -1, typlen, typbyval, typalign);
  
  	/*
  	 * Readjust result's LB to match the input's.  This does nothing in the
--- 146,154 ----
  	typbyval = my_extra->typbyval;
  	typalign = my_extra->typalign;
  
! 	result = DatumGetArrayTypeP(array_set(PointerGetDatum(v), 1, &indx,
! 										  newelem, isNull,
! 										  -1, typlen, typbyval, typalign));
  
  	/*
  	 * Readjust result's LB to match the input's.  This does nothing in the
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 5591b46..aa17946 100644
*** a/src/backend/utils/adt/arrayfuncs.c
--- b/src/backend/utils/adt/arrayfuncs.c
*************** array_cardinality(PG_FUNCTION_ARGS)
*** 1796,1809 ****
  
  /*
   * array_ref :
!  *	  This routine takes an array pointer and a subscript array and returns
   *	  the referenced item as a Datum.  Note that for a pass-by-reference
   *	  datatype, the returned Datum is a pointer into the array object.
   *
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	array: the array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied
   *	indx[]: the subscript values
   *	arraytyplen: pg_type.typlen for the array type
--- 1796,1809 ----
  
  /*
   * array_ref :
!  *	  This routine takes an array datum and a subscript array and returns
   *	  the referenced item as a Datum.  Note that for a pass-by-reference
   *	  datatype, the returned Datum is a pointer into the array object.
   *
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	arraydatum: the array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied
   *	indx[]: the subscript values
   *	arraytyplen: pg_type.typlen for the array type
*************** array_cardinality(PG_FUNCTION_ARGS)
*** 1816,1822 ****
   *	*isNull is set to indicate whether the element is NULL.
   */
  Datum
! array_ref(ArrayType *array,
  		  int nSubscripts,
  		  int *indx,
  		  int arraytyplen,
--- 1816,1822 ----
   *	*isNull is set to indicate whether the element is NULL.
   */
  Datum
! array_ref(Datum arraydatum,
  		  int nSubscripts,
  		  int *indx,
  		  int arraytyplen,
*************** array_ref(ArrayType *array,
*** 1825,1830 ****
--- 1825,1831 ----
  		  char elmalign,
  		  bool *isNull)
  {
+ 	ArrayType  *array;
  	int			i,
  				ndim,
  			   *dim,
*************** array_ref(ArrayType *array,
*** 1846,1858 ****
  		fixedLb[0] = 0;
  		dim = fixedDim;
  		lb = fixedLb;
! 		arraydataptr = (char *) array;
  		arraynullsptr = NULL;
  	}
  	else
  	{
  		/* detoast input array if necessary */
! 		array = DatumGetArrayTypeP(PointerGetDatum(array));
  
  		ndim = ARR_NDIM(array);
  		dim = ARR_DIMS(array);
--- 1847,1859 ----
  		fixedLb[0] = 0;
  		dim = fixedDim;
  		lb = fixedLb;
! 		arraydataptr = (char *) DatumGetPointer(arraydatum);
  		arraynullsptr = NULL;
  	}
  	else
  	{
  		/* detoast input array if necessary */
! 		array = DatumGetArrayTypeP(arraydatum);
  
  		ndim = ARR_NDIM(array);
  		dim = ARR_DIMS(array);
*************** array_ref(ArrayType *array,
*** 1910,1916 ****
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	array: the array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied (must be same for upper/lower)
   *	upperIndx[]: the upper subscript values
   *	lowerIndx[]: the lower subscript values
--- 1911,1917 ----
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	arraydatum: the array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied (must be same for upper/lower)
   *	upperIndx[]: the upper subscript values
   *	lowerIndx[]: the lower subscript values
*************** array_ref(ArrayType *array,
*** 1925,1932 ****
   * NOTE: we assume it is OK to scribble on the provided subscript arrays
   * lowerIndx[] and upperIndx[].  These are generally just temporaries.
   */
! ArrayType *
! array_get_slice(ArrayType *array,
  				int nSubscripts,
  				int *upperIndx,
  				int *lowerIndx,
--- 1926,1933 ----
   * NOTE: we assume it is OK to scribble on the provided subscript arrays
   * lowerIndx[] and upperIndx[].  These are generally just temporaries.
   */
! Datum
! array_get_slice(Datum arraydatum,
  				int nSubscripts,
  				int *upperIndx,
  				int *lowerIndx,
*************** array_get_slice(ArrayType *array,
*** 1935,1940 ****
--- 1936,1942 ----
  				bool elmbyval,
  				char elmalign)
  {
+ 	ArrayType  *array;
  	ArrayType  *newarray;
  	int			i,
  				ndim,
*************** array_get_slice(ArrayType *array,
*** 1973,1985 ****
  		dim = fixedDim;
  		lb = fixedLb;
  		elemtype = InvalidOid;	/* XXX */
! 		arraydataptr = (char *) array;
  		arraynullsptr = NULL;
  	}
  	else
  	{
  		/* detoast input array if necessary */
! 		array = DatumGetArrayTypeP(PointerGetDatum(array));
  
  		ndim = ARR_NDIM(array);
  		dim = ARR_DIMS(array);
--- 1975,1987 ----
  		dim = fixedDim;
  		lb = fixedLb;
  		elemtype = InvalidOid;	/* XXX */
! 		arraydataptr = (char *) DatumGetPointer(arraydatum);
  		arraynullsptr = NULL;
  	}
  	else
  	{
  		/* detoast input array if necessary */
! 		array = DatumGetArrayTypeP(arraydatum);
  
  		ndim = ARR_NDIM(array);
  		dim = ARR_DIMS(array);
*************** array_get_slice(ArrayType *array,
*** 1995,2001 ****
  	 * slice, return an empty array.
  	 */
  	if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
! 		return construct_empty_array(elemtype);
  
  	for (i = 0; i < nSubscripts; i++)
  	{
--- 1997,2003 ----
  	 * slice, return an empty array.
  	 */
  	if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
! 		return PointerGetDatum(construct_empty_array(elemtype));
  
  	for (i = 0; i < nSubscripts; i++)
  	{
*************** array_get_slice(ArrayType *array,
*** 2004,2010 ****
  		if (upperIndx[i] >= (dim[i] + lb[i]))
  			upperIndx[i] = dim[i] + lb[i] - 1;
  		if (lowerIndx[i] > upperIndx[i])
! 			return construct_empty_array(elemtype);
  	}
  	/* fill any missing subscript positions with full array range */
  	for (; i < ndim; i++)
--- 2006,2012 ----
  		if (upperIndx[i] >= (dim[i] + lb[i]))
  			upperIndx[i] = dim[i] + lb[i] - 1;
  		if (lowerIndx[i] > upperIndx[i])
! 			return PointerGetDatum(construct_empty_array(elemtype));
  	}
  	/* fill any missing subscript positions with full array range */
  	for (; i < ndim; i++)
*************** array_get_slice(ArrayType *array,
*** 2012,2018 ****
  		lowerIndx[i] = lb[i];
  		upperIndx[i] = dim[i] + lb[i] - 1;
  		if (lowerIndx[i] > upperIndx[i])
! 			return construct_empty_array(elemtype);
  	}
  
  	mda_get_range(ndim, span, lowerIndx, upperIndx);
--- 2014,2020 ----
  		lowerIndx[i] = lb[i];
  		upperIndx[i] = dim[i] + lb[i] - 1;
  		if (lowerIndx[i] > upperIndx[i])
! 			return PointerGetDatum(construct_empty_array(elemtype));
  	}
  
  	mda_get_range(ndim, span, lowerIndx, upperIndx);
*************** array_get_slice(ArrayType *array,
*** 2058,2064 ****
  						lowerIndx, upperIndx,
  						elmlen, elmbyval, elmalign);
  
! 	return newarray;
  }
  
  /*
--- 2060,2066 ----
  						lowerIndx, upperIndx,
  						elmlen, elmbyval, elmalign);
  
! 	return PointerGetDatum(newarray);
  }
  
  /*
*************** array_get_slice(ArrayType *array,
*** 2069,2075 ****
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	array: the initial array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied
   *	indx[]: the subscript values
   *	dataValue: the datum to be inserted at the given position
--- 2071,2077 ----
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	arraydatum: the initial array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied
   *	indx[]: the subscript values
   *	dataValue: the datum to be inserted at the given position
*************** array_get_slice(ArrayType *array,
*** 2091,2098 ****
   * NOTE: For assignments, we throw an error for invalid subscripts etc,
   * rather than returning a NULL as the fetch operations do.
   */
! ArrayType *
! array_set(ArrayType *array,
  		  int nSubscripts,
  		  int *indx,
  		  Datum dataValue,
--- 2093,2100 ----
   * NOTE: For assignments, we throw an error for invalid subscripts etc,
   * rather than returning a NULL as the fetch operations do.
   */
! Datum
! array_set(Datum arraydatum,
  		  int nSubscripts,
  		  int *indx,
  		  Datum dataValue,
*************** array_set(ArrayType *array,
*** 2102,2107 ****
--- 2104,2110 ----
  		  bool elmbyval,
  		  char elmalign)
  {
+ 	ArrayType  *array;
  	ArrayType  *newarray;
  	int			i,
  				ndim,
*************** array_set(ArrayType *array,
*** 2130,2135 ****
--- 2133,2140 ----
  		 * fixed-length arrays -- these are assumed to be 1-d, 0-based. We
  		 * cannot extend them, either.
  		 */
+ 		char	   *resultarray;
+ 
  		if (nSubscripts != 1)
  			ereport(ERROR,
  					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
*************** array_set(ArrayType *array,
*** 2145,2155 ****
  					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
  					 errmsg("cannot assign null value to an element of a fixed-length array")));
  
! 		newarray = (ArrayType *) palloc(arraytyplen);
! 		memcpy(newarray, array, arraytyplen);
! 		elt_ptr = (char *) newarray + indx[0] * elmlen;
  		ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
! 		return newarray;
  	}
  
  	if (nSubscripts <= 0 || nSubscripts > MAXDIM)
--- 2150,2160 ----
  					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
  					 errmsg("cannot assign null value to an element of a fixed-length array")));
  
! 		resultarray = (char *) palloc(arraytyplen);
! 		memcpy(resultarray, DatumGetPointer(arraydatum), arraytyplen);
! 		elt_ptr = (char *) resultarray + indx[0] * elmlen;
  		ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
! 		return PointerGetDatum(resultarray);
  	}
  
  	if (nSubscripts <= 0 || nSubscripts > MAXDIM)
*************** array_set(ArrayType *array,
*** 2162,2168 ****
  		dataValue = PointerGetDatum(PG_DETOAST_DATUM(dataValue));
  
  	/* detoast input array if necessary */
! 	array = DatumGetArrayTypeP(PointerGetDatum(array));
  
  	ndim = ARR_NDIM(array);
  
--- 2167,2173 ----
  		dataValue = PointerGetDatum(PG_DETOAST_DATUM(dataValue));
  
  	/* detoast input array if necessary */
! 	array = DatumGetArrayTypeP(arraydatum);
  
  	ndim = ARR_NDIM(array);
  
*************** array_set(ArrayType *array,
*** 2181,2189 ****
  			lb[i] = indx[i];
  		}
  
! 		return construct_md_array(&dataValue, &isNull, nSubscripts,
! 								  dim, lb, elmtype,
! 								  elmlen, elmbyval, elmalign);
  	}
  
  	if (ndim != nSubscripts)
--- 2186,2195 ----
  			lb[i] = indx[i];
  		}
  
! 		return PointerGetDatum(construct_md_array(&dataValue, &isNull,
! 												  nSubscripts, dim, lb,
! 												  elmtype,
! 												elmlen, elmbyval, elmalign));
  	}
  
  	if (ndim != nSubscripts)
*************** array_set(ArrayType *array,
*** 2345,2351 ****
  		}
  	}
  
! 	return newarray;
  }
  
  /*
--- 2351,2357 ----
  		}
  	}
  
! 	return PointerGetDatum(newarray);
  }
  
  /*
*************** array_set(ArrayType *array,
*** 2357,2368 ****
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	array: the initial array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied (must be same for upper/lower)
   *	upperIndx[]: the upper subscript values
   *	lowerIndx[]: the lower subscript values
!  *	srcArray: the source for the inserted values
!  *	isNull: indicates whether srcArray is NULL
   *	arraytyplen: pg_type.typlen for the array type
   *	elmlen: pg_type.typlen for the array's element type
   *	elmbyval: pg_type.typbyval for the array's element type
--- 2363,2374 ----
   * This handles both ordinary varlena arrays and fixed-length arrays.
   *
   * Inputs:
!  *	arraydatum: the initial array object (mustn't be NULL)
   *	nSubscripts: number of subscripts supplied (must be same for upper/lower)
   *	upperIndx[]: the upper subscript values
   *	lowerIndx[]: the lower subscript values
!  *	srcArrayDatum: the source for the inserted values
!  *	isNull: indicates whether srcArrayDatum is NULL
   *	arraytyplen: pg_type.typlen for the array type
   *	elmlen: pg_type.typlen for the array's element type
   *	elmbyval: pg_type.typbyval for the array's element type
*************** array_set(ArrayType *array,
*** 2383,2400 ****
   * NOTE: For assignments, we throw an error for silly subscripts etc,
   * rather than returning a NULL or empty array as the fetch operations do.
   */
! ArrayType *
! array_set_slice(ArrayType *array,
  				int nSubscripts,
  				int *upperIndx,
  				int *lowerIndx,
! 				ArrayType *srcArray,
  				bool isNull,
  				int arraytyplen,
  				int elmlen,
  				bool elmbyval,
  				char elmalign)
  {
  	ArrayType  *newarray;
  	int			i,
  				ndim,
--- 2389,2408 ----
   * NOTE: For assignments, we throw an error for silly subscripts etc,
   * rather than returning a NULL or empty array as the fetch operations do.
   */
! Datum
! array_set_slice(Datum arraydatum,
  				int nSubscripts,
  				int *upperIndx,
  				int *lowerIndx,
! 				Datum srcArrayDatum,
  				bool isNull,
  				int arraytyplen,
  				int elmlen,
  				bool elmbyval,
  				char elmalign)
  {
+ 	ArrayType  *array;
+ 	ArrayType  *srcArray;
  	ArrayType  *newarray;
  	int			i,
  				ndim,
*************** array_set_slice(ArrayType *array,
*** 2420,2426 ****
  
  	/* Currently, assignment from a NULL source array is a no-op */
  	if (isNull)
! 		return array;
  
  	if (arraytyplen > 0)
  	{
--- 2428,2434 ----
  
  	/* Currently, assignment from a NULL source array is a no-op */
  	if (isNull)
! 		return arraydatum;
  
  	if (arraytyplen > 0)
  	{
*************** array_set_slice(ArrayType *array,
*** 2433,2440 ****
  	}
  
  	/* detoast arrays if necessary */
! 	array = DatumGetArrayTypeP(PointerGetDatum(array));
! 	srcArray = DatumGetArrayTypeP(PointerGetDatum(srcArray));
  
  	/* note: we assume srcArray contains no toasted elements */
  
--- 2441,2448 ----
  	}
  
  	/* detoast arrays if necessary */
! 	array = DatumGetArrayTypeP(arraydatum);
! 	srcArray = DatumGetArrayTypeP(srcArrayDatum);
  
  	/* note: we assume srcArray contains no toasted elements */
  
*************** array_set_slice(ArrayType *array,
*** 2467,2475 ****
  					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
  					 errmsg("source array too small")));
  
! 		return construct_md_array(dvalues, dnulls, nSubscripts,
! 								  dim, lb, elmtype,
! 								  elmlen, elmbyval, elmalign);
  	}
  
  	if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
--- 2475,2483 ----
  					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
  					 errmsg("source array too small")));
  
! 		return PointerGetDatum(construct_md_array(dvalues, dnulls, nSubscripts,
! 												  dim, lb, elmtype,
! 												elmlen, elmbyval, elmalign));
  	}
  
  	if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
*************** array_set_slice(ArrayType *array,
*** 2671,2677 ****
  		}
  	}
  
! 	return newarray;
  }
  
  /*
--- 2679,2685 ----
  		}
  	}
  
! 	return PointerGetDatum(newarray);
  }
  
  /*
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index c1d860c..67cccfd 100644
*** a/src/backend/utils/adt/ruleutils.c
--- b/src/backend/utils/adt/ruleutils.c
*************** pg_get_functiondef(PG_FUNCTION_ARGS)
*** 2006,2012 ****
  		{
  			Datum		d;
  
! 			d = array_ref(a, 1, &i,
  						  -1 /* varlenarray */ ,
  						  -1 /* TEXT's typlen */ ,
  						  false /* TEXT's typbyval */ ,
--- 2006,2012 ----
  		{
  			Datum		d;
  
! 			d = array_ref(PointerGetDatum(a), 1, &i,
  						  -1 /* varlenarray */ ,
  						  -1 /* TEXT's typlen */ ,
  						  false /* TEXT's typbyval */ ,
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9572777..648dac1 100644
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** ProcessGUCArray(ArrayType *array,
*** 8916,8922 ****
  		char	   *name;
  		char	   *value;
  
! 		d = array_ref(array, 1, &i,
  					  -1 /* varlenarray */ ,
  					  -1 /* TEXT's typlen */ ,
  					  false /* TEXT's typbyval */ ,
--- 8916,8922 ----
  		char	   *name;
  		char	   *value;
  
! 		d = array_ref(PointerGetDatum(array), 1, &i,
  					  -1 /* varlenarray */ ,
  					  -1 /* TEXT's typlen */ ,
  					  false /* TEXT's typbyval */ ,
*************** GUCArrayAdd(ArrayType *array, const char
*** 8995,9001 ****
  			Datum		d;
  			char	   *current;
  
! 			d = array_ref(array, 1, &i,
  						  -1 /* varlenarray */ ,
  						  -1 /* TEXT's typlen */ ,
  						  false /* TEXT's typbyval */ ,
--- 8995,9001 ----
  			Datum		d;
  			char	   *current;
  
! 			d = array_ref(PointerGetDatum(array), 1, &i,
  						  -1 /* varlenarray */ ,
  						  -1 /* TEXT's typlen */ ,
  						  false /* TEXT's typbyval */ ,
*************** GUCArrayAdd(ArrayType *array, const char
*** 9013,9025 ****
  			}
  		}
  
! 		a = array_set(array, 1, &index,
! 					  datum,
! 					  false,
! 					  -1 /* varlena array */ ,
! 					  -1 /* TEXT's typlen */ ,
! 					  false /* TEXT's typbyval */ ,
! 					  'i' /* TEXT's typalign */ );
  	}
  	else
  		a = construct_array(&datum, 1,
--- 9013,9025 ----
  			}
  		}
  
! 		a = DatumGetArrayTypeP(array_set(PointerGetDatum(array), 1, &index,
! 										 datum,
! 										 false,
! 										 -1 /* varlena array */ ,
! 										 -1 /* TEXT's typlen */ ,
! 										 false /* TEXT's typbyval */ ,
! 										 'i' /* TEXT's typalign */ ));
  	}
  	else
  		a = construct_array(&datum, 1,
*************** GUCArrayDelete(ArrayType *array, const c
*** 9066,9072 ****
  		char	   *val;
  		bool		isnull;
  
! 		d = array_ref(array, 1, &i,
  					  -1 /* varlenarray */ ,
  					  -1 /* TEXT's typlen */ ,
  					  false /* TEXT's typbyval */ ,
--- 9066,9072 ----
  		char	   *val;
  		bool		isnull;
  
! 		d = array_ref(PointerGetDatum(array), 1, &i,
  					  -1 /* varlenarray */ ,
  					  -1 /* TEXT's typlen */ ,
  					  false /* TEXT's typbyval */ ,
*************** GUCArrayDelete(ArrayType *array, const c
*** 9083,9095 ****
  
  		/* else add it to the output array */
  		if (newarray)
! 			newarray = array_set(newarray, 1, &index,
! 								 d,
! 								 false,
! 								 -1 /* varlenarray */ ,
! 								 -1 /* TEXT's typlen */ ,
! 								 false /* TEXT's typbyval */ ,
! 								 'i' /* TEXT's typalign */ );
  		else
  			newarray = construct_array(&d, 1,
  									   TEXTOID,
--- 9083,9097 ----
  
  		/* else add it to the output array */
  		if (newarray)
! 			newarray =
! 				DatumGetArrayTypeP(array_set(PointerGetDatum(newarray),
! 											 1, &index,
! 											 d,
! 											 false,
! 											 -1 /* varlenarray */ ,
! 											 -1 /* TEXT's typlen */ ,
! 											 false /* TEXT's typbyval */ ,
! 											 'i' /* TEXT's typalign */ ));
  		else
  			newarray = construct_array(&d, 1,
  									   TEXTOID,
*************** GUCArrayReset(ArrayType *array)
*** 9132,9138 ****
  		char	   *eqsgn;
  		bool		isnull;
  
! 		d = array_ref(array, 1, &i,
  					  -1 /* varlenarray */ ,
  					  -1 /* TEXT's typlen */ ,
  					  false /* TEXT's typbyval */ ,
--- 9134,9140 ----
  		char	   *eqsgn;
  		bool		isnull;
  
! 		d = array_ref(PointerGetDatum(array), 1, &i,
  					  -1 /* varlenarray */ ,
  					  -1 /* TEXT's typlen */ ,
  					  false /* TEXT's typbyval */ ,
*************** GUCArrayReset(ArrayType *array)
*** 9151,9163 ****
  
  		/* else add it to the output array */
  		if (newarray)
! 			newarray = array_set(newarray, 1, &index,
! 								 d,
! 								 false,
! 								 -1 /* varlenarray */ ,
! 								 -1 /* TEXT's typlen */ ,
! 								 false /* TEXT's typbyval */ ,
! 								 'i' /* TEXT's typalign */ );
  		else
  			newarray = construct_array(&d, 1,
  									   TEXTOID,
--- 9153,9167 ----
  
  		/* else add it to the output array */
  		if (newarray)
! 			newarray =
! 				DatumGetArrayTypeP(array_set(PointerGetDatum(newarray),
! 											 1, &index,
! 											 d,
! 											 false,
! 											 -1 /* varlenarray */ ,
! 											 -1 /* TEXT's typlen */ ,
! 											 false /* TEXT's typbyval */ ,
! 											 'i' /* TEXT's typalign */ ));
  		else
  			newarray = construct_array(&d, 1,
  									   TEXTOID,
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 694bce7..b2d3fde 100644
*** a/src/include/utils/array.h
--- b/src/include/utils/array.h
*************** extern Datum array_remove(PG_FUNCTION_AR
*** 248,265 ****
  extern Datum array_replace(PG_FUNCTION_ARGS);
  extern Datum width_bucket_array(PG_FUNCTION_ARGS);
  
! extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
  		  int arraytyplen, int elmlen, bool elmbyval, char elmalign,
  		  bool *isNull);
! extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
  		  Datum dataValue, bool isNull,
  		  int arraytyplen, int elmlen, bool elmbyval, char elmalign);
! extern ArrayType *array_get_slice(ArrayType *array, int nSubscripts,
  				int *upperIndx, int *lowerIndx,
  				int arraytyplen, int elmlen, bool elmbyval, char elmalign);
! extern ArrayType *array_set_slice(ArrayType *array, int nSubscripts,
  				int *upperIndx, int *lowerIndx,
! 				ArrayType *srcArray, bool isNull,
  				int arraytyplen, int elmlen, bool elmbyval, char elmalign);
  
  extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType,
--- 248,265 ----
  extern Datum array_replace(PG_FUNCTION_ARGS);
  extern Datum width_bucket_array(PG_FUNCTION_ARGS);
  
! extern Datum array_ref(Datum arraydatum, int nSubscripts, int *indx,
  		  int arraytyplen, int elmlen, bool elmbyval, char elmalign,
  		  bool *isNull);
! extern Datum array_set(Datum arraydatum, int nSubscripts, int *indx,
  		  Datum dataValue, bool isNull,
  		  int arraytyplen, int elmlen, bool elmbyval, char elmalign);
! extern Datum array_get_slice(Datum arraydatum, int nSubscripts,
  				int *upperIndx, int *lowerIndx,
  				int arraytyplen, int elmlen, bool elmbyval, char elmalign);
! extern Datum array_set_slice(Datum arraydatum, int nSubscripts,
  				int *upperIndx, int *lowerIndx,
! 				Datum srcArrayDatum, bool isNull,
  				int arraytyplen, int elmlen, bool elmbyval, char elmalign);
  
  extern Datum array_map(FunctionCallInfo fcinfo, Oid inpType, Oid retType,
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index ae5421f..a754727 100644
*** a/src/pl/plpgsql/src/pl_exec.c
--- b/src/pl/plpgsql/src/pl_exec.c
*************** exec_assign_value(PLpgSQL_execstate *est
*** 4233,4244 ****
  				PLpgSQL_expr *subscripts[MAXDIM];
  				int			subscriptvals[MAXDIM];
  				Datum		oldarraydatum,
  							coerced_value;
  				bool		oldarrayisnull;
  				Oid			parenttypoid;
  				int32		parenttypmod;
- 				ArrayType  *oldarrayval;
- 				ArrayType  *newarrayval;
  				SPITupleTable *save_eval_tuptable;
  				MemoryContext oldcontext;
  
--- 4233,4243 ----
  				PLpgSQL_expr *subscripts[MAXDIM];
  				int			subscriptvals[MAXDIM];
  				Datum		oldarraydatum,
+ 							newarraydatum,
  							coerced_value;
  				bool		oldarrayisnull;
  				Oid			parenttypoid;
  				int32		parenttypmod;
  				SPITupleTable *save_eval_tuptable;
  				MemoryContext oldcontext;
  
*************** exec_assign_value(PLpgSQL_execstate *est
*** 4378,4403 ****
  					(oldarrayisnull || *isNull))
  					return;
  
! 				/* oldarrayval and newarrayval should be short-lived */
  				oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
  
  				if (oldarrayisnull)
! 					oldarrayval = construct_empty_array(arrayelem->elemtypoid);
! 				else
! 					oldarrayval = (ArrayType *) DatumGetPointer(oldarraydatum);
  
  				/*
  				 * Build the modified array value.
  				 */
! 				newarrayval = array_set(oldarrayval,
! 										nsubscripts,
! 										subscriptvals,
! 										coerced_value,
! 										*isNull,
! 										arrayelem->arraytyplen,
! 										arrayelem->elemtyplen,
! 										arrayelem->elemtypbyval,
! 										arrayelem->elemtypalign);
  
  				MemoryContextSwitchTo(oldcontext);
  
--- 4377,4400 ----
  					(oldarrayisnull || *isNull))
  					return;
  
! 				/* empty array, if any, and newarraydatum are short-lived */
  				oldcontext = MemoryContextSwitchTo(estate->eval_econtext->ecxt_per_tuple_memory);
  
  				if (oldarrayisnull)
! 					oldarraydatum = PointerGetDatum(construct_empty_array(arrayelem->elemtypoid));
  
  				/*
  				 * Build the modified array value.
  				 */
! 				newarraydatum = array_set(oldarraydatum,
! 										  nsubscripts,
! 										  subscriptvals,
! 										  coerced_value,
! 										  *isNull,
! 										  arrayelem->arraytyplen,
! 										  arrayelem->elemtyplen,
! 										  arrayelem->elemtypbyval,
! 										  arrayelem->elemtypalign);
  
  				MemoryContextSwitchTo(oldcontext);
  
*************** exec_assign_value(PLpgSQL_execstate *est
*** 4409,4415 ****
  				 */
  				*isNull = false;
  				exec_assign_value(estate, target,
! 								  PointerGetDatum(newarrayval),
  								  arrayelem->arraytypoid, isNull);
  				break;
  			}
--- 4406,4412 ----
  				 */
  				*isNull = false;
  				exec_assign_value(estate, target,
! 								  newarraydatum,
  								  arrayelem->arraytypoid, isNull);
  				break;
  			}
diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c
index 524534e..4c184c5 100644
*** a/src/pl/plpython/plpy_typeio.c
--- b/src/pl/plpython/plpy_typeio.c
*************** PLyList_FromArray(PLyDatumToOb *arg, Dat
*** 628,634 ****
  		int			offset;
  
  		offset = lbound + i;
! 		elem = array_ref(array, 1, &offset, arg->typlen,
  						 elm->typlen, elm->typbyval, elm->typalign,
  						 &isnull);
  		if (isnull)
--- 628,634 ----
  		int			offset;
  
  		offset = lbound + i;
! 		elem = array_ref(PointerGetDatum(array), 1, &offset, arg->typlen,
  						 elm->typlen, elm->typbyval, elm->typalign,
  						 &isnull);
  		if (isnull)
