Add construct_array_builtin, deconstruct_array_builtin
authorPeter Eisentraut <[email protected]>
Fri, 1 Jul 2022 08:51:45 +0000 (10:51 +0200)
committerPeter Eisentraut <[email protected]>
Fri, 1 Jul 2022 09:23:15 +0000 (11:23 +0200)
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.

Reviewed-by: Tom Lane <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/2914356f-9e5f-8c59-2995-5997fc48bcba%40enterprisedb.com

51 files changed:
contrib/hstore/hstore_gin.c
contrib/hstore/hstore_gist.c
contrib/hstore/hstore_io.c
contrib/hstore/hstore_op.c
contrib/pageinspect/btreefuncs.c
contrib/pageinspect/ginfuncs.c
contrib/pageinspect/gistfuncs.c
contrib/pageinspect/hashfuncs.c
contrib/pageinspect/heapfuncs.c
contrib/pg_trgm/trgm_op.c
contrib/pgcrypto/pgp-pgsql.c
src/backend/access/common/reloptions.c
src/backend/catalog/objectaddress.c
src/backend/catalog/pg_constraint.c
src/backend/catalog/pg_proc.c
src/backend/catalog/pg_subscription.c
src/backend/commands/analyze.c
src/backend/commands/event_trigger.c
src/backend/commands/extension.c
src/backend/commands/functioncmds.c
src/backend/commands/policy.c
src/backend/commands/prepare.c
src/backend/commands/statscmds.c
src/backend/commands/subscriptioncmds.c
src/backend/commands/typecmds.c
src/backend/executor/nodeTidscan.c
src/backend/parser/parse_type.c
src/backend/parser/parse_utilcmd.c
src/backend/replication/logical/logicalfuncs.c
src/backend/statistics/extended_stats.c
src/backend/tsearch/dict.c
src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/arrayutils.c
src/backend/utils/adt/hbafuncs.c
src/backend/utils/adt/json.c
src/backend/utils/adt/jsonb.c
src/backend/utils/adt/jsonb_gin.c
src/backend/utils/adt/jsonb_op.c
src/backend/utils/adt/jsonfuncs.c
src/backend/utils/adt/lockfuncs.c
src/backend/utils/adt/name.c
src/backend/utils/adt/orderedsetaggs.c
src/backend/utils/adt/pg_upgrade_support.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/tsvector_op.c
src/backend/utils/adt/xml.c
src/backend/utils/cache/evtcache.c
src/backend/utils/fmgr/funcapi.c
src/backend/utils/misc/guc.c
src/include/utils/array.h
src/test/modules/test_rls_hooks/test_rls_hooks.c

index 908530261aeab787ed449aac732312ffc88e88b7..766c00bb6a7352378061b703dbbff7b63e945230 100644 (file)
@@ -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);
 
index 016bfa4a4c0f96f87128b94a92a4c8b1677c49e5..39ba92a6bf4115152b8c6fe984e83563f3779553 100644 (file)
@@ -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;
 
index b3304ff84452c0205cbc1c86d1cf48f395106b10..fb72bb6cfe4586f1d0ae9990e9ce88dde68add12 100644 (file)
@@ -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;
 
index dd79d01cac308c5883366886450315d14581c4b8..2f540d7ed6cda3fef671ab1fa0a6f1e324dba099 100644 (file)
@@ -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);
 }
index 62f2c1b3159651f3580233bd2da53213d40754fd..9375d55e1496a275e219e2a8a4565a1fe20a32a5 100644 (file)
@@ -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
index 31aca7b0006281e3d79b3ab2f1590215bc5fa278..952e9d51a873e97c83bc586295a1277f241928f8 100644 (file)
@@ -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);
 
index 4943d6f75bd1905846e2c5d7f1884ae528b3da5e..d0a34a337561590af066034246927941987cf214 100644 (file)
@@ -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);
index 69af7b962ff3bc5e96e81db94361cc2ed32a809f..5287dbe1a308c9e0b2c9f288a3f1e06e31ea864a 100644 (file)
@@ -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, HASH_MAX_SPLITPOINTS, 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, HASH_MAX_BITMAPS, INT8OID));
 
    tuple = heap_form_tuple(tupleDesc, values, nulls);
 
index 3dd1a9bc2ab164c294c3e3e50290bf77400a1c7c..a654234c6bd7f261074a0eb7d9dbd47b3c58650c 100644 (file)
@@ -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);
 
index e9b7981619fb630e7df636b29f4ea5f3700d47d1..cbcc481a1722292818026d5158ae30f99d6181f5 100644 (file)
@@ -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]));
index 0536bfb8921c9b371991056f7d5e425b450ad945..d9b15b07b0f8194dca0b3722928f6a71db4b2eef 100644 (file)
@@ -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,
index 24211807ca1e31b6e5da6885379e6ed213442468..609329bb212b8687c197778e846c3c8b4f7a37ee 100644 (file)
@@ -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++)
    {
index 8377b4f7d4d1b87e31197fd4670eac5755ceb5e7..2d21db469012dfd30568a03eebf4109dfb30feb5 100644 (file)
@@ -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++)
index 489f0b2818ee7e5c0db4c2992df41bb41da038fb..bb65fb1e0ae28deb088bbc8a5f3f5cf37ac1389e 100644 (file)
@@ -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;
index 9644336dedcbb6637a326a3c05db3c36fc02155b..a9fe45e34714dd79117fab3f221caf9b44a48eda 100644 (file)
@@ -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;
index add51caadf2a1745b125d55001f5f1aba2d31db5..8856ce3b5017c76e2ac4112285283658693df693 100644 (file)
@@ -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;
index 2da6b75a155df3416d18df9c77b84d3b3555350b..07613c38b5cf4d566a968b7f65067a14c917c159 100644 (file)
@@ -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
index 46425278811b8f5e919eacb498aac3ba13f477a6..f46f86474aabc46bfff580430f46deeeb3735f69 100644 (file)
@@ -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));
 }
 
 /*
index 767d9b961904c7f8f4e09a2e802a4b9750f662e8..7b3aceee119c5ffd7ad4f30c56f8a011eea5c2d9 100644 (file)
@@ -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);
    }
index 00a6d282cfdb5635c0e902f1e85c530a416e8534..b016eecb2cd8b4d09337808d5ccfb9124dcf0dba 100644 (file)
@@ -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
    {
index a59ee3b947747258c9564452470b52eb25b66d82..d9dff9ecaabfdf6fec93e4bcb6f2c4a2407d7c30 100644 (file)
@@ -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. */
index 80738547ed80a8cdd259c785ae49cfc49db93104..633c9a40bbcb3d5874fd0f7e0d2398360ece2b70 100644 (file)
@@ -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);
 }
index 2e716743dd636ab24067fa360877b43b7e556e31..cd5e2f2b6b0e9b5e1df3cbab322931b1aa4030f4 100644 (file)
@@ -467,7 +467,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)
index 83e6eae855f9891026cc12979e87ee426a1f933b..e2852286a7dad222469919c53a8f60bf5b012bc6 100644 (file)
@@ -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);
 
index 9b92b0424206c9b143e9be2fe49b0ec00a896077..4f5e7c7ccb23ee66a3d6d6d4170f5d977e4b958c 100644 (file)
@@ -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 */
index 4116d1f3b583d1e9d21545a4985ccae0091b7c0c..a1c6325d64956a2d3a6cc5d404706d0a0e31f9f1 100644 (file)
@@ -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;
index 307114a30d682e866aaf722033947004ac214946..f7ad6894596edea72e2bedfc7303ad24aafc4567 100644 (file)
@@ -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);
index 1a64a522798919c7e1252867fd4446938740cbe8..f889726a28359790789f66840ebc26f46c78f2c5 100644 (file)
@@ -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++)
                {
index 6058d36e0d5ed5a9e8457f6f09535cb11be008d7..7fa2b2cba7f91d88d6d8dab1429d0b1e90f41a52 100644 (file)
@@ -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,
index ca48395d5c5a717a0161e54d9e7c5d12e9bb000a..7c02fb279ff3a118409dbadd76e2af5ea5f27cc1 100644 (file)
@@ -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
index 8dae2b8e99147a73fab07548013d7b3c755a416f..c6ea9f9269465b8a32c8f33d712ea266c887b018 100644 (file)
@@ -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)
index 2570e5e6301650322f5b9439bcf69f713ddf6e7a..b0c37ede87d2fb0159f3cf331837656d2af09b0d 100644 (file)
@@ -3330,6 +3330,92 @@ 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 by construct_array_builtin()", elmtype);
+           /* keep compiler quiet */
+           elmlen = 0;
+           elmbyval = false;
+           elmalign = 0;
+   }
+
+   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 +3569,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 +3634,75 @@ 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 by deconstruct_array_builtin()", elmtype);
+           /* keep compiler quiet */
+           elmlen = 0;
+           elmbyval = false;
+           elmalign = 0;
+   }
+
+   deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
+}
+
 /*
  * array_contains_nulls --- detect whether an array has any null elements
  *
index 464a37641e2addbd2836e67faa451b4723ba72cf..051169a149a32fbb0c7bf833140d7b2121f0c1c4 100644 (file)
@@ -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));
 
index 9fe7b62c9a0159d2b81ab6a4ad76c5f1a14b8257..598259718c439067b80167c07e1bb308affaa423 100644 (file)
@@ -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;
 }
index 553cc25eb9d6d598ba3e1513af835dabc09f7f11..5fdb7e32ce4459eeabf9a710991f4c4de3815e1a 100644 (file)
@@ -1450,9 +1450,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;
 
@@ -1526,13 +1524,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,
index 39355e242d22d46798cbb3137671b5283b4a8e6d..f700c5b4c93771b6b7d4ded011f89bbd1c3b7402 100644 (file)
@@ -1378,9 +1378,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;
 
@@ -1466,13 +1464,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,
index 5edf278cdb091d88b875ccc95eab4724cb2ddc76..c5325acde4fbb6fd2c52b887128a20c463881e2e 100644 (file)
@@ -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);
 
index ed37252e7f861377755abe62311e6d8c4bddd77b..202367e9964c1d876e7fc3b62c77378ca9fa5553 100644 (file)
@@ -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++)
    {
index d427bdfbe0de722b9823fd81ad9419545a82295e..9819e1a45ce63f1f47ecfbb1013c05dc08c6e13e 100644 (file)
@@ -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);
 
@@ -4370,8 +4368,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);
@@ -4523,8 +4520,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);
@@ -4635,8 +4631,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);
@@ -4681,8 +4676,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);
index 023a004ac899935c1c07c84924d944848e3ff4e5..dedee7af5cb767e2c9e5e383fd9ae62298dab464 100644 (file)
@@ -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));
 }
 
 
index e8bba3670cbd90689424f625f2bc19bf0a2f2b63..d22e1f277b479790bbf32d1dcba41b22ba37ea58 100644 (file)
@@ -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);
 }
index 6d4f6b7dca2349d2126517b81140d77fcfa65284..185b2cb848719d2b019efd98d881d7cf02546551 100644 (file)
@@ -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));
index 67b9675e92a4b3a9c74c1399bf01e66fbf37245c..65764d78a3d466e3d3920b6bfee4493c8bacee72 100644 (file)
@@ -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]);
index c3937a60fd35a181ec6e1087bcb11a73aa13acea..26cf4fa9a0e48d2978cf5a534e2065908e30cfc1 100644 (file)
@@ -2406,9 +2406,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++)
                    {
@@ -2531,9 +2530,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++)
@@ -2587,9 +2585,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++)
    {
@@ -12752,9 +12749,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++)
    {
index addc34915188adf57dfb191d6f06c532aee0971f..1786c18f895dadb887c1778941de6e2c8e26ec50 100644 (file)
@@ -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++)
    {
index 1ec6f1c2fd9356fe35b74af33d6d8adca33c3d22..60a85c46971395c5d72292d5ef654af179a89064 100644 (file)
@@ -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 */
index 3a9c9f0c50e52a3450a31294a9564afaa03f3417..f7f7165f7faefc28fa4f48cbdf0cbc2b654cb566 100644 (file)
@@ -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)
    {
index 9197b0f1e266cb5c609d719784753993fc51c3cc..a1fe50ffca8b44d10dc1d67a6fc8661b2fdd9457 100644 (file)
@@ -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);
    }
 
index a7cc49898b0289d9e76aeec05e1e7fd4085c2745..f640468f113a601f9719b9ddd5e0948b4541c8fa 100644 (file)
@@ -9974,7 +9974,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);
 }
 
@@ -11507,9 +11507,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;
 }
@@ -11576,9 +11574,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++;
    }
@@ -11644,9 +11640,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);
index 656c766a9a1decc37d1d75a34544aad771251999..2f794d116826220348419981a65b4aa8233c7616 100644 (file)
@@ -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,
index b8e0aa2d0b3f81114704add727d9bae635585407..fd2864130eb501c75a61199f5377b5aa68c8407c 100644 (file)
@@ -70,7 +70,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,
@@ -138,7 +138,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")),