[for PG16]

There are many calls to construct_array() and deconstruct_array() for built-in types, for example, when dealing with system catalog columns. These all hardcode the type attributes necessary to pass to these functions.

To simplify this a bit, add construct_array_builtin(), deconstruct_array_builtin() as wrappers that centralize this hardcoded knowledge. This simplifies many call sites and reduces the amount of hardcoded stuff that is spread around.

I also considered having genbki.pl generate lookup tables for these hardcoded values, similar to schemapg.h, but that ultimately seemed excessive.

Thoughts?
From 35fe30fec1692a4e329e9c9b1ed40863e3b970b2 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Mon, 2 May 2022 10:23:26 +0200
Subject: [PATCH] Add construct_array_builtin, deconstruct_array_builtin

There were many calls to construct_array() and deconstruct_array() for
built-in types, for example, when dealing with system catalog columns.
These all hardcoded the type attributes necessary to pass to these
functions.

To simplify this a bit, add construct_array_builtin(),
deconstruct_array_builtin() as wrappers that centralize this hardcoded
knowledge.  This simplifies many call sites and reduces the amount of
hardcoded stuff that is spread around.
---
 contrib/hstore/hstore_gin.c                   |   4 +-
 contrib/hstore/hstore_gist.c                  |   8 +-
 contrib/hstore/hstore_io.c                    |  12 +-
 contrib/hstore/hstore_op.c                    |  11 +-
 contrib/pageinspect/btreefuncs.c              |   6 +-
 contrib/pageinspect/ginfuncs.c                |  10 +-
 contrib/pageinspect/gistfuncs.c               |   4 +-
 contrib/pageinspect/hashfuncs.c               |  14 +-
 contrib/pageinspect/heapfuncs.c               |   4 +-
 contrib/pg_trgm/trgm_op.c                     |   7 +-
 contrib/pgcrypto/pgp-pgsql.c                  |   9 +-
 src/backend/access/common/reloptions.c        |   9 +-
 src/backend/catalog/objectaddress.c           |  12 +-
 src/backend/catalog/pg_constraint.c           |  21 +--
 src/backend/catalog/pg_proc.c                 |   5 +-
 src/backend/catalog/pg_subscription.c         |   4 +-
 src/backend/commands/analyze.c                |   5 +-
 src/backend/commands/event_trigger.c          |   3 +-
 src/backend/commands/extension.c              |  24 +--
 src/backend/commands/functioncmds.c           |  12 +-
 src/backend/commands/policy.c                 |   9 +-
 src/backend/commands/prepare.c                |   4 +-
 src/backend/commands/statscmds.c              |   2 +-
 src/backend/commands/subscriptioncmds.c       |   3 +-
 src/backend/commands/typecmds.c               |   7 +-
 src/backend/executor/nodeTidscan.c            |   4 +-
 src/backend/parser/parse_type.c               |   4 +-
 src/backend/parser/parse_utilcmd.c            |   4 +-
 .../replication/logical/logicalfuncs.c        |   3 +-
 src/backend/statistics/extended_stats.c       |   5 +-
 src/backend/tsearch/dict.c                    |   7 +-
 src/backend/utils/adt/arrayfuncs.c            | 153 +++++++++++++++++-
 src/backend/utils/adt/arrayutils.c            |   5 +-
 src/backend/utils/adt/hbafuncs.c              |   2 +-
 src/backend/utils/adt/json.c                  |  13 +-
 src/backend/utils/adt/jsonb.c                 |  13 +-
 src/backend/utils/adt/jsonb_gin.c             |   4 +-
 src/backend/utils/adt/jsonb_op.c              |   6 +-
 src/backend/utils/adt/jsonfuncs.c             |  18 +--
 src/backend/utils/adt/lockfuncs.c             |  10 +-
 src/backend/utils/adt/name.c                  |   6 +-
 src/backend/utils/adt/orderedsetaggs.c        |  20 +--
 src/backend/utils/adt/pg_upgrade_support.c    |   4 +-
 src/backend/utils/adt/ruleutils.c             |  20 +--
 src/backend/utils/adt/tsvector_op.c           |  19 +--
 src/backend/utils/adt/xml.c                   |   6 +-
 src/backend/utils/cache/evtcache.c            |   3 +-
 src/backend/utils/fmgr/funcapi.c              |  14 +-
 src/backend/utils/misc/guc.c                  |  14 +-
 src/include/utils/array.h                     |   4 +
 .../modules/test_rls_hooks/test_rls_hooks.c   |   4 +-
 51 files changed, 276 insertions(+), 298 deletions(-)

diff --git a/contrib/hstore/hstore_gin.c b/contrib/hstore/hstore_gin.c
index 908530261a..766c00bb6a 100644
--- a/contrib/hstore/hstore_gin.c
+++ b/contrib/hstore/hstore_gin.c
@@ -118,9 +118,7 @@ gin_extract_hstore_query(PG_FUNCTION_ARGS)
                                        j;
                text       *item;
 
-               deconstruct_array(query,
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &key_datums, &key_nulls, 
&key_count);
+               deconstruct_array_builtin(query, TEXTOID, &key_datums, 
&key_nulls, &key_count);
 
                entries = (Datum *) palloc(sizeof(Datum) * key_count);
 
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index 102c9cea72..0a95628837 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -560,9 +560,7 @@ ghstore_consistent(PG_FUNCTION_ARGS)
                int                     key_count;
                int                     i;
 
-               deconstruct_array(query,
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &key_datums, &key_nulls, 
&key_count);
+               deconstruct_array_builtin(query, TEXTOID, &key_datums, 
&key_nulls, &key_count);
 
                for (i = 0; res && i < key_count; ++i)
                {
@@ -583,9 +581,7 @@ ghstore_consistent(PG_FUNCTION_ARGS)
                int                     key_count;
                int                     i;
 
-               deconstruct_array(query,
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &key_datums, &key_nulls, 
&key_count);
+               deconstruct_array_builtin(query, TEXTOID, &key_datums, 
&key_nulls, &key_count);
 
                res = false;
 
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index b3304ff844..fb72bb6cfe 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -567,9 +567,7 @@ hstore_from_arrays(PG_FUNCTION_ARGS)
                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
                                 errmsg("wrong number of array subscripts")));
 
-       deconstruct_array(key_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &key_count);
+       deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, 
&key_count);
 
        /* see discussion in hstoreArrayToPairs() */
        if (key_count > MaxAllocSize / sizeof(Pairs))
@@ -606,9 +604,7 @@ hstore_from_arrays(PG_FUNCTION_ARGS)
                                        (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
                                         errmsg("arrays must have same 
bounds")));
 
-               deconstruct_array(value_array,
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &value_datums, &value_nulls, 
&value_count);
+               deconstruct_array_builtin(value_array, TEXTOID, &value_datums, 
&value_nulls, &value_count);
 
                Assert(key_count == value_count);
        }
@@ -696,9 +692,7 @@ hstore_from_array(PG_FUNCTION_ARGS)
                                         errmsg("wrong number of array 
subscripts")));
        }
 
-       deconstruct_array(in_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &in_datums, &in_nulls, &in_count);
+       deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, 
&in_count);
 
        count = in_count / 2;
 
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index dd79d01cac..2f540d7ed6 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -80,9 +80,7 @@ hstoreArrayToPairs(ArrayType *a, int *npairs)
        int                     i,
                                j;
 
-       deconstruct_array(a,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &key_count);
+       deconstruct_array_builtin(a, TEXTOID, &key_datums, &key_nulls, 
&key_count);
 
        if (key_count == 0)
        {
@@ -582,9 +580,7 @@ hstore_slice_to_array(PG_FUNCTION_ARGS)
        int                     key_count;
        int                     i;
 
-       deconstruct_array(key_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &key_count);
+       deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, 
&key_count);
 
        if (key_count == 0)
        {
@@ -719,8 +715,7 @@ hstore_akeys(PG_FUNCTION_ARGS)
                d[i] = PointerGetDatum(t);
        }
 
-       a = construct_array(d, count,
-                                               TEXTOID, -1, false, 
TYPALIGN_INT);
+       a = construct_array_builtin(d, count, TEXTOID);
 
        PG_RETURN_POINTER(a);
 }
diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index 62f2c1b315..9375d55e14 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -425,11 +425,7 @@ bt_page_print_tuples(struct user_args *uargs)
                tids_datum = (Datum *) palloc(nposting * sizeof(Datum));
                for (int i = 0; i < nposting; i++)
                        tids_datum[i] = ItemPointerGetDatum(&tids[i]);
-               values[j++] = PointerGetDatum(construct_array(tids_datum,
-                                                                               
                          nposting,
-                                                                               
                          TIDOID,
-                                                                               
                          sizeof(ItemPointerData),
-                                                                               
                          false, TYPALIGN_SHORT));
+               values[j++] = 
PointerGetDatum(construct_array_builtin(tids_datum, nposting, TIDOID));
                pfree(tids_datum);
        }
        else
diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c
index 31aca7b000..952e9d51a8 100644
--- a/contrib/pageinspect/ginfuncs.c
+++ b/contrib/pageinspect/ginfuncs.c
@@ -166,9 +166,7 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
 
        values[0] = Int64GetDatum(opaq->rightlink);
        values[1] = Int32GetDatum(opaq->maxoff);
-       values[2] = PointerGetDatum(construct_array(flags, nflags,
-                                                                               
                TEXTOID,
-                                                                               
                -1, false, TYPALIGN_INT));
+       values[2] = PointerGetDatum(construct_array_builtin(flags, nflags, 
TEXTOID));
 
        /* Build and return the result tuple. */
        resultTuple = heap_form_tuple(tupdesc, values, nulls);
@@ -273,11 +271,7 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
                tids_datum = (Datum *) palloc(ndecoded * sizeof(Datum));
                for (i = 0; i < ndecoded; i++)
                        tids_datum[i] = ItemPointerGetDatum(&tids[i]);
-               values[2] = PointerGetDatum(construct_array(tids_datum,
-                                                                               
                        ndecoded,
-                                                                               
                        TIDOID,
-                                                                               
                        sizeof(ItemPointerData),
-                                                                               
                        false, TYPALIGN_SHORT));
+               values[2] = PointerGetDatum(construct_array_builtin(tids_datum, 
ndecoded, TIDOID));
                pfree(tids_datum);
                pfree(tids);
 
diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c
index 9c29fbc7aa..fb48d6feca 100644
--- a/contrib/pageinspect/gistfuncs.c
+++ b/contrib/pageinspect/gistfuncs.c
@@ -104,9 +104,7 @@ gist_page_opaque_info(PG_FUNCTION_ARGS)
        values[0] = LSNGetDatum(PageGetLSN(page));
        values[1] = LSNGetDatum(GistPageGetNSN(page));
        values[2] = Int64GetDatum(opaq->rightlink);
-       values[3] = PointerGetDatum(construct_array(flags, nflags,
-                                                                               
                TEXTOID,
-                                                                               
                -1, false, TYPALIGN_INT));
+       values[3] = PointerGetDatum(construct_array_builtin(flags, nflags, 
TEXTOID));
 
        /* Build and return the result tuple. */
        resultTuple = heap_form_tuple(tupdesc, values, nulls);
diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index 69af7b962f..6e592e3770 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -564,21 +564,11 @@ hash_metapage_info(PG_FUNCTION_ARGS)
 
        for (i = 0; i < HASH_MAX_SPLITPOINTS; i++)
                spares[i] = Int64GetDatum((int64) metad->hashm_spares[i]);
-       values[j++] = PointerGetDatum(construct_array(spares,
-                                                                               
                  HASH_MAX_SPLITPOINTS,
-                                                                               
                  INT8OID,
-                                                                               
                  sizeof(int64),
-                                                                               
                  FLOAT8PASSBYVAL,
-                                                                               
                  TYPALIGN_DOUBLE));
+       values[j++] = PointerGetDatum(construct_array_builtin(spares, 
lengthof(spares), INT8OID));
 
        for (i = 0; i < HASH_MAX_BITMAPS; i++)
                mapp[i] = Int64GetDatum((int64) metad->hashm_mapp[i]);
-       values[j++] = PointerGetDatum(construct_array(mapp,
-                                                                               
                  HASH_MAX_BITMAPS,
-                                                                               
                  INT8OID,
-                                                                               
                  sizeof(int64),
-                                                                               
                  FLOAT8PASSBYVAL,
-                                                                               
                  TYPALIGN_DOUBLE));
+       values[j++] = PointerGetDatum(construct_array_builtin(mapp, 
lengthof(mapp), INT8OID));
 
        tuple = heap_form_tuple(tupleDesc, values, nulls);
 
diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c
index 3dd1a9bc2a..a654234c6b 100644
--- a/contrib/pageinspect/heapfuncs.c
+++ b/contrib/pageinspect/heapfuncs.c
@@ -590,7 +590,7 @@ heap_tuple_infomask_flags(PG_FUNCTION_ARGS)
 
        /* build value */
        Assert(cnt <= bitcnt);
-       a = construct_array(flags, cnt, TEXTOID, -1, false, TYPALIGN_INT);
+       a = construct_array_builtin(flags, cnt, TEXTOID);
        values[0] = PointerGetDatum(a);
 
        /*
@@ -612,7 +612,7 @@ heap_tuple_infomask_flags(PG_FUNCTION_ARGS)
        if (cnt == 0)
                a = construct_empty_array(TEXTOID);
        else
-               a = construct_array(flags, cnt, TEXTOID, -1, false, 
TYPALIGN_INT);
+               a = construct_array_builtin(flags, cnt, TEXTOID);
        pfree(flags);
        values[1] = PointerGetDatum(a);
 
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index e9b7981619..cbcc481a17 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -977,12 +977,7 @@ show_trgm(PG_FUNCTION_ARGS)
                d[i] = PointerGetDatum(item);
        }
 
-       a = construct_array(d,
-                                               ARRNELEM(trg),
-                                               TEXTOID,
-                                               -1,
-                                               false,
-                                               TYPALIGN_INT);
+       a = construct_array_builtin(d, ARRNELEM(trg), TEXTOID);
 
        for (i = 0; i < ARRNELEM(trg); i++)
                pfree(DatumGetPointer(d[i]));
diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c
index 0536bfb892..d9b15b07b0 100644
--- a/contrib/pgcrypto/pgp-pgsql.c
+++ b/contrib/pgcrypto/pgp-pgsql.c
@@ -774,13 +774,8 @@ parse_key_value_arrays(ArrayType *key_array, ArrayType 
*val_array,
        if (nkdims == 0)
                return 0;
 
-       deconstruct_array(key_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &key_count);
-
-       deconstruct_array(val_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &val_datums, &val_nulls, &val_count);
+       deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, 
&key_count);
+       deconstruct_array_builtin(val_array, TEXTOID, &val_datums, &val_nulls, 
&val_count);
 
        if (key_count != val_count)
                ereport(ERROR,
diff --git a/src/backend/access/common/reloptions.c 
b/src/backend/access/common/reloptions.c
index 599e160ca6..2b2ef63c35 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -1177,8 +1177,7 @@ transformRelOptions(Datum oldOptions, List *defList, 
const char *namspace,
                int                     noldoptions;
                int                     i;
 
-               deconstruct_array(array, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &oldoptions, NULL, 
&noldoptions);
+               deconstruct_array_builtin(array, TEXTOID, &oldoptions, NULL, 
&noldoptions);
 
                for (i = 0; i < noldoptions; i++)
                {
@@ -1345,8 +1344,7 @@ untransformRelOptions(Datum options)
 
        array = DatumGetArrayTypeP(options);
 
-       deconstruct_array(array, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &optiondatums, NULL, &noptions);
+       deconstruct_array_builtin(array, TEXTOID, &optiondatums, NULL, 
&noptions);
 
        for (i = 0; i < noptions; i++)
        {
@@ -1436,8 +1434,7 @@ parseRelOptionsInternal(Datum options, bool validate,
        int                     noptions;
        int                     i;
 
-       deconstruct_array(array, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &optiondatums, NULL, &noptions);
+       deconstruct_array_builtin(array, TEXTOID, &optiondatums, NULL, 
&noptions);
 
        for (i = 0; i < noptions; i++)
        {
diff --git a/src/backend/catalog/objectaddress.c 
b/src/backend/catalog/objectaddress.c
index 8377b4f7d4..2d21db4690 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -2099,8 +2099,7 @@ textarray_to_strvaluelist(ArrayType *arr)
        List       *list = NIL;
        int                     i;
 
-       deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &elems, &nulls, &nelems);
+       deconstruct_array_builtin(arr, TEXTOID, &elems, &nulls, &nelems);
 
        for (i = 0; i < nelems; i++)
        {
@@ -2156,8 +2155,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
                bool       *nulls;
                int                     nelems;
 
-               deconstruct_array(namearr, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &elems, &nulls, &nelems);
+               deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, 
&nelems);
                if (nelems != 1)
                        ereport(ERROR,
                                        
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -2174,8 +2172,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
                bool       *nulls;
                int                     nelems;
 
-               deconstruct_array(namearr, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &elems, &nulls, &nelems);
+               deconstruct_array_builtin(namearr, TEXTOID, &elems, &nulls, 
&nelems);
                if (nelems != 1)
                        ereport(ERROR,
                                        
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -2213,8 +2210,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
                int                     nelems;
                int                     i;
 
-               deconstruct_array(argsarr, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &elems, &nulls, &nelems);
+               deconstruct_array_builtin(argsarr, TEXTOID, &elems, &nulls, 
&nelems);
 
                args = NIL;
                for (i = 0; i < nelems; i++)
diff --git a/src/backend/catalog/pg_constraint.c 
b/src/backend/catalog/pg_constraint.c
index 472dbda211..454367a852 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -112,8 +112,7 @@ CreateConstraintEntry(const char *constraintName,
                conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));
                for (i = 0; i < constraintNKeys; i++)
                        conkey[i] = Int16GetDatum(constraintKey[i]);
-               conkeyArray = construct_array(conkey, constraintNKeys,
-                                                                         
INT2OID, 2, true, TYPALIGN_SHORT);
+               conkeyArray = construct_array_builtin(conkey, constraintNKeys, 
INT2OID);
        }
        else
                conkeyArray = NULL;
@@ -125,27 +124,22 @@ CreateConstraintEntry(const char *constraintName,
                fkdatums = (Datum *) palloc(foreignNKeys * sizeof(Datum));
                for (i = 0; i < foreignNKeys; i++)
                        fkdatums[i] = Int16GetDatum(foreignKey[i]);
-               confkeyArray = construct_array(fkdatums, foreignNKeys,
-                                                                          
INT2OID, 2, true, TYPALIGN_SHORT);
+               confkeyArray = construct_array_builtin(fkdatums, foreignNKeys, 
INT2OID);
                for (i = 0; i < foreignNKeys; i++)
                        fkdatums[i] = ObjectIdGetDatum(pfEqOp[i]);
-               conpfeqopArray = construct_array(fkdatums, foreignNKeys,
-                                                                               
 OIDOID, sizeof(Oid), true, TYPALIGN_INT);
+               conpfeqopArray = construct_array_builtin(fkdatums, 
foreignNKeys, OIDOID);
                for (i = 0; i < foreignNKeys; i++)
                        fkdatums[i] = ObjectIdGetDatum(ppEqOp[i]);
-               conppeqopArray = construct_array(fkdatums, foreignNKeys,
-                                                                               
 OIDOID, sizeof(Oid), true, TYPALIGN_INT);
+               conppeqopArray = construct_array_builtin(fkdatums, 
foreignNKeys, OIDOID);
                for (i = 0; i < foreignNKeys; i++)
                        fkdatums[i] = ObjectIdGetDatum(ffEqOp[i]);
-               conffeqopArray = construct_array(fkdatums, foreignNKeys,
-                                                                               
 OIDOID, sizeof(Oid), true, TYPALIGN_INT);
+               conffeqopArray = construct_array_builtin(fkdatums, 
foreignNKeys, OIDOID);
 
                if (numFkDeleteSetCols > 0)
                {
                        for (i = 0; i < numFkDeleteSetCols; i++)
                                fkdatums[i] = Int16GetDatum(fkDeleteSetCols[i]);
-                       confdelsetcolsArray = construct_array(fkdatums, 
numFkDeleteSetCols,
-                                                                               
   INT2OID, 2, true, TYPALIGN_SHORT);
+                       confdelsetcolsArray = construct_array_builtin(fkdatums, 
numFkDeleteSetCols, INT2OID);
                }
                else
                        confdelsetcolsArray = NULL;
@@ -166,8 +160,7 @@ CreateConstraintEntry(const char *constraintName,
                opdatums = (Datum *) palloc(constraintNKeys * sizeof(Datum));
                for (i = 0; i < constraintNKeys; i++)
                        opdatums[i] = ObjectIdGetDatum(exclOp[i]);
-               conexclopArray = construct_array(opdatums, constraintNKeys,
-                                                                               
 OIDOID, sizeof(Oid), true, TYPALIGN_INT);
+               conexclopArray = construct_array_builtin(opdatums, 
constraintNKeys, OIDOID);
        }
        else
                conexclopArray = NULL;
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index d82221fdb8..a4a30bccf6 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -1193,10 +1193,7 @@ oid_array_to_list(Datum datum)
        int                     i;
        List       *result = NIL;
 
-       deconstruct_array(array,
-                                         OIDOID,
-                                         sizeof(Oid), true, TYPALIGN_INT,
-                                         &values, NULL, &nelems);
+       deconstruct_array_builtin(array, OIDOID, &values, NULL, &nelems);
        for (i = 0; i < nelems; i++)
                result = lappend_oid(result, values[i]);
        return result;
diff --git a/src/backend/catalog/pg_subscription.c 
b/src/backend/catalog/pg_subscription.c
index add51caadf..8856ce3b50 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -260,9 +260,7 @@ textarray_to_stringlist(ArrayType *textarray)
                                i;
        List       *res = NIL;
 
-       deconstruct_array(textarray,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &elems, NULL, &nelems);
+       deconstruct_array_builtin(textarray, TEXTOID, &elems, NULL, &nelems);
 
        if (nelems == 0)
                return NIL;
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 305226692a..7f8652013e 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1688,10 +1688,7 @@ update_attstats(Oid relid, bool inh, int natts, 
VacAttrStats **vacattrstats)
 
                                for (n = 0; n < nnum; n++)
                                        numdatums[n] = 
Float4GetDatum(stats->stanumbers[k][n]);
-                               /* XXX knows more than it should about type 
float4: */
-                               arry = construct_array(numdatums, nnum,
-                                                                          
FLOAT4OID,
-                                                                          
sizeof(float4), true, TYPALIGN_INT);
+                               arry = construct_array_builtin(numdatums, nnum, 
FLOAT4OID);
                                values[i++] = PointerGetDatum(arry);    /* 
stanumbersN */
                        }
                        else
diff --git a/src/backend/commands/event_trigger.c 
b/src/backend/commands/event_trigger.c
index 4642527881..f46f86474a 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -351,8 +351,7 @@ filter_list_to_array(List *filterlist)
                pfree(result);
        }
 
-       return PointerGetDatum(construct_array(data, l, TEXTOID,
-                                                                               
   -1, false, TYPALIGN_INT));
+       return PointerGetDatum(construct_array_builtin(data, l, TEXTOID));
 }
 
 /*
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 1013790dbb..117ed80246 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2251,9 +2251,7 @@ convert_requires_to_datum(List *requires)
                datums[ndatums++] =
                        DirectFunctionCall1(namein, CStringGetDatum(curreq));
        }
-       a = construct_array(datums, ndatums,
-                                               NAMEOID,
-                                               NAMEDATALEN, false, 
TYPALIGN_CHAR);
+       a = construct_array_builtin(datums, ndatums, NAMEOID);
        return PointerGetDatum(a);
 }
 
@@ -2433,9 +2431,7 @@ pg_extension_config_dump(PG_FUNCTION_ARGS)
                arrayLength = 0;
                arrayIndex = 1;
 
-               a = construct_array(&elementDatum, 1,
-                                                       OIDOID,
-                                                       sizeof(Oid), true, 
TYPALIGN_INT);
+               a = construct_array_builtin(&elementDatum, 1, OIDOID);
        }
        else
        {
@@ -2486,9 +2482,7 @@ pg_extension_config_dump(PG_FUNCTION_ARGS)
                if (arrayLength != 0)
                        elog(ERROR, "extconfig and extcondition arrays do not 
match");
 
-               a = construct_array(&elementDatum, 1,
-                                                       TEXTOID,
-                                                       -1, false, 
TYPALIGN_INT);
+               a = construct_array_builtin(&elementDatum, 1, TEXTOID);
        }
        else
        {
@@ -2630,14 +2624,12 @@ extension_config_remove(Oid extensionoid, Oid tableoid)
                int                     i;
 
                /* We already checked there are no nulls */
-               deconstruct_array(a, OIDOID, sizeof(Oid), true, TYPALIGN_INT,
-                                                 &dvalues, NULL, &nelems);
+               deconstruct_array_builtin(a, OIDOID, &dvalues, NULL, &nelems);
 
                for (i = arrayIndex; i < arrayLength - 1; i++)
                        dvalues[i] = dvalues[i + 1];
 
-               a = construct_array(dvalues, arrayLength - 1,
-                                                       OIDOID, sizeof(Oid), 
true, TYPALIGN_INT);
+               a = construct_array_builtin(dvalues, arrayLength - 1, OIDOID);
 
                repl_val[Anum_pg_extension_extconfig - 1] = PointerGetDatum(a);
        }
@@ -2676,14 +2668,12 @@ extension_config_remove(Oid extensionoid, Oid tableoid)
                int                     i;
 
                /* We already checked there are no nulls */
-               deconstruct_array(a, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &dvalues, NULL, &nelems);
+               deconstruct_array_builtin(a, TEXTOID, &dvalues, NULL, &nelems);
 
                for (i = arrayIndex; i < arrayLength - 1; i++)
                        dvalues[i] = dvalues[i + 1];
 
-               a = construct_array(dvalues, arrayLength - 1,
-                                                       TEXTOID, -1, false, 
TYPALIGN_INT);
+               a = construct_array_builtin(dvalues, arrayLength - 1, TEXTOID);
 
                repl_val[Anum_pg_extension_extcondition - 1] = 
PointerGetDatum(a);
        }
diff --git a/src/backend/commands/functioncmds.c 
b/src/backend/commands/functioncmds.c
index 00a6d282cf..b016eecb2c 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -468,10 +468,8 @@ interpret_function_parameter_list(ParseState *pstate,
 
        if (outCount > 0 || varCount > 0)
        {
-               *allParameterTypes = construct_array(allTypes, parameterCount, 
OIDOID,
-                                                                               
         sizeof(Oid), true, TYPALIGN_INT);
-               *parameterModes = construct_array(paramModes, parameterCount, 
CHAROID,
-                                                                               
  1, true, TYPALIGN_CHAR);
+               *allParameterTypes = construct_array_builtin(allTypes, 
parameterCount, OIDOID);
+               *parameterModes = construct_array_builtin(paramModes, 
parameterCount, CHAROID);
                if (outCount > 1)
                        *requiredResultType = RECORDOID;
                /* otherwise we set requiredResultType correctly above */
@@ -489,8 +487,7 @@ interpret_function_parameter_list(ParseState *pstate,
                        if (paramNames[i] == PointerGetDatum(NULL))
                                paramNames[i] = CStringGetTextDatum("");
                }
-               *parameterNames = construct_array(paramNames, parameterCount, 
TEXTOID,
-                                                                               
  -1, false, TYPALIGN_INT);
+               *parameterNames = construct_array_builtin(paramNames, 
parameterCount, TEXTOID);
        }
        else
                *parameterNames = NULL;
@@ -1222,8 +1219,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt 
*stmt)
                i = 0;
                foreach(lc, trftypes_list)
                        arr[i++] = ObjectIdGetDatum(lfirst_oid(lc));
-               trftypes = construct_array(arr, list_length(trftypes_list),
-                                                                  OIDOID, 
sizeof(Oid), true, TYPALIGN_INT);
+               trftypes = construct_array_builtin(arr, 
list_length(trftypes_list), OIDOID);
        }
        else
        {
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index a59ee3b947..d9dff9ecaa 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -500,8 +500,7 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid 
policy_id)
                memset(isnull, 0, sizeof(isnull));
 
                /* This is the array for the new tuple */
-               role_ids = construct_array(role_oids, num_roles, OIDOID,
-                                                                  sizeof(Oid), 
true, TYPALIGN_INT);
+               role_ids = construct_array_builtin(role_oids, num_roles, 
OIDOID);
 
                replaces[Anum_pg_policy_polroles - 1] = true;
                values[Anum_pg_policy_polroles - 1] = PointerGetDatum(role_ids);
@@ -617,8 +616,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
 
        /* Collect role ids */
        role_oids = policy_role_list_to_array(stmt->roles, &nitems);
-       role_ids = construct_array(role_oids, nitems, OIDOID,
-                                                          sizeof(Oid), true, 
TYPALIGN_INT);
+       role_ids = construct_array_builtin(role_oids, nitems, OIDOID);
 
        /* Parse the supplied clause */
        qual_pstate = make_parsestate(NULL);
@@ -801,8 +799,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
        if (stmt->roles != NULL)
        {
                role_oids = policy_role_list_to_array(stmt->roles, &nitems);
-               role_ids = construct_array(role_oids, nitems, OIDOID,
-                                                                  sizeof(Oid), 
true, TYPALIGN_INT);
+               role_ids = construct_array_builtin(role_oids, nitems, OIDOID);
        }
 
        /* Get id of table.  Also handles permissions checks. */
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index 80738547ed..633c9a40bb 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -722,8 +722,6 @@ build_regtype_array(Oid *param_types, int num_params)
        for (i = 0; i < num_params; i++)
                tmp_ary[i] = ObjectIdGetDatum(param_types[i]);
 
-       /* XXX: this hardcodes assumptions about the regtype type */
-       result = construct_array(tmp_ary, num_params, REGTYPEOID,
-                                                        4, true, TYPALIGN_INT);
+       result = construct_array_builtin(tmp_ary, num_params, REGTYPEOID);
        return PointerGetDatum(result);
 }
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index 54a190722d..e54c2d90c9 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -466,7 +466,7 @@ CreateStatistics(CreateStatsStmt *stmt)
        if (build_expressions)
                types[ntypes++] = CharGetDatum(STATS_EXT_EXPRESSIONS);
        Assert(ntypes > 0 && ntypes <= lengthof(types));
-       stxkind = construct_array(types, ntypes, CHAROID, 1, true, 
TYPALIGN_CHAR);
+       stxkind = construct_array_builtin(types, ntypes, CHAROID);
 
        /* convert the expressions (if any) to a text datum */
        if (stxexprs != NIL)
diff --git a/src/backend/commands/subscriptioncmds.c 
b/src/backend/commands/subscriptioncmds.c
index b94236f74d..2e5f7b0b55 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -494,8 +494,7 @@ publicationListToArray(List *publist)
 
        MemoryContextSwitchTo(oldcxt);
 
-       arr = construct_array(datums, list_length(publist),
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT);
+       arr = construct_array_builtin(datums, list_length(publist), TEXTOID);
 
        MemoryContextDelete(memcxt);
 
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 9b92b04242..4f5e7c7ccb 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1893,12 +1893,9 @@ makeMultirangeConstructors(const char *name, Oid 
namespace,
        /* n-arg constructor - vararg */
        argtypes = buildoidvector(&rangeArrayOid, 1);
        allParamTypes = ObjectIdGetDatum(rangeArrayOid);
-       allParameterTypes = construct_array(&allParamTypes,
-                                                                               
1, OIDOID,
-                                                                               
sizeof(Oid), true, TYPALIGN_INT);
+       allParameterTypes = construct_array_builtin(&allParamTypes, 1, OIDOID);
        paramModes = CharGetDatum(FUNC_PARAM_VARIADIC);
-       parameterModes = construct_array(&paramModes, 1, CHAROID,
-                                                                        1, 
true, TYPALIGN_CHAR);
+       parameterModes = construct_array_builtin(&paramModes, 1, CHAROID);
        myself = ProcedureCreate(name,  /* name: same as multirange type */
                                                         namespace,
                                                         false, /* replace */
diff --git a/src/backend/executor/nodeTidscan.c 
b/src/backend/executor/nodeTidscan.c
index 4116d1f3b5..a1c6325d64 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -206,9 +206,7 @@ TidListEval(TidScanState *tidstate)
                        if (isNull)
                                continue;
                        itemarray = DatumGetArrayTypeP(arraydatum);
-                       deconstruct_array(itemarray,
-                                                         TIDOID, 
sizeof(ItemPointerData), false, TYPALIGN_SHORT,
-                                                         &ipdatums, &ipnulls, 
&ndatums);
+                       deconstruct_array_builtin(itemarray, TIDOID, &ipdatums, 
&ipnulls, &ndatums);
                        if (numTids + ndatums > numAllocTids)
                        {
                                numAllocTids = numTids + ndatums;
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 307114a30d..f7ad689459 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -411,9 +411,7 @@ typenameTypeMod(ParseState *pstate, const TypeName 
*typeName, Type typ)
                datums[n++] = CStringGetDatum(cstr);
        }
 
-       /* hardwired knowledge about cstring's representation details here */
-       arrtypmod = construct_array(datums, n, CSTRINGOID,
-                                                               -2, false, 
TYPALIGN_CHAR);
+       arrtypmod = construct_array_builtin(datums, n, CSTRINGOID);
 
        /* arrange to report location if type's typmodin function fails */
        setup_parser_errposition_callback(&pcbstate, pstate, 
typeName->location);
diff --git a/src/backend/parser/parse_utilcmd.c 
b/src/backend/parser/parse_utilcmd.c
index 1a64a52279..f889726a28 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1642,9 +1642,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation 
source_idx,
                                        elog(ERROR, "null conexclop for 
constraint %u",
                                                 constraintId);
 
-                               deconstruct_array(DatumGetArrayTypeP(datum),
-                                                                 OIDOID, 
sizeof(Oid), true, TYPALIGN_INT,
-                                                                 &elems, NULL, 
&nElems);
+                               
deconstruct_array_builtin(DatumGetArrayTypeP(datum), OIDOID, &elems, NULL, 
&nElems);
 
                                for (i = 0; i < nElems; i++)
                                {
diff --git a/src/backend/replication/logical/logicalfuncs.c 
b/src/backend/replication/logical/logicalfuncs.c
index 6058d36e0d..7fa2b2cba7 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -172,8 +172,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, 
bool confirm, bool bin
 
                Assert(ARR_ELEMTYPE(arr) == TEXTOID);
 
-               deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &datum_opts, NULL, &nelems);
+               deconstruct_array_builtin(arr, TEXTOID, &datum_opts, NULL, 
&nelems);
 
                if (nelems % 2 != 0)
                        ereport(ERROR,
diff --git a/src/backend/statistics/extended_stats.c 
b/src/backend/statistics/extended_stats.c
index ca48395d5c..7c02fb279f 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -2345,10 +2345,7 @@ serialize_expr_stats(AnlExprData *exprdata, int nexprs)
 
                                for (n = 0; n < nnum; n++)
                                        numdatums[n] = 
Float4GetDatum(stats->stanumbers[k][n]);
-                               /* XXX knows more than it should about type 
float4: */
-                               arry = construct_array(numdatums, nnum,
-                                                                          
FLOAT4OID,
-                                                                          
sizeof(float4), true, TYPALIGN_INT);
+                               arry = construct_array_builtin(numdatums, nnum, 
FLOAT4OID);
                                values[i++] = PointerGetDatum(arry);    /* 
stanumbersN */
                        }
                        else
diff --git a/src/backend/tsearch/dict.c b/src/backend/tsearch/dict.c
index 8dae2b8e99..c6ea9f9269 100644
--- a/src/backend/tsearch/dict.c
+++ b/src/backend/tsearch/dict.c
@@ -68,12 +68,7 @@ ts_lexize(PG_FUNCTION_ARGS)
                ptr++;
        }
 
-       a = construct_array(da,
-                                               ptr - res,
-                                               TEXTOID,
-                                               -1,
-                                               false,
-                                               TYPALIGN_INT);
+       a = construct_array_builtin(da, ptr - res, TEXTOID);
 
        ptr = res;
        while (ptr->lexeme)
diff --git a/src/backend/utils/adt/arrayfuncs.c 
b/src/backend/utils/adt/arrayfuncs.c
index 78e951a6bc..9f22349a0d 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -3330,6 +3330,88 @@ construct_array(Datum *elems, int nelems,
                                                          elmtype, elmlen, 
elmbyval, elmalign);
 }
 
+/*
+ * Like construct_array(), where elmtype must be a built-in type, and
+ * elmlen/elmbyval/elmalign is looked up from hardcoded data.  This is often
+ * useful when manipulating arrays from/for system catalogs.
+ */
+ArrayType *
+construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
+{
+       int                     elmlen;
+       bool            elmbyval;
+       char            elmalign;
+
+       switch (elmtype)
+       {
+               case CHAROID:
+                       elmlen = 1;
+                       elmbyval = true;
+                       elmalign = TYPALIGN_CHAR;
+                       break;
+
+               case CSTRINGOID:
+                       elmlen = -2;
+                       elmbyval = false;
+                       elmalign = TYPALIGN_CHAR;
+                       break;
+
+               case FLOAT4OID:
+                       elmlen = sizeof(float4);
+                       elmbyval = true;
+                       elmalign = TYPALIGN_INT;
+                       break;
+
+               case INT2OID:
+                       elmlen = sizeof(int16);
+                       elmbyval = true;
+                       elmalign = TYPALIGN_SHORT;
+                       break;
+
+               case INT4OID:
+                       elmlen = sizeof(int32);
+                       elmbyval = true;
+                       elmalign = TYPALIGN_INT;
+                       break;
+
+               case INT8OID:
+                       elmlen = sizeof(int64);
+                       elmbyval = FLOAT8PASSBYVAL;
+                       elmalign = TYPALIGN_DOUBLE;
+                       break;
+
+               case NAMEOID:
+                       elmlen = NAMEDATALEN;
+                       elmbyval = false;
+                       elmalign = TYPALIGN_CHAR;
+                       break;
+
+               case OIDOID:
+               case REGTYPEOID:
+                       elmlen = sizeof(Oid);
+                       elmbyval = true;
+                       elmalign = TYPALIGN_INT;
+                       break;
+
+               case TEXTOID:
+                       elmlen = -1;
+                       elmbyval = false;
+                       elmalign = TYPALIGN_INT;
+                       break;
+
+               case TIDOID:
+                       elmlen = sizeof(ItemPointerData);
+                       elmbyval = false;
+                       elmalign = TYPALIGN_SHORT;
+                       break;
+
+               default:
+                       elog(ERROR, "type %u not supported here", elmtype);
+       }
+
+       return construct_array(elems, nelems, elmtype, elmlen, elmbyval, 
elmalign);
+}
+
 /*
  * construct_md_array  --- simple method for constructing an array object
  *                                                     with arbitrary 
dimensions and possible NULLs
@@ -3483,9 +3565,9 @@ construct_empty_expanded_array(Oid element_type,
  * be pointers into the array object.
  *
  * NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
- * from the system catalogs, given the elmtype.  However, in most current
- * uses the type is hard-wired into the caller and so we can save a lookup
- * cycle by hard-wiring the type info as well.
+ * from the system catalogs, given the elmtype.  However, the caller is
+ * in a better position to cache this info across multiple uses, or even
+ * to hard-wire values if the element type is hard-wired.
  */
 void
 deconstruct_array(ArrayType *array,
@@ -3548,6 +3630,71 @@ deconstruct_array(ArrayType *array,
        }
 }
 
+/*
+ * Like deconstruct_array(), where elmtype must be a built-in type, and
+ * elmlen/elmbyval/elmalign is looked up from hardcoded data.  This is often
+ * useful when manipulating arrays from/for system catalogs.
+ */
+void
+deconstruct_array_builtin(ArrayType *array,
+                                                 Oid elmtype,
+                                                 Datum **elemsp, bool 
**nullsp, int *nelemsp)
+{
+       int                     elmlen;
+       bool            elmbyval;
+       char            elmalign;
+
+       switch (elmtype)
+       {
+               case CHAROID:
+                       elmlen = 1;
+                       elmbyval = true;
+                       elmalign = TYPALIGN_CHAR;
+                       break;
+
+               case CSTRINGOID:
+                       elmlen = -2;
+                       elmbyval = false;
+                       elmalign = TYPALIGN_CHAR;
+                       break;
+
+               case FLOAT8OID:
+                       elmlen = sizeof(float8);
+                       elmbyval = FLOAT8PASSBYVAL;
+                       elmalign = TYPALIGN_DOUBLE;
+                       break;
+
+               case INT2OID:
+                       elmlen = sizeof(int16);
+                       elmbyval = true;
+                       elmalign = TYPALIGN_SHORT;
+                       break;
+
+               case OIDOID:
+                       elmlen = sizeof(Oid);
+                       elmbyval = true;
+                       elmalign = TYPALIGN_INT;
+                       break;
+
+               case TEXTOID:
+                       elmlen = -1;
+                       elmbyval = false;
+                       elmalign = TYPALIGN_INT;
+                       break;
+
+               case TIDOID:
+                       elmlen = sizeof(ItemPointerData);
+                       elmbyval = false;
+                       elmalign = TYPALIGN_SHORT;
+                       break;
+
+               default:
+                       elog(ERROR, "type %u not supported here", elmtype);
+       }
+
+       deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, 
nullsp, nelemsp);
+}
+
 /*
  * array_contains_nulls --- detect whether an array has any null elements
  *
diff --git a/src/backend/utils/adt/arrayutils.c 
b/src/backend/utils/adt/arrayutils.c
index 464a37641e..051169a149 100644
--- a/src/backend/utils/adt/arrayutils.c
+++ b/src/backend/utils/adt/arrayutils.c
@@ -249,10 +249,7 @@ ArrayGetIntegerTypmods(ArrayType *arr, int *n)
                                (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
                                 errmsg("typmod array must not contain 
nulls")));
 
-       /* hardwired knowledge about cstring's representation details here */
-       deconstruct_array(arr, CSTRINGOID,
-                                         -2, false, TYPALIGN_CHAR,
-                                         &elem_values, NULL, n);
+       deconstruct_array_builtin(arr, CSTRINGOID, &elem_values, NULL, n);
 
        result = (int32 *) palloc(*n * sizeof(int32));
 
diff --git a/src/backend/utils/adt/hbafuncs.c b/src/backend/utils/adt/hbafuncs.c
index 9fe7b62c9a..598259718c 100644
--- a/src/backend/utils/adt/hbafuncs.c
+++ b/src/backend/utils/adt/hbafuncs.c
@@ -151,7 +151,7 @@ get_hba_options(HbaLine *hba)
        Assert(noptions <= MAX_HBA_OPTIONS);
 
        if (noptions > 0)
-               return construct_array(options, noptions, TEXTOID, -1, false, 
TYPALIGN_INT);
+               return construct_array_builtin(options, noptions, TEXTOID);
        else
                return NULL;
 }
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 63649ba735..73dd35f6ec 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -1447,9 +1447,7 @@ json_object(PG_FUNCTION_ARGS)
                                         errmsg("wrong number of array 
subscripts")));
        }
 
-       deconstruct_array(in_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &in_datums, &in_nulls, &in_count);
+       deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, 
&in_count);
 
        count = in_count / 2;
 
@@ -1523,13 +1521,8 @@ json_object_two_arg(PG_FUNCTION_ARGS)
        if (nkdims == 0)
                PG_RETURN_DATUM(CStringGetTextDatum("{}"));
 
-       deconstruct_array(key_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &key_count);
-
-       deconstruct_array(val_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &val_datums, &val_nulls, &val_count);
+       deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, 
&key_count);
+       deconstruct_array_builtin(val_array, TEXTOID, &val_datums, &val_nulls, 
&val_count);
 
        if (key_count != val_count)
                ereport(ERROR,
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index 26d81366c9..f70576f1c0 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -1376,9 +1376,7 @@ jsonb_object(PG_FUNCTION_ARGS)
                                         errmsg("wrong number of array 
subscripts")));
        }
 
-       deconstruct_array(in_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &in_datums, &in_nulls, &in_count);
+       deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, 
&in_count);
 
        count = in_count / 2;
 
@@ -1464,13 +1462,8 @@ jsonb_object_two_arg(PG_FUNCTION_ARGS)
        if (nkdims == 0)
                goto close_object;
 
-       deconstruct_array(key_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &key_count);
-
-       deconstruct_array(val_array,
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &val_datums, &val_nulls, &val_count);
+       deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, 
&key_count);
+       deconstruct_array_builtin(val_array, TEXTOID, &val_datums, &val_nulls, 
&val_count);
 
        if (key_count != val_count)
                ereport(ERROR,
diff --git a/src/backend/utils/adt/jsonb_gin.c 
b/src/backend/utils/adt/jsonb_gin.c
index 5edf278cdb..c5325acde4 100644
--- a/src/backend/utils/adt/jsonb_gin.c
+++ b/src/backend/utils/adt/jsonb_gin.c
@@ -885,9 +885,7 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
                int                     i,
                                        j;
 
-               deconstruct_array(query,
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &key_datums, &key_nulls, 
&key_count);
+               deconstruct_array_builtin(query, TEXTOID, &key_datums, 
&key_nulls, &key_count);
 
                entries = (Datum *) palloc(sizeof(Datum) * key_count);
 
diff --git a/src/backend/utils/adt/jsonb_op.c b/src/backend/utils/adt/jsonb_op.c
index ed37252e7f..202367e996 100644
--- a/src/backend/utils/adt/jsonb_op.c
+++ b/src/backend/utils/adt/jsonb_op.c
@@ -53,8 +53,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
        bool       *key_nulls;
        int                     elem_count;
 
-       deconstruct_array(keys, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &elem_count);
+       deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, 
&elem_count);
 
        for (i = 0; i < elem_count; i++)
        {
@@ -86,8 +85,7 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
        bool       *key_nulls;
        int                     elem_count;
 
-       deconstruct_array(keys, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &key_datums, &key_nulls, &elem_count);
+       deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, 
&elem_count);
 
        for (i = 0; i < elem_count; i++)
        {
diff --git a/src/backend/utils/adt/jsonfuncs.c 
b/src/backend/utils/adt/jsonfuncs.c
index d1356d6416..2a3f656899 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -1000,8 +1000,7 @@ get_path_all(FunctionCallInfo fcinfo, bool as_text)
        if (array_contains_nulls(path))
                PG_RETURN_NULL();
 
-       deconstruct_array(path, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &pathtext, &pathnulls, &npath);
+       deconstruct_array_builtin(path, TEXTOID, &pathtext, &pathnulls, &npath);
 
        tpath = palloc(npath * sizeof(char *));
        ipath = palloc(npath * sizeof(int));
@@ -1456,8 +1455,7 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text)
        if (array_contains_nulls(path))
                PG_RETURN_NULL();
 
-       deconstruct_array(path, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &pathtext, &pathnulls, &npath);
+       deconstruct_array_builtin(path, TEXTOID, &pathtext, &pathnulls, &npath);
 
        res = jsonb_get_element(jb, pathtext, npath, &isnull, as_text);
 
@@ -4369,8 +4367,7 @@ jsonb_delete_array(PG_FUNCTION_ARGS)
        if (JB_ROOT_COUNT(in) == 0)
                PG_RETURN_JSONB_P(in);
 
-       deconstruct_array(keys, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &keys_elems, &keys_nulls, &keys_len);
+       deconstruct_array_builtin(keys, TEXTOID, &keys_elems, &keys_nulls, 
&keys_len);
 
        if (keys_len == 0)
                PG_RETURN_JSONB_P(in);
@@ -4522,8 +4519,7 @@ jsonb_set(PG_FUNCTION_ARGS)
        if (JB_ROOT_COUNT(in) == 0 && !create)
                PG_RETURN_JSONB_P(in);
 
-       deconstruct_array(path, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &path_elems, &path_nulls, &path_len);
+       deconstruct_array_builtin(path, TEXTOID, &path_elems, &path_nulls, 
&path_len);
 
        if (path_len == 0)
                PG_RETURN_JSONB_P(in);
@@ -4634,8 +4630,7 @@ jsonb_delete_path(PG_FUNCTION_ARGS)
        if (JB_ROOT_COUNT(in) == 0)
                PG_RETURN_JSONB_P(in);
 
-       deconstruct_array(path, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &path_elems, &path_nulls, &path_len);
+       deconstruct_array_builtin(path, TEXTOID, &path_elems, &path_nulls, 
&path_len);
 
        if (path_len == 0)
                PG_RETURN_JSONB_P(in);
@@ -4680,8 +4675,7 @@ jsonb_insert(PG_FUNCTION_ARGS)
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                 errmsg("cannot set path in scalar")));
 
-       deconstruct_array(path, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &path_elems, &path_nulls, &path_len);
+       deconstruct_array_builtin(path, TEXTOID, &path_elems, &path_nulls, 
&path_len);
 
        if (path_len == 0)
                PG_RETURN_JSONB_P(in);
diff --git a/src/backend/utils/adt/lockfuncs.c 
b/src/backend/utils/adt/lockfuncs.c
index 023a004ac8..dedee7af5c 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -538,10 +538,7 @@ pg_blocking_pids(PG_FUNCTION_ARGS)
        /* Assert we didn't overrun arrayelems[] */
        Assert(narrayelems <= lockData->nlocks);
 
-       /* Construct array, using hardwired knowledge about int4 type */
-       PG_RETURN_ARRAYTYPE_P(construct_array(arrayelems, narrayelems,
-                                                                               
  INT4OID,
-                                                                               
  sizeof(int32), true, TYPALIGN_INT));
+       PG_RETURN_ARRAYTYPE_P(construct_array_builtin(arrayelems, narrayelems, 
INT4OID));
 }
 
 
@@ -579,10 +576,7 @@ pg_safe_snapshot_blocking_pids(PG_FUNCTION_ARGS)
        else
                blocker_datums = NULL;
 
-       /* Construct array, using hardwired knowledge about int4 type */
-       PG_RETURN_ARRAYTYPE_P(construct_array(blocker_datums, num_blockers,
-                                                                               
  INT4OID,
-                                                                               
  sizeof(int32), true, TYPALIGN_INT));
+       PG_RETURN_ARRAYTYPE_P(construct_array_builtin(blocker_datums, 
num_blockers, INT4OID));
 }
 
 
diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c
index e8bba3670c..d22e1f277b 100644
--- a/src/backend/utils/adt/name.c
+++ b/src/backend/utils/adt/name.c
@@ -314,11 +314,7 @@ current_schemas(PG_FUNCTION_ARGS)
        }
        list_free(search_path);
 
-       array = construct_array(names, i,
-                                                       NAMEOID,
-                                                       NAMEDATALEN,    /* 
sizeof(Name) */
-                                                       false,  /* Name is not 
by-val */
-                                                       TYPALIGN_CHAR); /* 
alignment of Name */
+       array = construct_array_builtin(names, i, NAMEOID);
 
        PG_RETURN_POINTER(array);
 }
diff --git a/src/backend/utils/adt/orderedsetaggs.c 
b/src/backend/utils/adt/orderedsetaggs.c
index 6d4f6b7dca..185b2cb848 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -759,12 +759,10 @@ percentile_disc_multi_final(PG_FUNCTION_ARGS)
                PG_RETURN_NULL();
        param = PG_GETARG_ARRAYTYPE_P(1);
 
-       deconstruct_array(param, FLOAT8OID,
-       /* hard-wired info on type float8 */
-                                         sizeof(float8), FLOAT8PASSBYVAL, 
TYPALIGN_DOUBLE,
-                                         &percentiles_datum,
-                                         &percentiles_null,
-                                         &num_percentiles);
+       deconstruct_array_builtin(param, FLOAT8OID,
+                                                         &percentiles_datum,
+                                                         &percentiles_null,
+                                                         &num_percentiles);
 
        if (num_percentiles == 0)
                
PG_RETURN_POINTER(construct_empty_array(osastate->qstate->sortColType));
@@ -883,12 +881,10 @@ percentile_cont_multi_final_common(FunctionCallInfo 
fcinfo,
                PG_RETURN_NULL();
        param = PG_GETARG_ARRAYTYPE_P(1);
 
-       deconstruct_array(param, FLOAT8OID,
-       /* hard-wired info on type float8 */
-                                         sizeof(float8), FLOAT8PASSBYVAL, 
TYPALIGN_DOUBLE,
-                                         &percentiles_datum,
-                                         &percentiles_null,
-                                         &num_percentiles);
+       deconstruct_array_builtin(param, FLOAT8OID,
+                                                         &percentiles_datum,
+                                                         &percentiles_null,
+                                                         &num_percentiles);
 
        if (num_percentiles == 0)
                
PG_RETURN_POINTER(construct_empty_array(osastate->qstate->sortColType));
diff --git a/src/backend/utils/adt/pg_upgrade_support.c 
b/src/backend/utils/adt/pg_upgrade_support.c
index 67b9675e92..65764d78a3 100644
--- a/src/backend/utils/adt/pg_upgrade_support.c
+++ b/src/backend/utils/adt/pg_upgrade_support.c
@@ -214,9 +214,7 @@ binary_upgrade_create_empty_extension(PG_FUNCTION_ARGS)
                int                     ndatums;
                int                     i;
 
-               deconstruct_array(textArray,
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &textDatums, NULL, &ndatums);
+               deconstruct_array_builtin(textArray, TEXTOID, &textDatums, 
NULL, &ndatums);
                for (i = 0; i < ndatums; i++)
                {
                        char       *extName = 
TextDatumGetCString(textDatums[i]);
diff --git a/src/backend/utils/adt/ruleutils.c 
b/src/backend/utils/adt/ruleutils.c
index 5d49f564a2..4d714666d5 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -2399,9 +2399,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool 
fullCommand,
                                        if (isnull)
                                                elog(ERROR, "null indkey for 
index %u", indexId);
 
-                                       
deconstruct_array(DatumGetArrayTypeP(cols),
-                                                                         
INT2OID, 2, true, TYPALIGN_SHORT,
-                                                                         
&keys, NULL, &nKeys);
+                                       
deconstruct_array_builtin(DatumGetArrayTypeP(cols), INT2OID,
+                                                                               
          &keys, NULL, &nKeys);
 
                                        for (j = keyatts; j < nKeys; j++)
                                        {
@@ -2524,9 +2523,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool 
fullCommand,
                                        elog(ERROR, "null conexclop for 
constraint %u",
                                                 constraintId);
 
-                               deconstruct_array(DatumGetArrayTypeP(val),
-                                                                 OIDOID, 
sizeof(Oid), true, TYPALIGN_INT,
-                                                                 &elems, NULL, 
&nElems);
+                               
deconstruct_array_builtin(DatumGetArrayTypeP(val), OIDOID,
+                                                                               
  &elems, NULL, &nElems);
 
                                operators = (Oid *) palloc(nElems * 
sizeof(Oid));
                                for (i = 0; i < nElems; i++)
@@ -2580,9 +2578,8 @@ decompile_column_index_array(Datum column_index_array, 
Oid relId,
        int                     j;
 
        /* Extract data from array of int16 */
-       deconstruct_array(DatumGetArrayTypeP(column_index_array),
-                                         INT2OID, 2, true, TYPALIGN_SHORT,
-                                         &keys, NULL, &nKeys);
+       deconstruct_array_builtin(DatumGetArrayTypeP(column_index_array), 
INT2OID,
+                                                         &keys, NULL, &nKeys);
 
        for (j = 0; j < nKeys; j++)
        {
@@ -12715,9 +12712,8 @@ get_reloptions(StringInfo buf, Datum reloptions)
        int                     noptions;
        int                     i;
 
-       deconstruct_array(DatumGetArrayTypeP(reloptions),
-                                         TEXTOID, -1, false, TYPALIGN_INT,
-                                         &options, NULL, &noptions);
+       deconstruct_array_builtin(DatumGetArrayTypeP(reloptions), TEXTOID,
+                                                         &options, NULL, 
&noptions);
 
        for (i = 0; i < noptions; i++)
        {
diff --git a/src/backend/utils/adt/tsvector_op.c 
b/src/backend/utils/adt/tsvector_op.c
index addc349151..1786c18f89 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -308,8 +308,7 @@ tsvector_setweight_by_filter(PG_FUNCTION_ARGS)
        memcpy(tsout, tsin, VARSIZE(tsin));
        entry = ARRPTR(tsout);
 
-       deconstruct_array(lexemes, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &dlexemes, &nulls, &nlexemes);
+       deconstruct_array_builtin(lexemes, TEXTOID, &dlexemes, &nulls, 
&nlexemes);
 
        /*
         * Assuming that lexemes array is significantly shorter than tsvector we
@@ -586,8 +585,7 @@ tsvector_delete_arr(PG_FUNCTION_ARGS)
        Datum      *dlexemes;
        bool       *nulls;
 
-       deconstruct_array(lexemes, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &dlexemes, &nulls, &nlex);
+       deconstruct_array_builtin(lexemes, TEXTOID, &dlexemes, &nulls, &nlex);
 
        /*
         * In typical use case array of lexemes to delete is relatively small. 
So
@@ -694,10 +692,8 @@ tsvector_unnest(PG_FUNCTION_ARGS)
                                                                                
                                                          1));
                        }
 
-                       values[1] = PointerGetDatum(construct_array(positions, 
posv->npos,
-                                                                               
                                INT2OID, 2, true, TYPALIGN_SHORT));
-                       values[2] = PointerGetDatum(construct_array(weights, 
posv->npos,
-                                                                               
                                TEXTOID, -1, false, TYPALIGN_INT));
+                       values[1] = 
PointerGetDatum(construct_array_builtin(positions, posv->npos, INT2OID));
+                       values[2] = 
PointerGetDatum(construct_array_builtin(weights, posv->npos, TEXTOID));
                }
                else
                {
@@ -733,7 +729,7 @@ tsvector_to_array(PG_FUNCTION_ARGS)
                                                                                
                                           arrin[i].len));
        }
 
-       array = construct_array(elements, tsin->size, TEXTOID, -1, false, 
TYPALIGN_INT);
+       array = construct_array_builtin(elements, tsin->size, TEXTOID);
 
        pfree(elements);
        PG_FREE_IF_COPY(tsin, 0);
@@ -757,7 +753,7 @@ array_to_tsvector(PG_FUNCTION_ARGS)
                                datalen = 0;
        char       *cur;
 
-       deconstruct_array(v, TEXTOID, -1, false, TYPALIGN_INT, &dlexemes, 
&nulls, &nitems);
+       deconstruct_array_builtin(v, TEXTOID, &dlexemes, &nulls, &nitems);
 
        /*
         * Reject nulls and zero length strings (maybe we should just ignore 
them,
@@ -833,8 +829,7 @@ tsvector_filter(PG_FUNCTION_ARGS)
        int                     cur_pos = 0;
        char            mask = 0;
 
-       deconstruct_array(weights, CHAROID, 1, true, TYPALIGN_CHAR,
-                                         &dweights, &nulls, &nweights);
+       deconstruct_array_builtin(weights, CHAROID, &dweights, &nulls, 
&nweights);
 
        for (i = 0; i < nweights; i++)
        {
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 1ec6f1c2fd..60a85c4697 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -4017,9 +4017,9 @@ xpath_internal(text *xpath_expr_text, xmltype *data, 
ArrayType *namespaces,
 
                Assert(ARR_ELEMTYPE(namespaces) == TEXTOID);
 
-               deconstruct_array(namespaces, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &ns_names_uris, 
&ns_names_uris_nulls,
-                                                 &ns_count);
+               deconstruct_array_builtin(namespaces, TEXTOID,
+                                                                 
&ns_names_uris, &ns_names_uris_nulls,
+                                                                 &ns_count);
 
                Assert((ns_count % 2) == 0);    /* checked above */
                ns_count /= 2;                  /* count pairs only */
diff --git a/src/backend/utils/cache/evtcache.c 
b/src/backend/utils/cache/evtcache.c
index 3a9c9f0c50..f7f7165f7f 100644
--- a/src/backend/utils/cache/evtcache.c
+++ b/src/backend/utils/cache/evtcache.c
@@ -228,8 +228,7 @@ DecodeTextArrayToBitmapset(Datum array)
 
        if (ARR_NDIM(arr) != 1 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != 
TEXTOID)
                elog(ERROR, "expected 1-D text array");
-       deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &elems, NULL, &nelems);
+       deconstruct_array_builtin(arr, TEXTOID, &elems, NULL, &nelems);
 
        for (bms = NULL, i = 0; i < nelems; ++i)
        {
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 9197b0f1e2..a1fe50ffca 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1390,9 +1390,8 @@ get_func_arg_info(HeapTuple procTup,
                *p_argnames = NULL;
        else
        {
-               deconstruct_array(DatumGetArrayTypeP(proargnames),
-                                                 TEXTOID, -1, false, 
TYPALIGN_INT,
-                                                 &elems, NULL, &nelems);
+               deconstruct_array_builtin(DatumGetArrayTypeP(proargnames), 
TEXTOID,
+                                                                 &elems, NULL, 
&nelems);
                if (nelems != numargs)  /* should not happen */
                        elog(ERROR, "proargnames must have the same number of 
elements as the function has arguments");
                *p_argnames = (char **) palloc(sizeof(char *) * numargs);
@@ -1506,8 +1505,7 @@ get_func_input_arg_names(Datum proargnames, Datum 
proargmodes,
                ARR_HASNULL(arr) ||
                ARR_ELEMTYPE(arr) != TEXTOID)
                elog(ERROR, "proargnames is not a 1-D text array or it contains 
nulls");
-       deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
-                                         &argnames, NULL, &numargs);
+       deconstruct_array_builtin(arr, TEXTOID, &argnames, NULL, &numargs);
        if (proargmodes != PointerGetDatum(NULL))
        {
                arr = DatumGetArrayTypeP(proargmodes);  /* ensure not toasted */
@@ -1621,8 +1619,7 @@ get_func_result_name(Oid functionId)
                        ARR_ELEMTYPE(arr) != TEXTOID)
                        elog(ERROR, "proargnames is not a 1-D text array of 
length %d or it contains nulls",
                                 numargs);
-               deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &argnames, NULL, &nargnames);
+               deconstruct_array_builtin(arr, TEXTOID, &argnames, NULL, 
&nargnames);
                Assert(nargnames == numargs);
 
                /* scan for output argument(s) */
@@ -1770,8 +1767,7 @@ build_function_result_tupdesc_d(char prokind,
                        ARR_ELEMTYPE(arr) != TEXTOID)
                        elog(ERROR, "proargnames is not a 1-D text array of 
length %d or it contains nulls",
                                 numargs);
-               deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT,
-                                                 &argnames, NULL, &nargnames);
+               deconstruct_array_builtin(arr, TEXTOID, &argnames, NULL, 
&nargnames);
                Assert(nargnames == numargs);
        }
 
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8e9b71375c..23f2cb4f8e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -9958,7 +9958,7 @@ pg_settings_get_flags(PG_FUNCTION_ARGS)
        Assert(cnt <= MAX_GUC_FLAGS);
 
        /* Returns the record as Datum */
-       a = construct_array(flags, cnt, TEXTOID, -1, false, TYPALIGN_INT);
+       a = construct_array_builtin(flags, cnt, TEXTOID);
        PG_RETURN_ARRAYTYPE_P(a);
 }
 
@@ -11491,9 +11491,7 @@ GUCArrayAdd(ArrayType *array, const char *name, const 
char *value)
                                          TYPALIGN_INT /* TEXT's typalign */ );
        }
        else
-               a = construct_array(&datum, 1,
-                                                       TEXTOID,
-                                                       -1, false, 
TYPALIGN_INT);
+               a = construct_array_builtin(&datum, 1, TEXTOID);
 
        return a;
 }
@@ -11560,9 +11558,7 @@ GUCArrayDelete(ArrayType *array, const char *name)
                                                                 false /* 
TEXT's typbyval */ ,
                                                                 TYPALIGN_INT 
/* TEXT's typalign */ );
                else
-                       newarray = construct_array(&d, 1,
-                                                                          
TEXTOID,
-                                                                          -1, 
false, TYPALIGN_INT);
+                       newarray = construct_array_builtin(&d, 1, TEXTOID);
 
                index++;
        }
@@ -11628,9 +11624,7 @@ GUCArrayReset(ArrayType *array)
                                                                 false /* 
TEXT's typbyval */ ,
                                                                 TYPALIGN_INT 
/* TEXT's typalign */ );
                else
-                       newarray = construct_array(&d, 1,
-                                                                          
TEXTOID,
-                                                                          -1, 
false, TYPALIGN_INT);
+                       newarray = construct_array_builtin(&d, 1, TEXTOID);
 
                index++;
                pfree(val);
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 656c766a9a..2f794d1168 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -387,6 +387,7 @@ extern void array_bitmap_copy(bits8 *destbitmap, int 
destoffset,
 extern ArrayType *construct_array(Datum *elems, int nelems,
                                                                  Oid elmtype,
                                                                  int elmlen, 
bool elmbyval, char elmalign);
+extern ArrayType *construct_array_builtin(Datum *elems, int nelems, Oid 
elmtype);
 extern ArrayType *construct_md_array(Datum *elems,
                                                                         bool 
*nulls,
                                                                         int 
ndims,
@@ -401,6 +402,9 @@ extern void deconstruct_array(ArrayType *array,
                                                          Oid elmtype,
                                                          int elmlen, bool 
elmbyval, char elmalign,
                                                          Datum **elemsp, bool 
**nullsp, int *nelemsp);
+extern void deconstruct_array_builtin(ArrayType *array,
+                                                                         Oid 
elmtype,
+                                                                         Datum 
**elemsp, bool **nullsp, int *nelemsp);
 extern bool array_contains_nulls(ArrayType *array);
 
 extern ArrayBuildState *initArrayResult(Oid element_type,
diff --git a/src/test/modules/test_rls_hooks/test_rls_hooks.c 
b/src/test/modules/test_rls_hooks/test_rls_hooks.c
index 4f862d081b..41bfc776ae 100644
--- a/src/test/modules/test_rls_hooks/test_rls_hooks.c
+++ b/src/test/modules/test_rls_hooks/test_rls_hooks.c
@@ -87,7 +87,7 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation)
 
        policy->policy_name = pstrdup("extension policy");
        policy->polcmd = '*';
-       policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true, 
TYPALIGN_INT);
+       policy->roles = construct_array_builtin(&role, 1, OIDOID);
 
        /*
         * policy->qual = (Expr *) makeConst(BOOLOID, -1, InvalidOid,
@@ -155,7 +155,7 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation 
relation)
 
        policy->policy_name = pstrdup("extension policy");
        policy->polcmd = '*';
-       policy->roles = construct_array(&role, 1, OIDOID, sizeof(Oid), true, 
TYPALIGN_INT);
+       policy->roles = construct_array_builtin(&role, 1, OIDOID);
 
        n = makeFuncCall(list_make2(makeString("pg_catalog"),
                                                                
makeString("current_user")),
-- 
2.35.1

Reply via email to