📄 int.c
字号:
PG_RETURN_INT32(result);}Datumint4mi(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(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(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint4mul(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); int32 result; result = arg1 * arg2; /* * Overflow check. We basically check to see if result / arg2 gives arg1 * again. There are two cases where this fails: arg2 = 0 (which cannot * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will * overflow and thus incorrectly match). * * Since the division is likely much more expensive than the actual * multiplication, we'd like to skip it where possible. The best bang for * the buck seems to be to check whether both inputs are in the int16 * range; if so, no overflow is possible. */ if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX && arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) && arg2 != 0 && (result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint4div(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); int32 result; if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); result = arg1 / arg2; /* * Overflow check. The only possible overflow case is for arg1 = INT_MIN, * arg2 = -1, where the correct result is -INT_MIN, which can't be * represented on a two's-complement machine. */ if (arg2 == -1 && arg1 < 0 && result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint4inc(PG_FUNCTION_ARGS){ int32 arg = PG_GETARG_INT32(0); int32 result; result = arg + 1; /* Overflow check */ if (arg > 0 && result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint2um(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);}Datumint2up(PG_FUNCTION_ARGS){ int16 arg = PG_GETARG_INT16(0); PG_RETURN_INT16(arg);}Datumint2pl(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); int16 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("smallint out of range"))); PG_RETURN_INT16(result);}Datumint2mi(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); int16 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("smallint out of range"))); PG_RETURN_INT16(result);}Datumint2mul(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); int32 result32; /* * The most practical way to detect overflow is to do the arithmetic in * int32 (so that the result can't overflow) and then do a range check. */ result32 = (int32) arg1 *(int32) arg2; if (result32 < SHRT_MIN || result32 > SHRT_MAX) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); PG_RETURN_INT16((int16) result32);}Datumint2div(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); int16 result; if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); result = arg1 / arg2; /* * Overflow check. The only possible overflow case is for arg1 = * SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN, which can't * be represented on a two's-complement machine. */ if (arg2 == -1 && arg1 < 0 && result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); PG_RETURN_INT16(result);}Datumint24pl(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(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(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint24mi(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(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(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint24mul(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(1); int32 result; result = arg1 * arg2; /* * Overflow check. We basically check to see if result / arg2 gives arg1 * again. There is one case where this fails: arg2 = 0 (which cannot * overflow). * * Since the division is likely much more expensive than the actual * multiplication, we'd like to skip it where possible. The best bang for * the buck seems to be to check whether both inputs are in the int16 * range; if so, no overflow is possible. */ if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) && result / arg2 != arg1) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint24div(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(1); if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT32((int32) arg1 / arg2);}Datumint42pl(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int16 arg2 = PG_GETARG_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(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint42mi(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int16 arg2 = PG_GETARG_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(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint42mul(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int16 arg2 = PG_GETARG_INT16(1); int32 result; result = arg1 * arg2; /* * Overflow check. We basically check to see if result / arg1 gives arg2 * again. There is one case where this fails: arg1 = 0 (which cannot * overflow). * * Since the division is likely much more expensive than the actual * multiplication, we'd like to skip it where possible. The best bang for * the buck seems to be to check whether both inputs are in the int16 * range; if so, no overflow is possible. */ if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) && result / arg1 != arg2) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint42div(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int16 arg2 = PG_GETARG_INT16(1); int32 result; if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); result = arg1 / arg2; /* * Overflow check. The only possible overflow case is for arg1 = INT_MIN, * arg2 = -1, where the correct result is -INT_MIN, which can't be * represented on a two's-complement machine. */ if (arg2 == -1 && arg1 < 0 && result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint4mod(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT32(arg1 % arg2);}Datumint2mod(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT16(arg1 % arg2);}Datumint24mod(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(1); if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT32(arg1 % arg2);}Datumint42mod(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int16 arg2 = PG_GETARG_INT16(1); if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT32(arg1 % arg2);}/* int[24]abs() * Absolute value */Datumint4abs(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 result; result = (arg1 < 0) ? -arg1 : arg1; /* overflow check (needed for INT_MIN) */ if (result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); PG_RETURN_INT32(result);}Datumint2abs(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 result; result = (arg1 < 0) ? -arg1 : arg1; /* overflow check (needed for SHRT_MIN) */ if (result < 0) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); PG_RETURN_INT16(result);}Datumint2larger(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);}Datumint2smaller(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);}Datumint4larger(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);}Datumint4smaller(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);}/* * Bit-pushing operators * * int[24]and - returns arg1 & arg2 * int[24]or - returns arg1 | arg2 * int[24]xor - returns arg1 # arg2 * int[24]not - returns ~arg1 * int[24]shl - returns arg1 << arg2 * int[24]shr - returns arg1 >> arg2 */Datumint4and(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32(arg1 & arg2);}Datumint4or(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32(arg1 | arg2);}Datumint4xor(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32(arg1 ^ arg2);}Datumint4shl(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32(arg1 << arg2);}Datumint4shr(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT32(arg1 >> arg2);}Datumint4not(PG_FUNCTION_ARGS){ int32 arg1 = PG_GETARG_INT32(0); PG_RETURN_INT32(~arg1);}Datumint2and(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); PG_RETURN_INT16(arg1 & arg2);}Datumint2or(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); PG_RETURN_INT16(arg1 | arg2);}Datumint2xor(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int16 arg2 = PG_GETARG_INT16(1); PG_RETURN_INT16(arg1 ^ arg2);}Datumint2not(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); PG_RETURN_INT16(~arg1);}Datumint2shl(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT16(arg1 << arg2);}Datumint2shr(PG_FUNCTION_ARGS){ int16 arg1 = PG_GETARG_INT16(0); int32 arg2 = PG_GETARG_INT32(1); PG_RETURN_INT16(arg1 >> arg2);}/* * non-persistent numeric series generator */Datumgenerate_series_int4(PG_FUNCTION_ARGS){ return generate_series_step_int4(fcinfo);}Datumgenerate_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; /* 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -