/*----------------------------------------------------------------------------- * array_prepend : * push an element onto the front of a one-dimensional array *---------------------------------------------------------------------------- */ Datum array_prepend(PG_FUNCTION_ARGS) { ExpandedArrayHeader *eah; Datum newelem; bool isNull; Datum result; int *lb; int indx; int lb0; ArrayMetaState *my_extra; isNull = PG_ARGISNULL(0); if (isNull) newelem = (Datum) 0; else newelem = PG_GETARG_DATUM(0); eah = fetch_array_arg_replace_nulls(fcinfo, 1); if (eah->ndims == 1) { /* prepend newelem */ lb = eah->lbound; indx = lb[0] - 1; lb0 = lb[0]; /* overflow? */ if (indx > lb[0]) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else if (eah->ndims == 0) { indx = 1; lb0 = 1; } else ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("argument must be empty or one-dimensional array"))); /* Perform element insertion */ 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); /* Readjust result's LB to match the input's, as expected for prepend */ Assert(result == EOHPGetRWDatum(&eah->hdr)); if (eah->ndims == 1) { /* This is ok whether we've deconstructed or not */ eah->lbound[0] = lb0; } PG_RETURN_DATUM(result); }
/*----------------------------------------------------------------------------- * array_append : * push an element onto the end of a one-dimensional array *---------------------------------------------------------------------------- */ Datum array_append(PG_FUNCTION_ARGS) { ExpandedArrayHeader *eah; Datum newelem; bool isNull; Datum result; int *dimv, *lb; int indx; ArrayMetaState *my_extra; eah = fetch_array_arg_replace_nulls(fcinfo, 0); isNull = PG_ARGISNULL(1); if (isNull) newelem = (Datum) 0; else newelem = PG_GETARG_DATUM(1); if (eah->ndims == 1) { /* append newelem */ int ub; lb = eah->lbound; dimv = eah->dims; ub = dimv[0] + lb[0] - 1; indx = ub + 1; /* overflow? */ if (indx < ub) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else if (eah->ndims == 0) indx = 1; else ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("argument must be empty or one-dimensional array"))); /* Perform element insertion */ 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); PG_RETURN_DATUM(result); }
/*----------------------------------------------------------------------------- * array_append : * push an element onto the end of a one-dimensional array *---------------------------------------------------------------------------- */ Datum array_append(PG_FUNCTION_ARGS) { ArrayType *v; Datum newelem; bool isNull; ArrayType *result; int *dimv, *lb; int indx; ArrayMetaState *my_extra; v = fetch_array_arg_replace_nulls(fcinfo, 0); isNull = PG_ARGISNULL(1); if (isNull) newelem = (Datum) 0; else newelem = PG_GETARG_DATUM(1); if (ARR_NDIM(v) == 1) { /* append newelem */ int ub; lb = ARR_LBOUND(v); dimv = ARR_DIMS(v); ub = dimv[0] + lb[0] - 1; indx = ub + 1; /* overflow? */ if (indx < ub) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else if (ARR_NDIM(v) == 0) indx = 1; else ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("argument must be empty or one-dimensional array"))); /* Perform element insertion */ my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; result = array_set(v, 1, &indx, newelem, isNull, -1, my_extra->typlen, my_extra->typbyval, my_extra->typalign); PG_RETURN_ARRAYTYPE_P(result); }
/*----------------------------------------------------------------------------- * array_prepend : * push an element onto the front of a one-dimensional array *---------------------------------------------------------------------------- */ Datum array_prepend(PG_FUNCTION_ARGS) { ArrayType *v; Datum newelem; bool isNull; ArrayType *result; int *lb; int indx; ArrayMetaState *my_extra; isNull = PG_ARGISNULL(0); if (isNull) newelem = (Datum) 0; else newelem = PG_GETARG_DATUM(0); v = fetch_array_arg_replace_nulls(fcinfo, 1); if (ARR_NDIM(v) == 1) { /* prepend newelem */ lb = ARR_LBOUND(v); indx = lb[0] - 1; /* overflow? */ if (indx > lb[0]) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else if (ARR_NDIM(v) == 0) indx = 1; else ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("argument must be empty or one-dimensional array"))); /* Perform element insertion */ my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; result = array_set(v, 1, &indx, newelem, isNull, -1, my_extra->typlen, my_extra->typbyval, my_extra->typalign); /* Readjust result's LB to match the input's, as expected for prepend */ if (ARR_NDIM(v) == 1) ARR_LBOUND(result)[0] = ARR_LBOUND(v)[0]; PG_RETURN_ARRAYTYPE_P(result); }