*
* int.c
* Functions for the built-in integer types (except int8).
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 2021, openGauss Contributors
*
*
* IDENTIFICATION
* src/backend/utils/adt/int.c
*
* -------------------------------------------------------------------------
*/
* OLD COMMENTS
* I/O routines:
* int2in, int2out, int2recv, int2send
* int4in, int4out, int4recv, int4send
* int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
* Boolean operators:
* inteq, intne, intlt, intle, intgt, intge
* Arithmetic operators:
* intpl, intmi, int4mul, intdiv
*
* Arithmetic operators:
* intmod
*/
#include "postgres.h"
#include "knl/knl_variable.h"
#include <ctype.h>
#include <limits.h>
#include "catalog/pg_type.h"
#include "common/int.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/numeric.h"
#include "utils/formatting.h"
#include "plugin_commands/mysqlmode.h"
#include "plugin_utils/int8.h"
#include "plugin_utils/tinyint.h"
#define SAMESIGN(a, b) (((a) < 0) == ((b) < 0))
#define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int16))
typedef struct {
int32 current;
int32 finish;
int32 step;
} generate_series_fctx;
* USER I/O ROUTINES *
*****************************************************************************/
* int2in - converts "num" to short
*/
Datum int2in(PG_FUNCTION_ARGS)
{
char* num = PG_GETARG_CSTRING(0);
#ifdef DOLPHIN
PG_RETURN_INT16(PgStrToIntInternal<false>(num, fcinfo->can_ignore || !SQL_MODE_STRICT(),
PG_INT16_MAX, PG_INT16_MIN, "smallint"));
#else
if (DB_IS_CMPT(A_FORMAT) && ACCEPT_FLOAT_STR_AS_INT) {
PG_RETURN_INT16(PgStrToIntInternal<false>(num, fcinfo->can_ignore,
PG_INT16_MAX, PG_INT16_MIN, "smallint"));
} else {
PG_RETURN_INT16(pg_strtoint16(num, fcinfo->can_ignore));
}
#endif
}
* int2out - converts short to "num"
*/
Datum int2out(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
char* result = (char*)palloc(7);
pg_itoa(arg1, result);
PG_RETURN_CSTRING(result);
}
* int2recv - converts external binary format to int2
*/
Datum int2recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
PG_RETURN_INT16((int16)pq_getmsgint(buf, sizeof(int16)));
}
* int2send - converts int2 to binary format
*/
Datum int2send(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint16(&buf, arg1);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
* construct int2vector given a raw array of int2s
*
* If int2s is NULL then caller must fill values[] afterward
*/
int2vector* buildint2vector(const int2* int2s, int n)
{
int2vector* result = NULL;
result = (int2vector*)palloc0(Int2VectorSize(n));
if (n > 0 && int2s) {
errno_t rc = memcpy_s(result->values, n * sizeof(int16), int2s, n * sizeof(int2));
securec_check(rc, "\0", "\0");
}
* Attach standard array header. For historical reasons, we set the index
* lower bound to 0 not 1.
*/
SET_VARSIZE(result, Int2VectorSize(n));
result->ndim = 1;
result->dataoffset = 0;
result->elemtype = INT2OID;
result->dim1 = n;
result->lbound1 = 0;
return result;
}
int2vector* int2vectorCopy(int2vector* from)
{
if (from == NULL || (from->dim1 == 1 && from->values[0] == 0)) {
return NULL;
}
int2vector* result = NULL;
int len = from->dim1;
result = buildint2vector(NULL, len);
for (int i = 0; i < len; i++) {
result->values[i] = from->values[i];
}
return result;
}
* int2vectorin - converts "num num ..." to internal form
*/
Datum int2vectorin(PG_FUNCTION_ARGS)
{
char* intString = PG_GETARG_CSTRING(0);
int2vector* result = NULL;
int n;
result = (int2vector*)palloc0(Int2VectorSize(FUNC_MAX_ARGS));
for (n = 0; *intString && n < FUNC_MAX_ARGS; n++) {
while (*intString && isspace((unsigned char)*intString))
intString++;
if (*intString == '\0')
break;
result->values[n] = pg_atoi(intString, sizeof(int16), ' ');
while (*intString && !isspace((unsigned char)*intString))
intString++;
}
while (*intString && isspace((unsigned char)*intString)) {
intString++;
}
if (*intString)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("int2vector has too many elements")));
SET_VARSIZE(result, Int2VectorSize(n));
result->ndim = 1;
result->dataoffset = 0;
result->elemtype = INT2OID;
result->dim1 = n;
result->lbound1 = 0;
PG_RETURN_POINTER(result);
}
* int2vectorout - converts internal form to "num num ..."
*/
Datum int2vectorout(PG_FUNCTION_ARGS)
{
int2vector* int2Array = (int2vector*)PG_GETARG_POINTER(0);
int num, nnums = int2Array->dim1;
char* rp = NULL;
char* result = NULL;
rp = result = (char*)palloc(nnums * 7 + 1);
for (num = 0; num < nnums; num++) {
if (num != 0)
*rp++ = ' ';
pg_itoa(int2Array->values[num], rp);
while (*++rp != '\0')
;
}
*rp = '\0';
PG_RETURN_CSTRING(result);
}
* int2vectorrecv - converts external binary format to int2vector
*/
Datum int2vectorrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
FunctionCallInfoData locfcinfo;
int2vector* result = NULL;
* Normally one would call array_recv() using DirectFunctionCall3, but
* that does not work since array_recv wants to cache some data using
* fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
* parameter.
*/
InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, InvalidOid, NULL, NULL);
locfcinfo.arg[0] = PointerGetDatum(buf);
locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
locfcinfo.arg[2] = Int32GetDatum(-1);
locfcinfo.argnull[0] = false;
locfcinfo.argnull[1] = false;
locfcinfo.argnull[2] = false;
result = (int2vector*)DatumGetPointer(array_recv(&locfcinfo));
Assert(!locfcinfo.isnull);
if (ARR_NDIM(result) != 1 || ARR_HASNULL(result) || ARR_ELEMTYPE(result) != INT2OID || ARR_LBOUND(result)[0] != 0)
ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid int2vector data")));
if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("oidvector has too many elements")));
PG_RETURN_POINTER(result);
}
* int2vectorsend - converts int2vector to binary format
*/
Datum int2vectorsend(PG_FUNCTION_ARGS)
{
return array_send(fcinfo);
}
Datum int2vectorin_extend(PG_FUNCTION_ARGS)
{
return int2vectorin(fcinfo);
}
Datum int2vectorout_extend(PG_FUNCTION_ARGS)
{
return int2vectorout(fcinfo);
}
Datum int2vectorrecv_extend(PG_FUNCTION_ARGS)
{
return int2vectorrecv(fcinfo);
}
Datum int2vectorsend_extend(PG_FUNCTION_ARGS)
{
return int2vectorsend(fcinfo);
}
* We don't have a complete set of int2vector support routines,
* but we need int2vectoreq for catcache indexing.
*/
Datum int2vectoreq(PG_FUNCTION_ARGS)
{
int2vector* a = (int2vector*)PG_GETARG_POINTER(0);
int2vector* b = (int2vector*)PG_GETARG_POINTER(1);
if (a->dim1 != b->dim1)
PG_RETURN_BOOL(false);
PG_RETURN_BOOL(memcmp(a->values, b->values, a->dim1 * sizeof(int2)) == 0);
}
* PUBLIC ROUTINES *
*****************************************************************************/
* Converts "num" to int4
*/
Datum int4in(PG_FUNCTION_ARGS)
{
char* num = PG_GETARG_CSTRING(0);
#ifdef DOLPHIN
PG_RETURN_INT32(PgStrToIntInternal<false>(num, fcinfo->can_ignore || !SQL_MODE_STRICT(),
PG_INT32_MAX, PG_INT32_MIN, "integer"));
#else
char* fmtStr = NULL;
if (u_sess) {
fmtStr = u_sess->parser_cxt.fmt_str;
}
if (!fmtStr) {
if (DB_IS_CMPT(A_FORMAT) && ACCEPT_FLOAT_STR_AS_INT) {
PG_RETURN_INT32(PgStrToIntInternal<false>(num, fcinfo->can_ignore,
PG_INT32_MAX, PG_INT32_MIN, "integer"));
} else {
PG_RETURN_INT32(pg_strtoint32(num, fcinfo->can_ignore));
}
}
Datum result;
bool resultNull = false;
text* numTxt = cstring_to_text(num);
text* fmtTxt = cstring_to_text(fmtStr);
result = to_numeric_to_number(numTxt, fmtTxt, PG_GET_COLLATION(), &resultNull);
if (resultNull) {
PG_RETURN_NULL();
}
return DatumGetInt32(DirectFunctionCall1(numeric_int4, NumericGetDatum(result)));
#endif
}
* Converts int4 to "num"
*/
Datum int4out(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
char* result = (char*)palloc(MAX_INT32_LEN + 1);
pg_ltoa(arg1, result);
PG_RETURN_CSTRING(result);
}
* int4recv - converts external binary format to int4
*/
Datum int4recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
PG_RETURN_INT32((int32)pq_getmsgint(buf, sizeof(int32)));
}
* int4send - converts int4 to binary format
*/
Datum int4send(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint32(&buf, arg1);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
* ===================
* CONVERSION ROUTINES
* ===================
*/
Datum i2toi4(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
PG_RETURN_INT32((int32)arg1);
}
Datum i4toi2(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
if (unlikely(arg1 < SHRT_MIN) || unlikely(arg1 > SHRT_MAX)) {
if (fcinfo->can_ignore || !SQL_MODE_STRICT()) {
ereport(WARNING, (errmsg("smallint out of range")));
PG_RETURN_INT16((int16)(arg1 < SHRT_MIN ? SHRT_MIN : SHRT_MAX));
} else {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
}
}
PG_RETURN_INT16((int16)arg1);
}
Datum int4_bool(PG_FUNCTION_ARGS)
{
if (PG_GETARG_INT32(0) == 0)
PG_RETURN_BOOL(false);
else
PG_RETURN_BOOL(true);
}
Datum bool_int4(PG_FUNCTION_ARGS)
{
if (PG_GETARG_BOOL(0) == false)
PG_RETURN_INT32(0);
else
PG_RETURN_INT32(1);
}
Datum int2_bool(PG_FUNCTION_ARGS)
{
if (PG_GETARG_INT16(0) == 0)
PG_RETURN_BOOL(false);
else
PG_RETURN_BOOL(true);
}
Datum bool_int2(PG_FUNCTION_ARGS)
{
if (PG_GETARG_BOOL(0) == false)
PG_RETURN_INT16(0);
else
PG_RETURN_INT16(1);
}
* ============================
* COMPARISON OPERATOR ROUTINES
* ============================
*/
* inteq - returns 1 iff arg1 == arg2
* intne - returns 1 iff arg1 != arg2
* intlt - returns 1 iff arg1 < arg2
* intle - returns 1 iff arg1 <= arg2
* intgt - returns 1 iff arg1 > arg2
* intge - returns 1 iff arg1 >= arg2
*/
Datum int4eq(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int4ne(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 != arg2);
}
Datum int4lt(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int4le(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int4gt(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int4ge(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum int2eq(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int2ne(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 != arg2);
}
Datum int2lt(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int2le(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int2gt(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int2ge(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum int24eq(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int24ne(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 != arg2);
}
Datum int24lt(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int24le(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int24gt(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int24ge(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum int42eq(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int42ne(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 != arg2);
}
Datum int42lt(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int42le(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int42gt(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int42ge(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
* int[24]pl - returns arg1 + arg2
* int[24]mi - returns arg1 - arg2
* int[24]mul - returns arg1 * arg2
* int[24]div - returns arg1 / arg2
*/
Datum int4um(PG_FUNCTION_ARGS)
{
int32 arg = PG_GETARG_INT32(0);
if (unlikely(arg == PG_INT32_MIN))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(-arg);
}
Datum int4up(PG_FUNCTION_ARGS)
{
int32 arg = PG_GETARG_INT32(0);
PG_RETURN_INT32(arg);
}
Datum int4pl(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
int32 result;
#ifdef DOLPHIN
result = int84_internal((int64)arg1 + (int64)arg2, fcinfo->can_ignore);
#else
if (unlikely(pg_add_s32_overflow(arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
#endif
PG_RETURN_INT32(result);
}
Datum int4mi(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
int32 result;
#ifdef DOLPHIN
result = int84_internal((int64)arg1 - (int64)arg2, fcinfo->can_ignore);
#else
if (unlikely(pg_sub_s32_overflow(arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
#endif
PG_RETURN_INT32(result);
}
Datum int4mul(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
int32 result;
#ifdef DOLPHIN
result = int84_internal((int64)arg1 * (int64)arg2, fcinfo->can_ignore);
#else
if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
#endif
PG_RETURN_INT32(result);
}
Datum int4div(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
float8 result;
if (arg2 == 0) {
#ifdef DOLPHIN
CheckErrDivByZero(fcinfo->can_ignore);
PG_RETURN_NULL();
#endif
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
if (arg1 == 0) {
PG_RETURN_FLOAT8(0);
}
* INT_MIN / -1 is problematic, since the result can't be represented on a
* two's-complement machine. Some machines produce INT_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) {
int64 res = (int64)arg1 * (-1);
if (SUPPORT_BIND_DIVIDE && unlikely(res > PG_INT32_MAX))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_FLOAT8(res);
}
result = (arg1 * 1.0) / (arg2 * 1.0);
PG_RETURN_FLOAT8(result);
}
Datum int4inc(PG_FUNCTION_ARGS)
{
int32 arg = PG_GETARG_INT32(0);
int32 result;
if (unlikely(pg_add_s32_overflow(arg, 1, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int2um(PG_FUNCTION_ARGS)
{
int16 arg = PG_GETARG_INT16(0);
if (unlikely(arg == PG_INT16_MIN))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
PG_RETURN_INT16(-arg);
}
Datum int2up(PG_FUNCTION_ARGS)
{
int16 arg = PG_GETARG_INT16(0);
PG_RETURN_INT16(arg);
}
Datum int2pl(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
int16 result;
if (unlikely(pg_add_s16_overflow(arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
PG_RETURN_INT16(result);
}
Datum int2mi(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
int16 result;
if (unlikely(pg_sub_s16_overflow(arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
PG_RETURN_INT16(result);
}
Datum int2mul(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
int16 result;
if (unlikely(pg_mul_s16_overflow(arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
PG_RETURN_INT16(result);
}
Datum int2div(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
float8 result;
if (arg2 == 0) {
#ifdef DOLPHIN
CheckErrDivByZero(fcinfo->can_ignore);
PG_RETURN_NULL();
#endif
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
if (arg1 == 0) {
PG_RETURN_FLOAT8(0);
}
* SHRT_MIN / -1 is problematic, since the result can't be represented on
* a two's-complement machine. Some machines produce SHRT_MIN, some
* produce zero, some throw an exception. We produce an exception like
* C db and D db do.
*/
if (arg2 == -1) {
int32 res = (int32)arg1 * (-1);
if (SUPPORT_BIND_DIVIDE && unlikely(res > PG_INT16_MAX))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
PG_RETURN_FLOAT8(res);
}
result = (arg1 * 1.0) / (arg2 * 1.0);
PG_RETURN_FLOAT8(result);
}
Datum int24pl(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
int32 result;
if (unlikely(pg_add_s32_overflow((int32)arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int24mi(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
int32 result;
if (unlikely(pg_sub_s32_overflow((int32)arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int24mul(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
int32 result;
if (unlikely(pg_mul_s32_overflow((int32)arg1, arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int24div(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
float8 result;
if (arg2 == 0) {
#ifdef DOLPHIN
CheckErrDivByZero(fcinfo->can_ignore);
PG_RETURN_NULL();
#endif
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
if (arg1 == 0) {
PG_RETURN_FLOAT8(0);
}
result = (arg1 * 1.0) / (arg2 * 1.0);
PG_RETURN_FLOAT8(result);
}
Datum int42pl(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
int32 result;
if (unlikely(pg_add_s32_overflow(arg1, (int32)arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int42mi(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
int32 result;
if (unlikely(pg_sub_s32_overflow(arg1, (int32)arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int42mul(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
int32 result;
if (unlikely(pg_mul_s32_overflow(arg1, (int32)arg2, &result)))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_INT32(result);
}
Datum int42div(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
float8 result;
if (arg2 == 0) {
#ifdef DOLPHIN
CheckErrDivByZero(fcinfo->can_ignore);
PG_RETURN_NULL();
#endif
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
if (arg1 == 0) {
PG_RETURN_FLOAT8(0);
}
* INT_MIN / -1 is problematic, since the result can't be represented on a
* two's-complement machine. Some machines produce INT_MIN, some produce
* zero, some throw an exception. We produce an exception like
* C db and D db do.
*/
if (arg2 == -1) {
int64 res = (int64)arg1 * (-1);
if (SUPPORT_BIND_DIVIDE && unlikely(res > PG_INT32_MAX))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
PG_RETURN_FLOAT8(res);
}
result = (arg1 * 1.0) / (arg2 * 1.0);
PG_RETURN_FLOAT8(result);
}
Datum int4mod(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
if (unlikely(arg2 == 0)) {
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
* Some machines throw a floating-point exception for INT_MIN % -1, which
* is a bit silly since the correct answer is perfectly well-defined,
* namely zero.
*/
if (arg2 == -1)
PG_RETURN_INT32(0);
PG_RETURN_INT32(arg1 % arg2);
}
Datum int2mod(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
if (unlikely(arg2 == 0)) {
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
* Some machines throw a floating-point exception for INT_MIN % -1, which
* is a bit silly since the correct answer is perfectly well-defined,
* namely zero. (It's not clear this ever happens when dealing with
* int16, but we might as well have the test for safety.)
*/
if (arg2 == -1)
PG_RETURN_INT16(0);
PG_RETURN_INT16(arg1 % arg2);
}
* Absolute value
*/
Datum int4abs(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 result;
if (unlikely(arg1 == PG_INT32_MIN))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range")));
result = (arg1 < 0) ? -arg1 : arg1;
PG_RETURN_INT32(result);
}
Datum int2abs(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 result;
if (unlikely(arg1 == PG_INT16_MIN))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
result = (arg1 < 0) ? -arg1 : arg1;
PG_RETURN_INT16(result);
}
Datum int2larger(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
}
Datum int2smaller(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
}
Datum int4larger(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
}
Datum int4smaller(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
*/
Datum int4and(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 & arg2);
}
Datum int4or(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 | arg2);
}
Datum int4xor(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 ^ arg2);
}
Datum int4shl(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 << arg2);
}
Datum int4shr(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 >> arg2);
}
Datum int4not(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
PG_RETURN_INT32(~arg1);
}
Datum int2and(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16(arg1 & arg2);
}
Datum int2or(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16(arg1 | arg2);
}
Datum int2xor(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16(arg1 ^ arg2);
}
Datum int2not(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
PG_RETURN_INT16(~arg1);
}
Datum int2shl(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT16(arg1 << arg2);
}
Datum int2shr(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
*/
Datum generate_series_int4(PG_FUNCTION_ARGS)
{
return generate_series_step_int4(fcinfo);
}
Datum generate_series_step_int4(PG_FUNCTION_ARGS)
{
FuncCallContext* funcctx = NULL;
generate_series_fctx* fctx = NULL;
int32 result;
MemoryContext oldcontext;
if (SRF_IS_FIRSTCALL()) {
int32 start = PG_GETARG_INT32(0);
int32 finish = PG_GETARG_INT32(1);
int32 step = 1;
if (PG_NARGS() == 3)
step = PG_GETARG_INT32(2);
if (step == 0)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("step size cannot equal zero")));
funcctx = SRF_FIRSTCALL_INIT();
* switch to memory context appropriate for multiple function calls
*/
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
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);
}
funcctx = SRF_PERCALL_SETUP();
* get the saved state and use current as the result for this iteration
*/
fctx = (generate_series_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. If next-value
* computation overflows, this is the final result.
*/
if (pg_add_s32_overflow(fctx->current, fctx->step, &fctx->current))
fctx->step = 0;
SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
}
SRF_RETURN_DONE(funcctx);
}
Datum int1in(PG_FUNCTION_ARGS)
{
char* num = PG_GETARG_CSTRING(0);
#ifdef DOLPHIN
PG_RETURN_INT8(PgStrToIntInternal<false>(num, fcinfo->can_ignore || !SQL_MODE_STRICT(),
PG_INT8_MAX, PG_INT8_MIN, "tinyint"));
#else
if (DB_IS_CMPT(A_FORMAT) && ACCEPT_FLOAT_STR_AS_INT) {
PG_RETURN_UINT8(PgStrToIntInternal<true>(num, fcinfo->can_ignore,
PG_UINT8_MAX, 0, "tinyint"));
} else {
PG_RETURN_UINT8((uint8)pg_atoi(num, sizeof(uint8), '\0', fcinfo->can_ignore));
}
#endif
}
Datum int1out(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
char* result = (char*)palloc(5);
pg_ctoa(arg1, result);
PG_RETURN_CSTRING(result);
}
Datum int1recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo)PG_GETARG_POINTER(0);
#ifdef DOLPHIN
PG_RETURN_INT8((int8)pq_getmsgint(buf, sizeof(int8)));
#else
PG_RETURN_UINT8((uint8)pq_getmsgint(buf, sizeof(uint8)));
#endif
}
Datum int1send(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint8(&buf, arg1);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
Datum int1and(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_UINT8(arg1 & arg2);
}
Datum int1or(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_UINT8(arg1 | arg2);
}
Datum int1xor(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_UINT8(arg1 ^ arg2);
}
Datum int1not(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
int8 arg1 = PG_GETARG_INT8(0);
#endif
PG_RETURN_UINT8((uint8)(~arg1));
}
Datum int1shl(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_UINT8((uint8)(arg1 << arg2));
}
Datum int1shr(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_UINT8(arg1 >> arg2);
}
* adapt Sybase, add a new data type int1
* int1eq - returns 1 if arg1 == arg2
* int1ne - returns 1 if arg1 != arg2
* int1lt - returns 1 if arg1 < arg2
* int1le - returns 1 if arg1 <= arg2
* int1gt - returns 1 if arg1 > arg2
* int1ge - returns 1 if arg1 >= arg2
*/
Datum int1eq(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int1ne(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_BOOL(arg1 != arg2);
}
Datum int1lt(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int1le(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int1gt(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int1ge(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum int1cmp(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
if (arg1 > arg2)
PG_RETURN_INT32(1);
else if (arg1 == arg2)
PG_RETURN_INT32(0);
else
PG_RETURN_INT32(-1);
}
#ifdef DOLPHIN
Datum int12eq(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int12lt(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int12le(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int12gt(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int12ge(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum int14eq(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int14lt(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int14le(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int14gt(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int14ge(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
Datum int18eq(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int64 arg2 = PG_GETARG_INT64(1);
PG_RETURN_BOOL(arg1 == arg2);
}
Datum int18lt(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int64 arg2 = PG_GETARG_INT64(1);
PG_RETURN_BOOL(arg1 < arg2);
}
Datum int18le(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int64 arg2 = PG_GETARG_INT64(1);
PG_RETURN_BOOL(arg1 <= arg2);
}
Datum int18gt(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int64 arg2 = PG_GETARG_INT64(1);
PG_RETURN_BOOL(arg1 > arg2);
}
Datum int18ge(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int64 arg2 = PG_GETARG_INT64(1);
PG_RETURN_BOOL(arg1 >= arg2);
}
int intCmp(int64 arg1, int64 arg2)
{
if (arg1 > arg2)
return 1;
else if (arg1 == arg2)
return 0;
else
return -1;
}
Datum int12cmp(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT32(intCmp(arg1, arg2));
}
Datum int14cmp(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(intCmp(arg1, arg2));
}
Datum int18cmp(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
int64 arg2 = PG_GETARG_INT64(1);
PG_RETURN_INT32(intCmp(arg1, arg2));
}
#endif
* ===================
* CONVERSION ROUTINES
* ===================
*/
Datum i1toi2(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
PG_RETURN_INT16((int16)arg1);
}
Datum i2toi1(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
#ifdef DOLPHIN
if (unlikely(arg1 < CHAR_MIN) || unlikely(arg1 > CHAR_MAX)) {
if (fcinfo->can_ignore || !SQL_MODE_STRICT()) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_UINT8((uint8)(arg1 < 0 ? CHAR_MIN : CHAR_MAX));
} else {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
}
PG_RETURN_INT8((int8)arg1);
#else
if (arg1 < 0 || arg1 > UCHAR_MAX) {
if (fcinfo->can_ignore) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_UINT8((uint8)(arg1 < 0 ? 0 : UCHAR_MAX));
}
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)arg1);
#endif
}
Datum i1toi4(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
PG_RETURN_INT32((int32)arg1);
}
Datum i4toi1(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
#ifdef DOLPHIN
if (unlikely(arg1 < CHAR_MIN) || unlikely(arg1 > CHAR_MAX)) {
if (fcinfo->can_ignore || !SQL_MODE_STRICT()) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_INT8((int8)(arg1 < 0 ? CHAR_MIN : CHAR_MAX));
} else {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
}
PG_RETURN_INT8((int8)arg1);
#else
if (arg1 < 0 || arg1 > UCHAR_MAX) {
if (fcinfo->can_ignore) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_UINT8((uint8)(arg1 < 0 ? 0 : UCHAR_MAX));
}
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)arg1);
#endif
}
Datum i1toi8(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
PG_RETURN_INT64((int64)arg1);
}
Datum i8toi1(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
#ifdef DOLPHIN
if (unlikely(arg1 < CHAR_MIN) || unlikely(arg1 > CHAR_MAX)) {
if (fcinfo->can_ignore || !SQL_MODE_STRICT()) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_INT8((int8)(arg1 < 0 ? CHAR_MIN : CHAR_MAX));
} else {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
}
PG_RETURN_INT8((int8)arg1);
#else
if (arg1 < 0 || arg1 > UCHAR_MAX) {
if (fcinfo->can_ignore) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_UINT8((uint8)(arg1 < 0 ? 0 : UCHAR_MAX));
}
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)arg1);
#endif
}
Datum i1tof4(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
PG_RETURN_FLOAT4((float4)arg1);
}
Datum i1tof8(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
PG_RETURN_FLOAT8((float8)arg1);
}
Datum f4toi1(PG_FUNCTION_ARGS)
{
float4 arg1 = PG_GETARG_FLOAT4(0);
#ifdef DOLPHIN
arg1 = round(arg1);
if (isnan(arg1))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
if (unlikely(arg1 < CHAR_MIN) || unlikely(arg1 > CHAR_MAX)) {
if (fcinfo->can_ignore || !SQL_MODE_STRICT()) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_INT8((int8)(arg1 < 0 ? CHAR_MIN : CHAR_MAX));
} else {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
}
PG_RETURN_INT8((int8)round(arg1));
#else
if (arg1 < 0 || arg1 > UCHAR_MAX) {
if (fcinfo->can_ignore) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_UINT8(arg1 < 0 ? 0 : UCHAR_MAX);
}
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)round(arg1));
#endif
}
Datum f8toi1(PG_FUNCTION_ARGS)
{
float8 arg1 = PG_GETARG_FLOAT8(0);
#ifdef DOLPHIN
arg1 = round(arg1);
if (isnan(arg1))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range")));
if (unlikely(arg1 < CHAR_MIN) || unlikely(arg1 > CHAR_MAX)) {
if (fcinfo->can_ignore || !SQL_MODE_STRICT()) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_INT8((int8)(arg1 < 0 ? CHAR_MIN : CHAR_MAX));
} else {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
}
PG_RETURN_INT8((int8)round(arg1));
#else
if (arg1 < 0 || arg1 > UCHAR_MAX) {
if (fcinfo->can_ignore) {
ereport(WARNING, (errmsg("tinyint out of range")));
PG_RETURN_UINT8(arg1 < 0 ? 0 : UCHAR_MAX);
}
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)round(arg1));
#endif
}
Datum int1_bool(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
if (PG_GETARG_INT8(0) == 0)
#else
if (PG_GETARG_UINT8(0) == 0)
#endif
PG_RETURN_BOOL(false);
else
PG_RETURN_BOOL(true);
}
Datum bool_int1(PG_FUNCTION_ARGS)
{
if (PG_GETARG_BOOL(0) == false)
#ifdef DOLPHIN
PG_RETURN_INT8(0);
else
PG_RETURN_INT8(1);
#else
PG_RETURN_UINT8(0);
else
PG_RETURN_UINT8(1);
#endif
}
Datum int1_interval(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall1(numeric_interval, DirectFunctionCall1(int1_numeric, PG_GETARG_DATUM(0))));
}
Datum int2_interval(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall1(numeric_interval, DirectFunctionCall1(int2_numeric, PG_GETARG_DATUM(0))));
}
Datum int4_interval(PG_FUNCTION_ARGS)
{
PG_RETURN_DATUM(DirectFunctionCall1(numeric_interval, DirectFunctionCall1(int4_numeric, PG_GETARG_DATUM(0))));
}
Datum int1_to_interval(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(1);
PG_RETURN_DATUM(DirectFunctionCall2(numeric_to_interval,
DirectFunctionCall1(int1_numeric, PG_GETARG_DATUM(0)),
Int32GetDatum(typmod)));
}
Datum int2_to_interval(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(1);
PG_RETURN_DATUM(DirectFunctionCall2(numeric_to_interval,
DirectFunctionCall1(int2_numeric, PG_GETARG_DATUM(0)),
Int32GetDatum(typmod)));
}
Datum int4_to_interval(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(1);
PG_RETURN_DATUM(DirectFunctionCall2(numeric_to_interval,
DirectFunctionCall1(int4_numeric, PG_GETARG_DATUM(0)),
Int32GetDatum(typmod)));
}
Datum int1um(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 result = PG_GETARG_INT8(0);
PG_RETURN_INT16(0 - result);
#else
uint16 result = PG_GETARG_UINT8(0);
PG_RETURN_INT16(0 - result);
#endif
}
Datum int1up(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg = PG_GETARG_INT8(0);
PG_RETURN_INT8(arg);
#else
uint8 arg = PG_GETARG_UINT8(0);
PG_RETURN_UINT8(arg);
#endif
}
Datum int1pl(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
int16 result;
result = arg1 + arg2;
if (result < CHAR_MIN || result > CHAR_MAX) {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_INT8((int8)result);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
uint16 result;
result = arg1 + arg2;
if (result > UCHAR_MAX) {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)result);
#endif
}
Datum int1mi(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
int16 result;
result = arg1 - arg2;
if (result < CHAR_MIN || result > CHAR_MAX) {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_INT8((int8)result);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
uint8 result;
if (arg1 < arg2) {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
result = arg1 - arg2;
PG_RETURN_UINT8(result);
#endif
}
Datum int1mul(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
int16 result16;
result16 = (int16)arg1 * (int16)arg2;
if ((result16 < CHAR_MIN) || (result16 > CHAR_MAX)) {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_INT8((int8)result16);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
int16 result16;
* The most practical way to detect overflow is to do the arithmetic in
* int16 (so that the result can't overflow) and then do a range check.
*/
result16 = (int16)arg1 * (int16)arg2;
if ((result16 < 0) || (result16 > UCHAR_MAX)) {
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
}
PG_RETURN_UINT8((uint8)result16);
#endif
}
Datum int1div(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
#endif
float8 result;
if (arg2 == 0) {
#ifdef DOLPHIN
CheckErrDivByZero(fcinfo->can_ignore);
PG_RETURN_NULL();
#endif
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
result = (arg1 * 1.0) / (arg2 * 1.0);
PG_RETURN_FLOAT8(result);
}
Datum int1abs(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 result;
if (unlikely(arg1 == PG_INT8_MIN))
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
result = (arg1 < 0) ? -arg1 : arg1;
PG_RETURN_INT8(result);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
PG_RETURN_UINT8(arg1);
#endif
}
Datum int1mod(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
if (arg2 == 0) {
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
PG_RETURN_INT8(arg1 % arg2);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
if (arg2 == 0) {
ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero")));
PG_RETURN_NULL();
}
PG_RETURN_UINT8(arg1 % arg2);
#endif
}
Datum int1larger(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
PG_RETURN_INT8((arg1 > arg2) ? arg1 : arg2);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
PG_RETURN_UINT8((arg1 > arg2) ? arg1 : arg2);
#endif
}
Datum int1smaller(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
int8 arg2 = PG_GETARG_INT8(1);
PG_RETURN_INT8((arg1 < arg2) ? arg1 : arg2);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
uint8 arg2 = PG_GETARG_UINT8(1);
PG_RETURN_UINT8((arg1 < arg2) ? arg1 : arg2);
#endif
}
Datum int1inc(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg = PG_GETARG_INT8(0);
#else
uint8 arg = PG_GETARG_UINT8(0);
#endif
int16 result;
result = arg + 1;
#ifdef DOLPHIN
if (result > CHAR_MAX)
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
PG_RETURN_INT8((int8)result);
#else
if (result > UCHAR_MAX)
ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("tinyint out of range")));
PG_RETURN_UINT8((uint8)result);
#endif
}
Datum int1_text(PG_FUNCTION_ARGS)
{
#ifdef DOLPHIN
int8 arg1 = PG_GETARG_INT8(0);
#else
uint8 arg1 = PG_GETARG_UINT8(0);
#endif
char* tmp = NULL;
Datum result;
tmp = DatumGetCString(DirectFunctionCall1(int1out, arg1));
result = DirectFunctionCall1(textin, CStringGetDatum(tmp));
pfree_ext(tmp);
PG_RETURN_DATUM(result);
}
Datum int2_text(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
char* tmp = NULL;
Datum result;
tmp = DatumGetCString(DirectFunctionCall1(int2out, arg1));
result = DirectFunctionCall1(textin, CStringGetDatum(tmp));
pfree_ext(tmp);
PG_RETURN_DATUM(result);
}
Datum int4_text(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
char* tmp = NULL;
Datum result;
tmp = DatumGetCString(DirectFunctionCall1(int4out, arg1));
result = DirectFunctionCall1(textin, CStringGetDatum(tmp));
pfree_ext(tmp);
PG_RETURN_DATUM(result);
}
Datum text_int1(PG_FUNCTION_ARGS)
{
Datum txt = PG_GETARG_DATUM(0);
char* tmp = NULL;
Datum result;
tmp = DatumGetCString(DirectFunctionCall1(textout, txt));
result = DirectFunctionCall1(int1in, CStringGetDatum(tmp));
pfree_ext(tmp);
PG_RETURN_DATUM(result);
}
Datum text_int2(PG_FUNCTION_ARGS)
{
Datum txt = PG_GETARG_DATUM(0);
char* tmp = NULL;
Datum result;
tmp = DatumGetCString(DirectFunctionCall1(textout, txt));
result = DirectFunctionCall1(int2in, CStringGetDatum(tmp));
pfree_ext(tmp);
PG_RETURN_DATUM(result);
}
Datum text_int4(PG_FUNCTION_ARGS)
{
Datum txt = PG_GETARG_DATUM(0);
char* tmp = NULL;
Datum result;
tmp = DatumGetCString(DirectFunctionCall1(textout, txt));
result = DirectFunctionCall1(int4in, CStringGetDatum(tmp));
pfree_ext(tmp);
PG_RETURN_DATUM(result);
}
#ifdef DOLPHIN
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int4pl);
extern "C" DLL_PUBLIC Datum dolphin_int4pl(PG_FUNCTION_ARGS);
Datum dolphin_int4pl(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT32(0);
int64 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT64(arg1 + arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int4mi);
extern "C" DLL_PUBLIC Datum dolphin_int4mi(PG_FUNCTION_ARGS);
Datum dolphin_int4mi(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT32(0);
int64 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT64(arg1 - arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int4mul);
extern "C" DLL_PUBLIC Datum dolphin_int4mul(PG_FUNCTION_ARGS);
Datum dolphin_int4mul(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT32(0);
int64 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT64(arg1 * arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int2pl);
extern "C" DLL_PUBLIC Datum dolphin_int2pl(PG_FUNCTION_ARGS);
Datum dolphin_int2pl(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT32(arg1 + arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int2mi);
extern "C" DLL_PUBLIC Datum dolphin_int2mi(PG_FUNCTION_ARGS);
Datum dolphin_int2mi(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT32(arg1 - arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int2mul);
extern "C" DLL_PUBLIC Datum dolphin_int2mul(PG_FUNCTION_ARGS);
Datum dolphin_int2mul(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT16(0);
int64 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT64(arg1 * arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int1pl);
extern "C" DLL_PUBLIC Datum dolphin_int1pl(PG_FUNCTION_ARGS);
Datum dolphin_int1pl(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT8(1);
PG_RETURN_INT32(arg1 + arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int1mi);
extern "C" DLL_PUBLIC Datum dolphin_int1mi(PG_FUNCTION_ARGS);
Datum dolphin_int1mi(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT8(1);
PG_RETURN_INT32(arg1 - arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int1mul);
extern "C" DLL_PUBLIC Datum dolphin_int1mul(PG_FUNCTION_ARGS);
Datum dolphin_int1mul(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT8(0);
int32 arg2 = PG_GETARG_INT8(1);
PG_RETURN_INT32(arg1 * arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int24pl);
extern "C" DLL_PUBLIC Datum dolphin_int24pl(PG_FUNCTION_ARGS);
Datum dolphin_int24pl(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT16(0);
int64 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT64(arg1 + arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int24mi);
extern "C" DLL_PUBLIC Datum dolphin_int24mi(PG_FUNCTION_ARGS);
Datum dolphin_int24mi(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT16(0);
int64 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT64(arg1 - arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int24mul);
extern "C" DLL_PUBLIC Datum dolphin_int24mul(PG_FUNCTION_ARGS);
Datum dolphin_int24mul(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT16(0);
int64 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT64(arg1 * arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int42pl);
extern "C" DLL_PUBLIC Datum dolphin_int42pl(PG_FUNCTION_ARGS);
Datum dolphin_int42pl(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT32(0);
int64 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT64(arg1 + arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int42mi);
extern "C" DLL_PUBLIC Datum dolphin_int42mi(PG_FUNCTION_ARGS);
Datum dolphin_int42mi(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT32(0);
int64 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT64(arg1 - arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int42mul);
extern "C" DLL_PUBLIC Datum dolphin_int42mul(PG_FUNCTION_ARGS);
Datum dolphin_int42mul(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT32(0);
int64 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT64(arg1 * arg2);
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int1not);
extern "C" DLL_PUBLIC Datum dolphin_int1not(PG_FUNCTION_ARGS);
Datum dolphin_int1not(PG_FUNCTION_ARGS)
{
int8 arg1 = PG_GETARG_INT8(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int2not);
extern "C" DLL_PUBLIC Datum dolphin_int2not(PG_FUNCTION_ARGS);
Datum dolphin_int2not(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int4not);
extern "C" DLL_PUBLIC Datum dolphin_int4not(PG_FUNCTION_ARGS);
Datum dolphin_int4not(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_int8not);
extern "C" DLL_PUBLIC Datum dolphin_int8not(PG_FUNCTION_ARGS);
Datum dolphin_int8not(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_uint1not);
extern "C" DLL_PUBLIC Datum dolphin_uint1not(PG_FUNCTION_ARGS);
Datum dolphin_uint1not(PG_FUNCTION_ARGS)
{
uint8 arg1 = PG_GETARG_UINT8(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_uint2not);
extern "C" DLL_PUBLIC Datum dolphin_uint2not(PG_FUNCTION_ARGS);
Datum dolphin_uint2not(PG_FUNCTION_ARGS)
{
uint16 arg1 = PG_GETARG_UINT16(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_uint4not);
extern "C" DLL_PUBLIC Datum dolphin_uint4not(PG_FUNCTION_ARGS);
Datum dolphin_uint4not(PG_FUNCTION_ARGS)
{
uint32 arg1 = PG_GETARG_UINT32(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
PG_FUNCTION_INFO_V1_PUBLIC(dolphin_uint8not);
extern "C" DLL_PUBLIC Datum dolphin_uint8not(PG_FUNCTION_ARGS);
Datum dolphin_uint8not(PG_FUNCTION_ARGS)
{
uint64 arg1 = PG_GETARG_UINT64(0);
PG_RETURN_UINT64(~((uint64)arg1));
}
* common code for bittypmodin and varbittypmodin
*/
static int32 anyint_typmodin(ArrayType* ta, const char* typname)
{
int32 typmod;
int32* tl = NULL;
int n;
tl = ArrayGetIntegerTypmods(ta, &n);
* we're not too tense about good error message here because grammar
* shouldn't allow wrong number of modifiers for BIT
*/
if (n != 1)
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid type modifier")));
if (*tl < 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("length for type %s must be at least 1", typname)));
if (*((uint32*)tl) > MAX_INT_PRECISION) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("length for type %s cannot exceed %u", typname, MAX_INT_PRECISION)));
}
typmod = *tl;
return typmod;
}
* common code for bittypmodout and varbittypmodout
*/
static char* anyint_typmodout(int32 typmod)
{
const size_t buffer_len = 64;
char* res = (char*)palloc(buffer_len);
errno_t rc = 0;
if (typmod >= 0) {
rc = snprintf_s(res, buffer_len, buffer_len - 1, "(%d)", typmod);
securec_check_ss(rc, "\0", "\0");
} else
*res = '\0';
return res;
}
PG_FUNCTION_INFO_V1_PUBLIC(int1_typmodin);
extern "C" DLL_PUBLIC Datum int1_typmodin(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1_PUBLIC(int1_typmodout);
extern "C" DLL_PUBLIC Datum int1_typmodout(PG_FUNCTION_ARGS);
Datum int1_typmodin(PG_FUNCTION_ARGS)
{
ArrayType* ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anyint_typmodin(ta, "int1"));
}
Datum int1_typmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anyint_typmodout(typmod));
}
PG_FUNCTION_INFO_V1_PUBLIC(int2_typmodin);
extern "C" DLL_PUBLIC Datum int2_typmodin(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1_PUBLIC(int2_typmodout);
extern "C" DLL_PUBLIC Datum int2_typmodout(PG_FUNCTION_ARGS);
Datum int2_typmodin(PG_FUNCTION_ARGS)
{
ArrayType* ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anyint_typmodin(ta, "int2"));
}
Datum int2_typmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anyint_typmodout(typmod));
}
PG_FUNCTION_INFO_V1_PUBLIC(int4_typmodin);
extern "C" DLL_PUBLIC Datum int4_typmodin(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1_PUBLIC(int4_typmodout);
extern "C" DLL_PUBLIC Datum int4_typmodout(PG_FUNCTION_ARGS);
Datum int4_typmodin(PG_FUNCTION_ARGS)
{
ArrayType* ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anyint_typmodin(ta, "int4"));
}
Datum int4_typmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anyint_typmodout(typmod));
}
PG_FUNCTION_INFO_V1_PUBLIC(int8_typmodin);
extern "C" DLL_PUBLIC Datum int8_typmodin(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1_PUBLIC(int8_typmodout);
extern "C" DLL_PUBLIC Datum int8_typmodout(PG_FUNCTION_ARGS);
Datum int8_typmodin(PG_FUNCTION_ARGS)
{
ArrayType* ta = PG_GETARG_ARRAYTYPE_P(0);
PG_RETURN_INT32(anyint_typmodin(ta, "int8"));
}
Datum int8_typmodout(PG_FUNCTION_ARGS)
{
int32 typmod = PG_GETARG_INT32(0);
PG_RETURN_CSTRING(anyint_typmodout(typmod));
}
#endif