From: Tom Lane Date: Thu, 18 Aug 2016 18:48:51 +0000 (-0400) Subject: In plpgsql, don't try to convert int2vector or oidvector to expanded array. X-Git-Tag: REL9_5_5~93 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8fc1950520985f321d4d07da9b1c633c0addd97;p=thirdparty%2Fpostgresql.git In plpgsql, don't try to convert int2vector or oidvector to expanded array. These types are storage-compatible with real arrays, but they don't support toasting, so of course they can't support expansion either. Per bug #14289 from Michael Overmeyer. Back-patch to 9.5 where expanded arrays were introduced. Report: <20160818174414.1529.37913@wrigleys.postgresql.org> --- diff --git a/src/include/utils/array.h b/src/include/utils/array.h index c25b80d272a..0f934b61738 100644 --- a/src/include/utils/array.h +++ b/src/include/utils/array.h @@ -36,7 +36,7 @@ * * The OIDVECTOR and INT2VECTOR datatypes are storage-compatible with * generic arrays, but they support only one-dimensional arrays with no - * nulls (and no null bitmap). + * nulls (and no null bitmap). They don't support being toasted, either. * * There are also some "fixed-length array" datatypes, such as NAME and * POINT. These are simply a sequence of a fixed number of items each diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 0ff20860f3b..53c150fa54c 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -2204,14 +2204,19 @@ build_datatype(HeapTuple typeTup, int32 typmod, Oid collation) /* NB: this is only used to decide whether to apply expand_array */ if (typeStruct->typtype == TYPTYPE_BASE) { - /* this test should match what get_element_type() checks */ + /* + * This test should include what get_element_type() checks. We also + * disallow non-toastable array types (i.e. oidvector and int2vector). + */ typ->typisarray = (typeStruct->typlen == -1 && - OidIsValid(typeStruct->typelem)); + OidIsValid(typeStruct->typelem) && + typeStruct->typstorage != 'p'); } else if (typeStruct->typtype == TYPTYPE_DOMAIN) { /* we can short-circuit looking up base types if it's not varlena */ typ->typisarray = (typeStruct->typlen == -1 && + typeStruct->typstorage != 'p' && OidIsValid(get_base_element_type(typeStruct->typbasetype))); } else