Newer
Older
/*-------------------------------------------------------------------------
*
* int.c
* Functions for the built-in integer types (except int8).
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.61 2004/08/29 04:12:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* OLD COMMENTS
* int2in, int2out, int2recv, int2send
* int4in, int4out, int4recv, int4send
* int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
* Conversion routines:
* itoi, int2_text, int4_text
* Boolean operators:
* inteq, intne, intlt, intle, intgt, intge
* Arithmetic operators:
* intpl, intmi, int4mul, intdiv
* Arithmetic operators:
* intmod
#include <ctype.h>
#include <limits.h>
#include "funcapi.h"
#include "libpq/pqformat.h"
#ifndef SHRT_MAX
#define SHRT_MAX (0x7FFF)
#endif
#ifndef SHRT_MIN
#define SHRT_MIN (-0x8000)
#endif
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);
PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
* int2out - converts short to "num"
Datum
int2out(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
char *result = (char *) palloc(7); /* sign, 5 digits, '\0' */
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_sendint(&buf, arg1, sizeof(int16));
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
Bruce Momjian
committed
* int2vectorin - converts "num num ..." to internal form
* Note: Fills any missing slots with zeroes.
Datum
int2vectorin(PG_FUNCTION_ARGS)
char *intString = PG_GETARG_CSTRING(0);
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
for (slot = 0; *intString && slot < INDEX_MAX_KEYS; slot++)
if (sscanf(intString, "%hd", &result[slot]) != 1)
break;
while (*intString && isspace((unsigned char) *intString))
intString++;
while (*intString && !isspace((unsigned char) *intString))
while (*intString && isspace((unsigned char) *intString))
intString++;
if (*intString)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("int2vector has too many elements")));
while (slot < INDEX_MAX_KEYS)
result[slot++] = 0;
PG_RETURN_POINTER(result);
Bruce Momjian
committed
* int2vectorout - converts internal form to "num num ..."
Datum
int2vectorout(PG_FUNCTION_ARGS)
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
char *rp;
Bruce Momjian
committed
char *result;
/* find last non-zero value in vector */
for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
if (int2Array[maxnum] != 0)
break;
/* assumes sign, 5 digits, ' ' */
rp = result = (char *) palloc((maxnum + 1) * 7 + 1);
for (num = 0; num <= maxnum; num++)
if (num != 0)
*rp++ = ' ';
pg_itoa(int2Array[num], rp);
while (*++rp != '\0')
;
}
*rp = '\0';
PG_RETURN_CSTRING(result);
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* int2vectorrecv - converts external binary format to int2vector
*/
Datum
int2vectorrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
int slot;
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
PG_RETURN_POINTER(result);
}
/*
* int2vectorsend - converts int2vector to binary format
*/
Datum
int2vectorsend(PG_FUNCTION_ARGS)
{
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
StringInfoData buf;
int slot;
pq_begintypsend(&buf);
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
pq_sendint(&buf, int2Array[slot], sizeof(int16));
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*
* We don't have a complete set of int2vector support routines,
* but we need int2vectoreq for catcache indexing.
*/
Datum
int2vectoreq(PG_FUNCTION_ARGS)
int16 *arg1 = (int16 *) PG_GETARG_POINTER(0);
int16 *arg2 = (int16 *) PG_GETARG_POINTER(1);
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0);
/*****************************************************************************
* PUBLIC ROUTINES *
*****************************************************************************/
/*
* int4in - converts "num" to int4
Datum
int4in(PG_FUNCTION_ARGS)
char *num = PG_GETARG_CSTRING(0);
PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
* int4out - converts int4 to "num"
Datum
int4out(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */
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_sendint(&buf, arg1, sizeof(int32));
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 (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("integer out of range")));
PG_RETURN_INT16((int16) arg1);
Datum
int2_text(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
text *result = (text *) palloc(7 + VARHDRSZ); /* sign,5 digits, '\0' */
pg_itoa(arg1, VARDATA(result));
PG_RETURN_TEXT_P(result);
}
Datum
text_int2(PG_FUNCTION_ARGS)
text *string = PG_GETARG_TEXT_P(0);
Datum result;
int len;
char *str;
len = VARSIZE(string) - VARHDRSZ;
str = palloc(len + 1);
memcpy(str, VARDATA(string), len);
*(str + len) = '\0';
result = DirectFunctionCall1(int2in, CStringGetDatum(str));
Bruce Momjian
committed
pfree(str);
Datum
int4_text(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
text *result = (text *) palloc(12 + VARHDRSZ); /* sign,10 digits,'\0' */
pg_ltoa(arg1, VARDATA(result));
PG_RETURN_TEXT_P(result);
}
Datum
text_int4(PG_FUNCTION_ARGS)
text *string = PG_GETARG_TEXT_P(0);
Datum result;
int len;
char *str;
len = VARSIZE(string) - VARHDRSZ;
str = palloc(len + 1);
memcpy(str, VARDATA(string), len);
*(str + len) = '\0';
result = DirectFunctionCall1(int4in, CStringGetDatum(str));
Bruce Momjian
committed
pfree(str);
* ============================
* 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);
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);
PG_RETURN_INT32(arg1 + arg2);
Datum
int4mi(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 - arg2);
Datum
int4mul(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 * arg2);
Datum
int4div(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")));
PG_RETURN_INT32(arg1 / arg2);
Datum
int4inc(PG_FUNCTION_ARGS)
int32 arg = PG_GETARG_INT32(0);
PG_RETURN_INT32(arg + 1);
Datum
int2um(PG_FUNCTION_ARGS)
int16 arg = PG_GETARG_INT16(0);
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);
PG_RETURN_INT16(arg1 + arg2);
Datum
int2mi(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16(arg1 - arg2);
Datum
int2mul(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT16(arg1 * arg2);
Datum
int2div(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")));
PG_RETURN_INT16(arg1 / arg2);
Datum
int24pl(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 + arg2);
Datum
int24mi(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 - arg2);
Datum
int24mul(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
int32 arg2 = PG_GETARG_INT32(1);
PG_RETURN_INT32(arg1 * arg2);
Datum
int24div(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")));
PG_RETURN_INT32(arg1 / arg2);
Datum
int42pl(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT32(arg1 + arg2);
Datum
int42mi(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT32(arg1 - arg2);
Datum
int42mul(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
int16 arg2 = PG_GETARG_INT16(1);
PG_RETURN_INT32(arg1 * arg2);
Datum
int42div(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")));
PG_RETURN_INT32(arg1 / arg2);
Datum
int4mod(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")));
PG_RETURN_INT32(arg1 % arg2);
Datum
int2mod(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")));
PG_RETURN_INT16(arg1 % arg2);
Datum
int24mod(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")));
PG_RETURN_INT32(arg1 % arg2);
Datum
int42mod(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")));
PG_RETURN_INT32(arg1 % arg2);
/* int[24]abs()
* Absolute value
*/
Datum
int4abs(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);
PG_RETURN_INT32((arg1 < 0) ? -arg1 : arg1);
}
Datum
int2abs(PG_FUNCTION_ARGS)
int16 arg1 = PG_GETARG_INT16(0);
PG_RETURN_INT16((arg1 < 0) ? -arg1 : arg1);
}
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);
Peter Eisentraut
committed
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
/* Binary arithmetics
*
* 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);
}
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
/*
* 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;
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);
}