diff options
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r-- | src/backend/utils/adt/arrayfuncs.c | 161 |
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 |