arrayelemhdr.patch
text/plain
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| contrib/hstore/hstore_gin.c | 1 | 1 |
| contrib/hstore/hstore_gist.c | 2 | 2 |
| contrib/hstore/hstore_io.c | 12 | 12 |
| contrib/hstore/hstore_op.c | 9 | 6 |
| contrib/ltree/lquery_op.c | 9 | 2 |
| contrib/ltree/_ltree_gist.c | 16 | 3 |
| contrib/ltree/ltree_gist.c | 13 | 2 |
| contrib/ltree/ltree.h | 24 | 0 |
| contrib/ltree/_ltree_op.c | 34 | 6 |
| src/backend/access/common/reloptions.c | 4 | 4 |
| src/backend/access/gin/ginarrayproc.c | 8 | 6 |
| src/backend/access/nbtree/nbtutils.c | 4 | 3 |
| src/backend/bootstrap/bootstrap.c | 99 | 0 |
| src/backend/catalog/objectaddress.c | 2 | 1 |
| src/backend/catalog/pg_attrdef.c | 2 | 1 |
| src/backend/commands/analyze.c | 2 | 1 |
| src/backend/commands/extension.c | 4 | 2 |
| src/backend/commands/tablecmds.c | 3 | 1 |
| src/backend/executor/execExpr.c | 5 | 4 |
| src/backend/executor/execExprInterp.c | 2 | 1 |
| src/backend/executor/nodeIndexscan.c | 4 | 3 |
| src/backend/optimizer/path/indxpath.c | 3 | 2 |
| src/backend/optimizer/util/predtest.c | 4 | 3 |
| src/backend/partitioning/partbounds.c | 5 | 2 |
| src/backend/partitioning/partprune.c | 4 | 3 |
| src/backend/statistics/extended_stats.c | 4 | 1 |
| src/backend/statistics/mcv.c | 4 | 3 |
| src/backend/utils/adt/array_expanded.c | 12 | 4 |
| src/backend/utils/adt/arrayfuncs.c | 206 | 129 |
| src/backend/utils/adt/array_selfuncs.c | 1 | 0 |
| src/backend/utils/adt/arraysubs.c | 16 | 8 |
| src/backend/utils/adt/array_typanalyze.c | 4 | 0 |
| src/backend/utils/adt/array_userfuncs.c | 31 | 16 |
| src/backend/utils/adt/enum.c | 1 | 1 |
| src/backend/utils/adt/jsonb.c | 4 | 3 |
| src/backend/utils/adt/json.c | 4 | 3 |
| src/backend/utils/adt/multirangetypes.c | 2 | 1 |
| src/backend/utils/adt/orderedsetaggs.c | 13 | 7 |
| src/backend/utils/adt/rangetypes.c | 1 | 4 |
| src/backend/utils/adt/regexp.c | 2 | 1 |
| src/backend/utils/adt/ruleutils.c | 1 | 0 |
| src/backend/utils/adt/selfuncs.c | 8 | 6 |
| src/backend/utils/adt/tsvector_op.c | 8 | 8 |
| src/backend/utils/adt/varlena.c | 5 | 7 |
| src/backend/utils/adt/xml.c | 4 | 2 |
| src/backend/utils/cache/lsyscache.c | 82 | 0 |
| src/backend/utils/cache/relcache.c | 1 | 0 |
| src/backend/utils/fmgr/funcapi.c | 4 | 3 |
| src/backend/utils/misc/guc.c | 10 | 3 |
| src/include/access/tupmacs.h | 29 | 0 |
| src/include/bootstrap/bootstrap.h | 6 | 0 |
| src/include/catalog/pg_type.h | 4 | 0 |
| src/include/commands/vacuum.h | 1 | 0 |
| src/include/executor/execExpr.h | 1 | 0 |
| src/include/utils/array.h | 20 | 11 |
| src/include/utils/lsyscache.h | 6 | 0 |
| src/include/utils/palloc.h | 6 | 0 |
| src/pl/plperl/plperl.c | 5 | 2 |
| src/pl/plpgsql/src/pl_exec.c | 3 | 1 |
| src/test/modules/test_regex/test_regex.c | 4 | 2 |
diff --git a/contrib/hstore/hstore_gin.c b/contrib/hstore/hstore_gin.c
index 766c00bb6a7..b6bd617df45 100644
--- a/contrib/hstore/hstore_gin.c
+++ b/contrib/hstore/hstore_gin.c
@@ -127,7 +127,7 @@ gin_extract_hstore_query(PG_FUNCTION_ARGS)
/* Nulls in the array are ignored, cf hstoreArrayToPairs */
if (key_nulls[i])
continue;
- item = makeitem(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, KEYFLAG);
+ item = makeitem(VARDATA_ANY(key_datums[i]), VARSIZE_ANY_EXHDR(key_datums[i]), KEYFLAG);
entries[j++] = PointerGetDatum(item);
}
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index a3b08af3850..9e330d7be4f 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -576,7 +576,7 @@ ghstore_consistent(PG_FUNCTION_ARGS)
if (key_nulls[i])
continue;
- crc = crc32_sz(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ);
+ crc = crc32_sz(VARDATA_ANY(key_datums[i]), VARSIZE_ANY_EXHDR(key_datums[i]));
if (!(GETBIT(sign, HASHVAL(crc, siglen))))
res = false;
}
@@ -599,7 +599,7 @@ ghstore_consistent(PG_FUNCTION_ARGS)
if (key_nulls[i])
continue;
- crc = crc32_sz(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ);
+ crc = crc32_sz(VARDATA_ANY(key_datums[i]), VARSIZE_ANY_EXHDR(key_datums[i]));
if (GETBIT(sign, HASHVAL(crc, siglen)))
res = true;
}
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index 2125436e40c..51461a6ec32 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -681,22 +681,22 @@ hstore_from_arrays(PG_FUNCTION_ARGS)
if (!value_nulls || value_nulls[i])
{
- pairs[i].key = VARDATA(key_datums[i]);
+ pairs[i].key = VARDATA_ANY(key_datums[i]);
pairs[i].val = NULL;
pairs[i].keylen =
- hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
+ hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(key_datums[i]));
pairs[i].vallen = 4;
pairs[i].isnull = true;
pairs[i].needfree = false;
}
else
{
- pairs[i].key = VARDATA(key_datums[i]);
- pairs[i].val = VARDATA(value_datums[i]);
+ pairs[i].key = VARDATA_ANY(key_datums[i]);
+ pairs[i].val = VARDATA_ANY(value_datums[i]);
pairs[i].keylen =
- hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
+ hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(key_datums[i]));
pairs[i].vallen =
- hstoreCheckValLen(VARSIZE(value_datums[i]) - VARHDRSZ);
+ hstoreCheckValLen(VARSIZE_ANY_EXHDR(value_datums[i]));
pairs[i].isnull = false;
pairs[i].needfree = false;
}
@@ -775,22 +775,22 @@ hstore_from_array(PG_FUNCTION_ARGS)
if (in_nulls[i * 2 + 1])
{
- pairs[i].key = VARDATA(in_datums[i * 2]);
+ pairs[i].key = VARDATA_ANY(in_datums[i * 2]);
pairs[i].val = NULL;
pairs[i].keylen =
- hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
+ hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(in_datums[i * 2]));
pairs[i].vallen = 4;
pairs[i].isnull = true;
pairs[i].needfree = false;
}
else
{
- pairs[i].key = VARDATA(in_datums[i * 2]);
- pairs[i].val = VARDATA(in_datums[i * 2 + 1]);
+ pairs[i].key = VARDATA_ANY(in_datums[i * 2]);
+ pairs[i].val = VARDATA_ANY(in_datums[i * 2 + 1]);
pairs[i].keylen =
- hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
+ hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(in_datums[i * 2]));
pairs[i].vallen =
- hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ);
+ hstoreCheckValLen(VARSIZE_ANY_EXHDR(in_datums[i * 2 + 1]));
pairs[i].isnull = false;
pairs[i].needfree = false;
}
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index 5e57eceffc8..da6aa12e8c4 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -107,8 +107,8 @@ hstoreArrayToPairs(ArrayType *a, int *npairs)
{
if (!key_nulls[i])
{
- key_pairs[j].key = VARDATA(key_datums[i]);
- key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ;
+ key_pairs[j].key = VARDATA_ANY(key_datums[i]);
+ key_pairs[j].keylen = VARSIZE_ANY_EXHDR(key_datums[i]);
key_pairs[j].val = NULL;
key_pairs[j].vallen = 0;
key_pairs[j].needfree = 0;
@@ -599,7 +599,7 @@ hstore_slice_to_array(PG_FUNCTION_ARGS)
if (key_nulls[i])
idx = -1;
else
- idx = hstoreFindKey(hs, NULL, VARDATA(key), VARSIZE(key) - VARHDRSZ);
+ idx = hstoreFindKey(hs, NULL, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
if (idx < 0 || HSTORE_VALISNULL(entries, idx))
{
@@ -619,7 +619,8 @@ hstore_slice_to_array(PG_FUNCTION_ARGS)
ARR_NDIM(key_array),
ARR_DIMS(key_array),
ARR_LBOUND(key_array),
- TEXTOID, -1, false, TYPALIGN_INT);
+ TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
PG_RETURN_POINTER(aout);
}
@@ -762,7 +763,8 @@ hstore_avals(PG_FUNCTION_ARGS)
}
a = construct_md_array(d, nulls, 1, &count, &lb,
- TEXTOID, -1, false, TYPALIGN_INT);
+ TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
PG_RETURN_POINTER(a);
}
@@ -814,7 +816,8 @@ hstore_to_array_internal(HStore *hs, int ndims)
return construct_md_array(out_datums, out_nulls,
ndims, out_size, lb,
- TEXTOID, -1, false, TYPALIGN_INT);
+ TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
}
PG_FUNCTION_INFO_V1(hstore_to_array);
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 286ad24fbe8..ce84ee89d8e 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -26,7 +26,7 @@ PG_FUNCTION_INFO_V1(_ltree_consistent);
PG_FUNCTION_INFO_V1(_ltree_gist_options);
#define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
-#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
+#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE_ANY(x) ) ) )
#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
@@ -60,6 +60,7 @@ _ltree_compress(PG_FUNCTION_ARGS)
ArrayType *val = DatumGetArrayTypeP(entry->key);
int num = ArrayGetNItems(ARR_NDIM(val), ARR_DIMS(val));
ltree *item = (ltree *) ARR_DATA_PTR(val);
+ ltree *newitem;
if (ARR_NDIM(val) > 1)
ereport(ERROR,
@@ -74,7 +75,10 @@ _ltree_compress(PG_FUNCTION_ARGS)
while (num > 0)
{
- hashing(LTG_SIGN(key), item, siglen);
+ newitem = (ltree *)ltree_norm_short_item((char *)item);
+
+ hashing(LTG_SIGN(key), newitem, siglen);
+ PFREE_IF_NEW(newitem, item);
num--;
item = NEXTVAL(item);
}
@@ -481,6 +485,7 @@ static bool
_arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
{
lquery *query = (lquery *) ARR_DATA_PTR(_query);
+ lquery *newqry;
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
if (ARR_NDIM(_query) > 1)
@@ -494,8 +499,16 @@ _arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
while (num > 0)
{
- if (gist_qe(key, query, siglen))
+ newqry = (lquery *)ltree_norm_short_item((char *)query);
+
+ if (gist_qe(key, newqry, siglen))
+ {
+ PFREE_IF_NEW(newqry, query);
return true;
+ }
+
+ PFREE_IF_NEW(newqry, query);
+
num--;
query = (lquery *) NEXTVAL(query);
}
diff --git a/contrib/ltree/_ltree_op.c b/contrib/ltree/_ltree_op.c
index b4a8097328d..274f8c6bd79 100644
--- a/contrib/ltree/_ltree_op.c
+++ b/contrib/ltree/_ltree_op.c
@@ -32,13 +32,14 @@ PG_FUNCTION_INFO_V1(_lca);
typedef Datum (*PGCALL2) (PG_FUNCTION_ARGS);
-#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
+#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE_ANY(x) ) ) )
static bool
array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
{
int num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
ltree *item = (ltree *) ARR_DATA_PTR(la);
+ ltree *newitem;
if (ARR_NDIM(la) > 1)
ereport(ERROR,
@@ -53,14 +54,20 @@ array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
*found = NULL;
while (num > 0)
{
+ newitem = (ltree *)ltree_norm_short_item((char *)item);
+
if (DatumGetBool(DirectFunctionCall2(callback,
- PointerGetDatum(item), PointerGetDatum(param))))
+ PointerGetDatum(newitem), PointerGetDatum(param))))
{
+ PFREE_IF_NEW(newitem, item);
if (found)
*found = item;
return true;
}
+
+ PFREE_IF_NEW(newitem, item);
+
num--;
item = NEXTVAL(item);
}
@@ -137,6 +144,7 @@ _lt_q_regex(PG_FUNCTION_ARGS)
ArrayType *_tree = PG_GETARG_ARRAYTYPE_P(0);
ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
lquery *query = (lquery *) ARR_DATA_PTR(_query);
+ lquery *newqry;
bool res = false;
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
@@ -151,11 +159,18 @@ _lt_q_regex(PG_FUNCTION_ARGS)
while (num > 0)
{
- if (array_iterator(_tree, ltq_regex, query, NULL))
+ newqry = (lquery *)ltree_norm_short_item((char *)query);
+
+ if (array_iterator(_tree, ltq_regex, newqry, NULL))
{
+ PFREE_IF_NEW(newqry, query);
+
res = true;
break;
}
+
+ PFREE_IF_NEW(newqry, query);
+
num--;
query = (lquery *) NEXTVAL(query);
}
@@ -297,6 +312,8 @@ _lca(PG_FUNCTION_ARGS)
ltree *item = (ltree *) ARR_DATA_PTR(la);
ltree **a,
*res;
+ int i;
+ bool *copied;
if (ARR_NDIM(la) > 1)
ereport(ERROR,
@@ -308,14 +325,25 @@ _lca(PG_FUNCTION_ARGS)
errmsg("array must not contain nulls")));
a = (ltree **) palloc(sizeof(ltree *) * num);
- while (num > 0)
+ copied = (bool *)palloc(sizeof(bool) * num);
+
+ for (i = 0; i < num; i++)
{
- num--;
- a[num] = item;
+ a[i] = (ltree *)ltree_norm_short_item((char *)item);
+ copied[i] = (a[i] != item);
item = NEXTVAL(item);
}
+
res = lca_inner(a, ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la)));
+
+ for (i = 0; i < num; i++)
+ {
+ if (copied[i])
+ pfree(a[i]);
+ }
+
pfree(a);
+ pfree(copied);
PG_FREE_IF_COPY(la, 0);
diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c
index a6466f575fd..a55ee51de04 100644
--- a/contrib/ltree/lquery_op.c
+++ b/contrib/ltree/lquery_op.c
@@ -19,7 +19,7 @@ PG_FUNCTION_INFO_V1(ltq_rregex);
PG_FUNCTION_INFO_V1(lt_q_regex);
PG_FUNCTION_INFO_V1(lt_q_rregex);
-#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
+#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE_ANY(x) ) ) )
static char *
getlexeme(char *start, char *end, int *len)
@@ -241,6 +241,7 @@ lt_q_regex(PG_FUNCTION_ARGS)
ltree *tree = PG_GETARG_LTREE_P(0);
ArrayType *_query = PG_GETARG_ARRAYTYPE_P(1);
lquery *query = (lquery *) ARR_DATA_PTR(_query);
+ lquery *newqry;
bool res = false;
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
@@ -255,13 +256,19 @@ lt_q_regex(PG_FUNCTION_ARGS)
while (num > 0)
{
+ newqry = (lquery *)ltree_norm_short_item((char *)query);
+
if (DatumGetBool(DirectFunctionCall2(ltq_regex,
- PointerGetDatum(tree), PointerGetDatum(query))))
+ PointerGetDatum(tree), PointerGetDatum(newqry))))
{
+ PFREE_IF_NEW(newqry, query);
res = true;
break;
}
+
+ PFREE_IF_NEW(newqry, query);
+
num--;
query = NEXTVAL(query);
}
diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h
index 5e0761641d3..28075bd3498 100644
--- a/contrib/ltree/ltree.h
+++ b/contrib/ltree/ltree.h
@@ -6,6 +6,7 @@
#include "fmgr.h"
#include "tsearch/ts_locale.h"
#include "utils/memutils.h"
+#include "varatt.h"
/* ltree */
@@ -212,6 +213,29 @@ bool compare_subnode(ltree_level *t, char *qn, int len,
ltree *lca_inner(ltree **a, int len);
int ltree_strncasecmp(const char *a, const char *b, size_t s);
+/* normalize ltree/lquery in array if it is short version. */
+static inline char*
+ltree_norm_short_item(char *item)
+{
+ if (VARATT_IS_SHORT(item))
+ {
+ /*
+ * This is a short-header varlena --- convert to 4-byte header format
+ */
+ char *newitem;
+ Size data_size = VARSIZE_SHORT(item) - VARHDRSZ_SHORT;
+ Size new_size = data_size + VARHDRSZ;
+
+ newitem = palloc(new_size);
+ SET_VARSIZE(newitem, new_size);
+ memcpy(VARDATA(newitem), VARDATA_SHORT(item), data_size);
+
+ return newitem;
+ }
+ else
+ return item;
+}
+
/* fmgr macros for ltree objects */
#define DatumGetLtreeP(X) ((ltree *) PG_DETOAST_DATUM(X))
#define DatumGetLtreePCopy(X) ((ltree *) PG_DETOAST_DATUM_COPY(X))
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 932f69bff2d..5733d5a1c2d 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -12,7 +12,7 @@
#include "ltree.h"
#include "utils/array.h"
-#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
+#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE_ANY(x) ) ) )
#define ISEQ(a,b) ( (a)->numlevel == (b)->numlevel && ltree_compare(a,b)==0 )
PG_FUNCTION_INFO_V1(ltree_gist_in);
@@ -592,6 +592,7 @@ static bool
arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
{
lquery *query = (lquery *) ARR_DATA_PTR(_query);
+ lquery *newqry;
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
if (ARR_NDIM(_query) > 1)
@@ -605,11 +606,21 @@ arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
while (num > 0)
{
- if (gist_qe(key, query, siglen) && gist_between(key, query, siglen))
+ newqry = (lquery *)ltree_norm_short_item((char *)query);
+
+ if (gist_qe(key, newqry, siglen) && gist_between(key, newqry, siglen))
+ {
+ PFREE_IF_NEW(newqry, query);
+
return true;
+ }
+
+ PFREE_IF_NEW(newqry, query);
+
num--;
query = NEXTVAL(query);
}
+
return false;
}
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 49fd35bfc55..26e31a583a4 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -1179,8 +1179,8 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
for (i = 0; i < noldoptions; i++)
{
- char *text_str = VARDATA(oldoptions[i]);
- int text_len = VARSIZE(oldoptions[i]) - VARHDRSZ;
+ char *text_str = VARDATA_ANY(oldoptions[i]);
+ int text_len = VARSIZE_ANY_EXHDR(oldoptions[i]);
/* Search for a match in defList */
foreach(cell, defList)
@@ -1436,8 +1436,8 @@ parseRelOptionsInternal(Datum options, bool validate,
for (i = 0; i < noptions; i++)
{
- char *text_str = VARDATA(optiondatums[i]);
- int text_len = VARSIZE(optiondatums[i]) - VARHDRSZ;
+ char *text_str = VARDATA_ANY(optiondatums[i]);
+ int text_len = VARSIZE_ANY_EXHDR(optiondatums[i]);
int j;
/* Search for a match in reloptions */
diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index 2373e76f77e..b8311d21858 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -39,16 +39,17 @@ ginarrayextract(PG_FUNCTION_ARGS)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
Datum *elems;
bool *nulls;
int nelems;
- get_typlenbyvalalign(ARR_ELEMTYPE(array),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(array),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(array,
ARR_ELEMTYPE(array),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elems, &nulls, &nelems);
*nkeys = nelems;
@@ -90,16 +91,17 @@ ginqueryarrayextract(PG_FUNCTION_ARGS)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
Datum *elems;
bool *nulls;
int nelems;
- get_typlenbyvalalign(ARR_ELEMTYPE(array),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(array),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(array,
ARR_ELEMTYPE(array),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elems, &nulls, &nelems);
*nkeys = nelems;
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index a531d37908a..c3aa979c572 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -340,6 +340,7 @@ _bt_preprocess_array_keys(IndexScanDesc scan, int *new_numberOfKeys)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int num_elems;
Datum *elem_values;
bool *elem_nulls;
@@ -364,11 +365,11 @@ _bt_preprocess_array_keys(IndexScanDesc scan, int *new_numberOfKeys)
*/
arrayval = DatumGetArrayTypeP(cur->sk_argument);
/* We could cache this data, but not clear it's worth it */
- get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(arrayval),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(arrayval,
ARR_ELEMTYPE(arrayval),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elem_values, &elem_nulls, &num_elems);
/*
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index e0cb70ee9da..79ebac5b78c 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -903,6 +903,105 @@ boot_get_type_io_data(Oid typid,
}
}
+/* ----------------
+ * boot_array_type_metadata
+ *
+ * Obtain type metadata at bootstrap time. This intentionally has
+ * almost the same API as lsyscache.c's array_type_metadata, except that
+ * we only support obtaining the typinput and typoutput routines, not
+ * the binary I/O routines. It is exported so that array_in and array_out
+ * can be made to work during early bootstrap.
+ * ----------------
+ */
+void
+boot_array_type_metadata(Oid typid,
+ IOFuncSelector which_func,
+ ArrayMetaState *metadata)
+{
+ if (Typ != NIL)
+ {
+ /* We have the boot-time contents of pg_type, so use it */
+ struct typmap *ap = NULL;
+ ListCell *lc;
+
+ foreach(lc, Typ)
+ {
+ ap = lfirst(lc);
+ if (ap->am_oid == typid)
+ break;
+ }
+
+ if (!ap || ap->am_oid != typid)
+ elog(ERROR, "type OID %u not found in Typ list", typid);
+
+ metadata->typlen = ap->am_typ.typlen;
+ metadata->typbyval = ap->am_typ.typbyval;
+ metadata->typalign = ap->am_typ.typalign;
+ metadata->typstorage = ap->am_typ.typstorage;
+ metadata->typdelim = ap->am_typ.typdelim;
+
+ /* XXX this logic must match getTypeIOParam() */
+ if (OidIsValid(ap->am_typ.typelem))
+ metadata->typioparam = ap->am_typ.typelem;
+ else
+ metadata->typioparam = typid;
+
+ switch (which_func)
+ {
+ case IOFunc_input:
+ metadata->typiofunc = ap->am_typ.typinput;
+ break;
+ case IOFunc_output:
+ metadata->typiofunc = ap->am_typ.typoutput;
+ break;
+ default:
+ elog(ERROR, "binary I/O not supported during bootstrap");
+ break;
+ }
+
+ return;
+ }
+ else
+ {
+ /* We don't have pg_type yet, so use the hard-wired TypInfo array */
+ int typeindex;
+
+ for (typeindex = 0; typeindex < n_types; typeindex++)
+ {
+ if (TypInfo[typeindex].oid == typid)
+ break;
+ }
+ if (typeindex >= n_types)
+ elog(ERROR, "type OID %u not found in TypInfo", typid);
+
+ metadata->typlen = TypInfo[typeindex].len;
+ metadata->typbyval = TypInfo[typeindex].byval;
+ metadata->typalign = TypInfo[typeindex].align;
+ metadata->typstorage = TypInfo[typeindex].storage;
+ /* We assume typdelim is ',' for all boot-time types */
+ metadata->typdelim = ',';
+
+ /* XXX this logic must match getTypeIOParam() */
+ if (OidIsValid(TypInfo[typeindex].elem))
+ metadata->typioparam = TypInfo[typeindex].elem;
+ else
+ metadata->typioparam = typid;
+
+ switch (which_func)
+ {
+ case IOFunc_input:
+ metadata->typiofunc = TypInfo[typeindex].inproc;
+ break;
+ case IOFunc_output:
+ metadata->typiofunc = TypInfo[typeindex].outproc;
+ break;
+ default:
+ elog(ERROR, "binary I/O not supported during bootstrap");
+ break;
+ }
+ }
+}
+
/* ----------------
* AllocateAttribute
*
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index be7e4a5dd01..c9e6bf73872 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -6126,7 +6126,8 @@ strlist_to_textarray(List *list)
lb[0] = 1;
arr = construct_md_array(datums, nulls, 1, &j,
- lb, TEXTOID, -1, false, TYPALIGN_INT);
+ lb, TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
MemoryContextDelete(memcxt);
diff --git a/src/backend/catalog/pg_attrdef.c b/src/backend/catalog/pg_attrdef.c
index 003ae70b4d2..ce73000e4c7 100644
--- a/src/backend/catalog/pg_attrdef.c
+++ b/src/backend/catalog/pg_attrdef.c
@@ -148,7 +148,8 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
defAttStruct->atttypid,
defAttStruct->attlen,
defAttStruct->attbyval,
- defAttStruct->attalign));
+ defAttStruct->attalign,
+ defAttStruct->attstorage));
}
valuesAtt[Anum_pg_attribute_atthasmissing - 1] = !missingIsNull;
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 9a56de2282f..ba449b2c495 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1721,7 +1721,8 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
stats->statypid[k],
stats->statyplen[k],
stats->statypbyval[k],
- stats->statypalign[k]);
+ stats->statypalign[k],
+ stats->statypstorage[k]);
values[i++] = PointerGetDatum(arry); /* stavaluesN */
}
else
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index e683c520a82..b51348d65ce 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2654,7 +2654,8 @@ pg_extension_config_dump(PG_FUNCTION_ARGS)
-1 /* varlena array */ ,
sizeof(Oid) /* OID's typlen */ ,
true /* OID's typbyval */ ,
- TYPALIGN_INT /* OID's typalign */ );
+ TYPALIGN_INT /* OID's typalign */,
+ TYPSTORAGE_PLAIN /* OID's typstorage */ );
}
repl_val[Anum_pg_extension_extconfig - 1] = PointerGetDatum(a);
repl_repl[Anum_pg_extension_extconfig - 1] = true;
@@ -2690,7 +2691,8 @@ pg_extension_config_dump(PG_FUNCTION_ARGS)
-1 /* varlena array */ ,
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
- TYPALIGN_INT /* TEXT's typalign */ );
+ TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typstorage */ );
}
repl_val[Anum_pg_extension_extcondition - 1] = PointerGetDatum(a);
repl_repl[Anum_pg_extension_extcondition - 1] = true;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 49374782625..b4840d60e0a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -13750,13 +13750,15 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
attTup->attlen,
attTup->attbyval,
attTup->attalign,
+ attTup->attstorage,
&isNull);
missingval = PointerGetDatum(construct_array(&missingval,
1,
targettype,
tform->typlen,
tform->typbyval,
- tform->typalign));
+ tform->typalign,
+ tform->typstorage));
valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval;
replacesAtt[Anum_pg_attribute_attmissingval - 1] = true;
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 3d01a90bd64..5d73e2b21b0 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -1886,10 +1886,11 @@ ExecInitExprRec(Expr *node, ExprState *state,
scratch.d.arrayexpr.elemtype = arrayexpr->element_typeid;
/* do one-time catalog lookup for type info */
- get_typlenbyvalalign(arrayexpr->element_typeid,
- &scratch.d.arrayexpr.elemlength,
- &scratch.d.arrayexpr.elembyval,
- &scratch.d.arrayexpr.elemalign);
+ get_type_stores(arrayexpr->element_typeid,
+ &scratch.d.arrayexpr.elemlength,
+ &scratch.d.arrayexpr.elembyval,
+ &scratch.d.arrayexpr.elemalign,
+ &scratch.d.arrayexpr.elemstorage);
/* prepare to evaluate all arguments */
elemoff = 0;
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index d2987663e63..9de7f7b523b 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -3211,7 +3211,8 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
element_type,
op->d.arrayexpr.elemlength,
op->d.arrayexpr.elembyval,
- op->d.arrayexpr.elemalign);
+ op->d.arrayexpr.elemalign,
+ op->d.arrayexpr.elemstorage);
}
else
{
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 8000feff4c9..7a33d697c35 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -678,6 +678,7 @@ ExecIndexEvalArrayKeys(ExprContext *econtext,
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int num_elems;
Datum *elem_values;
bool *elem_nulls;
@@ -696,11 +697,11 @@ ExecIndexEvalArrayKeys(ExprContext *econtext,
}
arrayval = DatumGetArrayTypeP(arraydatum);
/* We could cache this data, but not clear it's worth it */
- get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(arrayval),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(arrayval,
ARR_ELEMTYPE(arrayval),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elem_values, &elem_nulls, &num_elems);
if (num_elems <= 0)
{
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 5d102a0d371..83ee95a2656 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -3428,11 +3428,12 @@ match_orclause_to_indexcol(PlannerInfo *root,
int16 typlen;
bool typbyval;
char typalign;
+ char typstor;
Datum *elems;
int i = 0;
ArrayType *arrayConst;
- get_typlenbyvalalign(consttype, &typlen, &typbyval, &typalign);
+ get_type_stores(consttype, &typlen, &typbyval, &typalign, &typstor);
elems = (Datum *) palloc(sizeof(Datum) * list_length(consts));
foreach_node(Const, value, consts)
@@ -3443,7 +3444,7 @@ match_orclause_to_indexcol(PlannerInfo *root,
}
arrayConst = construct_array(elems, i, consttype,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
arrayNode = (Node *) makeConst(arraytype, -1, inputcollid,
-1, PointerGetDatum(arrayConst),
false, false);
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 0a132610140..20e7dd220f0 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -965,6 +965,7 @@ arrayconst_startup_fn(Node *clause, PredIterInfo info)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
/* Create working state struct */
state = (ArrayConstIterState *) palloc(sizeof(ArrayConstIterState));
@@ -973,11 +974,11 @@ arrayconst_startup_fn(Node *clause, PredIterInfo info)
/* Deconstruct the array literal */
arrayconst = (Const *) lsecond(saop->args);
arrayval = DatumGetArrayTypeP(arrayconst->constvalue);
- get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(arrayval),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(arrayval,
ARR_ELEMTYPE(arrayval),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&state->elem_values, &state->elem_nulls,
&state->num_elems);
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index c28639d2e3f..3064c943254 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -4778,6 +4778,7 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
int16 variadic_typlen;
bool variadic_typbyval;
char variadic_typalign;
+ char variadic_typstorage;
Oid partcollid[PARTITION_MAX_KEYS];
FmgrInfo partsupfunc[FLEXIBLE_ARRAY_MEMBER];
} ColumnsHashData;
@@ -4881,10 +4882,11 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
my_extra->relid = parentId;
my_extra->nkeys = key->partnatts;
my_extra->variadic_type = ARR_ELEMTYPE(variadic_array);
- get_typlenbyvalalign(my_extra->variadic_type,
+ get_type_stores(my_extra->variadic_type,
&my_extra->variadic_typlen,
&my_extra->variadic_typbyval,
- &my_extra->variadic_typalign);
+ &my_extra->variadic_typalign,
+ &my_extra->variadic_typstorage);
my_extra->partcollid[0] = key->partcollation[0];
/* check argument types */
@@ -4949,6 +4951,7 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
my_extra->variadic_typlen,
my_extra->variadic_typbyval,
my_extra->variadic_typalign,
+ my_extra->variadic_typstorage,
&datum, &isnull, &nelems);
/* complain if wrong number of column values */
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 4e12ae5d1e3..faf825b9cd5 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -2280,6 +2280,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
int16 elemlen;
bool elembyval;
char elemalign;
+ char elemstor;
Datum *elem_values;
bool *elem_nulls;
int num_elems,
@@ -2290,11 +2291,11 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
return PARTCLAUSE_MATCH_CONTRADICT;
arrval = DatumGetArrayTypeP(arr->constvalue);
- get_typlenbyvalalign(ARR_ELEMTYPE(arrval),
- &elemlen, &elembyval, &elemalign);
+ get_type_stores(ARR_ELEMTYPE(arrval),
+ &elemlen, &elembyval, &elemalign, &elemstor);
deconstruct_array(arrval,
ARR_ELEMTYPE(arrval),
- elemlen, elembyval, elemalign,
+ elemlen, elembyval, elemalign, elemstor,
&elem_values, &elem_nulls,
&num_elems);
for (i = 0; i < num_elems; i++)
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 99fdf208dba..3c1335fd707 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -575,6 +575,7 @@ examine_attribute(Node *expr)
stats->statyplen[i] = stats->attrtype->typlen;
stats->statypbyval[i] = stats->attrtype->typbyval;
stats->statypalign[i] = stats->attrtype->typalign;
+ stats->statypstorage[i] = stats->attrtype->typstorage;
}
/*
@@ -660,6 +661,7 @@ examine_expression(Node *expr, int stattarget)
stats->statyplen[i] = stats->attrtype->typlen;
stats->statypbyval[i] = stats->attrtype->typbyval;
stats->statypalign[i] = stats->attrtype->typalign;
+ stats->statypstorage[i] = stats->attrtype->typstorage;
}
/*
@@ -2393,7 +2395,8 @@ serialize_expr_stats(AnlExprData *exprdata, int nexprs)
stats->statypid[k],
stats->statyplen[k],
stats->statypbyval[k],
- stats->statypalign[k]);
+ stats->statypalign[k],
+ stats->statypstorage[k]);
values[i++] = PointerGetDatum(arry); /* stavaluesN */
}
else
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index b0e9aead84e..c2fddf69526 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -1724,6 +1724,7 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int num_elems;
Datum *elem_values;
bool *elem_nulls;
@@ -1745,11 +1746,11 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses,
if (!cst->constisnull)
{
arrayval = DatumGetArrayTypeP(cst->constvalue);
- get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(arrayval),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(arrayval,
ARR_ELEMTYPE(arrayval),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elem_values, &elem_nulls, &num_elems);
}
diff --git a/src/backend/utils/adt/array_expanded.c b/src/backend/utils/adt/array_expanded.c
index cc3713b97b7..9882f1e0df8 100644
--- a/src/backend/utils/adt/array_expanded.c
+++ b/src/backend/utils/adt/array_expanded.c
@@ -92,6 +92,7 @@ expand_array(Datum arraydatum, MemoryContext parentcontext,
metacache->typlen = oldeah->typlen;
metacache->typbyval = oldeah->typbyval;
metacache->typalign = oldeah->typalign;
+ metacache->typstorage = oldeah->typstorage;
/*
* If element type is pass-by-value and we have a Datum-array
@@ -144,14 +145,17 @@ expand_array(Datum arraydatum, MemoryContext parentcontext,
eah->typlen = metacache->typlen;
eah->typbyval = metacache->typbyval;
eah->typalign = metacache->typalign;
+ eah->typstorage = metacache->typstorage;
}
else
{
/* No, so look it up */
- get_typlenbyvalalign(eah->element_type,
+ get_type_stores(eah->element_type,
&eah->typlen,
&eah->typbyval,
- &eah->typalign);
+ &eah->typalign,
+ &eah->typstorage);
+
/* Update cache if provided */
if (metacache)
{
@@ -159,6 +163,7 @@ expand_array(Datum arraydatum, MemoryContext parentcontext,
metacache->typlen = eah->typlen;
metacache->typbyval = eah->typbyval;
metacache->typalign = eah->typalign;
+ metacache->typstorage = eah->typstorage;
}
}
@@ -203,6 +208,7 @@ copy_byval_expanded_array(ExpandedArrayHeader *eah,
eah->typlen = oldeah->typlen;
eah->typbyval = oldeah->typbyval;
eah->typalign = oldeah->typalign;
+ eah->typstorage = oldeah->typstorage;
/* Copy the deconstructed representation */
eah->dvalues = (Datum *) MemoryContextAlloc(objcxt,
@@ -333,7 +339,7 @@ EA_flatten_into(ExpandedObjectHeader *eohptr,
CopyArrayEls(aresult,
eah->dvalues, eah->dnulls, nelems,
- eah->typlen, eah->typbyval, eah->typalign,
+ eah->typlen, eah->typbyval, eah->typalign, eah->typstorage,
false);
}
@@ -384,6 +390,7 @@ DatumGetExpandedArrayX(Datum d, ArrayMetaState *metacache)
metacache->typlen = eah->typlen;
metacache->typbyval = eah->typbyval;
metacache->typalign = eah->typalign;
+ metacache->typstorage = eah->typstorage;
}
return eah;
}
@@ -433,7 +440,8 @@ deconstruct_expanded_array(ExpandedArrayHeader *eah)
dnulls = NULL;
deconstruct_array(eah->fvalue,
eah->element_type,
- eah->typlen, eah->typbyval, eah->typalign,
+ eah->typlen, eah->typbyval,
+ eah->typalign, eah->typstorage,
&dvalues,
ARR_HASNULL(eah->fvalue) ? &dnulls : NULL,
&nelems);
diff --git a/src/backend/utils/adt/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c
index e2af89f5cc5..d1857fa66f3 100644
--- a/src/backend/utils/adt/array_selfuncs.c
+++ b/src/backend/utils/adt/array_selfuncs.c
@@ -448,6 +448,7 @@ mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry,
typentry->typlen,
typentry->typbyval,
typentry->typalign,
+ typentry->typstorage,
&elem_values, &elem_nulls, &num_elems);
/* Collapse out any null elements */
diff --git a/src/backend/utils/adt/array_typanalyze.c b/src/backend/utils/adt/array_typanalyze.c
index 2c633bee6b1..148197694b0 100644
--- a/src/backend/utils/adt/array_typanalyze.c
+++ b/src/backend/utils/adt/array_typanalyze.c
@@ -42,6 +42,7 @@ typedef struct
bool typbyval; /* physical properties of element type */
int16 typlen;
char typalign;
+ char typstorage;
/*
* Lookup data for element type's comparison and hash functions (these are
@@ -139,6 +140,7 @@ array_typanalyze(PG_FUNCTION_ARGS)
extra_data->typbyval = typentry->typbyval;
extra_data->typlen = typentry->typlen;
extra_data->typalign = typentry->typalign;
+ extra_data->typstorage = typentry->typstorage;
extra_data->cmp = &typentry->cmp_proc_finfo;
extra_data->hash = &typentry->hash_proc_finfo;
@@ -340,6 +342,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
extra_data->typlen,
extra_data->typbyval,
extra_data->typalign,
+ extra_data->typstorage,
&elem_values, &elem_nulls, &num_elems);
/*
@@ -568,6 +571,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc,
stats->statyplen[slot_idx] = extra_data->typlen;
stats->statypbyval[slot_idx] = extra_data->typbyval;
stats->statypalign[slot_idx] = extra_data->typalign;
+ stats->statypstorage[slot_idx] = extra_data->typstorage;
slot_idx++;
}
diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c
index 304a93112e2..2d533a59185 100644
--- a/src/backend/utils/adt/array_userfuncs.c
+++ b/src/backend/utils/adt/array_userfuncs.c
@@ -161,8 +161,9 @@ array_append(PG_FUNCTION_ARGS)
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
result = array_set_element(EOHPGetRWDatum(&eah->hdr),
- 1, &indx, newelem, isNull,
- -1, my_extra->typlen, my_extra->typbyval, my_extra->typalign);
+ 1, &indx, newelem, isNull, -1,
+ my_extra->typlen, my_extra->typbyval,
+ my_extra->typalign, my_extra->typstorage);
PG_RETURN_DATUM(result);
}
@@ -216,8 +217,9 @@ array_prepend(PG_FUNCTION_ARGS)
my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
result = array_set_element(EOHPGetRWDatum(&eah->hdr),
- 1, &indx, newelem, isNull,
- -1, my_extra->typlen, my_extra->typbyval, my_extra->typalign);
+ 1, &indx, newelem, isNull, -1,
+ my_extra->typlen, my_extra->typbyval,
+ my_extra->typalign, my_extra->typstorage);
/* Readjust result's LB to match the input's, as expected for prepend */
Assert(result == EOHPGetRWDatum(&eah->hdr));
@@ -654,6 +656,9 @@ array_agg_serialize(PG_FUNCTION_ARGS)
/* typalign */
pq_sendbyte(&buf, state->typalign);
+ /* typstorage */
+ pq_sendbyte(&buf, state->typstorage);
+
/* dnulls */
pq_sendbytes(&buf, state->dnulls, sizeof(bool) * state->nelems);
@@ -749,6 +754,9 @@ array_agg_deserialize(PG_FUNCTION_ARGS)
/* typalign */
result->typalign = pq_getmsgbyte(&buf);
+ /* typstorage */
+ result->typstorage = pq_getmsgbyte(&buf);
+
/* dnulls */
temp = pq_getmsgbytes(&buf, sizeof(bool) * nelems);
memcpy(result->dnulls, temp, sizeof(bool) * nelems);
@@ -1321,10 +1329,11 @@ array_position_common(FunctionCallInfo fcinfo)
if (my_extra->element_type != element_type)
{
- get_typlenbyvalalign(element_type,
- &my_extra->typlen,
- &my_extra->typbyval,
- &my_extra->typalign);
+ get_type_stores(element_type,
+ &my_extra->typlen,
+ &my_extra->typbyval,
+ &my_extra->typalign,
+ &my_extra->typstorage);
typentry = lookup_type_cache(element_type, TYPECACHE_EQ_OPR_FINFO);
@@ -1464,10 +1473,12 @@ array_positions(PG_FUNCTION_ARGS)
if (my_extra->element_type != element_type)
{
- get_typlenbyvalalign(element_type,
- &my_extra->typlen,
- &my_extra->typbyval,
- &my_extra->typalign);
+ get_type_stores(element_type,
+ &my_extra->typlen,
+ &my_extra->typbyval,
+ &my_extra->typalign,
+ &my_extra->typstorage);
+
typentry = lookup_type_cache(element_type, TYPECACHE_EQ_OPR_FINFO);
@@ -1548,6 +1559,7 @@ array_shuffle_n(ArrayType *array, int n, bool keep_lb,
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
Datum *elms,
*ielms;
bool *nuls,
@@ -1560,12 +1572,13 @@ array_shuffle_n(ArrayType *array, int n, bool keep_lb,
elmlen = typentry->typlen;
elmbyval = typentry->typbyval;
elmalign = typentry->typalign;
+ elmstor = typentry->typstorage;
/* If the target array is empty, exit fast */
if (ndim < 1 || dims[0] < 1 || n < 1)
return construct_empty_array(elmtyp);
- deconstruct_array(array, elmtyp, elmlen, elmbyval, elmalign,
+ deconstruct_array(array, elmtyp, elmlen, elmbyval, elmalign, elmstor,
&elms, &nuls, &nelm);
nitem = dims[0]; /* total number of items */
@@ -1608,7 +1621,7 @@ array_shuffle_n(ArrayType *array, int n, bool keep_lb,
rlbs[0] = 1;
result = construct_md_array(elms, nuls, ndim, rdims, rlbs,
- elmtyp, elmlen, elmbyval, elmalign);
+ elmtyp, elmlen, elmbyval, elmalign, elmstor);
pfree(elms);
pfree(nuls);
@@ -1709,6 +1722,7 @@ array_reverse_n(ArrayType *array, Oid elmtyp, TypeCacheEntry *typentry)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
Datum *elms,
*ielms;
bool *nuls,
@@ -1721,8 +1735,9 @@ array_reverse_n(ArrayType *array, Oid elmtyp, TypeCacheEntry *typentry)
elmlen = typentry->typlen;
elmbyval = typentry->typbyval;
elmalign = typentry->typalign;
+ elmstor = typentry->typstorage;
- deconstruct_array(array, elmtyp, elmlen, elmbyval, elmalign,
+ deconstruct_array(array, elmtyp, elmlen, elmbyval, elmalign, elmstor,
&elms, &nuls, &nelm);
nitem = dims[0]; /* total number of items */
@@ -1756,7 +1771,7 @@ array_reverse_n(ArrayType *array, Oid elmtyp, TypeCacheEntry *typentry)
rdims[0] = nitem;
result = construct_md_array(elms, nuls, ndim, rdims, rlbs,
- elmtyp, elmlen, elmbyval, elmalign);
+ elmtyp, elmlen, elmbyval, elmalign, elmstor);
pfree(elms);
pfree(nuls);
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 593775c27f3..f8dad59c27f 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -74,6 +74,7 @@ typedef struct ArrayIteratorData
int16 typlen; /* element type's length */
bool typbyval; /* element type's byval property */
char typalign; /* element type's align property */
+ char typstorage; /* element type's storage property */
/* information about the requested slice size */
int slice_ndim; /* slice dimension, or 0 if not slicing */
@@ -105,46 +106,51 @@ static ArrayToken ReadArrayToken(char **srcptr, StringInfo elembuf, char typdeli
const char *origStr, Node *escontext);
static void ReadArrayBinary(StringInfo buf, int nitems,
FmgrInfo *receiveproc, Oid typioparam, int32 typmod,
- int typlen, bool typbyval, char typalign,
+ int typlen, bool typbyval, char typalign, char typstor,
Datum *values, bool *nulls,
bool *hasnulls, int32 *nbytes);
static Datum array_get_element_expanded(Datum arraydatum,
int nSubscripts, int *indx,
int arraytyplen,
- int elmlen, bool elmbyval, char elmalign,
- bool *isNull);
+ int elmlen, bool elmbyval,
+ char elmalign, char typstor, bool *isNull);
static Datum array_set_element_expanded(Datum arraydatum,
int nSubscripts, int *indx,
Datum dataValue, bool isNull,
int arraytyplen,
- int elmlen, bool elmbyval, char elmalign);
+ int elmlen, bool elmbyval,
+ char elmalign, char typstor);
static bool array_get_isnull(const bits8 *nullbitmap, int offset);
static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull);
static Datum ArrayCast(char *value, bool byval, int len);
static int ArrayCastAndSet(Datum src,
- int typlen, bool typbyval, char typalign,
- char *dest);
+ int typlen, bool typbyval,
+ char typalign, char typstor, char *dest);
static char *array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
- int typlen, bool typbyval, char typalign);
+ int typlen, bool typbyval, char typalign, char typstor);
static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap,
- int nitems, int typlen, bool typbyval, char typalign);
+ int nitems, int typlen, bool typbyval,
+ char typalign, char typstor);
static int array_copy(char *destptr, int nitems,
char *srcptr, int offset, bits8 *nullbitmap,
- int typlen, bool typbyval, char typalign);
+ int typlen, bool typbyval, char typalign, char typstor);
static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr,
int ndim, int *dim, int *lb,
int *st, int *endp,
- int typlen, bool typbyval, char typalign);
+ int typlen, bool typbyval,
+ char typalign, char typstor);
static void array_extract_slice(ArrayType *newarray,
int ndim, int *dim, int *lb,
char *arraydataptr, bits8 *arraynullsptr,
int *st, int *endp,
- int typlen, bool typbyval, char typalign);
+ int typlen, bool typbyval,
+ char typalign, char typstor);
static void array_insert_slice(ArrayType *destArray, ArrayType *origArray,
ArrayType *srcArray,
int ndim, int *dim, int *lb,
int *st, int *endp,
- int typlen, bool typbyval, char typalign);
+ int typlen, bool typbyval,
+ char typalign, char typstor);
static int array_cmp(FunctionCallInfo fcinfo);
static ArrayType *create_array_envelope(int ndims, int *dimv, int *lbsv, int nbytes,
Oid elmtype, int dataoffset);
@@ -187,6 +193,7 @@ array_in(PG_FUNCTION_ARGS)
bool typbyval;
char typalign;
char typdelim;
+ char typstor;
Oid typioparam;
char *p;
int nitems;
@@ -220,10 +227,7 @@ array_in(PG_FUNCTION_ARGS)
/*
* Get info about element type, including its input conversion proc
*/
- get_type_io_data(element_type, IOFunc_input,
- &my_extra->typlen, &my_extra->typbyval,
- &my_extra->typalign, &my_extra->typdelim,
- &my_extra->typioparam, &my_extra->typiofunc);
+ array_type_metadata(element_type, IOFunc_input, my_extra);
fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
fcinfo->flinfo->fn_mcxt);
my_extra->element_type = element_type;
@@ -231,6 +235,7 @@ array_in(PG_FUNCTION_ARGS)
typlen = my_extra->typlen;
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
+ typstor = my_extra->typstorage;
typdelim = my_extra->typdelim;
typioparam = my_extra->typioparam;
@@ -326,7 +331,7 @@ array_in(PG_FUNCTION_ARGS)
/* let's just make sure data is not toasted */
if (typlen == -1)
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
- nbytes = att_addlength_datum(nbytes, typlen, values[i]);
+ nbytes = att_addvarsize_datum(nbytes, typlen, typstor, values[i]);
nbytes = att_align_nominal(nbytes, typalign);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
@@ -366,7 +371,7 @@ array_in(PG_FUNCTION_ARGS)
CopyArrayEls(retval,
values, nulls, nitems,
- typlen, typbyval, typalign,
+ typlen, typbyval, typalign, typstor,
true);
pfree(values);
@@ -949,7 +954,7 @@ ending_error:
* values: array of Datums to be copied
* nulls: array of is-null flags (can be NULL if no nulls)
* nitems: number of Datums to be copied
- * typbyval, typlen, typalign: info about element datatype
+ * typbyval, typlen, typalign, typstor: info about element datatype
* freedata: if true and element type is pass-by-ref, pfree data values
* referenced by Datums after copying them.
*
@@ -965,6 +970,7 @@ CopyArrayEls(ArrayType *array,
int typlen,
bool typbyval,
char typalign,
+ char typstor,
bool freedata)
{
char *p = ARR_DATA_PTR(array);
@@ -987,7 +993,8 @@ CopyArrayEls(ArrayType *array,
else
{
bitval |= bitmask;
- p += ArrayCastAndSet(values[i], typlen, typbyval, typalign, p);
+ p += ArrayCastAndSet(values[i],
+ typlen, typbyval, typalign, typstor, p);
if (freedata)
pfree(DatumGetPointer(values[i]));
}
@@ -1065,10 +1072,7 @@ array_out(PG_FUNCTION_ARGS)
/*
* Get info about element type, including its output conversion proc
*/
- get_type_io_data(element_type, IOFunc_output,
- &my_extra->typlen, &my_extra->typbyval,
- &my_extra->typalign, &my_extra->typdelim,
- &my_extra->typioparam, &my_extra->typiofunc);
+ array_type_metadata(element_type, IOFunc_output, my_extra);
fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
fcinfo->flinfo->fn_mcxt);
my_extra->element_type = element_type;
@@ -1278,6 +1282,7 @@ array_recv(PG_FUNCTION_ARGS)
int typlen;
bool typbyval;
char typalign;
+ char typstor;
Oid typioparam;
int i,
nitems;
@@ -1368,10 +1373,7 @@ array_recv(PG_FUNCTION_ARGS)
if (my_extra->element_type != element_type)
{
/* Get info about element type, including its receive proc */
- get_type_io_data(element_type, IOFunc_receive,
- &my_extra->typlen, &my_extra->typbyval,
- &my_extra->typalign, &my_extra->typdelim,
- &my_extra->typioparam, &my_extra->typiofunc);
+ array_type_metadata(element_type, IOFunc_receive, my_extra);
if (!OidIsValid(my_extra->typiofunc))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1391,13 +1393,14 @@ array_recv(PG_FUNCTION_ARGS)
typlen = my_extra->typlen;
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
+ typstor = my_extra->typstorage;
typioparam = my_extra->typioparam;
dataPtr = (Datum *) palloc(nitems * sizeof(Datum));
nullsPtr = (bool *) palloc(nitems * sizeof(bool));
ReadArrayBinary(buf, nitems,
&my_extra->proc, typioparam, typmod,
- typlen, typbyval, typalign,
+ typlen, typbyval, typalign, typstor,
dataPtr, nullsPtr,
&hasnulls, &nbytes);
if (hasnulls)
@@ -1420,7 +1423,7 @@ array_recv(PG_FUNCTION_ARGS)
CopyArrayEls(retval,
dataPtr, nullsPtr, nitems,
- typlen, typbyval, typalign,
+ typlen, typbyval, typalign, typstor,
true);
pfree(dataPtr);
@@ -1438,7 +1441,7 @@ array_recv(PG_FUNCTION_ARGS)
* nitems: total number of array elements (already read).
* receiveproc: type-specific receive procedure for element datatype.
* typioparam, typmod: auxiliary values to pass to receiveproc.
- * typlen, typbyval, typalign: storage parameters of element datatype.
+ * typlen, typbyval, typalign, typstor: storage parameters of element datatype.
*
* Outputs:
* values[]: filled with converted data values.
@@ -1459,6 +1462,7 @@ ReadArrayBinary(StringInfo buf,
int typlen,
bool typbyval,
char typalign,
+ char typstor,
Datum *values,
bool *nulls,
bool *hasnulls,
@@ -1524,7 +1528,7 @@ ReadArrayBinary(StringInfo buf,
/* let's just make sure data is not toasted */
if (typlen == -1)
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
- totbytes = att_addlength_datum(totbytes, typlen, values[i]);
+ totbytes = att_addvarsize_datum(totbytes, typlen, typstor, values[i]);
totbytes = att_align_nominal(totbytes, typalign);
/* check for overflow of total request */
if (!AllocSizeIsValid(totbytes))
@@ -1578,10 +1582,7 @@ array_send(PG_FUNCTION_ARGS)
if (my_extra->element_type != element_type)
{
/* Get info about element type, including its send proc */
- get_type_io_data(element_type, IOFunc_send,
- &my_extra->typlen, &my_extra->typbyval,
- &my_extra->typalign, &my_extra->typdelim,
- &my_extra->typioparam, &my_extra->typiofunc);
+ array_type_metadata(element_type, IOFunc_send, my_extra);
if (!OidIsValid(my_extra->typiofunc))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
@@ -1811,6 +1812,7 @@ array_cardinality(PG_FUNCTION_ARGS)
* elmlen: pg_type.typlen for the array's element type
* elmbyval: pg_type.typbyval for the array's element type
* elmalign: pg_type.typalign for the array's element type
+ * elmstor: pg_type.typstorage for the array's element type
*
* Outputs:
* The return value is the element Datum.
@@ -1824,6 +1826,7 @@ array_get_element(Datum arraydatum,
int elmlen,
bool elmbyval,
char elmalign,
+ char elmstor,
bool *isNull)
{
int i,
@@ -1860,6 +1863,7 @@ array_get_element(Datum arraydatum,
elmlen,
elmbyval,
elmalign,
+ elmstor,
isNull);
}
else
@@ -1910,7 +1914,7 @@ array_get_element(Datum arraydatum,
*/
*isNull = false;
retptr = array_seek(arraydataptr, 0, arraynullsptr, offset,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
return ArrayCast(retptr, elmbyval, elmlen);
}
@@ -1921,7 +1925,8 @@ static Datum
array_get_element_expanded(Datum arraydatum,
int nSubscripts, int *indx,
int arraytyplen,
- int elmlen, bool elmbyval, char elmalign,
+ int elmlen, bool elmbyval,
+ char elmalign, char typstor,
bool *isNull)
{
ExpandedArrayHeader *eah;
@@ -1941,6 +1946,7 @@ array_get_element_expanded(Datum arraydatum,
Assert(elmlen == eah->typlen);
Assert(elmbyval == eah->typbyval);
Assert(elmalign == eah->typalign);
+ Assert(typstor == eah->typstorage);
ndim = eah->ndims;
dim = eah->dims;
@@ -2015,6 +2021,7 @@ array_get_element_expanded(Datum arraydatum,
* elmlen: pg_type.typlen for the array's element type
* elmbyval: pg_type.typbyval for the array's element type
* elmalign: pg_type.typalign for the array's element type
+ * elmstor: pg_type.typstorage for the array's element type
*
* Outputs:
* The return value is the new array Datum (it's never NULL)
@@ -2036,7 +2043,8 @@ array_get_slice(Datum arraydatum,
int arraytyplen,
int elmlen,
bool elmbyval,
- char elmalign)
+ char elmalign,
+ char elmstor)
{
ArrayType *array;
ArrayType *newarray;
@@ -2124,7 +2132,7 @@ array_get_slice(Datum arraydatum,
bytes = array_slice_size(arraydataptr, arraynullsptr,
ndim, dim, lb,
lowerIndx, upperIndx,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
/*
* Currently, we put a null bitmap in the result if the source has one;
@@ -2160,7 +2168,7 @@ array_get_slice(Datum arraydatum,
ndim, dim, lb,
arraydataptr, arraynullsptr,
lowerIndx, upperIndx,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
return PointerGetDatum(newarray);
}
@@ -2182,6 +2190,7 @@ array_get_slice(Datum arraydatum,
* elmlen: pg_type.typlen for the array's element type
* elmbyval: pg_type.typbyval for the array's element type
* elmalign: pg_type.typalign for the array's element type
+ * elmstor: pg_type.typstorage for the array's element type
*
* Result:
* A new array is returned, just like the old except for the one
@@ -2206,7 +2215,8 @@ array_set_element(Datum arraydatum,
int arraytyplen,
int elmlen,
bool elmbyval,
- char elmalign)
+ char elmalign,
+ char elmstor)
{
ArrayType *array;
ArrayType *newarray;
@@ -2257,7 +2267,7 @@ array_set_element(Datum arraydatum,
resultarray = (char *) palloc(arraytyplen);
memcpy(resultarray, DatumGetPointer(arraydatum), arraytyplen);
elt_ptr = (char *) resultarray + indx[0] * elmlen;
- ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elt_ptr);
+ ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elmstor, elt_ptr);
return PointerGetDatum(resultarray);
}
@@ -2281,7 +2291,8 @@ array_set_element(Datum arraydatum,
arraytyplen,
elmlen,
elmbyval,
- elmalign);
+ elmalign,
+ elmstor);
}
/* detoast input array if necessary */
@@ -2307,7 +2318,8 @@ array_set_element(Datum arraydatum,
return PointerGetDatum(construct_md_array(&dataValue, &isNull,
nSubscripts, dim, lb,
elmtype,
- elmlen, elmbyval, elmalign));
+ elmlen, elmbyval,
+ elmalign, elmstor));
}
if (ndim != nSubscripts)
@@ -2408,13 +2420,13 @@ array_set_element(Datum arraydatum,
{
offset = ArrayGetOffset(nSubscripts, dim, lb, indx);
elt_ptr = array_seek(ARR_DATA_PTR(array), 0, oldnullbitmap, offset,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
lenbefore = (int) (elt_ptr - ARR_DATA_PTR(array));
if (array_get_isnull(oldnullbitmap, offset))
olditemlen = 0;
else
{
- olditemlen = att_addlength_pointer(0, elmlen, elt_ptr);
+ olditemlen = att_addvarsize_pointer(0, elmlen, elmstor, elt_ptr);
olditemlen = att_align_nominal(olditemlen, elmalign);
}
lenafter = (int) (olddatasize - lenbefore - olditemlen);
@@ -2424,7 +2436,7 @@ array_set_element(Datum arraydatum,
newitemlen = 0;
else
{
- newitemlen = att_addlength_datum(0, elmlen, dataValue);
+ newitemlen = att_addvarsize_datum(0, elmlen, elmstor, dataValue);
newitemlen = att_align_nominal(newitemlen, elmalign);
}
@@ -2448,7 +2460,7 @@ array_set_element(Datum arraydatum,
(char *) array + oldoverheadlen,
lenbefore);
if (!isNull)
- ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign,
+ ArrayCastAndSet(dataValue, elmlen, elmbyval, elmalign, elmstor,
(char *) newarray + overheadlen + lenbefore);
memcpy((char *) newarray + overheadlen + lenbefore + newitemlen,
(char *) array + oldoverheadlen + lenbefore + olditemlen,
@@ -2502,7 +2514,8 @@ array_set_element_expanded(Datum arraydatum,
int nSubscripts, int *indx,
Datum dataValue, bool isNull,
int arraytyplen,
- int elmlen, bool elmbyval, char elmalign)
+ int elmlen, bool elmbyval,
+ char elmalign, char typstor)
{
ExpandedArrayHeader *eah;
Datum *dvalues;
@@ -2526,6 +2539,7 @@ array_set_element_expanded(Datum arraydatum,
Assert(elmlen == eah->typlen);
Assert(elmbyval == eah->typbyval);
Assert(elmalign == eah->typalign);
+ Assert(typstor == eah->typstorage);
/*
* Copy dimension info into local storage. This allows us to modify the
@@ -2782,6 +2796,7 @@ array_set_element_expanded(Datum arraydatum,
* elmlen: pg_type.typlen for the array's element type
* elmbyval: pg_type.typbyval for the array's element type
* elmalign: pg_type.typalign for the array's element type
+ * elmstor: pg_type.typstorage for the array's element type
*
* Result:
* A new array is returned, just like the old except for the
@@ -2814,7 +2829,8 @@ array_set_slice(Datum arraydatum,
int arraytyplen,
int elmlen,
bool elmbyval,
- char elmalign)
+ char elmalign,
+ char elmstor)
{
ArrayType *array;
ArrayType *srcArray;
@@ -2875,7 +2891,7 @@ array_set_slice(Datum arraydatum,
int nelems;
Oid elmtype = ARR_ELEMTYPE(array);
- deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign,
+ deconstruct_array(srcArray, elmtype, elmlen, elmbyval, elmalign, elmstor,
&dvalues, &dnulls, &nelems);
for (i = 0; i < nSubscripts; i++)
@@ -2906,7 +2922,8 @@ array_set_slice(Datum arraydatum,
return PointerGetDatum(construct_md_array(dvalues, dnulls, nSubscripts,
dim, lb, elmtype,
- elmlen, elmbyval, elmalign));
+ elmlen, elmbyval,
+ elmalign, elmstor));
}
if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
@@ -3026,7 +3043,7 @@ array_set_slice(Datum arraydatum,
overheadlen = ARR_OVERHEAD_NONULLS(ndim);
newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), 0,
ARR_NULLBITMAP(srcArray), nsrcitems,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
oldoverheadlen = ARR_DATA_OFFSET(array);
olddatasize = ARR_SIZE(array) - oldoverheadlen;
if (ndim > 1)
@@ -3039,7 +3056,7 @@ array_set_slice(Datum arraydatum,
ARR_NULLBITMAP(array),
ndim, dim, lb,
lowerIndx, upperIndx,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
lenbefore = lenafter = 0; /* keep compiler quiet */
itemsbefore = itemsafter = nolditems = 0;
}
@@ -3060,7 +3077,7 @@ array_set_slice(Datum arraydatum,
itemsbefore = Min(slicelb, oldub + 1) - oldlb;
lenbefore = array_nelems_size(oldarraydata, 0, oldarraybitmap,
itemsbefore,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
/* count/size of old array entries that will be replaced by slice */
if (slicelb > sliceub)
{
@@ -3073,7 +3090,7 @@ array_set_slice(Datum arraydatum,
olditemsize = array_nelems_size(oldarraydata + lenbefore,
itemsbefore, oldarraybitmap,
nolditems,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
}
/* count/size of old array entries that will go after the slice */
itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);
@@ -3099,7 +3116,7 @@ array_set_slice(Datum arraydatum,
array_insert_slice(newarray, array, srcArray,
ndim, dim, lb,
lowerIndx, upperIndx,
- elmlen, elmbyval, elmalign);
+ elmlen, elmbyval, elmalign, elmstor);
}
else
{
@@ -3144,11 +3161,11 @@ array_set_slice(Datum arraydatum,
*/
Datum
array_ref(ArrayType *array, int nSubscripts, int *indx,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign,
- bool *isNull)
+ int arraytyplen, int elmlen, bool elmbyval,
+ char elmalign, char elmstor, bool *isNull)
{
return array_get_element(PointerGetDatum(array), nSubscripts, indx,
- arraytyplen, elmlen, elmbyval, elmalign,
+ arraytyplen, elmlen, elmbyval, elmalign, elmstor,
isNull);
}
@@ -3161,14 +3178,15 @@ array_ref(ArrayType *array, int nSubscripts, int *indx,
*/
ArrayType *
array_set(ArrayType *array, int nSubscripts, int *indx,
- Datum dataValue, bool isNull,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign)
+ Datum dataValue, bool isNull, int arraytyplen,
+ int elmlen, bool elmbyval, char elmalign, char elmstor)
{
return DatumGetArrayTypeP(array_set_element(PointerGetDatum(array),
nSubscripts, indx,
dataValue, isNull,
arraytyplen,
- elmlen, elmbyval, elmalign));
+ elmlen, elmbyval,
+ elmalign, elmstor));
}
/*
@@ -3220,6 +3238,7 @@ array_map(Datum arrayd,
int typlen;
bool typbyval;
char typalign;
+ char typstor;
array_iter iter;
ArrayMetaState *inp_extra;
ArrayMetaState *ret_extra;
@@ -3260,15 +3279,17 @@ array_map(Datum arrayd,
if (ret_extra->element_type != retType)
{
- get_typlenbyvalalign(retType,
- &ret_extra->typlen,
- &ret_extra->typbyval,
- &ret_extra->typalign);
+ get_type_stores(retType,
+ &ret_extra->typlen,
+ &ret_extra->typbyval,
+ &ret_extra->typalign,
+ &ret_extra->typstorage);
ret_extra->element_type = retType;
}
typlen = ret_extra->typlen;
typbyval = ret_extra->typbyval;
typalign = ret_extra->typalign;
+ typstor = ret_extra->typstorage;
/* Allocate temporary arrays for new values */
values = (Datum *) palloc(nitems * sizeof(Datum));
@@ -3296,7 +3317,7 @@ array_map(Datum arrayd,
if (typlen == -1)
values[i] = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
/* Update total result size */
- nbytes = att_addlength_datum(nbytes, typlen, values[i]);
+ nbytes = att_addvarsize_datum(nbytes, typlen, typstor, values[i]);
nbytes = att_align_nominal(nbytes, typalign);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
@@ -3328,7 +3349,7 @@ array_map(Datum arrayd,
CopyArrayEls(result,
values, nulls, nitems,
- typlen, typbyval, typalign,
+ typlen, typbyval, typalign, typstor,
false);
/*
@@ -3346,7 +3367,8 @@ array_map(Datum arrayd,
* elems: array of Datum items to become the array contents
* (NULL element values are not supported).
* nelems: number of items
- * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign, elmstor:
+ * info for the datatype of the items
*
* A palloc'd 1-D array object is constructed and returned. Note that
* elem values will be copied into the object even if pass-by-ref type.
@@ -3360,7 +3382,7 @@ array_map(Datum arrayd,
ArrayType *
construct_array(Datum *elems, int nelems,
Oid elmtype,
- int elmlen, bool elmbyval, char elmalign)
+ int elmlen, bool elmbyval, char elmalign, char elmstor)
{
int dims[1];
int lbs[1];
@@ -3369,13 +3391,13 @@ construct_array(Datum *elems, int nelems,
lbs[0] = 1;
return construct_md_array(elems, NULL, 1, dims, lbs,
- elmtype, elmlen, elmbyval, elmalign);
+ elmtype, elmlen, elmbyval, elmalign, elmstor);
}
/*
* 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.
+ * elmlen/elmbyval/elmalign/elmstor 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)
@@ -3383,6 +3405,7 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
int elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
switch (elmtype)
{
@@ -3390,48 +3413,56 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
elmlen = 1;
elmbyval = true;
elmalign = TYPALIGN_CHAR;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case CSTRINGOID:
elmlen = -2;
elmbyval = false;
elmalign = TYPALIGN_CHAR;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case FLOAT4OID:
elmlen = sizeof(float4);
elmbyval = true;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case FLOAT8OID:
elmlen = sizeof(float8);
elmbyval = FLOAT8PASSBYVAL;
elmalign = TYPALIGN_DOUBLE;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case INT2OID:
elmlen = sizeof(int16);
elmbyval = true;
elmalign = TYPALIGN_SHORT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case INT4OID:
elmlen = sizeof(int32);
elmbyval = true;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case INT8OID:
elmlen = sizeof(int64);
elmbyval = FLOAT8PASSBYVAL;
elmalign = TYPALIGN_DOUBLE;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case NAMEOID:
elmlen = NAMEDATALEN;
elmbyval = false;
elmalign = TYPALIGN_CHAR;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case OIDOID:
@@ -3439,24 +3470,28 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
elmlen = sizeof(Oid);
elmbyval = true;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case TEXTOID:
elmlen = -1;
elmbyval = false;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_EXTENDED;
break;
case TIDOID:
elmlen = sizeof(ItemPointerData);
elmbyval = false;
elmalign = TYPALIGN_SHORT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case XIDOID:
elmlen = sizeof(TransactionId);
elmbyval = true;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
default:
@@ -3465,9 +3500,11 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
elmlen = 0;
elmbyval = false;
elmalign = 0;
+ elmstor = 0;
}
- return construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign);
+ return construct_array(elems, nelems, elmtype, elmlen, elmbyval,
+ elmalign, elmstor);
}
/*
@@ -3479,7 +3516,8 @@ construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
* ndims: number of dimensions
* dims: integer array with size of each dimension
* lbs: integer array with lower bound of each dimension
- * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign, elmstor:
+ * info for the datatype of the items
*
* A palloc'd ndims-D array object is constructed and returned. Note that
* elem values will be copied into the object even if pass-by-ref type.
@@ -3496,7 +3534,8 @@ construct_md_array(Datum *elems,
int ndims,
int *dims,
int *lbs,
- Oid elmtype, int elmlen, bool elmbyval, char elmalign)
+ Oid elmtype, int elmlen, bool elmbyval,
+ char elmalign, char elmstor)
{
ArrayType *result;
bool hasnulls;
@@ -3536,7 +3575,7 @@ construct_md_array(Datum *elems,
/* make sure data is not toasted */
if (elmlen == -1)
elems[i] = PointerGetDatum(PG_DETOAST_DATUM(elems[i]));
- nbytes = att_addlength_datum(nbytes, elmlen, elems[i]);
+ nbytes = att_addvarsize_datum(nbytes, elmlen, elmstor, elems[i]);
nbytes = att_align_nominal(nbytes, elmalign);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
@@ -3567,7 +3606,7 @@ construct_md_array(Datum *elems,
CopyArrayEls(result,
elems, nulls, nelems,
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
false);
return result;
@@ -3610,7 +3649,8 @@ construct_empty_expanded_array(Oid element_type,
* deconstruct_array --- simple method for extracting data from an array
*
* array: array object to examine (must not be NULL)
- * elmtype, elmlen, elmbyval, elmalign: info for the datatype of the items
+ * elmtype, elmlen, elmbyval, elmalign, elmstor:
+ * info for the datatype of the items
* elemsp: return value, set to point to palloc'd array of Datum values
* nullsp: return value, set to point to palloc'd array of isnull markers
* nelemsp: return value, set to number of extracted values
@@ -3622,15 +3662,15 @@ construct_empty_expanded_array(Oid element_type,
* If array elements are pass-by-ref data type, the returned Datums will
* 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, the caller is
+ * NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign/elmstor
+ * info 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,
Oid elmtype,
- int elmlen, bool elmbyval, char elmalign,
+ int elmlen, bool elmbyval, char elmalign, char elmstor,
Datum **elemsp, bool **nullsp, int *nelemsp)
{
Datum *elems;
@@ -3701,6 +3741,7 @@ deconstruct_array_builtin(ArrayType *array,
int elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
switch (elmtype)
{
@@ -3708,42 +3749,49 @@ deconstruct_array_builtin(ArrayType *array,
elmlen = 1;
elmbyval = true;
elmalign = TYPALIGN_CHAR;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case CSTRINGOID:
elmlen = -2;
elmbyval = false;
elmalign = TYPALIGN_CHAR;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case FLOAT8OID:
elmlen = sizeof(float8);
elmbyval = FLOAT8PASSBYVAL;
elmalign = TYPALIGN_DOUBLE;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case INT2OID:
elmlen = sizeof(int16);
elmbyval = true;
elmalign = TYPALIGN_SHORT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case OIDOID:
elmlen = sizeof(Oid);
elmbyval = true;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
case TEXTOID:
elmlen = -1;
elmbyval = false;
elmalign = TYPALIGN_INT;
+ elmstor = TYPSTORAGE_EXTENDED;
break;
case TIDOID:
elmlen = sizeof(ItemPointerData);
elmbyval = false;
elmalign = TYPALIGN_SHORT;
+ elmstor = TYPSTORAGE_PLAIN;
break;
default:
@@ -3752,9 +3800,11 @@ deconstruct_array_builtin(ArrayType *array,
elmlen = 0;
elmbyval = false;
elmalign = 0;
+ elmstor = 0;
}
- deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
+ deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elmstor,
+ elemsp, nullsp, nelemsp);
}
/*
@@ -4215,6 +4265,7 @@ hash_array(PG_FUNCTION_ARGS)
record_typentry->typlen = typentry->typlen;
record_typentry->typbyval = typentry->typbyval;
record_typentry->typalign = typentry->typalign;
+ record_typentry->typstorage = typentry->typstorage;
fmgr_info(F_HASH_RECORD, &record_typentry->hash_proc_finfo);
MemoryContextSwitchTo(oldcontext);
@@ -4392,6 +4443,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
int typlen;
bool typbyval;
char typalign;
+ char typstor;
int i;
int j;
array_iter it1;
@@ -4423,6 +4475,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
typlen = typentry->typlen;
typbyval = typentry->typbyval;
typalign = typentry->typalign;
+ typstor = typentry->typstorage;
/*
* Since we probably will need to scan array2 multiple times, it's
@@ -4439,7 +4492,7 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation,
}
else
deconstruct_array((ArrayType *) array2,
- element_type, typlen, typbyval, typalign,
+ element_type, typlen, typbyval, typalign, typstor,
&values2, &nulls2, &nelems2);
/*
@@ -4619,12 +4672,14 @@ array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate)
iterator->typlen = mstate->typlen;
iterator->typbyval = mstate->typbyval;
iterator->typalign = mstate->typalign;
+ iterator->typstorage = mstate->typstorage;
}
else
- get_typlenbyvalalign(ARR_ELEMTYPE(arr),
- &iterator->typlen,
- &iterator->typbyval,
- &iterator->typalign);
+ get_type_stores(ARR_ELEMTYPE(arr),
+ &iterator->typlen,
+ &iterator->typbyval,
+ &iterator->typalign,
+ &iterator->typstorage);
/*
* Remember the slicing parameters.
@@ -4743,7 +4798,8 @@ array_iterate(ArrayIterator iterator, Datum *value, bool *isnull)
ARR_ELEMTYPE(iterator->arr),
iterator->typlen,
iterator->typbyval,
- iterator->typalign);
+ iterator->typalign,
+ iterator->typstorage);
*isnull = false;
*value = PointerGetDatum(result);
@@ -4828,6 +4884,7 @@ ArrayCastAndSet(Datum src,
int typlen,
bool typbyval,
char typalign,
+ char typstor,
char *dest)
{
int inc;
@@ -4840,6 +4897,14 @@ ArrayCastAndSet(Datum src,
memmove(dest, DatumGetPointer(src), typlen);
inc = att_align_nominal(typlen, typalign);
}
+ else if (TYPE_IS_PACKABLE(typlen, typstor) && VARATT_CAN_MAKE_SHORT(src))
+ {
+ Assert(!typbyval);
+ inc = VARATT_CONVERTED_SHORT_SIZE(src);
+ SET_VARSIZE_SHORT(dest, inc);
+ memcpy(dest + 1, VARDATA(DatumGetPointer(src)), inc - 1);
+ inc = att_align_nominal(inc, typalign);
+ }
else
{
Assert(!typbyval);
@@ -4858,13 +4923,14 @@ ArrayCastAndSet(Datum src,
* offset: 0-based linear element number of first element (the one at *ptr)
* nullbitmap: start of array's null bitmap, or NULL if none
* nitems: number of array elements to advance over (>= 0)
- * typlen, typbyval, typalign: storage parameters of array element datatype
+ * typlen, typbyval, typalign, typstor:
+ * storage parameters of array element datatype
*
* It is caller's responsibility to ensure that nitems is within range
*/
static char *
array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
- int typlen, bool typbyval, char typalign)
+ int typlen, bool typbyval, char typalign, char typstor)
{
int bitmask;
int i;
@@ -4883,7 +4949,7 @@ array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
{
if (*nullbitmap & bitmask)
{
- ptr = att_addlength_pointer(ptr, typlen, ptr);
+ ptr = att_addvarsize_pointer(ptr, typlen, typstor, ptr);
ptr = (char *) att_align_nominal(ptr, typalign);
}
bitmask <<= 1;
@@ -4898,7 +4964,7 @@ array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
{
for (i = 0; i < nitems; i++)
{
- ptr = att_addlength_pointer(ptr, typlen, ptr);
+ ptr = att_addvarsize_pointer(ptr, typlen, typstor, ptr);
ptr = (char *) att_align_nominal(ptr, typalign);
}
}
@@ -4912,10 +4978,10 @@ array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems,
*/
static int
array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems,
- int typlen, bool typbyval, char typalign)
+ int typlen, bool typbyval, char typalign, char typstor)
{
return array_seek(ptr, offset, nullbitmap, nitems,
- typlen, typbyval, typalign) - ptr;
+ typlen, typbyval, typalign, typstor) - ptr;
}
/*
@@ -4926,7 +4992,8 @@ array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems,
* srcptr: starting location in source array
* offset: 0-based linear element number of first element (the one at *srcptr)
* nullbitmap: start of source array's null bitmap, or NULL if none
- * typlen, typbyval, typalign: storage parameters of array element datatype
+ * typlen, typbyval, typalign, typstor:
+ * storage parameters of array element datatype
*
* Returns number of bytes copied
*
@@ -4935,12 +5002,12 @@ array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, int nitems,
static int
array_copy(char *destptr, int nitems,
char *srcptr, int offset, bits8 *nullbitmap,
- int typlen, bool typbyval, char typalign)
+ int typlen, bool typbyval, char typalign, char typstor)
{
int numbytes;
numbytes = array_nelems_size(srcptr, offset, nullbitmap, nitems,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
memcpy(destptr, srcptr, numbytes);
return numbytes;
}
@@ -5037,7 +5104,7 @@ static int
array_slice_size(char *arraydataptr, bits8 *arraynullsptr,
int ndim, int *dim, int *lb,
int *st, int *endp,
- int typlen, bool typbyval, char typalign)
+ int typlen, bool typbyval, char typalign, char typstor)
{
int src_offset,
span[MAXDIM],
@@ -5059,7 +5126,7 @@ array_slice_size(char *arraydataptr, bits8 *arraynullsptr,
/* Else gotta do it the hard way */
src_offset = ArrayGetOffset(ndim, dim, lb, st);
ptr = array_seek(arraydataptr, 0, arraynullsptr, src_offset,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
mda_get_prod(ndim, dim, prod);
mda_get_offset_values(ndim, dist, prod, span);
for (i = 0; i < ndim; i++)
@@ -5070,12 +5137,12 @@ array_slice_size(char *arraydataptr, bits8 *arraynullsptr,
if (dist[j])
{
ptr = array_seek(ptr, src_offset, arraynullsptr, dist[j],
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
src_offset += dist[j];
}
if (!array_get_isnull(arraynullsptr, src_offset))
{
- inc = att_addlength_pointer(0, typlen, ptr);
+ inc = att_addvarsize_pointer(0, typlen, typstor, ptr);
inc = att_align_nominal(inc, typalign);
ptr += inc;
count += inc;
@@ -5104,7 +5171,8 @@ array_extract_slice(ArrayType *newarray,
int *endp,
int typlen,
bool typbyval,
- char typalign)
+ char typalign,
+ char typstor)
{
char *destdataptr = ARR_DATA_PTR(newarray);
bits8 *destnullsptr = ARR_NULLBITMAP(newarray);
@@ -5121,7 +5189,7 @@ array_extract_slice(ArrayType *newarray,
src_offset = ArrayGetOffset(ndim, dim, lb, st);
srcdataptr = array_seek(arraydataptr, 0, arraynullsptr, src_offset,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
mda_get_prod(ndim, dim, prod);
mda_get_range(ndim, span, st, endp);
mda_get_offset_values(ndim, dist, prod, span);
@@ -5136,12 +5204,12 @@ array_extract_slice(ArrayType *newarray,
/* skip unwanted elements */
srcdataptr = array_seek(srcdataptr, src_offset, arraynullsptr,
dist[j],
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
src_offset += dist[j];
}
inc = array_copy(destdataptr, 1,
srcdataptr, src_offset, arraynullsptr,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
if (destnullsptr)
array_bitmap_copy(destnullsptr, dest_offset,
arraynullsptr, src_offset,
@@ -5177,7 +5245,8 @@ array_insert_slice(ArrayType *destArray,
int *endp,
int typlen,
bool typbyval,
- char typalign)
+ char typalign,
+ char typstor)
{
char *destPtr = ARR_DATA_PTR(destArray);
char *origPtr = ARR_DATA_PTR(origArray);
@@ -5202,7 +5271,7 @@ array_insert_slice(ArrayType *destArray,
/* copy items before the slice start */
inc = array_copy(destPtr, dest_offset,
origPtr, 0, origBitmap,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
destPtr += inc;
origPtr += inc;
if (destBitmap)
@@ -5222,7 +5291,7 @@ array_insert_slice(ArrayType *destArray,
{
inc = array_copy(destPtr, dist[j],
origPtr, orig_offset, origBitmap,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
destPtr += inc;
origPtr += inc;
if (destBitmap)
@@ -5235,7 +5304,7 @@ array_insert_slice(ArrayType *destArray,
/* Copy new element at this slice position */
inc = array_copy(destPtr, 1,
srcPtr, src_offset, srcBitmap,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
if (destBitmap)
array_bitmap_copy(destBitmap, dest_offset,
srcBitmap, src_offset,
@@ -5246,14 +5315,14 @@ array_insert_slice(ArrayType *destArray,
src_offset++;
/* Advance over old element at this slice position */
origPtr = array_seek(origPtr, orig_offset, origBitmap, 1,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
orig_offset++;
} while ((j = mda_next_tuple(ndim, indx, span)) != -1);
/* don't miss any data at the end */
array_copy(destPtr, orignitems - orig_offset,
origPtr, orig_offset, origBitmap,
- typlen, typbyval, typalign);
+ typlen, typbyval, typalign, typstor);
if (destBitmap)
array_bitmap_copy(destBitmap, dest_offset,
origBitmap, orig_offset,
@@ -5330,10 +5399,11 @@ initArrayResultWithSize(Oid element_type, MemoryContext rcontext,
MemoryContextAlloc(arr_context, astate->alen * sizeof(bool));
astate->nelems = 0;
astate->element_type = element_type;
- get_typlenbyvalalign(element_type,
- &astate->typlen,
- &astate->typbyval,
- &astate->typalign);
+ get_type_stores(element_type,
+ &astate->typlen,
+ &astate->typbyval,
+ &astate->typalign,
+ &astate->typstorage);
return astate;
}
@@ -5470,7 +5540,8 @@ makeMdArrayResult(ArrayBuildState *astate,
astate->element_type,
astate->typlen,
astate->typbyval,
- astate->typalign);
+ astate->typalign,
+ astate->typstorage);
MemoryContextSwitchTo(oldcontext);
@@ -6093,6 +6164,7 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
ArrayMetaState *my_extra;
/*
@@ -6177,16 +6249,18 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
if (my_extra->element_type != elmtype)
{
/* Get info about element type */
- get_typlenbyvalalign(elmtype,
- &my_extra->typlen,
- &my_extra->typbyval,
- &my_extra->typalign);
+ get_type_stores(elmtype,
+ &my_extra->typlen,
+ &my_extra->typbyval,
+ &my_extra->typalign,
+ &my_extra->typstorage);
my_extra->element_type = elmtype;
}
elmlen = my_extra->typlen;
elmbyval = my_extra->typbyval;
elmalign = my_extra->typalign;
+ elmstor = my_extra->typstorage;
/* compute required space */
if (!isnull)
@@ -6225,7 +6299,7 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs,
p = ARR_DATA_PTR(result);
for (i = 0; i < nitems; i++)
- p += ArrayCastAndSet(value, elmlen, elmbyval, elmalign, p);
+ p += ArrayCastAndSet(value, elmlen, elmbyval, elmalign, elmstor, p);
}
else
{
@@ -6398,6 +6472,7 @@ array_replace_internal(ArrayType *array,
int typlen;
bool typbyval;
char typalign;
+ char typstor;
char *arraydataptr;
bits8 *bitmap;
int bitmask;
@@ -6442,6 +6517,7 @@ array_replace_internal(ArrayType *array,
typlen = typentry->typlen;
typbyval = typentry->typbyval;
typalign = typentry->typalign;
+ typstor = typentry->typstorage;
/*
* Detoast values if they are toasted. The replacement value must be
@@ -6502,7 +6578,7 @@ array_replace_internal(ArrayType *array,
{
isNull = false;
elt = fetch_att(arraydataptr, typbyval, typlen);
- arraydataptr = att_addlength_datum(arraydataptr, typlen, elt);
+ arraydataptr = att_addvarsize_datum(arraydataptr, typlen, typstor, elt);
arraydataptr = (char *) att_align_nominal(arraydataptr, typalign);
if (search_isnull)
@@ -6549,7 +6625,7 @@ array_replace_internal(ArrayType *array,
else
{
/* Update total result size */
- nbytes = att_addlength_datum(nbytes, typlen, values[nresult]);
+ nbytes = att_addvarsize_datum(nbytes, typlen, typstor, values[nresult]);
nbytes = att_align_nominal(nbytes, typalign);
/* check for overflow of total request */
if (!AllocSizeIsValid(nbytes))
@@ -6619,7 +6695,7 @@ array_replace_internal(ArrayType *array,
/* Insert data into result array */
CopyArrayEls(result,
values, nulls, nresult,
- typlen, typbyval, typalign,
+ typlen, typbyval, typalign, typstor,
false);
pfree(values);
@@ -6925,6 +7001,7 @@ trim_array(PG_FUNCTION_ARGS)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int lower[MAXDIM];
int upper[MAXDIM];
bool lowerProvided[MAXDIM];
@@ -6948,12 +7025,12 @@ trim_array(PG_FUNCTION_ARGS)
}
/* Fetch the needed information about the element type */
- get_typlenbyvalalign(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign, &elmstor);
/* Get the slice */
result = array_get_slice(PointerGetDatum(v), 1,
upper, lower, upperProvided, lowerProvided,
- -1, elmlen, elmbyval, elmalign);
+ -1, elmlen, elmbyval, elmalign, elmstor);
PG_RETURN_DATUM(result);
}
diff --git a/src/backend/utils/adt/arraysubs.c b/src/backend/utils/adt/arraysubs.c
index 6f68dfa5b23..1af83eff70a 100644
--- a/src/backend/utils/adt/arraysubs.c
+++ b/src/backend/utils/adt/arraysubs.c
@@ -34,6 +34,7 @@ typedef struct ArraySubWorkspace
int16 refelemlength; /* typlen of the array element type */
bool refelembyval; /* is the element type pass-by-value? */
char refelemalign; /* typalign of the element type */
+ char refelemstorage; /* typstorage of the element type */
/*
* Subscript values converted to integers. Note that these arrays must be
@@ -250,6 +251,7 @@ array_subscript_fetch(ExprState *state,
workspace->refelemlength,
workspace->refelembyval,
workspace->refelemalign,
+ workspace->refelemstorage,
op->resnull);
}
@@ -280,7 +282,8 @@ array_subscript_fetch_slice(ExprState *state,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
- workspace->refelemalign);
+ workspace->refelemalign,
+ workspace->refelemstorage);
/* The slice is never NULL, so no need to change *op->resnull */
}
@@ -330,7 +333,8 @@ array_subscript_assign(ExprState *state,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
- workspace->refelemalign);
+ workspace->refelemalign,
+ workspace->refelemstorage);
/* The result is never NULL, so no need to change *op->resnull */
}
@@ -383,7 +387,8 @@ array_subscript_assign_slice(ExprState *state,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
- workspace->refelemalign);
+ workspace->refelemalign,
+ workspace->refelemstorage);
/* The result is never NULL, so no need to change *op->resnull */
}
@@ -417,6 +422,7 @@ array_subscript_fetch_old(ExprState *state,
workspace->refelemlength,
workspace->refelembyval,
workspace->refelemalign,
+ workspace->refelemstorage,
&sbsrefstate->prevnull);
}
@@ -460,7 +466,8 @@ array_subscript_fetch_old_slice(ExprState *state,
workspace->refattrlength,
workspace->refelemlength,
workspace->refelembyval,
- workspace->refelemalign);
+ workspace->refelemalign,
+ workspace->refelemstorage);
/* slices of non-null arrays are never null */
sbsrefstate->prevnull = false;
}
@@ -504,10 +511,11 @@ array_exec_setup(const SubscriptingRef *sbsref,
*/
workspace->refelemtype = sbsref->refelemtype;
workspace->refattrlength = get_typlen(sbsref->refcontainertype);
- get_typlenbyvalalign(sbsref->refelemtype,
- &workspace->refelemlength,
- &workspace->refelembyval,
- &workspace->refelemalign);
+ get_type_stores(sbsref->refelemtype,
+ &workspace->refelemlength,
+ &workspace->refelembyval,
+ &workspace->refelemalign,
+ &workspace->refelemstorage);
/*
* Pass back pointers to appropriate step execution functions.
diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c
index d4c2aa0e7e9..4d74ac90117 100644
--- a/src/backend/utils/adt/enum.c
+++ b/src/backend/utils/adt/enum.c
@@ -608,7 +608,7 @@ enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
/* and build the result array */
/* note this hardwires some details about the representation of Oid */
result = construct_array(elems, cnt, enumtypoid,
- sizeof(Oid), true, TYPALIGN_INT);
+ sizeof(Oid), true, TYPALIGN_INT, TYPSTORAGE_PLAIN);
pfree(elems);
diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c
index 058aade2af4..ef473cec622 100644
--- a/src/backend/utils/adt/json.c
+++ b/src/backend/utils/adt/json.c
@@ -484,6 +484,7 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
int16 typlen;
bool typbyval;
char typalign;
+ char typstor;
JsonTypeCategory tcategory;
Oid outfuncoid;
@@ -497,14 +498,14 @@ array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
return;
}
- get_typlenbyvalalign(element_type,
- &typlen, &typbyval, &typalign);
+ get_type_stores(element_type,
+ &typlen, &typbyval, &typalign, &typstor);
json_categorize_type(element_type, false,
&tcategory, &outfuncoid);
deconstruct_array(v, element_type, typlen, typbyval,
- typalign, &elements, &nulls,
+ typalign, typstor, &elements, &nulls,
&nitems);
array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index d602df4eeb5..4ccf4400ea7 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -904,6 +904,7 @@ array_to_jsonb_internal(Datum array, JsonbInState *result)
int16 typlen;
bool typbyval;
char typalign;
+ char typstor;
JsonTypeCategory tcategory;
Oid outfuncoid;
@@ -918,14 +919,14 @@ array_to_jsonb_internal(Datum array, JsonbInState *result)
return;
}
- get_typlenbyvalalign(element_type,
- &typlen, &typbyval, &typalign);
+ get_type_stores(element_type,
+ &typlen, &typbyval, &typalign, &typstor);
json_categorize_type(element_type, true,
&tcategory, &outfuncoid);
deconstruct_array(v, element_type, typlen, typbyval,
- typalign, &elements, &nulls,
+ typalign, typstor, &elements, &nulls,
&nitems);
array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
diff --git a/src/backend/utils/adt/multirangetypes.c b/src/backend/utils/adt/multirangetypes.c
index 35fd825babe..a28f9735606 100644
--- a/src/backend/utils/adt/multirangetypes.c
+++ b/src/backend/utils/adt/multirangetypes.c
@@ -996,7 +996,8 @@ multirange_constructor2(PG_FUNCTION_ARGS)
else
{
deconstruct_array(rangeArray, rngtypid, rangetyp->typlen, rangetyp->typbyval,
- rangetyp->typalign, &elements, &nulls, &range_count);
+ rangetyp->typalign, rangetyp->typstorage,
+ &elements, &nulls, &range_count);
ranges = palloc0(range_count * sizeof(RangeType *));
for (i = 0; i < range_count; i++)
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index b8bdc667dbc..da63a04af31 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -80,6 +80,7 @@ typedef struct OSAPerQueryState
int16 typLen;
bool typByVal;
char typAlign;
+ char typStorage;
/* Info about sort ordering: */
Oid sortOperator;
Oid eqOperator;
@@ -264,10 +265,11 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
qstate->sortNullsFirst = sortcl->nulls_first;
/* Save datatype info */
- get_typlenbyvalalign(qstate->sortColType,
- &qstate->typLen,
- &qstate->typByVal,
- &qstate->typAlign);
+ get_type_stores(qstate->sortColType,
+ &qstate->typLen,
+ &qstate->typByVal,
+ &qstate->typAlign,
+ &qstate->typStorage);
}
fcinfo->flinfo->fn_extra = qstate;
@@ -838,7 +840,8 @@ percentile_disc_multi_final(PG_FUNCTION_ARGS)
osastate->qstate->sortColType,
osastate->qstate->typLen,
osastate->qstate->typByVal,
- osastate->qstate->typAlign));
+ osastate->qstate->typAlign,
+ osastate->qstate->typStorage));
}
/*
@@ -847,7 +850,8 @@ percentile_disc_multi_final(PG_FUNCTION_ARGS)
static Datum
percentile_cont_multi_final_common(FunctionCallInfo fcinfo,
Oid expect_type,
- int16 typLen, bool typByVal, char typAlign,
+ int16 typLen, bool typByVal,
+ char typAlign, char typStor,
LerpFunc lerpfunc)
{
OSAPerGroupState *osastate;
@@ -994,7 +998,7 @@ percentile_cont_multi_final_common(FunctionCallInfo fcinfo,
expect_type,
typLen,
typByVal,
- typAlign));
+ typAlign, typStor));
}
/*
@@ -1009,6 +1013,7 @@ percentile_cont_float8_multi_final(PG_FUNCTION_ARGS)
sizeof(float8),
FLOAT8PASSBYVAL,
TYPALIGN_DOUBLE,
+ TYPSTORAGE_PLAIN,
float8_lerp);
}
@@ -1022,6 +1027,7 @@ percentile_cont_interval_multi_final(PG_FUNCTION_ARGS)
INTERVALOID,
/* hard-wired info on type interval */
16, false, TYPALIGN_DOUBLE,
+ TYPSTORAGE_PLAIN,
interval_lerp);
}
diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c
index dc714345222..80b0a240251 100644
--- a/src/backend/utils/adt/rangetypes.c
+++ b/src/backend/utils/adt/rangetypes.c
@@ -30,6 +30,7 @@
*/
#include "postgres.h"
+#include "catalog/pg_type.h"
#include "common/hashfn.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
@@ -2671,10 +2672,6 @@ range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum
* details.
*/
-/* Does datatype allow packing into the 1-byte-header varlena format? */
-#define TYPE_IS_PACKABLE(typlen, typstorage) \
- ((typlen) == -1 && (typstorage) != TYPSTORAGE_PLAIN)
-
/*
* Increment data_length by the space needed by the datum, including any
* preceding alignment padding.
diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c
index 42aec95738d..d6589bd24be 100644
--- a/src/backend/utils/adt/regexp.c
+++ b/src/backend/utils/adt/regexp.c
@@ -1664,7 +1664,8 @@ build_regexp_match_result(regexp_matches_ctx *matchctx)
lbs[0] = 1;
/* XXX: this hardcodes assumptions about the text type */
return construct_md_array(elems, nulls, 1, dims, lbs,
- TEXTOID, -1, false, TYPALIGN_INT);
+ TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
}
/*
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index be1f1f50b78..15d769f55b9 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3055,6 +3055,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typalign */ ,
&isnull);
if (!isnull)
{
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 08fa6774d9c..48e6212354c 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -1926,6 +1926,7 @@ scalararraysel(PlannerInfo *root,
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int num_elems;
Datum *elem_values;
bool *elem_nulls;
@@ -1934,11 +1935,11 @@ scalararraysel(PlannerInfo *root,
if (arrayisnull) /* qual can't succeed if null array */
return (Selectivity) 0.0;
arrayval = DatumGetArrayTypeP(arraydatum);
- get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(arrayval),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(arrayval,
ARR_ELEMTYPE(arrayval),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elem_values, &elem_nulls, &num_elems);
/*
@@ -7488,6 +7489,7 @@ gincost_scalararrayopexpr(PlannerInfo *root,
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int numElems;
Datum *elemValues;
bool *elemNulls;
@@ -7523,11 +7525,11 @@ gincost_scalararrayopexpr(PlannerInfo *root,
/* Otherwise, extract the array elements and iterate over them */
arrayval = DatumGetArrayTypeP(((Const *) rightop)->constvalue);
- get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(ARR_ELEMTYPE(arrayval),
+ &elmlen, &elmbyval, &elmalign, &elmstor);
deconstruct_array(arrayval,
ARR_ELEMTYPE(arrayval),
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elemValues, &elemNulls, &numElems);
memset(&arraycounts, 0, sizeof(arraycounts));
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index f75e25388ca..6c4c6c30163 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -329,8 +329,8 @@ tsvector_setweight_by_filter(PG_FUNCTION_ARGS)
if (nulls[i])
continue;
- lex = VARDATA(dlexemes[i]);
- lex_len = VARSIZE(dlexemes[i]) - VARHDRSZ;
+ lex = VARDATA_ANY(dlexemes[i]);
+ lex_len = VARSIZE_ANY_EXHDR(dlexemes[i]);
lex_pos = tsvector_bsearch(tsout, lex, lex_len);
if (lex_pos >= 0 && (j = POSDATALEN(tsout, entry + lex_pos)) != 0)
@@ -605,8 +605,8 @@ tsvector_delete_arr(PG_FUNCTION_ARGS)
if (nulls[i])
continue;
- lex = VARDATA(dlexemes[i]);
- lex_len = VARSIZE(dlexemes[i]) - VARHDRSZ;
+ lex = VARDATA_ANY(dlexemes[i]);
+ lex_len = VARSIZE_ANY_EXHDR(dlexemes[i]);
lex_pos = tsvector_bsearch(tsin, lex, lex_len);
if (lex_pos >= 0)
@@ -770,7 +770,7 @@ array_to_tsvector(PG_FUNCTION_ARGS)
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("lexeme array may not contain nulls")));
- if (VARSIZE(dlexemes[i]) - VARHDRSZ == 0)
+ if (VARSIZE_ANY_EXHDR(dlexemes[i]) == 0)
ereport(ERROR,
(errcode(ERRCODE_ZERO_LENGTH_CHARACTER_STRING),
errmsg("lexeme array may not contain empty strings")));
@@ -786,7 +786,7 @@ array_to_tsvector(PG_FUNCTION_ARGS)
/* Calculate space needed for surviving lexemes. */
for (i = 0; i < nitems; i++)
- datalen += VARSIZE(dlexemes[i]) - VARHDRSZ;
+ datalen += VARSIZE_ANY_EXHDR(dlexemes[i]);
tslen = CALCDATASIZE(nitems, datalen);
/* Allocate and fill tsvector. */
@@ -798,8 +798,8 @@ array_to_tsvector(PG_FUNCTION_ARGS)
cur = STRPTR(tsout);
for (i = 0; i < nitems; i++)
{
- char *lex = VARDATA(dlexemes[i]);
- int lex_len = VARSIZE(dlexemes[i]) - VARHDRSZ;
+ char *lex = VARDATA_ANY(dlexemes[i]);
+ int lex_len = VARSIZE_ANY_EXHDR(dlexemes[i]);
memcpy(cur, lex, lex_len);
arrout[i].haspos = 0;
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 533bebc1c7b..4b43f934c2a 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -4867,10 +4867,7 @@ array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v,
/*
* Get info about element type, including its output conversion proc
*/
- get_type_io_data(element_type, IOFunc_output,
- &my_extra->typlen, &my_extra->typbyval,
- &my_extra->typalign, &my_extra->typdelim,
- &my_extra->typioparam, &my_extra->typiofunc);
+ array_type_metadata(element_type, IOFunc_output, my_extra);
fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
fcinfo->flinfo->fn_mcxt);
my_extra->element_type = element_type;
@@ -5678,6 +5675,7 @@ text_format(PG_FUNCTION_ARGS)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int nitems;
/* Should have just the one argument */
@@ -5702,12 +5700,12 @@ text_format(PG_FUNCTION_ARGS)
/* Get info about array element type */
element_type = ARR_ELEMTYPE(arr);
- get_typlenbyvalalign(element_type,
- &elmlen, &elmbyval, &elmalign);
+ get_type_stores(element_type,
+ &elmlen, &elmbyval, &elmalign, &elmstor);
/* Extract all array elements */
deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
- &elements, &nulls, &nitems);
+ elmstor, &elements, &nulls, &nitems);
}
nargs = nitems + 1;
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 0898cb1be4c..fd28af187ad 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -2482,6 +2482,7 @@ map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
int16 elmlen;
bool elmbyval;
char elmalign;
+ char elmstor;
int num_elems;
Datum *elem_values;
bool *elem_nulls;
@@ -2490,10 +2491,11 @@ map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
array = DatumGetArrayTypeP(value);
elmtype = ARR_ELEMTYPE(array);
- get_typlenbyvalalign(elmtype, &elmlen, &elmbyval, &elmalign);
+ get_type_stores(elmtype, &elmlen,
+ &elmbyval, &elmalign, &elmstor);
deconstruct_array(array, elmtype,
- elmlen, elmbyval, elmalign,
+ elmlen, elmbyval, elmalign, elmstor,
&elem_values, &elem_nulls,
&num_elems);
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index a85dc0d891f..ec2775918ba 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2284,6 +2284,30 @@ get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
ReleaseSysCache(tp);
}
+/*
+ * get_type_stores
+ *
+ * A four-fer: given the type OID, return typlen,
+ * typbyval, typalign, typstorage.
+ */
+void
+get_type_stores(Oid typid, int16 *typlen, bool *typbyval,
+ char *typalign, char *typstor)
+{
+ HeapTuple tp;
+ Form_pg_type typtup;
+
+ tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for type %u", typid);
+ typtup = (Form_pg_type) GETSTRUCT(tp);
+ *typlen = typtup->typlen;
+ *typbyval = typtup->typbyval;
+ *typalign = typtup->typalign;
+ *typstor = typtup->typstorage;
+ ReleaseSysCache(tp);
+}
+
/*
* getTypeIOParam
* Given a pg_type row, select the type OID to pass to I/O functions
@@ -2394,6 +2418,63 @@ get_type_io_data(Oid typid,
ReleaseSysCache(typeTuple);
}
+/*
+ * array_type_metadata
+ *
+ * A six-fer: given the type OID, return typlen, typbyval, typalign,
+ * typdelim, typioparam, and IO function OID. The IO function
+ * returned is controlled by IOFuncSelector
+ */
+void
+array_type_metadata(Oid typid,
+ IOFuncSelector which_func,
+ ArrayMetaState *metadata)
+{
+ HeapTuple typeTuple;
+ Form_pg_type typeStruct;
+
+ /*
+ * In bootstrap mode, pass it off to bootstrap.c. This hack allows us to
+ * use array_in and array_out during bootstrap.
+ */
+ if (unlikely(IsBootstrapProcessingMode()))
+ {
+ boot_array_type_metadata(typid,
+ which_func,
+ metadata);
+
+ return;
+ }
+
+ typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
+ if (!HeapTupleIsValid(typeTuple))
+ elog(ERROR, "cache lookup failed for type %u", typid);
+ typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
+
+ metadata->typlen = typeStruct->typlen;
+ metadata->typbyval = typeStruct->typbyval;
+ metadata->typalign = typeStruct->typalign;
+ metadata->typstorage = typeStruct->typstorage;
+ metadata->typdelim = typeStruct->typdelim;
+ metadata->typioparam = getTypeIOParam(typeTuple);
+ switch (which_func)
+ {
+ case IOFunc_input:
+ metadata->typiofunc = typeStruct->typinput;
+ break;
+ case IOFunc_output:
+ metadata->typiofunc = typeStruct->typoutput;
+ break;
+ case IOFunc_receive:
+ metadata->typiofunc = typeStruct->typreceive;
+ break;
+ case IOFunc_send:
+ metadata->typiofunc = typeStruct->typsend;
+ break;
+ }
+ ReleaseSysCache(typeTuple);
+}
+
#ifdef NOT_USED
char
get_typalign(Oid typid)
@@ -3287,6 +3368,7 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
typeForm->typlen,
typeForm->typbyval,
typeForm->typalign,
+ typeForm->typstorage,
&sslot->values, NULL, &sslot->nvalues);
/*
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 1ce7eb9da8f..f6483a6d02e 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -627,6 +627,7 @@ RelationBuildTupleDesc(Relation relation)
attp->attlen,
attp->attbyval,
attp->attalign,
+ attp->attstorage,
&is_null);
Assert(!is_null);
if (attp->attbyval)
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 05d763fa06e..c85f6048029 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -2023,6 +2023,7 @@ extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start,
Oid element_type;
bool typbyval;
char typalign;
+ char typstor;
int16 typlen;
Assert(PG_NARGS() == variadic_start + 1);
@@ -2033,10 +2034,10 @@ extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start,
array_in = PG_GETARG_ARRAYTYPE_P(variadic_start);
element_type = ARR_ELEMTYPE(array_in);
- get_typlenbyvalalign(element_type,
- &typlen, &typbyval, &typalign);
+ get_type_stores(element_type,
+ &typlen, &typbyval, &typalign, &typstor);
deconstruct_array(array_in, element_type, typlen, typbyval,
- typalign, &args_res, &nulls_res,
+ typalign, typstor, &args_res, &nulls_res,
&nargs);
/* All the elements of the array have the same type */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index c10c0844ab6..c79a04a3472 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -6420,6 +6420,7 @@ TransformGUCArray(ArrayType *array, List **names, List **values)
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typalign */ ,
&isnull);
if (isnull)
@@ -6529,6 +6530,7 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typalign */ ,
&isnull);
if (isnull)
continue;
@@ -6548,7 +6550,8 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
-1 /* varlena array */ ,
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
- TYPALIGN_INT /* TEXT's typalign */ );
+ TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typstorage */ );
}
else
a = construct_array_builtin(&datum, 1, TEXTOID);
@@ -6598,6 +6601,7 @@ GUCArrayDelete(ArrayType *array, const char *name)
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typalign */ ,
&isnull);
if (isnull)
continue;
@@ -6616,7 +6620,8 @@ GUCArrayDelete(ArrayType *array, const char *name)
-1 /* varlenarray */ ,
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
- TYPALIGN_INT /* TEXT's typalign */ );
+ TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typstorage */ );
else
newarray = construct_array_builtin(&d, 1, TEXTOID);
@@ -6662,6 +6667,7 @@ GUCArrayReset(ArrayType *array)
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typalign */ ,
&isnull);
if (isnull)
continue;
@@ -6682,7 +6688,8 @@ GUCArrayReset(ArrayType *array)
-1 /* varlenarray */ ,
-1 /* TEXT's typlen */ ,
false /* TEXT's typbyval */ ,
- TYPALIGN_INT /* TEXT's typalign */ );
+ TYPALIGN_INT /* TEXT's typalign */ ,
+ TYPSTORAGE_EXTENDED /* TEXT's typstorage */ );
else
newarray = construct_array_builtin(&d, 1, TEXTOID);
diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h
index 0de67e3602a..f2264767fbb 100644
--- a/src/include/access/tupmacs.h
+++ b/src/include/access/tupmacs.h
@@ -199,6 +199,35 @@ fetch_att(const void *T, bool attbyval, int attlen)
)) \
)
+/*
+ * att_addvarsize_datum increments the given offset by the space needed for
+ * the given Datum variable to store it. attdatum is only accessed if we are
+ * dealing with a variable-length attribute.
+ */
+#define att_addvarsize_datum(cur_offset, typlen, typstor, datum) \
+ att_addvarsize_pointer(cur_offset, typlen, typstor, DatumGetPointer(datum))
+
+#define att_addvarsize_pointer(cur_offset, typlen, typstor, ptr) \
+( \
+ ((typlen) > 0) ? \
+ ( \
+ (cur_offset) + (typlen) \
+ ) \
+ : (((typlen) == -1) ? \
+ ( \
+ ((TYPE_IS_PACKABLE(typlen, typstor) && VARATT_CAN_MAKE_SHORT(ptr)) ? \
+ (cur_offset) + VARATT_CONVERTED_SHORT_SIZE(ptr) \
+ : \
+ (cur_offset) + VARSIZE_ANY(ptr) \
+ ) \
+ ) \
+ : \
+ ( \
+ AssertMacro((typlen) == -2), \
+ (cur_offset) + (strlen((char *) (ptr)) + 1) \
+ )) \
+)
+
#ifndef FRONTEND
/*
* store_att_byval is a partial inverse of fetch_att: store a given Datum
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index 33035d4ed82..9d55dcc419e 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -16,6 +16,8 @@
#include "nodes/execnodes.h"
#include "nodes/parsenodes.h"
+#include "utils/array.h"
+#include "utils/lsyscache.h"
/*
@@ -61,6 +63,10 @@ union YYSTYPE;
typedef void *yyscan_t;
#endif
+extern void boot_array_type_metadata(Oid typid,
+ IOFuncSelector which_func,
+ ArrayMetaState *metadata);
+
extern int boot_yyparse(yyscan_t yyscanner);
extern int boot_yylex_init(yyscan_t *yyscannerp);
extern int boot_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index e9259697321..652e9467333 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -345,6 +345,10 @@ MAKE_SYSCACHE(TYPENAMENSP, pg_type_typname_nsp_index, 64);
#endif /* EXPOSE_TO_CLIENT_CODE */
+/* Does datatype allow packing into the 1-byte-header varlena format? */
+#define TYPE_IS_PACKABLE(typlen, typstorage) \
+ ((typlen) == -1 && (typstorage) != TYPSTORAGE_PLAIN)
+
extern ObjectAddress TypeShellMake(const char *typeName,
Oid typeNamespace,
Oid ownerId);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 759f9a87d38..84e2def31cb 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -163,6 +163,7 @@ typedef struct VacAttrStats
int16 statyplen[STATISTIC_NUM_SLOTS];
bool statypbyval[STATISTIC_NUM_SLOTS];
char statypalign[STATISTIC_NUM_SLOTS];
+ char statypstorage[STATISTIC_NUM_SLOTS];
/*
* These fields are private to the main ANALYZE code and should not be
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index 56fb0d0adbe..f17cedc26b0 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -458,6 +458,7 @@ typedef struct ExprEvalStep
int16 elemlength; /* typlen of the array element type */
bool elembyval; /* is the element type pass-by-value? */
char elemalign; /* typalign of the element type */
+ char elemstorage; /* typstorage of the element type */
bool multidims; /* is array expression multi-D? */
} arrayexpr;
diff --git a/src/include/utils/array.h b/src/include/utils/array.h
index 157cc0e4c6e..711b37f6714 100644
--- a/src/include/utils/array.h
+++ b/src/include/utils/array.h
@@ -130,6 +130,7 @@ typedef struct ExpandedArrayHeader
int16 typlen; /* needed info about element datatype */
bool typbyval;
char typalign;
+ char typstorage;
/*
* If we have a Datum-array representation of the array, it's kept here;
@@ -195,6 +196,7 @@ typedef struct ArrayBuildState
int16 typlen; /* needed info about datatype */
bool typbyval;
char typalign;
+ char typstorage;
bool private_cxt; /* use private memory context */
} ArrayBuildState;
@@ -240,6 +242,7 @@ typedef struct ArrayMetaState
bool typbyval;
char typalign;
char typdelim;
+ char typstorage;
Oid typioparam;
Oid typiofunc;
FmgrInfo proc;
@@ -358,30 +361,34 @@ extern void CopyArrayEls(ArrayType *array,
int typlen,
bool typbyval,
char typalign,
+ char typstor,
bool freedata);
extern Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign,
- bool *isNull);
+ int arraytyplen, int elmlen, bool elmbyval,
+ char elmalign, char elmstor, bool *isNull);
extern Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx,
Datum dataValue, bool isNull,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign);
+ int arraytyplen, int elmlen, bool elmbyval,
+ char elmalign, char elmstor);
extern Datum array_get_slice(Datum arraydatum, int nSubscripts,
int *upperIndx, int *lowerIndx,
bool *upperProvided, bool *lowerProvided,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign);
+ int arraytyplen, int elmlen, bool elmbyval,
+ char elmalign, char typstor);
extern Datum array_set_slice(Datum arraydatum, int nSubscripts,
int *upperIndx, int *lowerIndx,
bool *upperProvided, bool *lowerProvided,
Datum srcArrayDatum, bool isNull,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign);
+ int arraytyplen, int elmlen, bool elmbyval,
+ char elmalign, char elmstor);
extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
int arraytyplen, int elmlen, bool elmbyval, char elmalign,
- bool *isNull);
+ char elmstor, bool *isNull);
extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx,
- Datum dataValue, bool isNull,
- int arraytyplen, int elmlen, bool elmbyval, char elmalign);
+ Datum dataValue, bool isNull, int arraytyplen,
+ int elmlen, bool elmbyval, char elmalign, char elmstor);
extern Datum array_map(Datum arrayd,
struct ExprState *exprstate, struct ExprContext *econtext,
@@ -393,21 +400,23 @@ 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);
+ int elmlen, bool elmbyval,
+ char elmalign, char elmstor);
extern ArrayType *construct_array_builtin(Datum *elems, int nelems, Oid elmtype);
extern ArrayType *construct_md_array(Datum *elems,
bool *nulls,
int ndims,
int *dims,
int *lbs,
- Oid elmtype, int elmlen, bool elmbyval, char elmalign);
+ Oid elmtype, int elmlen, bool elmbyval,
+ char elmalign, char elmstor);
extern ArrayType *construct_empty_array(Oid elmtype);
extern ExpandedArrayHeader *construct_empty_expanded_array(Oid element_type,
MemoryContext parentcontext,
ArrayMetaState *metacache);
extern void deconstruct_array(ArrayType *array,
Oid elmtype,
- int elmlen, bool elmbyval, char elmalign,
+ int elmlen, bool elmbyval, char elmalign, char elmstor,
Datum **elemsp, bool **nullsp, int *nelemsp);
extern void deconstruct_array_builtin(ArrayType *array,
Oid elmtype,
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 20446f6f836..5ee3ab2cdb8 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -16,6 +16,7 @@
#include "access/attnum.h"
#include "access/htup.h"
#include "nodes/pg_list.h"
+#include "utils/array.h"
/* avoid including subscripting.h here */
struct SubscriptRoutines;
@@ -150,7 +151,12 @@ extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval);
extern void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval,
char *typalign);
+extern void get_type_stores(Oid typid, int16 *typlen,
+ bool *typbyval, char *typalign, char *typstor);
extern Oid getTypeIOParam(HeapTuple typeTuple);
+extern void array_type_metadata(Oid typid,
+ IOFuncSelector which_func,
+ ArrayMetaState *metadata);
extern void get_type_io_data(Oid typid,
IOFuncSelector which_func,
int16 *typlen,
diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h
index 773a5d2c347..339745f5081 100644
--- a/src/include/utils/palloc.h
+++ b/src/include/utils/palloc.h
@@ -85,6 +85,12 @@ extern pg_nodiscard void *repalloc_extended(void *pointer,
extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size);
extern void pfree(void *pointer);
+#define PFREE_IF_NEW(newptr, oldptr) \
+ do { \
+ if ((Pointer)(newptr) != (Pointer)(oldptr)) \
+ pfree(newptr); \
+ } while (0)
+
/*
* Variants with easier notation and more type safety
*/
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 1b1677e333b..85b5b1be9f4 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -1484,6 +1484,7 @@ plperl_ref_from_pg_array(Datum arg, Oid typid)
int16 typlen;
bool typbyval;
char typalign,
+ typstor,
typdelim;
Oid typioparam;
Oid typoutputfunc;
@@ -1506,6 +1507,8 @@ plperl_ref_from_pg_array(Datum arg, Oid typid)
&typlen, &typbyval, &typalign,
&typdelim, &typioparam, &typoutputfunc);
+ typstor = get_typstorage(elementtype);
+
/* Check for a transform function */
transform_funcid = get_transform_fromsql(elementtype,
current_call_data->prodesc->lang_oid,
@@ -1531,8 +1534,8 @@ plperl_ref_from_pg_array(Datum arg, Oid typid)
else
{
deconstruct_array(ar, elementtype, typlen, typbyval,
- typalign, &info->elements, &info->nulls,
- &nitems);
+ typalign, typstor,
+ &info->elements, &info->nulls, &nitems);
/* Get total number of elements in each dimension */
info->nelems = palloc(sizeof(int) * info->ndims);
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index e31206e7f4c..067b82427d6 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -1491,7 +1491,9 @@ plpgsql_fulfill_promise(PLpgSQL_execstate *estate,
PointerGetDatum(construct_md_array(elems, NULL,
1, dims, lbs,
TEXTOID,
- -1, false, TYPALIGN_INT)),
+ -1, false,
+ TYPALIGN_INT,
+ TYPSTORAGE_EXTENDED)),
false, true);
}
else
diff --git a/src/test/modules/test_regex/test_regex.c b/src/test/modules/test_regex/test_regex.c
index a780c678fbc..b3e0564f6da 100644
--- a/src/test/modules/test_regex/test_regex.c
+++ b/src/test/modules/test_regex/test_regex.c
@@ -678,7 +678,8 @@ build_test_info_result(regex_t *cpattern, test_re_flags *flags)
lbs[0] = 1;
/* XXX: this hardcodes assumptions about the text type */
return construct_md_array(elems, NULL, 1, dims, lbs,
- TEXTOID, -1, false, TYPALIGN_INT);
+ TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
}
/*
@@ -758,5 +759,6 @@ build_test_match_result(test_regex_ctx *matchctx)
lbs[0] = 1;
/* XXX: this hardcodes assumptions about the text type */
return construct_md_array(elems, nulls, 1, dims, lbs,
- TEXTOID, -1, false, TYPALIGN_INT);
+ TEXTOID, -1, false,
+ TYPALIGN_INT, TYPSTORAGE_EXTENDED);
}