Example #1
0
/*-----------------------------------------------------------------------------
 * 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);
}
Example #2
0
/*-----------------------------------------------------------------------------
 * 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);
}
Example #3
0
/*-----------------------------------------------------------------------------
 * 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);
}
Example #4
0
/*-----------------------------------------------------------------------------
 * 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);
}