1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-11 10:01:57 +03:00

Add trim_array() function.

This has been in the SQL spec since 2008.  It's a pretty thin
wrapper around the array slice functionality, but the spec
says we should have it, so here it is.

Vik Fearing, reviewed by Dian Fay

Discussion: https://postgr.es/m/fc92ce17-9655-8ff1-c62a-4dc4c8ccd815@postgresfriends.org
This commit is contained in:
Tom Lane
2021-03-03 16:39:57 -05:00
parent 3769e11a31
commit 0a687c8f10
7 changed files with 100 additions and 2 deletions

View File

@ -6631,3 +6631,46 @@ width_bucket_array_variable(Datum operand,
return left;
}
/*
* Trim the last N elements from an array by building an appropriate slice.
* Only the first dimension is trimmed.
*/
Datum
trim_array(PG_FUNCTION_ARGS)
{
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
int n = PG_GETARG_INT32(1);
int array_length = ARR_DIMS(v)[0];
int16 elmlen;
bool elmbyval;
char elmalign;
int lower[MAXDIM];
int upper[MAXDIM];
bool lowerProvided[MAXDIM];
bool upperProvided[MAXDIM];
Datum result;
/* Per spec, throw an error if out of bounds */
if (n < 0 || n > array_length)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
errmsg("number of elements to trim must be between 0 and %d",
array_length)));
/* Set all the bounds as unprovided except the first upper bound */
memset(lowerProvided, false, sizeof(lowerProvided));
memset(upperProvided, false, sizeof(upperProvided));
upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1;
upperProvided[0] = true;
/* Fetch the needed information about the element type */
get_typlenbyvalalign(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign);
/* Get the slice */
result = array_get_slice(PointerGetDatum(v), 1,
upper, lower, upperProvided, lowerProvided,
-1, elmlen, elmbyval, elmalign);
PG_RETURN_DATUM(result);
}