diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
new file mode 100644
index e55b503..179a081
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** COPY postgres_log FROM '/full/path/to/lo
*** 4888,4893 ****
--- 4888,4910 ----
        </listitem>
       </varlistentry>
  
+      <varlistentry id="guc-array-output" xreflabel="array_output">
+       <term><varname>array_output</varname> (<type>enum</type>)</term>
+       <indexterm>
+        <primary><varname>array_output</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+         Sets the output format for binary encoding of values of
+         type <type>array</type>. Valid values are
+         <literal>smallfixed</literal> (the default)
+         and <literal>full</literal> (the traditional PostgreSQL
+         format).  The <type>array</type> type always
+         accepts both formats on input, regardless of this setting.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
       <varlistentry id="guc-xmlbinary" xreflabel="xmlbinary">
        <term><varname>xmlbinary</varname> (<type>enum</type>)</term>
        <indexterm>
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
new file mode 100644
index 5582a06..6192a2e
*** a/src/backend/utils/adt/arrayfuncs.c
--- b/src/backend/utils/adt/arrayfuncs.c
***************
*** 30,41 ****
--- 30,45 ----
   * GUC parameter
   */
  bool		Array_nulls = true;
+ int			array_output = ARRAY_OUTPUT_SMALLFIXED;
  
  /*
   * Local definitions
   */
  #define ASSGN	 "="
  
+ #define FLAG_HASNULLS 1
+ #define FLAG_FIXEDLEN 2
+ 
  typedef enum
  {
  	ARRAY_NO_LEVEL,
*************** static void ReadArrayBinary(StringInfo b
*** 86,92 ****
  				FmgrInfo *receiveproc, Oid typioparam, int32 typmod,
  				int typlen, bool typbyval, char typalign,
  				Datum *values, bool *nulls,
! 				bool *hasnulls, int32 *nbytes);
  static void CopyArrayEls(ArrayType *array,
  			 Datum *values, bool *nulls, int nitems,
  			 int typlen, bool typbyval, char typalign,
--- 90,96 ----
  				FmgrInfo *receiveproc, Oid typioparam, int32 typmod,
  				int typlen, bool typbyval, char typalign,
  				Datum *values, bool *nulls,
! 				bool *hasnulls, int32 *nbytes, bool fixedlen);
  static void CopyArrayEls(ArrayType *array,
  			 Datum *values, bool *nulls, int nitems,
  			 int typlen, bool typbyval, char typalign,
*************** array_recv(PG_FUNCTION_ARGS)
*** 1242,1248 ****
  						ndim, MAXDIM)));
  
  	flags = pq_getmsgint(buf, 4);
! 	if (flags != 0 && flags != 1)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
  				 errmsg("invalid array flags")));
--- 1246,1252 ----
  						ndim, MAXDIM)));
  
  	flags = pq_getmsgint(buf, 4);
! 	if ((flags & ~(FLAG_HASNULLS|FLAG_FIXEDLEN)) != 0)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
  				 errmsg("invalid array flags")));
*************** array_recv(PG_FUNCTION_ARGS)
*** 1327,1333 ****
  					&my_extra->proc, typioparam, typmod,
  					typlen, typbyval, typalign,
  					dataPtr, nullsPtr,
! 					&hasnulls, &nbytes);
  	if (hasnulls)
  	{
  		dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
--- 1331,1337 ----
  					&my_extra->proc, typioparam, typmod,
  					typlen, typbyval, typalign,
  					dataPtr, nullsPtr,
! 					&hasnulls, &nbytes, (flags & FLAG_FIXEDLEN) != 0);
  	if (hasnulls)
  	{
  		dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
*************** ReadArrayBinary(StringInfo buf,
*** 1390,1396 ****
  				Datum *values,
  				bool *nulls,
  				bool *hasnulls,
! 				int32 *nbytes)
  {
  	int			i;
  	bool		hasnull;
--- 1394,1401 ----
  				Datum *values,
  				bool *nulls,
  				bool *hasnulls,
! 				int32 *nbytes,
! 				bool fixedlen)
  {
  	int			i;
  	bool		hasnull;
*************** ReadArrayBinary(StringInfo buf,
*** 1403,1409 ****
  		char		csave;
  
  		/* Get and check the item length */
! 		itemlen = pq_getmsgint(buf, 4);
  		if (itemlen < -1 || itemlen > (buf->len - buf->cursor))
  			ereport(ERROR,
  					(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
--- 1408,1414 ----
  		char		csave;
  
  		/* Get and check the item length */
! 		itemlen = fixedlen ? typlen : pq_getmsgint(buf, 4);
  		if (itemlen < -1 || itemlen > (buf->len - buf->cursor))
  			ereport(ERROR,
  					(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
*************** array_send(PG_FUNCTION_ARGS)
*** 1496,1501 ****
--- 1501,1507 ----
  	int			bitmask;
  	int			nitems,
  				i;
+ 	int			flags;
  	int			ndim,
  			   *dim;
  	StringInfoData buf;
*************** array_send(PG_FUNCTION_ARGS)
*** 1535,1540 ****
--- 1541,1550 ----
  	typbyval = my_extra->typbyval;
  	typalign = my_extra->typalign;
  
+ 	flags = ARR_HASNULL(v) ? FLAG_HASNULLS : 0;
+ 	if (array_output == ARRAY_OUTPUT_SMALLFIXED && flags == 0 && typlen > 0)
+ 		flags |= FLAG_FIXEDLEN;
+ 
  	ndim = ARR_NDIM(v);
  	dim = ARR_DIMS(v);
  	nitems = ArrayGetNItems(ndim, dim);
*************** array_send(PG_FUNCTION_ARGS)
*** 1543,1549 ****
  
  	/* Send the array header information */
  	pq_sendint(&buf, ndim, 4);
! 	pq_sendint(&buf, ARR_HASNULL(v) ? 1 : 0, 4);
  	pq_sendint(&buf, element_type, sizeof(Oid));
  	for (i = 0; i < ndim; i++)
  	{
--- 1553,1559 ----
  
  	/* Send the array header information */
  	pq_sendint(&buf, ndim, 4);
! 	pq_sendint(&buf, flags, 4);
  	pq_sendint(&buf, element_type, sizeof(Oid));
  	for (i = 0; i < ndim; i++)
  	{
*************** array_send(PG_FUNCTION_ARGS)
*** 1571,1577 ****
  
  			itemvalue = fetch_att(p, typbyval, typlen);
  			outputbytes = SendFunctionCall(&my_extra->proc, itemvalue);
! 			pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
  			pq_sendbytes(&buf, VARDATA(outputbytes),
  						 VARSIZE(outputbytes) - VARHDRSZ);
  			pfree(outputbytes);
--- 1581,1588 ----
  
  			itemvalue = fetch_att(p, typbyval, typlen);
  			outputbytes = SendFunctionCall(&my_extra->proc, itemvalue);
! 			if ((flags & FLAG_FIXEDLEN) == 0)
! 				pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
  			pq_sendbytes(&buf, VARDATA(outputbytes),
  						 VARSIZE(outputbytes) - VARHDRSZ);
  			pfree(outputbytes);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index 9fc96b2..636b8d3
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 64,69 ****
--- 64,70 ----
  #include "storage/predicate.h"
  #include "tcop/tcopprot.h"
  #include "tsearch/ts_cache.h"
+ #include "utils/array.h"
  #include "utils/builtins.h"
  #include "utils/bytea.h"
  #include "utils/guc_tables.h"
*************** static const struct config_enum_entry by
*** 225,230 ****
--- 226,243 ----
  };
  
  /*
+  * Options for enum values defined in this module.
+  *
+  * NOTE! Option values may not contain double quotes!
+  */
+ 
+ static const struct config_enum_entry array_output_options[] = {
+ 	{"full", ARRAY_OUTPUT_FULL, false},
+ 	{"smallfixed", ARRAY_OUTPUT_SMALLFIXED, false},
+ 	{NULL, 0, false}
+ };
+ 
+ /*
   * We have different sets for client and server message level options because
   * they sort slightly different (see "log" level)
   */
*************** static struct config_enum ConfigureNames
*** 3047,3052 ****
--- 3060,3075 ----
  		NULL, NULL, NULL
  	},
  
+ 	{
+ 		{"array_output", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
+ 			gettext_noop("Sets the binary output format for arrays."),
+ 			NULL
+ 		},
+ 		&bytea_output,
+ 		ARRAY_OUTPUT_SMALLFIXED, array_output_options,
+ 		NULL, NULL, NULL
+ 	},
+ 
  	{
  		{"client_min_messages", PGC_USERSET, LOGGING_WHEN,
  			gettext_noop("Sets the message levels that are sent to the client."),
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
new file mode 100644
index c6d0ad6..58658f6
*** a/src/include/utils/array.h
--- b/src/include/utils/array.h
***************
*** 58,63 ****
--- 58,71 ----
  
  #include "fmgr.h"
  
+ typedef enum
+ {
+ 	ARRAY_OUTPUT_FULL,
+ 	ARRAY_OUTPUT_SMALLFIXED
+ }	ArrayOutputType;
+ 
+ extern int	array_output;		/* ArrayOutputType, but int for GUC enum */
+ 
  /*
   * Arrays are varlena objects, so must meet the varlena convention that
   * the first int32 of the object contains the total object size in bytes.
