1
/*-------------------------------------------------------------------------
4
* Functions for the built-in integer types (except int8).
6
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.64 2004-12-31 22:01:22 pgsql Exp $
13
*-------------------------------------------------------------------------
18
* int2in, int2out, int2recv, int2send
19
* int4in, int4out, int4recv, int4send
20
* int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
21
* Conversion routines:
22
* itoi, int2_text, int4_text
24
* inteq, intne, intlt, intle, intgt, intge
25
* Arithmetic operators:
26
* intpl, intmi, int4mul, intdiv
28
* Arithmetic operators:
37
#include "libpq/pqformat.h"
38
#include "utils/builtins.h"
42
#define SHRT_MAX (0x7FFF)
45
#define SHRT_MIN (-0x8000)
48
#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
55
} generate_series_fctx;
58
/*****************************************************************************
60
*****************************************************************************/
63
* int2in - converts "num" to short
66
int2in(PG_FUNCTION_ARGS)
68
char *num = PG_GETARG_CSTRING(0);
70
PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
74
* int2out - converts short to "num"
77
int2out(PG_FUNCTION_ARGS)
79
int16 arg1 = PG_GETARG_INT16(0);
80
char *result = (char *) palloc(7); /* sign, 5 digits, '\0' */
82
pg_itoa(arg1, result);
83
PG_RETURN_CSTRING(result);
87
* int2recv - converts external binary format to int2
90
int2recv(PG_FUNCTION_ARGS)
92
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
94
PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
98
* int2send - converts int2 to binary format
101
int2send(PG_FUNCTION_ARGS)
103
int16 arg1 = PG_GETARG_INT16(0);
106
pq_begintypsend(&buf);
107
pq_sendint(&buf, arg1, sizeof(int16));
108
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
112
* int2vectorin - converts "num num ..." to internal form
114
* Note: Fills any missing slots with zeroes.
117
int2vectorin(PG_FUNCTION_ARGS)
119
char *intString = PG_GETARG_CSTRING(0);
120
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
123
for (slot = 0; *intString && slot < INDEX_MAX_KEYS; slot++)
125
if (sscanf(intString, "%hd", &result[slot]) != 1)
127
while (*intString && isspace((unsigned char) *intString))
129
while (*intString && !isspace((unsigned char) *intString))
132
while (*intString && isspace((unsigned char) *intString))
136
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
137
errmsg("int2vector has too many elements")));
139
while (slot < INDEX_MAX_KEYS)
142
PG_RETURN_POINTER(result);
146
* int2vectorout - converts internal form to "num num ..."
149
int2vectorout(PG_FUNCTION_ARGS)
151
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
157
/* find last non-zero value in vector */
158
for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--)
159
if (int2Array[maxnum] != 0)
162
/* assumes sign, 5 digits, ' ' */
163
rp = result = (char *) palloc((maxnum + 1) * 7 + 1);
164
for (num = 0; num <= maxnum; num++)
168
pg_itoa(int2Array[num], rp);
169
while (*++rp != '\0')
173
PG_RETURN_CSTRING(result);
177
* int2vectorrecv - converts external binary format to int2vector
180
int2vectorrecv(PG_FUNCTION_ARGS)
182
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
183
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
186
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
187
result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
188
PG_RETURN_POINTER(result);
192
* int2vectorsend - converts int2vector to binary format
195
int2vectorsend(PG_FUNCTION_ARGS)
197
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
201
pq_begintypsend(&buf);
202
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
203
pq_sendint(&buf, int2Array[slot], sizeof(int16));
204
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
208
* We don't have a complete set of int2vector support routines,
209
* but we need int2vectoreq for catcache indexing.
212
int2vectoreq(PG_FUNCTION_ARGS)
214
int16 *arg1 = (int16 *) PG_GETARG_POINTER(0);
215
int16 *arg2 = (int16 *) PG_GETARG_POINTER(1);
217
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0);
221
/*****************************************************************************
223
*****************************************************************************/
226
* int4in - converts "num" to int4
229
int4in(PG_FUNCTION_ARGS)
231
char *num = PG_GETARG_CSTRING(0);
233
PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
237
* int4out - converts int4 to "num"
240
int4out(PG_FUNCTION_ARGS)
242
int32 arg1 = PG_GETARG_INT32(0);
243
char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */
245
pg_ltoa(arg1, result);
246
PG_RETURN_CSTRING(result);
250
* int4recv - converts external binary format to int4
253
int4recv(PG_FUNCTION_ARGS)
255
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
257
PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
261
* int4send - converts int4 to binary format
264
int4send(PG_FUNCTION_ARGS)
266
int32 arg1 = PG_GETARG_INT32(0);
269
pq_begintypsend(&buf);
270
pq_sendint(&buf, arg1, sizeof(int32));
271
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
276
* ===================
277
* CONVERSION ROUTINES
278
* ===================
282
i2toi4(PG_FUNCTION_ARGS)
284
int16 arg1 = PG_GETARG_INT16(0);
286
PG_RETURN_INT32((int32) arg1);
290
i4toi2(PG_FUNCTION_ARGS)
292
int32 arg1 = PG_GETARG_INT32(0);
294
if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
296
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
297
errmsg("smallint out of range")));
299
PG_RETURN_INT16((int16) arg1);
303
int2_text(PG_FUNCTION_ARGS)
305
int16 arg1 = PG_GETARG_INT16(0);
306
text *result = (text *) palloc(7 + VARHDRSZ); /* sign,5 digits, '\0' */
308
pg_itoa(arg1, VARDATA(result));
309
VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
310
PG_RETURN_TEXT_P(result);
314
text_int2(PG_FUNCTION_ARGS)
316
text *string = PG_GETARG_TEXT_P(0);
321
len = VARSIZE(string) - VARHDRSZ;
323
str = palloc(len + 1);
324
memcpy(str, VARDATA(string), len);
327
result = DirectFunctionCall1(int2in, CStringGetDatum(str));
334
int4_text(PG_FUNCTION_ARGS)
336
int32 arg1 = PG_GETARG_INT32(0);
337
text *result = (text *) palloc(12 + VARHDRSZ); /* sign,10 digits,'\0' */
339
pg_ltoa(arg1, VARDATA(result));
340
VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
341
PG_RETURN_TEXT_P(result);
345
text_int4(PG_FUNCTION_ARGS)
347
text *string = PG_GETARG_TEXT_P(0);
352
len = VARSIZE(string) - VARHDRSZ;
354
str = palloc(len + 1);
355
memcpy(str, VARDATA(string), len);
358
result = DirectFunctionCall1(int4in, CStringGetDatum(str));
366
* ============================
367
* COMPARISON OPERATOR ROUTINES
368
* ============================
372
* inteq - returns 1 iff arg1 == arg2
373
* intne - returns 1 iff arg1 != arg2
374
* intlt - returns 1 iff arg1 < arg2
375
* intle - returns 1 iff arg1 <= arg2
376
* intgt - returns 1 iff arg1 > arg2
377
* intge - returns 1 iff arg1 >= arg2
381
int4eq(PG_FUNCTION_ARGS)
383
int32 arg1 = PG_GETARG_INT32(0);
384
int32 arg2 = PG_GETARG_INT32(1);
386
PG_RETURN_BOOL(arg1 == arg2);
390
int4ne(PG_FUNCTION_ARGS)
392
int32 arg1 = PG_GETARG_INT32(0);
393
int32 arg2 = PG_GETARG_INT32(1);
395
PG_RETURN_BOOL(arg1 != arg2);
399
int4lt(PG_FUNCTION_ARGS)
401
int32 arg1 = PG_GETARG_INT32(0);
402
int32 arg2 = PG_GETARG_INT32(1);
404
PG_RETURN_BOOL(arg1 < arg2);
408
int4le(PG_FUNCTION_ARGS)
410
int32 arg1 = PG_GETARG_INT32(0);
411
int32 arg2 = PG_GETARG_INT32(1);
413
PG_RETURN_BOOL(arg1 <= arg2);
417
int4gt(PG_FUNCTION_ARGS)
419
int32 arg1 = PG_GETARG_INT32(0);
420
int32 arg2 = PG_GETARG_INT32(1);
422
PG_RETURN_BOOL(arg1 > arg2);
426
int4ge(PG_FUNCTION_ARGS)
428
int32 arg1 = PG_GETARG_INT32(0);
429
int32 arg2 = PG_GETARG_INT32(1);
431
PG_RETURN_BOOL(arg1 >= arg2);
435
int2eq(PG_FUNCTION_ARGS)
437
int16 arg1 = PG_GETARG_INT16(0);
438
int16 arg2 = PG_GETARG_INT16(1);
440
PG_RETURN_BOOL(arg1 == arg2);
444
int2ne(PG_FUNCTION_ARGS)
446
int16 arg1 = PG_GETARG_INT16(0);
447
int16 arg2 = PG_GETARG_INT16(1);
449
PG_RETURN_BOOL(arg1 != arg2);
453
int2lt(PG_FUNCTION_ARGS)
455
int16 arg1 = PG_GETARG_INT16(0);
456
int16 arg2 = PG_GETARG_INT16(1);
458
PG_RETURN_BOOL(arg1 < arg2);
462
int2le(PG_FUNCTION_ARGS)
464
int16 arg1 = PG_GETARG_INT16(0);
465
int16 arg2 = PG_GETARG_INT16(1);
467
PG_RETURN_BOOL(arg1 <= arg2);
471
int2gt(PG_FUNCTION_ARGS)
473
int16 arg1 = PG_GETARG_INT16(0);
474
int16 arg2 = PG_GETARG_INT16(1);
476
PG_RETURN_BOOL(arg1 > arg2);
480
int2ge(PG_FUNCTION_ARGS)
482
int16 arg1 = PG_GETARG_INT16(0);
483
int16 arg2 = PG_GETARG_INT16(1);
485
PG_RETURN_BOOL(arg1 >= arg2);
489
int24eq(PG_FUNCTION_ARGS)
491
int16 arg1 = PG_GETARG_INT16(0);
492
int32 arg2 = PG_GETARG_INT32(1);
494
PG_RETURN_BOOL(arg1 == arg2);
498
int24ne(PG_FUNCTION_ARGS)
500
int16 arg1 = PG_GETARG_INT16(0);
501
int32 arg2 = PG_GETARG_INT32(1);
503
PG_RETURN_BOOL(arg1 != arg2);
507
int24lt(PG_FUNCTION_ARGS)
509
int16 arg1 = PG_GETARG_INT16(0);
510
int32 arg2 = PG_GETARG_INT32(1);
512
PG_RETURN_BOOL(arg1 < arg2);
516
int24le(PG_FUNCTION_ARGS)
518
int16 arg1 = PG_GETARG_INT16(0);
519
int32 arg2 = PG_GETARG_INT32(1);
521
PG_RETURN_BOOL(arg1 <= arg2);
525
int24gt(PG_FUNCTION_ARGS)
527
int16 arg1 = PG_GETARG_INT16(0);
528
int32 arg2 = PG_GETARG_INT32(1);
530
PG_RETURN_BOOL(arg1 > arg2);
534
int24ge(PG_FUNCTION_ARGS)
536
int16 arg1 = PG_GETARG_INT16(0);
537
int32 arg2 = PG_GETARG_INT32(1);
539
PG_RETURN_BOOL(arg1 >= arg2);
543
int42eq(PG_FUNCTION_ARGS)
545
int32 arg1 = PG_GETARG_INT32(0);
546
int16 arg2 = PG_GETARG_INT16(1);
548
PG_RETURN_BOOL(arg1 == arg2);
552
int42ne(PG_FUNCTION_ARGS)
554
int32 arg1 = PG_GETARG_INT32(0);
555
int16 arg2 = PG_GETARG_INT16(1);
557
PG_RETURN_BOOL(arg1 != arg2);
561
int42lt(PG_FUNCTION_ARGS)
563
int32 arg1 = PG_GETARG_INT32(0);
564
int16 arg2 = PG_GETARG_INT16(1);
566
PG_RETURN_BOOL(arg1 < arg2);
570
int42le(PG_FUNCTION_ARGS)
572
int32 arg1 = PG_GETARG_INT32(0);
573
int16 arg2 = PG_GETARG_INT16(1);
575
PG_RETURN_BOOL(arg1 <= arg2);
579
int42gt(PG_FUNCTION_ARGS)
581
int32 arg1 = PG_GETARG_INT32(0);
582
int16 arg2 = PG_GETARG_INT16(1);
584
PG_RETURN_BOOL(arg1 > arg2);
588
int42ge(PG_FUNCTION_ARGS)
590
int32 arg1 = PG_GETARG_INT32(0);
591
int16 arg2 = PG_GETARG_INT16(1);
593
PG_RETURN_BOOL(arg1 >= arg2);
597
* int[24]pl - returns arg1 + arg2
598
* int[24]mi - returns arg1 - arg2
599
* int[24]mul - returns arg1 * arg2
600
* int[24]div - returns arg1 / arg2
604
int4um(PG_FUNCTION_ARGS)
606
int32 arg = PG_GETARG_INT32(0);
610
/* overflow check (needed for INT_MIN) */
611
if (arg != 0 && SAMESIGN(result, arg))
613
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
614
errmsg("integer out of range")));
615
PG_RETURN_INT32(result);
619
int4up(PG_FUNCTION_ARGS)
621
int32 arg = PG_GETARG_INT32(0);
623
PG_RETURN_INT32(arg);
627
int4pl(PG_FUNCTION_ARGS)
629
int32 arg1 = PG_GETARG_INT32(0);
630
int32 arg2 = PG_GETARG_INT32(1);
633
result = arg1 + arg2;
635
* Overflow check. If the inputs are of different signs then their sum
636
* cannot overflow. If the inputs are of the same sign, their sum
637
* had better be that sign too.
639
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
641
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
642
errmsg("integer out of range")));
643
PG_RETURN_INT32(result);
647
int4mi(PG_FUNCTION_ARGS)
649
int32 arg1 = PG_GETARG_INT32(0);
650
int32 arg2 = PG_GETARG_INT32(1);
653
result = arg1 - arg2;
655
* Overflow check. If the inputs are of the same sign then their
656
* difference cannot overflow. If they are of different signs then
657
* the result should be of the same sign as the first input.
659
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
661
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
662
errmsg("integer out of range")));
663
PG_RETURN_INT32(result);
667
int4mul(PG_FUNCTION_ARGS)
669
int32 arg1 = PG_GETARG_INT32(0);
670
int32 arg2 = PG_GETARG_INT32(1);
673
result = arg1 * arg2;
675
* Overflow check. We basically check to see if result / arg2 gives
676
* arg1 again. There are two cases where this fails: arg2 = 0 (which
677
* cannot overflow) and arg1 = INT_MIN, arg2 = -1 (where the division
678
* itself will overflow and thus incorrectly match).
680
* Since the division is likely much more expensive than the actual
681
* multiplication, we'd like to skip it where possible. The best
682
* bang for the buck seems to be to check whether both inputs are in
683
* the int16 range; if so, no overflow is possible.
685
if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
686
arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
688
(result/arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
690
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
691
errmsg("integer out of range")));
692
PG_RETURN_INT32(result);
696
int4div(PG_FUNCTION_ARGS)
698
int32 arg1 = PG_GETARG_INT32(0);
699
int32 arg2 = PG_GETARG_INT32(1);
704
(errcode(ERRCODE_DIVISION_BY_ZERO),
705
errmsg("division by zero")));
707
result = arg1 / arg2;
709
* Overflow check. The only possible overflow case is for
710
* arg1 = INT_MIN, arg2 = -1, where the correct result is -INT_MIN,
711
* which can't be represented on a two's-complement machine.
713
if (arg2 == -1 && arg1 < 0 && result < 0)
715
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
716
errmsg("integer out of range")));
717
PG_RETURN_INT32(result);
721
int4inc(PG_FUNCTION_ARGS)
723
int32 arg = PG_GETARG_INT32(0);
728
if (arg > 0 && result < 0)
730
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
731
errmsg("integer out of range")));
733
PG_RETURN_INT32(result);
737
int2um(PG_FUNCTION_ARGS)
739
int16 arg = PG_GETARG_INT16(0);
743
/* overflow check (needed for SHRT_MIN) */
744
if (arg != 0 && SAMESIGN(result, arg))
746
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
747
errmsg("smallint out of range")));
748
PG_RETURN_INT16(result);
752
int2up(PG_FUNCTION_ARGS)
754
int16 arg = PG_GETARG_INT16(0);
756
PG_RETURN_INT16(arg);
760
int2pl(PG_FUNCTION_ARGS)
762
int16 arg1 = PG_GETARG_INT16(0);
763
int16 arg2 = PG_GETARG_INT16(1);
766
result = arg1 + arg2;
768
* Overflow check. If the inputs are of different signs then their sum
769
* cannot overflow. If the inputs are of the same sign, their sum
770
* had better be that sign too.
772
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
774
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
775
errmsg("smallint out of range")));
776
PG_RETURN_INT16(result);
780
int2mi(PG_FUNCTION_ARGS)
782
int16 arg1 = PG_GETARG_INT16(0);
783
int16 arg2 = PG_GETARG_INT16(1);
786
result = arg1 - arg2;
788
* Overflow check. If the inputs are of the same sign then their
789
* difference cannot overflow. If they are of different signs then
790
* the result should be of the same sign as the first input.
792
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
794
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
795
errmsg("smallint out of range")));
796
PG_RETURN_INT16(result);
800
int2mul(PG_FUNCTION_ARGS)
802
int16 arg1 = PG_GETARG_INT16(0);
803
int16 arg2 = PG_GETARG_INT16(1);
807
* The most practical way to detect overflow is to do the arithmetic
808
* in int32 (so that the result can't overflow) and then do a range
811
result32 = (int32) arg1 * (int32) arg2;
812
if (result32 < SHRT_MIN || result32 > SHRT_MAX)
814
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
815
errmsg("smallint out of range")));
817
PG_RETURN_INT16((int16) result32);
821
int2div(PG_FUNCTION_ARGS)
823
int16 arg1 = PG_GETARG_INT16(0);
824
int16 arg2 = PG_GETARG_INT16(1);
829
(errcode(ERRCODE_DIVISION_BY_ZERO),
830
errmsg("division by zero")));
832
result = arg1 / arg2;
834
* Overflow check. The only possible overflow case is for
835
* arg1 = SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN,
836
* which can't be represented on a two's-complement machine.
838
if (arg2 == -1 && arg1 < 0 && result < 0)
840
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
841
errmsg("smallint out of range")));
842
PG_RETURN_INT16(result);
846
int24pl(PG_FUNCTION_ARGS)
848
int16 arg1 = PG_GETARG_INT16(0);
849
int32 arg2 = PG_GETARG_INT32(1);
852
result = arg1 + arg2;
854
* Overflow check. If the inputs are of different signs then their sum
855
* cannot overflow. If the inputs are of the same sign, their sum
856
* had better be that sign too.
858
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
860
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
861
errmsg("integer out of range")));
862
PG_RETURN_INT32(result);
866
int24mi(PG_FUNCTION_ARGS)
868
int16 arg1 = PG_GETARG_INT16(0);
869
int32 arg2 = PG_GETARG_INT32(1);
872
result = arg1 - arg2;
874
* Overflow check. If the inputs are of the same sign then their
875
* difference cannot overflow. If they are of different signs then
876
* the result should be of the same sign as the first input.
878
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
880
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
881
errmsg("integer out of range")));
882
PG_RETURN_INT32(result);
886
int24mul(PG_FUNCTION_ARGS)
888
int16 arg1 = PG_GETARG_INT16(0);
889
int32 arg2 = PG_GETARG_INT32(1);
892
result = arg1 * arg2;
894
* Overflow check. We basically check to see if result / arg2 gives
895
* arg1 again. There is one case where this fails: arg2 = 0 (which
898
* Since the division is likely much more expensive than the actual
899
* multiplication, we'd like to skip it where possible. The best
900
* bang for the buck seems to be to check whether both inputs are in
901
* the int16 range; if so, no overflow is possible.
903
if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
906
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
907
errmsg("integer out of range")));
908
PG_RETURN_INT32(result);
912
int24div(PG_FUNCTION_ARGS)
914
int16 arg1 = PG_GETARG_INT16(0);
915
int32 arg2 = PG_GETARG_INT32(1);
919
(errcode(ERRCODE_DIVISION_BY_ZERO),
920
errmsg("division by zero")));
921
/* No overflow is possible */
922
PG_RETURN_INT32((int32) arg1 / arg2);
926
int42pl(PG_FUNCTION_ARGS)
928
int32 arg1 = PG_GETARG_INT32(0);
929
int16 arg2 = PG_GETARG_INT16(1);
932
result = arg1 + arg2;
934
* Overflow check. If the inputs are of different signs then their sum
935
* cannot overflow. If the inputs are of the same sign, their sum
936
* had better be that sign too.
938
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
940
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
941
errmsg("integer out of range")));
942
PG_RETURN_INT32(result);
946
int42mi(PG_FUNCTION_ARGS)
948
int32 arg1 = PG_GETARG_INT32(0);
949
int16 arg2 = PG_GETARG_INT16(1);
952
result = arg1 - arg2;
954
* Overflow check. If the inputs are of the same sign then their
955
* difference cannot overflow. If they are of different signs then
956
* the result should be of the same sign as the first input.
958
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
960
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
961
errmsg("integer out of range")));
962
PG_RETURN_INT32(result);
966
int42mul(PG_FUNCTION_ARGS)
968
int32 arg1 = PG_GETARG_INT32(0);
969
int16 arg2 = PG_GETARG_INT16(1);
972
result = arg1 * arg2;
974
* Overflow check. We basically check to see if result / arg1 gives
975
* arg2 again. There is one case where this fails: arg1 = 0 (which
978
* Since the division is likely much more expensive than the actual
979
* multiplication, we'd like to skip it where possible. The best
980
* bang for the buck seems to be to check whether both inputs are in
981
* the int16 range; if so, no overflow is possible.
983
if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
986
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
987
errmsg("integer out of range")));
988
PG_RETURN_INT32(result);
992
int42div(PG_FUNCTION_ARGS)
994
int32 arg1 = PG_GETARG_INT32(0);
995
int16 arg2 = PG_GETARG_INT16(1);
1000
(errcode(ERRCODE_DIVISION_BY_ZERO),
1001
errmsg("division by zero")));
1003
result = arg1 / arg2;
1005
* Overflow check. The only possible overflow case is for
1006
* arg1 = INT_MIN, arg2 = -1, where the correct result is -INT_MIN,
1007
* which can't be represented on a two's-complement machine.
1009
if (arg2 == -1 && arg1 < 0 && result < 0)
1011
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1012
errmsg("integer out of range")));
1013
PG_RETURN_INT32(result);
1017
int4mod(PG_FUNCTION_ARGS)
1019
int32 arg1 = PG_GETARG_INT32(0);
1020
int32 arg2 = PG_GETARG_INT32(1);
1024
(errcode(ERRCODE_DIVISION_BY_ZERO),
1025
errmsg("division by zero")));
1026
/* No overflow is possible */
1028
PG_RETURN_INT32(arg1 % arg2);
1032
int2mod(PG_FUNCTION_ARGS)
1034
int16 arg1 = PG_GETARG_INT16(0);
1035
int16 arg2 = PG_GETARG_INT16(1);
1039
(errcode(ERRCODE_DIVISION_BY_ZERO),
1040
errmsg("division by zero")));
1041
/* No overflow is possible */
1043
PG_RETURN_INT16(arg1 % arg2);
1047
int24mod(PG_FUNCTION_ARGS)
1049
int16 arg1 = PG_GETARG_INT16(0);
1050
int32 arg2 = PG_GETARG_INT32(1);
1054
(errcode(ERRCODE_DIVISION_BY_ZERO),
1055
errmsg("division by zero")));
1056
/* No overflow is possible */
1058
PG_RETURN_INT32(arg1 % arg2);
1062
int42mod(PG_FUNCTION_ARGS)
1064
int32 arg1 = PG_GETARG_INT32(0);
1065
int16 arg2 = PG_GETARG_INT16(1);
1069
(errcode(ERRCODE_DIVISION_BY_ZERO),
1070
errmsg("division by zero")));
1071
/* No overflow is possible */
1073
PG_RETURN_INT32(arg1 % arg2);
1081
int4abs(PG_FUNCTION_ARGS)
1083
int32 arg1 = PG_GETARG_INT32(0);
1086
result = (arg1 < 0) ? -arg1 : arg1;
1087
/* overflow check (needed for INT_MIN) */
1090
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1091
errmsg("integer out of range")));
1092
PG_RETURN_INT32(result);
1096
int2abs(PG_FUNCTION_ARGS)
1098
int16 arg1 = PG_GETARG_INT16(0);
1101
result = (arg1 < 0) ? -arg1 : arg1;
1102
/* overflow check (needed for SHRT_MIN) */
1105
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1106
errmsg("smallint out of range")));
1107
PG_RETURN_INT16(result);
1111
int2larger(PG_FUNCTION_ARGS)
1113
int16 arg1 = PG_GETARG_INT16(0);
1114
int16 arg2 = PG_GETARG_INT16(1);
1116
PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
1120
int2smaller(PG_FUNCTION_ARGS)
1122
int16 arg1 = PG_GETARG_INT16(0);
1123
int16 arg2 = PG_GETARG_INT16(1);
1125
PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
1129
int4larger(PG_FUNCTION_ARGS)
1131
int32 arg1 = PG_GETARG_INT32(0);
1132
int32 arg2 = PG_GETARG_INT32(1);
1134
PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
1138
int4smaller(PG_FUNCTION_ARGS)
1140
int32 arg1 = PG_GETARG_INT32(0);
1141
int32 arg2 = PG_GETARG_INT32(1);
1143
PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
1147
* Bit-pushing operators
1149
* int[24]and - returns arg1 & arg2
1150
* int[24]or - returns arg1 | arg2
1151
* int[24]xor - returns arg1 # arg2
1152
* int[24]not - returns ~arg1
1153
* int[24]shl - returns arg1 << arg2
1154
* int[24]shr - returns arg1 >> arg2
1158
int4and(PG_FUNCTION_ARGS)
1160
int32 arg1 = PG_GETARG_INT32(0);
1161
int32 arg2 = PG_GETARG_INT32(1);
1163
PG_RETURN_INT32(arg1 & arg2);
1167
int4or(PG_FUNCTION_ARGS)
1169
int32 arg1 = PG_GETARG_INT32(0);
1170
int32 arg2 = PG_GETARG_INT32(1);
1172
PG_RETURN_INT32(arg1 | arg2);
1176
int4xor(PG_FUNCTION_ARGS)
1178
int32 arg1 = PG_GETARG_INT32(0);
1179
int32 arg2 = PG_GETARG_INT32(1);
1181
PG_RETURN_INT32(arg1 ^ arg2);
1185
int4shl(PG_FUNCTION_ARGS)
1187
int32 arg1 = PG_GETARG_INT32(0);
1188
int32 arg2 = PG_GETARG_INT32(1);
1190
PG_RETURN_INT32(arg1 << arg2);
1194
int4shr(PG_FUNCTION_ARGS)
1196
int32 arg1 = PG_GETARG_INT32(0);
1197
int32 arg2 = PG_GETARG_INT32(1);
1199
PG_RETURN_INT32(arg1 >> arg2);
1203
int4not(PG_FUNCTION_ARGS)
1205
int32 arg1 = PG_GETARG_INT32(0);
1207
PG_RETURN_INT32(~arg1);
1211
int2and(PG_FUNCTION_ARGS)
1213
int16 arg1 = PG_GETARG_INT16(0);
1214
int16 arg2 = PG_GETARG_INT16(1);
1216
PG_RETURN_INT16(arg1 & arg2);
1220
int2or(PG_FUNCTION_ARGS)
1222
int16 arg1 = PG_GETARG_INT16(0);
1223
int16 arg2 = PG_GETARG_INT16(1);
1225
PG_RETURN_INT16(arg1 | arg2);
1229
int2xor(PG_FUNCTION_ARGS)
1231
int16 arg1 = PG_GETARG_INT16(0);
1232
int16 arg2 = PG_GETARG_INT16(1);
1234
PG_RETURN_INT16(arg1 ^ arg2);
1238
int2not(PG_FUNCTION_ARGS)
1240
int16 arg1 = PG_GETARG_INT16(0);
1242
PG_RETURN_INT16(~arg1);
1247
int2shl(PG_FUNCTION_ARGS)
1249
int16 arg1 = PG_GETARG_INT16(0);
1250
int32 arg2 = PG_GETARG_INT32(1);
1252
PG_RETURN_INT16(arg1 << arg2);
1256
int2shr(PG_FUNCTION_ARGS)
1258
int16 arg1 = PG_GETARG_INT16(0);
1259
int32 arg2 = PG_GETARG_INT32(1);
1261
PG_RETURN_INT16(arg1 >> arg2);
1265
* non-persistent numeric series generator
1268
generate_series_int4(PG_FUNCTION_ARGS)
1270
return generate_series_step_int4(fcinfo);
1274
generate_series_step_int4(PG_FUNCTION_ARGS)
1276
FuncCallContext *funcctx;
1277
generate_series_fctx *fctx;
1279
MemoryContext oldcontext;
1281
/* stuff done only on the first call of the function */
1282
if (SRF_IS_FIRSTCALL())
1284
int32 start = PG_GETARG_INT32(0);
1285
int32 finish = PG_GETARG_INT32(1);
1288
/* see if we were given an explicit step size */
1289
if (PG_NARGS() == 3)
1290
step = PG_GETARG_INT32(2);
1293
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1294
errmsg("step size may not equal zero")));
1296
/* create a function context for cross-call persistence */
1297
funcctx = SRF_FIRSTCALL_INIT();
1300
* switch to memory context appropriate for multiple function
1303
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1305
/* allocate memory for user context */
1306
fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1309
* Use fctx to keep state from call to call. Seed current with the
1310
* original start value
1312
fctx->current = start;
1313
fctx->finish = finish;
1316
funcctx->user_fctx = fctx;
1317
MemoryContextSwitchTo(oldcontext);
1320
/* stuff done on every call of the function */
1321
funcctx = SRF_PERCALL_SETUP();
1324
* get the saved state and use current as the result for this
1327
fctx = funcctx->user_fctx;
1328
result = fctx->current;
1330
if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1331
(fctx->step < 0 && fctx->current >= fctx->finish))
1333
/* increment current in preparation for next iteration */
1334
fctx->current += fctx->step;
1336
/* do when there is more left to send */
1337
SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
1340
/* do when there is no more left */
1341
SRF_RETURN_DONE(funcctx);