aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
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