예제 #1
0
파일: int8.c 프로젝트: winlibs/postgresql
Datum
int84mi(PG_FUNCTION_ARGS)
{
	int64		arg1 = PG_GETARG_INT64(0);
	int32		arg2 = PG_GETARG_INT32(1);
	int64		result;

	result = arg1 - arg2;

	/*
	 * Overflow check.  If the inputs are of the same sign then their
	 * difference cannot overflow.  If they are of different signs then the
	 * result should be of the same sign as the first input.
	 */
	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("bigint out of range")));
	PG_RETURN_INT64(result);
}
예제 #2
0
파일: int8.c 프로젝트: winlibs/postgresql
Datum
int84pl(PG_FUNCTION_ARGS)
{
	int64		arg1 = PG_GETARG_INT64(0);
	int32		arg2 = PG_GETARG_INT32(1);
	int64		result;

	result = arg1 + arg2;

	/*
	 * Overflow check.  If the inputs are of different signs then their sum
	 * cannot overflow.  If the inputs are of the same sign, their sum had
	 * better be that sign too.
	 */
	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("bigint out of range")));
	PG_RETURN_INT64(result);
}
예제 #3
0
파일: int.c 프로젝트: colinet/sqlix
datum_t int42mi(PG_FUNC_ARGS)
{
	int32 arg1 = ARG_INT32(0);
	int16 arg2 = ARG_INT16(1);
	int32 result;

	result = arg1 - arg2;

	/*
	 * Overflow check.      If the inputs are of the same sign then their
	 * difference cannot overflow.  If they are of different signs then the
	 * result should be of the same sign as the first input.
	 */
	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
		ereport(ERROR, (
		errcode(E_NUMERIC_VALUE_OUT_OF_RANGE),
		errmsg("integer out of range")));

	RET_INT32(result);
}
예제 #4
0
파일: int.c 프로젝트: colinet/sqlix
datum_t int42pl(PG_FUNC_ARGS)
{
	int32 arg1 = ARG_INT32(0);
	int16 arg2 = ARG_INT16(1);
	int32 result;

	result = arg1 + arg2;

	/*
	 * Overflow check.      If the inputs are of different signs then their sum
	 * cannot overflow.  If the inputs are of the same sign, their sum had
	 * better be that sign too.
	 */
	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
		ereport(ERROR, (
		errcode(E_NUMERIC_VALUE_OUT_OF_RANGE),
		errmsg("integer out of range")));

	RET_INT32(result);
}
예제 #5
0
Datum
int2um(PG_FUNCTION_ARGS)
{
	int16		arg = PG_GETARG_INT16(0);
	int16		result;

	result = -arg;
	/* overflow check (needed for SHRT_MIN) */
	if (arg != 0 && SAMESIGN(result, arg))
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("smallint out of range")));
	PG_RETURN_INT16(result);
}
예제 #6
0
Datum
int4um(PG_FUNCTION_ARGS)
{
	int32		arg = PG_GETARG_INT32(0);
	int32		result;

	result = -arg;
	/* overflow check (needed for INT_MIN) */
	if (arg != 0 && SAMESIGN(result, arg))
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("integer out of range")));
	PG_RETURN_INT32(result);
}
예제 #7
0
파일: int8.c 프로젝트: pgresql/postgres-xl
Datum
int84div(PG_FUNCTION_ARGS)
{
    int64		arg1 = PG_GETARG_INT64(0);
    int32		arg2 = PG_GETARG_INT32(1);
    int64		result;

    if (arg2 == 0)
    {
        ereport(ERROR,
                (errcode(ERRCODE_DIVISION_BY_ZERO),
                 errmsg("division by zero")));
        /* ensure compiler realizes we mustn't reach the division (gcc bug) */
        PG_RETURN_NULL();
    }

    /*
     * INT64_MIN / -1 is problematic, since the result can't be represented on
     * a two's-complement machine.  Some machines produce INT64_MIN, some
     * produce zero, some throw an exception.  We can dodge the problem by
     * recognizing that division by -1 is the same as negation.
     */
    if (arg2 == -1)
    {
        result = -arg1;
        /* overflow check (needed for INT64_MIN) */
        if (arg1 != 0 && SAMESIGN(result, arg1))
            ereport(ERROR,
                    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                     errmsg("bigint out of range")));
        PG_RETURN_INT64(result);
    }

    /* No overflow is possible */

    result = arg1 / arg2;

    PG_RETURN_INT64(result);
}
예제 #8
0
Datum
generate_series_step_int4(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	generate_series_fctx *fctx;
	int32		result;
	MemoryContext oldcontext;

	/* stuff done only on the first call of the function */
	if (SRF_IS_FIRSTCALL())
	{
		int32		start = PG_GETARG_INT32(0);
		int32		finish = PG_GETARG_INT32(1);
		int32		step = 1;

		/* see if we were given an explicit step size */
		if (PG_NARGS() == 3)
			step = PG_GETARG_INT32(2);
		if (step == 0)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("step size may not equal zero")));

		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		 * switch to memory context appropriate for multiple function calls
		 */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* allocate memory for user context */
		fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));

		/*
		 * Use fctx to keep state from call to call. Seed current with the
		 * original start value
		 */
		fctx->current = start;
		fctx->finish = finish;
		fctx->step = step;

		funcctx->user_fctx = fctx;
		MemoryContextSwitchTo(oldcontext);
	}

	/* stuff done on every call of the function */
	funcctx = SRF_PERCALL_SETUP();

	/*
	 * get the saved state and use current as the result for this iteration
	 */
	fctx = funcctx->user_fctx;
	result = fctx->current;

	if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
		(fctx->step < 0 && fctx->current >= fctx->finish))
	{
		/* increment current in preparation for next iteration */
		fctx->current += fctx->step;

		/* if next-value computation overflows, this is the final result */
		if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
			fctx->step = 0;

		/* do when there is more left to send */
		SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
	}
	else
		/* do when there is no more left */
		SRF_RETURN_DONE(funcctx);
}