]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/int.c
669355e4540a891ab8cfdc79326f1fe6bbe0f163
[postgresql] / src / backend / utils / adt / int.c
1 /*-------------------------------------------------------------------------
2  *
3  * int.c
4  *        Functions for the built-in integer types (except int8).
5  *
6  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/backend/utils/adt/int.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 /*
16  * OLD COMMENTS
17  *              I/O routines:
18  *               int2in, int2out, int2recv, int2send
19  *               int4in, int4out, int4recv, int4send
20  *               int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
21  *              Boolean operators:
22  *               inteq, intne, intlt, intle, intgt, intge
23  *              Arithmetic operators:
24  *               intpl, intmi, int4mul, intdiv
25  *
26  *              Arithmetic operators:
27  *               intmod
28  */
29 #include "postgres.h"
30
31 #include <ctype.h>
32 #include <limits.h>
33
34 #include "catalog/pg_type.h"
35 #include "funcapi.h"
36 #include "libpq/pqformat.h"
37 #include "utils/array.h"
38 #include "utils/builtins.h"
39
40
41 #define SAMESIGN(a,b)   (((a) < 0) == ((b) < 0))
42
43 #define Int2VectorSize(n)       (offsetof(int2vector, values) + (n) * sizeof(int16))
44
45 typedef struct
46 {
47         int32           current;
48         int32           finish;
49         int32           step;
50 } generate_series_fctx;
51
52
53 /*****************************************************************************
54  *       USER I/O ROUTINES                                                                                                               *
55  *****************************************************************************/
56
57 /*
58  *              int2in                  - converts "num" to short
59  */
60 Datum
61 int2in(PG_FUNCTION_ARGS)
62 {
63         char       *num = PG_GETARG_CSTRING(0);
64
65         PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
66 }
67
68 /*
69  *              int2out                 - converts short to "num"
70  */
71 Datum
72 int2out(PG_FUNCTION_ARGS)
73 {
74         int16           arg1 = PG_GETARG_INT16(0);
75         char       *result = (char *) palloc(7);        /* sign, 5 digits, '\0' */
76
77         pg_itoa(arg1, result);
78         PG_RETURN_CSTRING(result);
79 }
80
81 /*
82  *              int2recv                        - converts external binary format to int2
83  */
84 Datum
85 int2recv(PG_FUNCTION_ARGS)
86 {
87         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
88
89         PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
90 }
91
92 /*
93  *              int2send                        - converts int2 to binary format
94  */
95 Datum
96 int2send(PG_FUNCTION_ARGS)
97 {
98         int16           arg1 = PG_GETARG_INT16(0);
99         StringInfoData buf;
100
101         pq_begintypsend(&buf);
102         pq_sendint(&buf, arg1, sizeof(int16));
103         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
104 }
105
106 /*
107  * construct int2vector given a raw array of int2s
108  *
109  * If int2s is NULL then caller must fill values[] afterward
110  */
111 int2vector *
112 buildint2vector(const int16 *int2s, int n)
113 {
114         int2vector *result;
115
116         result = (int2vector *) palloc0(Int2VectorSize(n));
117
118         if (n > 0 && int2s)
119                 memcpy(result->values, int2s, n * sizeof(int16));
120
121         /*
122          * Attach standard array header.  For historical reasons, we set the index
123          * lower bound to 0 not 1.
124          */
125         SET_VARSIZE(result, Int2VectorSize(n));
126         result->ndim = 1;
127         result->dataoffset = 0;         /* never any nulls */
128         result->elemtype = INT2OID;
129         result->dim1 = n;
130         result->lbound1 = 0;
131
132         return result;
133 }
134
135 /*
136  *              int2vectorin                    - converts "num num ..." to internal form
137  */
138 Datum
139 int2vectorin(PG_FUNCTION_ARGS)
140 {
141         char       *intString = PG_GETARG_CSTRING(0);
142         int2vector *result;
143         int                     n;
144
145         result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
146
147         for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)
148         {
149                 while (*intString && isspace((unsigned char) *intString))
150                         intString++;
151                 if (*intString == '\0')
152                         break;
153                 result->values[n] = pg_atoi(intString, sizeof(int16), ' ');
154                 while (*intString && !isspace((unsigned char) *intString))
155                         intString++;
156         }
157         while (*intString && isspace((unsigned char) *intString))
158                 intString++;
159         if (*intString)
160                 ereport(ERROR,
161                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
162                                  errmsg("int2vector has too many elements")));
163
164         SET_VARSIZE(result, Int2VectorSize(n));
165         result->ndim = 1;
166         result->dataoffset = 0;         /* never any nulls */
167         result->elemtype = INT2OID;
168         result->dim1 = n;
169         result->lbound1 = 0;
170
171         PG_RETURN_POINTER(result);
172 }
173
174 /*
175  *              int2vectorout           - converts internal form to "num num ..."
176  */
177 Datum
178 int2vectorout(PG_FUNCTION_ARGS)
179 {
180         int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
181         int                     num,
182                                 nnums = int2Array->dim1;
183         char       *rp;
184         char       *result;
185
186         /* assumes sign, 5 digits, ' ' */
187         rp = result = (char *) palloc(nnums * 7 + 1);
188         for (num = 0; num < nnums; num++)
189         {
190                 if (num != 0)
191                         *rp++ = ' ';
192                 pg_itoa(int2Array->values[num], rp);
193                 while (*++rp != '\0')
194                         ;
195         }
196         *rp = '\0';
197         PG_RETURN_CSTRING(result);
198 }
199
200 /*
201  *              int2vectorrecv                  - converts external binary format to int2vector
202  */
203 Datum
204 int2vectorrecv(PG_FUNCTION_ARGS)
205 {
206         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
207         FunctionCallInfoData locfcinfo;
208         int2vector *result;
209
210         /*
211          * Normally one would call array_recv() using DirectFunctionCall3, but
212          * that does not work since array_recv wants to cache some data using
213          * fcinfo->flinfo->fn_extra.  So we need to pass it our own flinfo
214          * parameter.
215          */
216         InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
217                                                          InvalidOid, NULL, NULL);
218
219         locfcinfo.arg[0] = PointerGetDatum(buf);
220         locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
221         locfcinfo.arg[2] = Int32GetDatum(-1);
222         locfcinfo.argnull[0] = false;
223         locfcinfo.argnull[1] = false;
224         locfcinfo.argnull[2] = false;
225
226         result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));
227
228         Assert(!locfcinfo.isnull);
229
230         /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
231         if (ARR_NDIM(result) != 1 ||
232                 ARR_HASNULL(result) ||
233                 ARR_ELEMTYPE(result) != INT2OID ||
234                 ARR_LBOUND(result)[0] != 0)
235                 ereport(ERROR,
236                                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
237                                  errmsg("invalid int2vector data")));
238
239         /* check length for consistency with int2vectorin() */
240         if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
241                 ereport(ERROR,
242                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
243                                  errmsg("oidvector has too many elements")));
244
245         PG_RETURN_POINTER(result);
246 }
247
248 /*
249  *              int2vectorsend                  - converts int2vector to binary format
250  */
251 Datum
252 int2vectorsend(PG_FUNCTION_ARGS)
253 {
254         return array_send(fcinfo);
255 }
256
257 /*
258  * We don't have a complete set of int2vector support routines,
259  * but we need int2vectoreq for catcache indexing.
260  */
261 Datum
262 int2vectoreq(PG_FUNCTION_ARGS)
263 {
264         int2vector *a = (int2vector *) PG_GETARG_POINTER(0);
265         int2vector *b = (int2vector *) PG_GETARG_POINTER(1);
266
267         if (a->dim1 != b->dim1)
268                 PG_RETURN_BOOL(false);
269         PG_RETURN_BOOL(memcmp(a->values, b->values, a->dim1 * sizeof(int16)) == 0);
270 }
271
272
273 /*****************************************************************************
274  *       PUBLIC ROUTINES                                                                                                                 *
275  *****************************************************************************/
276
277 /*
278  *              int4in                  - converts "num" to int4
279  */
280 Datum
281 int4in(PG_FUNCTION_ARGS)
282 {
283         char       *num = PG_GETARG_CSTRING(0);
284
285         PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
286 }
287
288 /*
289  *              int4out                 - converts int4 to "num"
290  */
291 Datum
292 int4out(PG_FUNCTION_ARGS)
293 {
294         int32           arg1 = PG_GETARG_INT32(0);
295         char       *result = (char *) palloc(12);       /* sign, 10 digits, '\0' */
296
297         pg_ltoa(arg1, result);
298         PG_RETURN_CSTRING(result);
299 }
300
301 /*
302  *              int4recv                        - converts external binary format to int4
303  */
304 Datum
305 int4recv(PG_FUNCTION_ARGS)
306 {
307         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
308
309         PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
310 }
311
312 /*
313  *              int4send                        - converts int4 to binary format
314  */
315 Datum
316 int4send(PG_FUNCTION_ARGS)
317 {
318         int32           arg1 = PG_GETARG_INT32(0);
319         StringInfoData buf;
320
321         pq_begintypsend(&buf);
322         pq_sendint(&buf, arg1, sizeof(int32));
323         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
324 }
325
326
327 /*
328  *              ===================
329  *              CONVERSION ROUTINES
330  *              ===================
331  */
332
333 Datum
334 i2toi4(PG_FUNCTION_ARGS)
335 {
336         int16           arg1 = PG_GETARG_INT16(0);
337
338         PG_RETURN_INT32((int32) arg1);
339 }
340
341 Datum
342 i4toi2(PG_FUNCTION_ARGS)
343 {
344         int32           arg1 = PG_GETARG_INT32(0);
345
346         if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
347                 ereport(ERROR,
348                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
349                                  errmsg("smallint out of range")));
350
351         PG_RETURN_INT16((int16) arg1);
352 }
353
354 /* Cast int4 -> bool */
355 Datum
356 int4_bool(PG_FUNCTION_ARGS)
357 {
358         if (PG_GETARG_INT32(0) == 0)
359                 PG_RETURN_BOOL(false);
360         else
361                 PG_RETURN_BOOL(true);
362 }
363
364 /* Cast bool -> int4 */
365 Datum
366 bool_int4(PG_FUNCTION_ARGS)
367 {
368         if (PG_GETARG_BOOL(0) == false)
369                 PG_RETURN_INT32(0);
370         else
371                 PG_RETURN_INT32(1);
372 }
373
374 /*
375  *              ============================
376  *              COMPARISON OPERATOR ROUTINES
377  *              ============================
378  */
379
380 /*
381  *              inteq                   - returns 1 iff arg1 == arg2
382  *              intne                   - returns 1 iff arg1 != arg2
383  *              intlt                   - returns 1 iff arg1 < arg2
384  *              intle                   - returns 1 iff arg1 <= arg2
385  *              intgt                   - returns 1 iff arg1 > arg2
386  *              intge                   - returns 1 iff arg1 >= arg2
387  */
388
389 Datum
390 int4eq(PG_FUNCTION_ARGS)
391 {
392         int32           arg1 = PG_GETARG_INT32(0);
393         int32           arg2 = PG_GETARG_INT32(1);
394
395         PG_RETURN_BOOL(arg1 == arg2);
396 }
397
398 Datum
399 int4ne(PG_FUNCTION_ARGS)
400 {
401         int32           arg1 = PG_GETARG_INT32(0);
402         int32           arg2 = PG_GETARG_INT32(1);
403
404         PG_RETURN_BOOL(arg1 != arg2);
405 }
406
407 Datum
408 int4lt(PG_FUNCTION_ARGS)
409 {
410         int32           arg1 = PG_GETARG_INT32(0);
411         int32           arg2 = PG_GETARG_INT32(1);
412
413         PG_RETURN_BOOL(arg1 < arg2);
414 }
415
416 Datum
417 int4le(PG_FUNCTION_ARGS)
418 {
419         int32           arg1 = PG_GETARG_INT32(0);
420         int32           arg2 = PG_GETARG_INT32(1);
421
422         PG_RETURN_BOOL(arg1 <= arg2);
423 }
424
425 Datum
426 int4gt(PG_FUNCTION_ARGS)
427 {
428         int32           arg1 = PG_GETARG_INT32(0);
429         int32           arg2 = PG_GETARG_INT32(1);
430
431         PG_RETURN_BOOL(arg1 > arg2);
432 }
433
434 Datum
435 int4ge(PG_FUNCTION_ARGS)
436 {
437         int32           arg1 = PG_GETARG_INT32(0);
438         int32           arg2 = PG_GETARG_INT32(1);
439
440         PG_RETURN_BOOL(arg1 >= arg2);
441 }
442
443 Datum
444 int2eq(PG_FUNCTION_ARGS)
445 {
446         int16           arg1 = PG_GETARG_INT16(0);
447         int16           arg2 = PG_GETARG_INT16(1);
448
449         PG_RETURN_BOOL(arg1 == arg2);
450 }
451
452 Datum
453 int2ne(PG_FUNCTION_ARGS)
454 {
455         int16           arg1 = PG_GETARG_INT16(0);
456         int16           arg2 = PG_GETARG_INT16(1);
457
458         PG_RETURN_BOOL(arg1 != arg2);
459 }
460
461 Datum
462 int2lt(PG_FUNCTION_ARGS)
463 {
464         int16           arg1 = PG_GETARG_INT16(0);
465         int16           arg2 = PG_GETARG_INT16(1);
466
467         PG_RETURN_BOOL(arg1 < arg2);
468 }
469
470 Datum
471 int2le(PG_FUNCTION_ARGS)
472 {
473         int16           arg1 = PG_GETARG_INT16(0);
474         int16           arg2 = PG_GETARG_INT16(1);
475
476         PG_RETURN_BOOL(arg1 <= arg2);
477 }
478
479 Datum
480 int2gt(PG_FUNCTION_ARGS)
481 {
482         int16           arg1 = PG_GETARG_INT16(0);
483         int16           arg2 = PG_GETARG_INT16(1);
484
485         PG_RETURN_BOOL(arg1 > arg2);
486 }
487
488 Datum
489 int2ge(PG_FUNCTION_ARGS)
490 {
491         int16           arg1 = PG_GETARG_INT16(0);
492         int16           arg2 = PG_GETARG_INT16(1);
493
494         PG_RETURN_BOOL(arg1 >= arg2);
495 }
496
497 Datum
498 int24eq(PG_FUNCTION_ARGS)
499 {
500         int16           arg1 = PG_GETARG_INT16(0);
501         int32           arg2 = PG_GETARG_INT32(1);
502
503         PG_RETURN_BOOL(arg1 == arg2);
504 }
505
506 Datum
507 int24ne(PG_FUNCTION_ARGS)
508 {
509         int16           arg1 = PG_GETARG_INT16(0);
510         int32           arg2 = PG_GETARG_INT32(1);
511
512         PG_RETURN_BOOL(arg1 != arg2);
513 }
514
515 Datum
516 int24lt(PG_FUNCTION_ARGS)
517 {
518         int16           arg1 = PG_GETARG_INT16(0);
519         int32           arg2 = PG_GETARG_INT32(1);
520
521         PG_RETURN_BOOL(arg1 < arg2);
522 }
523
524 Datum
525 int24le(PG_FUNCTION_ARGS)
526 {
527         int16           arg1 = PG_GETARG_INT16(0);
528         int32           arg2 = PG_GETARG_INT32(1);
529
530         PG_RETURN_BOOL(arg1 <= arg2);
531 }
532
533 Datum
534 int24gt(PG_FUNCTION_ARGS)
535 {
536         int16           arg1 = PG_GETARG_INT16(0);
537         int32           arg2 = PG_GETARG_INT32(1);
538
539         PG_RETURN_BOOL(arg1 > arg2);
540 }
541
542 Datum
543 int24ge(PG_FUNCTION_ARGS)
544 {
545         int16           arg1 = PG_GETARG_INT16(0);
546         int32           arg2 = PG_GETARG_INT32(1);
547
548         PG_RETURN_BOOL(arg1 >= arg2);
549 }
550
551 Datum
552 int42eq(PG_FUNCTION_ARGS)
553 {
554         int32           arg1 = PG_GETARG_INT32(0);
555         int16           arg2 = PG_GETARG_INT16(1);
556
557         PG_RETURN_BOOL(arg1 == arg2);
558 }
559
560 Datum
561 int42ne(PG_FUNCTION_ARGS)
562 {
563         int32           arg1 = PG_GETARG_INT32(0);
564         int16           arg2 = PG_GETARG_INT16(1);
565
566         PG_RETURN_BOOL(arg1 != arg2);
567 }
568
569 Datum
570 int42lt(PG_FUNCTION_ARGS)
571 {
572         int32           arg1 = PG_GETARG_INT32(0);
573         int16           arg2 = PG_GETARG_INT16(1);
574
575         PG_RETURN_BOOL(arg1 < arg2);
576 }
577
578 Datum
579 int42le(PG_FUNCTION_ARGS)
580 {
581         int32           arg1 = PG_GETARG_INT32(0);
582         int16           arg2 = PG_GETARG_INT16(1);
583
584         PG_RETURN_BOOL(arg1 <= arg2);
585 }
586
587 Datum
588 int42gt(PG_FUNCTION_ARGS)
589 {
590         int32           arg1 = PG_GETARG_INT32(0);
591         int16           arg2 = PG_GETARG_INT16(1);
592
593         PG_RETURN_BOOL(arg1 > arg2);
594 }
595
596 Datum
597 int42ge(PG_FUNCTION_ARGS)
598 {
599         int32           arg1 = PG_GETARG_INT32(0);
600         int16           arg2 = PG_GETARG_INT16(1);
601
602         PG_RETURN_BOOL(arg1 >= arg2);
603 }
604
605 /*
606  *              int[24]pl               - returns arg1 + arg2
607  *              int[24]mi               - returns arg1 - arg2
608  *              int[24]mul              - returns arg1 * arg2
609  *              int[24]div              - returns arg1 / arg2
610  */
611
612 Datum
613 int4um(PG_FUNCTION_ARGS)
614 {
615         int32           arg = PG_GETARG_INT32(0);
616         int32           result;
617
618         result = -arg;
619         /* overflow check (needed for INT_MIN) */
620         if (arg != 0 && SAMESIGN(result, arg))
621                 ereport(ERROR,
622                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
623                                  errmsg("integer out of range")));
624         PG_RETURN_INT32(result);
625 }
626
627 Datum
628 int4up(PG_FUNCTION_ARGS)
629 {
630         int32           arg = PG_GETARG_INT32(0);
631
632         PG_RETURN_INT32(arg);
633 }
634
635 Datum
636 int4pl(PG_FUNCTION_ARGS)
637 {
638         int32           arg1 = PG_GETARG_INT32(0);
639         int32           arg2 = PG_GETARG_INT32(1);
640         int32           result;
641
642         result = arg1 + arg2;
643
644         /*
645          * Overflow check.      If the inputs are of different signs then their sum
646          * cannot overflow.  If the inputs are of the same sign, their sum had
647          * better be that sign too.
648          */
649         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
650                 ereport(ERROR,
651                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
652                                  errmsg("integer out of range")));
653         PG_RETURN_INT32(result);
654 }
655
656 Datum
657 int4mi(PG_FUNCTION_ARGS)
658 {
659         int32           arg1 = PG_GETARG_INT32(0);
660         int32           arg2 = PG_GETARG_INT32(1);
661         int32           result;
662
663         result = arg1 - arg2;
664
665         /*
666          * Overflow check.      If the inputs are of the same sign then their
667          * difference cannot overflow.  If they are of different signs then the
668          * result should be of the same sign as the first input.
669          */
670         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
671                 ereport(ERROR,
672                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
673                                  errmsg("integer out of range")));
674         PG_RETURN_INT32(result);
675 }
676
677 Datum
678 int4mul(PG_FUNCTION_ARGS)
679 {
680         int32           arg1 = PG_GETARG_INT32(0);
681         int32           arg2 = PG_GETARG_INT32(1);
682         int32           result;
683
684         result = arg1 * arg2;
685
686         /*
687          * Overflow check.      We basically check to see if result / arg2 gives arg1
688          * again.  There are two cases where this fails: arg2 = 0 (which cannot
689          * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will
690          * overflow and thus incorrectly match).
691          *
692          * Since the division is likely much more expensive than the actual
693          * multiplication, we'd like to skip it where possible.  The best bang for
694          * the buck seems to be to check whether both inputs are in the int16
695          * range; if so, no overflow is possible.
696          */
697         if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
698                   arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
699                 arg2 != 0 &&
700                 ((arg2 == -1 && arg1 < 0 && result < 0) ||
701                  result / arg2 != arg1))
702                 ereport(ERROR,
703                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
704                                  errmsg("integer out of range")));
705         PG_RETURN_INT32(result);
706 }
707
708 Datum
709 int4div(PG_FUNCTION_ARGS)
710 {
711         int32           arg1 = PG_GETARG_INT32(0);
712         int32           arg2 = PG_GETARG_INT32(1);
713         int32           result;
714
715         if (arg2 == 0)
716         {
717                 ereport(ERROR,
718                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
719                                  errmsg("division by zero")));
720                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
721                 PG_RETURN_NULL();
722         }
723
724         /*
725          * INT_MIN / -1 is problematic, since the result can't be represented on a
726          * two's-complement machine.  Some machines produce INT_MIN, some produce
727          * zero, some throw an exception.  We can dodge the problem by recognizing
728          * that division by -1 is the same as negation.
729          */
730         if (arg2 == -1)
731         {
732                 result = -arg1;
733                 /* overflow check (needed for INT_MIN) */
734                 if (arg1 != 0 && SAMESIGN(result, arg1))
735                         ereport(ERROR,
736                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
737                                          errmsg("integer out of range")));
738                 PG_RETURN_INT32(result);
739         }
740
741         /* No overflow is possible */
742
743         result = arg1 / arg2;
744
745         PG_RETURN_INT32(result);
746 }
747
748 Datum
749 int4inc(PG_FUNCTION_ARGS)
750 {
751         int32           arg = PG_GETARG_INT32(0);
752         int32           result;
753
754         result = arg + 1;
755         /* Overflow check */
756         if (arg > 0 && result < 0)
757                 ereport(ERROR,
758                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
759                                  errmsg("integer out of range")));
760
761         PG_RETURN_INT32(result);
762 }
763
764 Datum
765 int2um(PG_FUNCTION_ARGS)
766 {
767         int16           arg = PG_GETARG_INT16(0);
768         int16           result;
769
770         result = -arg;
771         /* overflow check (needed for SHRT_MIN) */
772         if (arg != 0 && SAMESIGN(result, arg))
773                 ereport(ERROR,
774                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
775                                  errmsg("smallint out of range")));
776         PG_RETURN_INT16(result);
777 }
778
779 Datum
780 int2up(PG_FUNCTION_ARGS)
781 {
782         int16           arg = PG_GETARG_INT16(0);
783
784         PG_RETURN_INT16(arg);
785 }
786
787 Datum
788 int2pl(PG_FUNCTION_ARGS)
789 {
790         int16           arg1 = PG_GETARG_INT16(0);
791         int16           arg2 = PG_GETARG_INT16(1);
792         int16           result;
793
794         result = arg1 + arg2;
795
796         /*
797          * Overflow check.      If the inputs are of different signs then their sum
798          * cannot overflow.  If the inputs are of the same sign, their sum had
799          * better be that sign too.
800          */
801         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
802                 ereport(ERROR,
803                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
804                                  errmsg("smallint out of range")));
805         PG_RETURN_INT16(result);
806 }
807
808 Datum
809 int2mi(PG_FUNCTION_ARGS)
810 {
811         int16           arg1 = PG_GETARG_INT16(0);
812         int16           arg2 = PG_GETARG_INT16(1);
813         int16           result;
814
815         result = arg1 - arg2;
816
817         /*
818          * Overflow check.      If the inputs are of the same sign then their
819          * difference cannot overflow.  If they are of different signs then the
820          * result should be of the same sign as the first input.
821          */
822         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
823                 ereport(ERROR,
824                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
825                                  errmsg("smallint out of range")));
826         PG_RETURN_INT16(result);
827 }
828
829 Datum
830 int2mul(PG_FUNCTION_ARGS)
831 {
832         int16           arg1 = PG_GETARG_INT16(0);
833         int16           arg2 = PG_GETARG_INT16(1);
834         int32           result32;
835
836         /*
837          * The most practical way to detect overflow is to do the arithmetic in
838          * int32 (so that the result can't overflow) and then do a range check.
839          */
840         result32 = (int32) arg1 *(int32) arg2;
841
842         if (result32 < SHRT_MIN || result32 > SHRT_MAX)
843                 ereport(ERROR,
844                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
845                                  errmsg("smallint out of range")));
846
847         PG_RETURN_INT16((int16) result32);
848 }
849
850 Datum
851 int2div(PG_FUNCTION_ARGS)
852 {
853         int16           arg1 = PG_GETARG_INT16(0);
854         int16           arg2 = PG_GETARG_INT16(1);
855         int16           result;
856
857         if (arg2 == 0)
858         {
859                 ereport(ERROR,
860                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
861                                  errmsg("division by zero")));
862                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
863                 PG_RETURN_NULL();
864         }
865
866         /*
867          * SHRT_MIN / -1 is problematic, since the result can't be represented on
868          * a two's-complement machine.  Some machines produce SHRT_MIN, some
869          * produce zero, some throw an exception.  We can dodge the problem by
870          * recognizing that division by -1 is the same as negation.
871          */
872         if (arg2 == -1)
873         {
874                 result = -arg1;
875                 /* overflow check (needed for SHRT_MIN) */
876                 if (arg1 != 0 && SAMESIGN(result, arg1))
877                         ereport(ERROR,
878                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
879                                          errmsg("smallint out of range")));
880                 PG_RETURN_INT16(result);
881         }
882
883         /* No overflow is possible */
884
885         result = arg1 / arg2;
886
887         PG_RETURN_INT16(result);
888 }
889
890 Datum
891 int24pl(PG_FUNCTION_ARGS)
892 {
893         int16           arg1 = PG_GETARG_INT16(0);
894         int32           arg2 = PG_GETARG_INT32(1);
895         int32           result;
896
897         result = arg1 + arg2;
898
899         /*
900          * Overflow check.      If the inputs are of different signs then their sum
901          * cannot overflow.  If the inputs are of the same sign, their sum had
902          * better be that sign too.
903          */
904         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
905                 ereport(ERROR,
906                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
907                                  errmsg("integer out of range")));
908         PG_RETURN_INT32(result);
909 }
910
911 Datum
912 int24mi(PG_FUNCTION_ARGS)
913 {
914         int16           arg1 = PG_GETARG_INT16(0);
915         int32           arg2 = PG_GETARG_INT32(1);
916         int32           result;
917
918         result = arg1 - arg2;
919
920         /*
921          * Overflow check.      If the inputs are of the same sign then their
922          * difference cannot overflow.  If they are of different signs then the
923          * result should be of the same sign as the first input.
924          */
925         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
926                 ereport(ERROR,
927                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
928                                  errmsg("integer out of range")));
929         PG_RETURN_INT32(result);
930 }
931
932 Datum
933 int24mul(PG_FUNCTION_ARGS)
934 {
935         int16           arg1 = PG_GETARG_INT16(0);
936         int32           arg2 = PG_GETARG_INT32(1);
937         int32           result;
938
939         result = arg1 * arg2;
940
941         /*
942          * Overflow check.      We basically check to see if result / arg2 gives arg1
943          * again.  There is one case where this fails: arg2 = 0 (which cannot
944          * overflow).
945          *
946          * Since the division is likely much more expensive than the actual
947          * multiplication, we'd like to skip it where possible.  The best bang for
948          * the buck seems to be to check whether both inputs are in the int16
949          * range; if so, no overflow is possible.
950          */
951         if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
952                 result / arg2 != arg1)
953                 ereport(ERROR,
954                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
955                                  errmsg("integer out of range")));
956         PG_RETURN_INT32(result);
957 }
958
959 Datum
960 int24div(PG_FUNCTION_ARGS)
961 {
962         int16           arg1 = PG_GETARG_INT16(0);
963         int32           arg2 = PG_GETARG_INT32(1);
964
965         if (arg2 == 0)
966         {
967                 ereport(ERROR,
968                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
969                                  errmsg("division by zero")));
970                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
971                 PG_RETURN_NULL();
972         }
973
974         /* No overflow is possible */
975         PG_RETURN_INT32((int32) arg1 / arg2);
976 }
977
978 Datum
979 int42pl(PG_FUNCTION_ARGS)
980 {
981         int32           arg1 = PG_GETARG_INT32(0);
982         int16           arg2 = PG_GETARG_INT16(1);
983         int32           result;
984
985         result = arg1 + arg2;
986
987         /*
988          * Overflow check.      If the inputs are of different signs then their sum
989          * cannot overflow.  If the inputs are of the same sign, their sum had
990          * better be that sign too.
991          */
992         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
993                 ereport(ERROR,
994                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
995                                  errmsg("integer out of range")));
996         PG_RETURN_INT32(result);
997 }
998
999 Datum
1000 int42mi(PG_FUNCTION_ARGS)
1001 {
1002         int32           arg1 = PG_GETARG_INT32(0);
1003         int16           arg2 = PG_GETARG_INT16(1);
1004         int32           result;
1005
1006         result = arg1 - arg2;
1007
1008         /*
1009          * Overflow check.      If the inputs are of the same sign then their
1010          * difference cannot overflow.  If they are of different signs then the
1011          * result should be of the same sign as the first input.
1012          */
1013         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1014                 ereport(ERROR,
1015                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1016                                  errmsg("integer out of range")));
1017         PG_RETURN_INT32(result);
1018 }
1019
1020 Datum
1021 int42mul(PG_FUNCTION_ARGS)
1022 {
1023         int32           arg1 = PG_GETARG_INT32(0);
1024         int16           arg2 = PG_GETARG_INT16(1);
1025         int32           result;
1026
1027         result = arg1 * arg2;
1028
1029         /*
1030          * Overflow check.      We basically check to see if result / arg1 gives arg2
1031          * again.  There is one case where this fails: arg1 = 0 (which cannot
1032          * overflow).
1033          *
1034          * Since the division is likely much more expensive than the actual
1035          * multiplication, we'd like to skip it where possible.  The best bang for
1036          * the buck seems to be to check whether both inputs are in the int16
1037          * range; if so, no overflow is possible.
1038          */
1039         if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
1040                 result / arg1 != arg2)
1041                 ereport(ERROR,
1042                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1043                                  errmsg("integer out of range")));
1044         PG_RETURN_INT32(result);
1045 }
1046
1047 Datum
1048 int42div(PG_FUNCTION_ARGS)
1049 {
1050         int32           arg1 = PG_GETARG_INT32(0);
1051         int16           arg2 = PG_GETARG_INT16(1);
1052         int32           result;
1053
1054         if (arg2 == 0)
1055         {
1056                 ereport(ERROR,
1057                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1058                                  errmsg("division by zero")));
1059                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1060                 PG_RETURN_NULL();
1061         }
1062
1063         /*
1064          * INT_MIN / -1 is problematic, since the result can't be represented on a
1065          * two's-complement machine.  Some machines produce INT_MIN, some produce
1066          * zero, some throw an exception.  We can dodge the problem by recognizing
1067          * that division by -1 is the same as negation.
1068          */
1069         if (arg2 == -1)
1070         {
1071                 result = -arg1;
1072                 /* overflow check (needed for INT_MIN) */
1073                 if (arg1 != 0 && SAMESIGN(result, arg1))
1074                         ereport(ERROR,
1075                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1076                                          errmsg("integer out of range")));
1077                 PG_RETURN_INT32(result);
1078         }
1079
1080         /* No overflow is possible */
1081
1082         result = arg1 / arg2;
1083
1084         PG_RETURN_INT32(result);
1085 }
1086
1087 Datum
1088 int4mod(PG_FUNCTION_ARGS)
1089 {
1090         int32           arg1 = PG_GETARG_INT32(0);
1091         int32           arg2 = PG_GETARG_INT32(1);
1092
1093         if (arg2 == 0)
1094         {
1095                 ereport(ERROR,
1096                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1097                                  errmsg("division by zero")));
1098                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1099                 PG_RETURN_NULL();
1100         }
1101
1102         /*
1103          * Some machines throw a floating-point exception for INT_MIN % -1, which
1104          * is a bit silly since the correct answer is perfectly well-defined,
1105          * namely zero.
1106          */
1107         if (arg2 == -1)
1108                 PG_RETURN_INT32(0);
1109
1110         /* No overflow is possible */
1111
1112         PG_RETURN_INT32(arg1 % arg2);
1113 }
1114
1115 Datum
1116 int2mod(PG_FUNCTION_ARGS)
1117 {
1118         int16           arg1 = PG_GETARG_INT16(0);
1119         int16           arg2 = PG_GETARG_INT16(1);
1120
1121         if (arg2 == 0)
1122         {
1123                 ereport(ERROR,
1124                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1125                                  errmsg("division by zero")));
1126                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1127                 PG_RETURN_NULL();
1128         }
1129
1130         /*
1131          * Some machines throw a floating-point exception for INT_MIN % -1, which
1132          * is a bit silly since the correct answer is perfectly well-defined,
1133          * namely zero.  (It's not clear this ever happens when dealing with
1134          * int16, but we might as well have the test for safety.)
1135          */
1136         if (arg2 == -1)
1137                 PG_RETURN_INT16(0);
1138
1139         /* No overflow is possible */
1140
1141         PG_RETURN_INT16(arg1 % arg2);
1142 }
1143
1144
1145 /* int[24]abs()
1146  * Absolute value
1147  */
1148 Datum
1149 int4abs(PG_FUNCTION_ARGS)
1150 {
1151         int32           arg1 = PG_GETARG_INT32(0);
1152         int32           result;
1153
1154         result = (arg1 < 0) ? -arg1 : arg1;
1155         /* overflow check (needed for INT_MIN) */
1156         if (result < 0)
1157                 ereport(ERROR,
1158                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1159                                  errmsg("integer out of range")));
1160         PG_RETURN_INT32(result);
1161 }
1162
1163 Datum
1164 int2abs(PG_FUNCTION_ARGS)
1165 {
1166         int16           arg1 = PG_GETARG_INT16(0);
1167         int16           result;
1168
1169         result = (arg1 < 0) ? -arg1 : arg1;
1170         /* overflow check (needed for SHRT_MIN) */
1171         if (result < 0)
1172                 ereport(ERROR,
1173                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1174                                  errmsg("smallint out of range")));
1175         PG_RETURN_INT16(result);
1176 }
1177
1178 Datum
1179 int2larger(PG_FUNCTION_ARGS)
1180 {
1181         int16           arg1 = PG_GETARG_INT16(0);
1182         int16           arg2 = PG_GETARG_INT16(1);
1183
1184         PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
1185 }
1186
1187 Datum
1188 int2smaller(PG_FUNCTION_ARGS)
1189 {
1190         int16           arg1 = PG_GETARG_INT16(0);
1191         int16           arg2 = PG_GETARG_INT16(1);
1192
1193         PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
1194 }
1195
1196 Datum
1197 int4larger(PG_FUNCTION_ARGS)
1198 {
1199         int32           arg1 = PG_GETARG_INT32(0);
1200         int32           arg2 = PG_GETARG_INT32(1);
1201
1202         PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
1203 }
1204
1205 Datum
1206 int4smaller(PG_FUNCTION_ARGS)
1207 {
1208         int32           arg1 = PG_GETARG_INT32(0);
1209         int32           arg2 = PG_GETARG_INT32(1);
1210
1211         PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
1212 }
1213
1214 /*
1215  * Bit-pushing operators
1216  *
1217  *              int[24]and              - returns arg1 & arg2
1218  *              int[24]or               - returns arg1 | arg2
1219  *              int[24]xor              - returns arg1 # arg2
1220  *              int[24]not              - returns ~arg1
1221  *              int[24]shl              - returns arg1 << arg2
1222  *              int[24]shr              - returns arg1 >> arg2
1223  */
1224
1225 Datum
1226 int4and(PG_FUNCTION_ARGS)
1227 {
1228         int32           arg1 = PG_GETARG_INT32(0);
1229         int32           arg2 = PG_GETARG_INT32(1);
1230
1231         PG_RETURN_INT32(arg1 & arg2);
1232 }
1233
1234 Datum
1235 int4or(PG_FUNCTION_ARGS)
1236 {
1237         int32           arg1 = PG_GETARG_INT32(0);
1238         int32           arg2 = PG_GETARG_INT32(1);
1239
1240         PG_RETURN_INT32(arg1 | arg2);
1241 }
1242
1243 Datum
1244 int4xor(PG_FUNCTION_ARGS)
1245 {
1246         int32           arg1 = PG_GETARG_INT32(0);
1247         int32           arg2 = PG_GETARG_INT32(1);
1248
1249         PG_RETURN_INT32(arg1 ^ arg2);
1250 }
1251
1252 Datum
1253 int4shl(PG_FUNCTION_ARGS)
1254 {
1255         int32           arg1 = PG_GETARG_INT32(0);
1256         int32           arg2 = PG_GETARG_INT32(1);
1257
1258         PG_RETURN_INT32(arg1 << arg2);
1259 }
1260
1261 Datum
1262 int4shr(PG_FUNCTION_ARGS)
1263 {
1264         int32           arg1 = PG_GETARG_INT32(0);
1265         int32           arg2 = PG_GETARG_INT32(1);
1266
1267         PG_RETURN_INT32(arg1 >> arg2);
1268 }
1269
1270 Datum
1271 int4not(PG_FUNCTION_ARGS)
1272 {
1273         int32           arg1 = PG_GETARG_INT32(0);
1274
1275         PG_RETURN_INT32(~arg1);
1276 }
1277
1278 Datum
1279 int2and(PG_FUNCTION_ARGS)
1280 {
1281         int16           arg1 = PG_GETARG_INT16(0);
1282         int16           arg2 = PG_GETARG_INT16(1);
1283
1284         PG_RETURN_INT16(arg1 & arg2);
1285 }
1286
1287 Datum
1288 int2or(PG_FUNCTION_ARGS)
1289 {
1290         int16           arg1 = PG_GETARG_INT16(0);
1291         int16           arg2 = PG_GETARG_INT16(1);
1292
1293         PG_RETURN_INT16(arg1 | arg2);
1294 }
1295
1296 Datum
1297 int2xor(PG_FUNCTION_ARGS)
1298 {
1299         int16           arg1 = PG_GETARG_INT16(0);
1300         int16           arg2 = PG_GETARG_INT16(1);
1301
1302         PG_RETURN_INT16(arg1 ^ arg2);
1303 }
1304
1305 Datum
1306 int2not(PG_FUNCTION_ARGS)
1307 {
1308         int16           arg1 = PG_GETARG_INT16(0);
1309
1310         PG_RETURN_INT16(~arg1);
1311 }
1312
1313
1314 Datum
1315 int2shl(PG_FUNCTION_ARGS)
1316 {
1317         int16           arg1 = PG_GETARG_INT16(0);
1318         int32           arg2 = PG_GETARG_INT32(1);
1319
1320         PG_RETURN_INT16(arg1 << arg2);
1321 }
1322
1323 Datum
1324 int2shr(PG_FUNCTION_ARGS)
1325 {
1326         int16           arg1 = PG_GETARG_INT16(0);
1327         int32           arg2 = PG_GETARG_INT32(1);
1328
1329         PG_RETURN_INT16(arg1 >> arg2);
1330 }
1331
1332 /*
1333  * non-persistent numeric series generator
1334  */
1335 Datum
1336 generate_series_int4(PG_FUNCTION_ARGS)
1337 {
1338         return generate_series_step_int4(fcinfo);
1339 }
1340
1341 Datum
1342 generate_series_step_int4(PG_FUNCTION_ARGS)
1343 {
1344         FuncCallContext *funcctx;
1345         generate_series_fctx *fctx;
1346         int32           result;
1347         MemoryContext oldcontext;
1348
1349         /* stuff done only on the first call of the function */
1350         if (SRF_IS_FIRSTCALL())
1351         {
1352                 int32           start = PG_GETARG_INT32(0);
1353                 int32           finish = PG_GETARG_INT32(1);
1354                 int32           step = 1;
1355
1356                 /* see if we were given an explicit step size */
1357                 if (PG_NARGS() == 3)
1358                         step = PG_GETARG_INT32(2);
1359                 if (step == 0)
1360                         ereport(ERROR,
1361                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1362                                          errmsg("step size cannot equal zero")));
1363
1364                 /* create a function context for cross-call persistence */
1365                 funcctx = SRF_FIRSTCALL_INIT();
1366
1367                 /*
1368                  * switch to memory context appropriate for multiple function calls
1369                  */
1370                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1371
1372                 /* allocate memory for user context */
1373                 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1374
1375                 /*
1376                  * Use fctx to keep state from call to call. Seed current with the
1377                  * original start value
1378                  */
1379                 fctx->current = start;
1380                 fctx->finish = finish;
1381                 fctx->step = step;
1382
1383                 funcctx->user_fctx = fctx;
1384                 MemoryContextSwitchTo(oldcontext);
1385         }
1386
1387         /* stuff done on every call of the function */
1388         funcctx = SRF_PERCALL_SETUP();
1389
1390         /*
1391          * get the saved state and use current as the result for this iteration
1392          */
1393         fctx = funcctx->user_fctx;
1394         result = fctx->current;
1395
1396         if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1397                 (fctx->step < 0 && fctx->current >= fctx->finish))
1398         {
1399                 /* increment current in preparation for next iteration */
1400                 fctx->current += fctx->step;
1401
1402                 /* if next-value computation overflows, this is the final result */
1403                 if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
1404                         fctx->step = 0;
1405
1406                 /* do when there is more left to send */
1407                 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
1408         }
1409         else
1410                 /* do when there is no more left */
1411                 SRF_RETURN_DONE(funcctx);
1412 }