fixed_length_array_protocol.patch

text/plain

Filename: fixed_length_array_protocol.patch
Type: text/plain
Part: 1
Message: Add minor version to v3 protocol to allow changes without breaking backwards compatibility

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/utils/adt/arrayfuncs.c 14 7
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index bfb6065..d1028be 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -86,7 +86,7 @@ static void ReadArrayBinary(StringInfo buf, int nitems,
 				FmgrInfo *receiveproc, Oid typioparam, int32 typmod,
 				int typlen, bool typbyval, char typalign,
 				Datum *values, bool *nulls,
-				bool *hasnulls, int32 *nbytes);
+				bool *hasnulls, int32 *nbytes, bool fixedlen);
 static void CopyArrayEls(ArrayType *array,
 			 Datum *values, bool *nulls, int nitems,
 			 int typlen, bool typbyval, char typalign,
@@ -1242,7 +1242,7 @@ array_recv(PG_FUNCTION_ARGS)
 						ndim, MAXDIM)));
 
 	flags = pq_getmsgint(buf, 4);
-	if (flags != 0 && flags != 1)
+	if ((flags & ~3) != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
 				 errmsg("invalid array flags")));
@@ -1327,7 +1327,7 @@ array_recv(PG_FUNCTION_ARGS)
 					&my_extra->proc, typioparam, typmod,
 					typlen, typbyval, typalign,
 					dataPtr, nullsPtr,
-					&hasnulls, &nbytes);
+					&hasnulls, &nbytes, (flags & 2) != 0);
 	if (hasnulls)
 	{
 		dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
@@ -1390,7 +1390,8 @@ ReadArrayBinary(StringInfo buf,
 				Datum *values,
 				bool *nulls,
 				bool *hasnulls,
-				int32 *nbytes)
+				int32 *nbytes,
+				bool fixedlen)
 {
 	int			i;
 	bool		hasnull;
@@ -1403,7 +1404,7 @@ ReadArrayBinary(StringInfo buf,
 		char		csave;
 
 		/* Get and check the item length */
-		itemlen = pq_getmsgint(buf, 4);
+		itemlen = fixedlen ? typlen : pq_getmsgint(buf, 4);
 		if (itemlen < -1 || itemlen > (buf->len - buf->cursor))
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
@@ -1496,6 +1497,7 @@ array_send(PG_FUNCTION_ARGS)
 	int			bitmask;
 	int			nitems,
 				i;
+	int			flags;
 	int			ndim,
 			   *dim;
 	StringInfoData buf;
@@ -1535,6 +1537,10 @@ array_send(PG_FUNCTION_ARGS)
 	typbyval = my_extra->typbyval;
 	typalign = my_extra->typalign;
 
+	flags = ARR_HASNULL(v) ? 1 : 0;
+	if (binary_minor >= 1 && flags == 0 && typlen > 0)
+		flags |= 2;
+
 	ndim = ARR_NDIM(v);
 	dim = ARR_DIMS(v);
 	nitems = ArrayGetNItems(ndim, dim);
@@ -1543,7 +1549,7 @@ array_send(PG_FUNCTION_ARGS)
 
 	/* Send the array header information */
 	pq_sendint(&buf, ndim, 4);
-	pq_sendint(&buf, ARR_HASNULL(v) ? 1 : 0, 4);
+	pq_sendint(&buf, flags, 4);
 	pq_sendint(&buf, element_type, sizeof(Oid));
 	for (i = 0; i < ndim; i++)
 	{
@@ -1571,7 +1577,8 @@ array_send(PG_FUNCTION_ARGS)
 
 			itemvalue = fetch_att(p, typbyval, typlen);
 			outputbytes = SendFunctionCall(&my_extra->proc, itemvalue);
-			pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
+			if ((flags & 2) == 0)
+				pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4);
 			pq_sendbytes(&buf, VARDATA(outputbytes),
 						 VARSIZE(outputbytes) - VARHDRSZ);
 			pfree(outputbytes);