aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2022-07-01 10:51:45 +0200
committerPeter Eisentraut <peter@eisentraut.org>2022-07-01 11:23:15 +0200
commitd746021de18baf0f29eff0388204a0664f41eb8b (patch)
tree21074e7935e62cd054e702d79e5c1fe7c8544733 /src/backend/utils/adt/arrayfuncs.c
parent7c2d6f8d3400edab2b91de7765db9ec71235fac9 (diff)
downloadpostgresql-d746021de18baf0f29eff0388204a0664f41eb8b.tar.gz
postgresql-d746021de18baf0f29eff0388204a0664f41eb8b.zip
Add construct_array_builtin, deconstruct_array_builtin
There were many calls to construct_array() and deconstruct_array() for built-in types, for example, when dealing with system catalog columns. These all hardcoded the type attributes necessary to pass to these functions. To simplify this a bit, add construct_array_builtin(), deconstruct_array_builtin() as wrappers that centralize this hardcoded knowledge. This simplifies many call sites and reduces the amount of hardcoded stuff that is spread around. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/2914356f-9e5f-8c59-2995-5997fc48bcba%40enterprisedb.com
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c161
1 files changed, 158 insertions, 3 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 2570e5e6301..b0c37ede87d 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -3331,6 +3331,92 @@ construct_array(Datum *elems, int nelems,
}
/*
+ * Like construct_array(), where elmtype must be a built-in type, and
+ * elmlen/elmbyval/elmalign is looked up from hardcoded data. This is often
+ * useful when manipulating arrays from/for system catalogs.
+ */
+ArrayType *
+construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
+{
+ int elmlen;
+ bool elmbyval;
+ char elmalign;
+
+ switch (elmtype)
+ {
+ case CHAROID:
+ elmlen = 1;
+ elmbyval = true;
+ elmalign = TYPALIGN_CHAR;
+ break;
+
+ case CSTRINGOID:
+ elmlen = -2;
+ elmbyval = false;
+ elmalign = TYPALIGN_CHAR;
+ break;
+
+ case FLOAT4OID:
+ elmlen = sizeof(float4);
+ elmbyval = true;
+ elmalign = TYPALIGN_INT;
+ break;
+
+ case INT2OID:
+ elmlen = sizeof(int16);
+ elmbyval = true;
+ elmalign = TYPALIGN_SHORT;
+ break;
+
+ case INT4OID:
+ elmlen = sizeof(int32);
+ elmbyval = true;
+ elmalign = TYPALIGN_INT;
+ break;
+
+ case INT8OID:
+ elmlen = sizeof(int64);
+ elmbyval = FLOAT8PASSBYVAL;
+ elmalign = TYPALIGN_DOUBLE;
+ break;
+
+ case NAMEOID:
+ elmlen = NAMEDATALEN;
+ elmbyval = false;
+ elmalign = TYPALIGN_CHAR;
+ break;
+
+ case OIDOID:
+ case REGTYPEOID:
+ elmlen = sizeof(Oid);
+ elmbyval = true;
+ elmalign = TYPALIGN_INT;
+ break;
+
+ case TEXTOID:
+ elmlen = -1;
+ elmbyval = false;
+ elmalign = TYPALIGN_INT;
+ break;
+
+ case TIDOID:
+ elmlen = sizeof(ItemPointerData);
+ elmbyval = false;
+ elmalign = TYPALIGN_SHORT;
+ break;
+
+ default:
+ elog(ERROR, "type %u not supported by construct_array_builtin()", elmtype);
+ /* keep compiler quiet */
+ elmlen = 0;
+ elmbyval = false;
+ elmalign = 0;
+ }
+
+ return construct_array(elems, nelems, elmtype, elmlen, elmbyval, elmalign);
+}
+
+/*
* construct_md_array --- simple method for constructing an array object
* with arbitrary dimensions and possible NULLs
*
@@ -3483,9 +3569,9 @@ construct_empty_expanded_array(Oid element_type,
* be pointers into the array object.
*
* NOTE: it would be cleaner to look up the elmlen/elmbval/elmalign info
- * from the system catalogs, given the elmtype. However, in most current
- * uses the type is hard-wired into the caller and so we can save a lookup
- * cycle by hard-wiring the type info as well.
+ * from the system catalogs, given the elmtype. However, the caller is
+ * in a better position to cache this info across multiple uses, or even
+ * to hard-wire values if the element type is hard-wired.
*/
void
deconstruct_array(ArrayType *array,
@@ -3549,6 +3635,75 @@ deconstruct_array(ArrayType *array,
}
/*
+ * Like deconstruct_array(), where elmtype must be a built-in type, and
+ * elmlen/elmbyval/elmalign is looked up from hardcoded data. This is often
+ * useful when manipulating arrays from/for system catalogs.
+ */
+void
+deconstruct_array_builtin(ArrayType *array,
+ Oid elmtype,
+ Datum **elemsp, bool **nullsp, int *nelemsp)
+{
+ int elmlen;
+ bool elmbyval;
+ char elmalign;
+
+ switch (elmtype)
+ {
+ case CHAROID:
+ elmlen = 1;
+ elmbyval = true;
+ elmalign = TYPALIGN_CHAR;
+ break;
+
+ case CSTRINGOID:
+ elmlen = -2;
+ elmbyval = false;
+ elmalign = TYPALIGN_CHAR;
+ break;
+
+ case FLOAT8OID:
+ elmlen = sizeof(float8);
+ elmbyval = FLOAT8PASSBYVAL;
+ elmalign = TYPALIGN_DOUBLE;
+ break;
+
+ case INT2OID:
+ elmlen = sizeof(int16);
+ elmbyval = true;
+ elmalign = TYPALIGN_SHORT;
+ break;
+
+ case OIDOID:
+ elmlen = sizeof(Oid);
+ elmbyval = true;
+ elmalign = TYPALIGN_INT;
+ break;
+
+ case TEXTOID:
+ elmlen = -1;
+ elmbyval = false;
+ elmalign = TYPALIGN_INT;
+ break;
+
+ case TIDOID:
+ elmlen = sizeof(ItemPointerData);
+ elmbyval = false;
+ elmalign = TYPALIGN_SHORT;
+ break;
+
+ default:
+ elog(ERROR, "type %u not supported by deconstruct_array_builtin()", elmtype);
+ /* keep compiler quiet */
+ elmlen = 0;
+ elmbyval = false;
+ elmalign = 0;
+ }
+
+ deconstruct_array(array, elmtype, elmlen, elmbyval, elmalign, elemsp, nullsp, nelemsp);
+}
+
+/*
* array_contains_nulls --- detect whether an array has any null elements
*
* This gives an accurate answer, whereas testing ARR_HASNULL only tells