]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/int.c
Pass collations to functions in FunctionCallInfoData, not FmgrInfo.
[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-2011, 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(int2))
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 int2 *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(int2));
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(int2)) == 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 #ifdef WIN32
685
686         /*
687          * Win32 doesn't throw a catchable exception for SELECT -2147483648 *
688          * (-1);  -- INT_MIN
689          */
690         if (arg2 == -1 && arg1 == INT_MIN)
691                 ereport(ERROR,
692                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
693                                  errmsg("integer out of range")));
694 #endif
695
696         result = arg1 * arg2;
697
698         /*
699          * Overflow check.      We basically check to see if result / arg2 gives arg1
700          * again.  There are two cases where this fails: arg2 = 0 (which cannot
701          * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will
702          * overflow and thus incorrectly match).
703          *
704          * Since the division is likely much more expensive than the actual
705          * multiplication, we'd like to skip it where possible.  The best bang for
706          * the buck seems to be to check whether both inputs are in the int16
707          * range; if so, no overflow is possible.
708          */
709         if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
710                   arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
711                 arg2 != 0 &&
712                 (result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
713                 ereport(ERROR,
714                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
715                                  errmsg("integer out of range")));
716         PG_RETURN_INT32(result);
717 }
718
719 Datum
720 int4div(PG_FUNCTION_ARGS)
721 {
722         int32           arg1 = PG_GETARG_INT32(0);
723         int32           arg2 = PG_GETARG_INT32(1);
724         int32           result;
725
726         if (arg2 == 0)
727         {
728                 ereport(ERROR,
729                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
730                                  errmsg("division by zero")));
731                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
732                 PG_RETURN_NULL();
733         }
734
735 #ifdef WIN32
736
737         /*
738          * Win32 doesn't throw a catchable exception for SELECT -2147483648 /
739          * (-1); -- INT_MIN
740          */
741         if (arg2 == -1 && arg1 == INT_MIN)
742                 ereport(ERROR,
743                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
744                                  errmsg("integer out of range")));
745 #endif
746
747         result = arg1 / arg2;
748
749         /*
750          * Overflow check.      The only possible overflow case is for arg1 = INT_MIN,
751          * arg2 = -1, where the correct result is -INT_MIN, which can't be
752          * represented on a two's-complement machine.  Most machines produce
753          * INT_MIN but it seems some produce zero.
754          */
755         if (arg2 == -1 && arg1 < 0 && result <= 0)
756                 ereport(ERROR,
757                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
758                                  errmsg("integer out of range")));
759         PG_RETURN_INT32(result);
760 }
761
762 Datum
763 int4inc(PG_FUNCTION_ARGS)
764 {
765         int32           arg = PG_GETARG_INT32(0);
766         int32           result;
767
768         result = arg + 1;
769         /* Overflow check */
770         if (arg > 0 && result < 0)
771                 ereport(ERROR,
772                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
773                                  errmsg("integer out of range")));
774
775         PG_RETURN_INT32(result);
776 }
777
778 Datum
779 int2um(PG_FUNCTION_ARGS)
780 {
781         int16           arg = PG_GETARG_INT16(0);
782         int16           result;
783
784         result = -arg;
785         /* overflow check (needed for SHRT_MIN) */
786         if (arg != 0 && SAMESIGN(result, arg))
787                 ereport(ERROR,
788                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
789                                  errmsg("smallint out of range")));
790         PG_RETURN_INT16(result);
791 }
792
793 Datum
794 int2up(PG_FUNCTION_ARGS)
795 {
796         int16           arg = PG_GETARG_INT16(0);
797
798         PG_RETURN_INT16(arg);
799 }
800
801 Datum
802 int2pl(PG_FUNCTION_ARGS)
803 {
804         int16           arg1 = PG_GETARG_INT16(0);
805         int16           arg2 = PG_GETARG_INT16(1);
806         int16           result;
807
808         result = arg1 + arg2;
809
810         /*
811          * Overflow check.      If the inputs are of different signs then their sum
812          * cannot overflow.  If the inputs are of the same sign, their sum had
813          * better be that sign too.
814          */
815         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
816                 ereport(ERROR,
817                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
818                                  errmsg("smallint out of range")));
819         PG_RETURN_INT16(result);
820 }
821
822 Datum
823 int2mi(PG_FUNCTION_ARGS)
824 {
825         int16           arg1 = PG_GETARG_INT16(0);
826         int16           arg2 = PG_GETARG_INT16(1);
827         int16           result;
828
829         result = arg1 - arg2;
830
831         /*
832          * Overflow check.      If the inputs are of the same sign then their
833          * difference cannot overflow.  If they are of different signs then the
834          * result should be of the same sign as the first input.
835          */
836         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
837                 ereport(ERROR,
838                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
839                                  errmsg("smallint out of range")));
840         PG_RETURN_INT16(result);
841 }
842
843 Datum
844 int2mul(PG_FUNCTION_ARGS)
845 {
846         int16           arg1 = PG_GETARG_INT16(0);
847         int16           arg2 = PG_GETARG_INT16(1);
848         int32           result32;
849
850         /*
851          * The most practical way to detect overflow is to do the arithmetic in
852          * int32 (so that the result can't overflow) and then do a range check.
853          */
854         result32 = (int32) arg1 *(int32) arg2;
855
856         if (result32 < SHRT_MIN || result32 > SHRT_MAX)
857                 ereport(ERROR,
858                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
859                                  errmsg("smallint out of range")));
860
861         PG_RETURN_INT16((int16) result32);
862 }
863
864 Datum
865 int2div(PG_FUNCTION_ARGS)
866 {
867         int16           arg1 = PG_GETARG_INT16(0);
868         int16           arg2 = PG_GETARG_INT16(1);
869         int16           result;
870
871         if (arg2 == 0)
872         {
873                 ereport(ERROR,
874                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
875                                  errmsg("division by zero")));
876                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
877                 PG_RETURN_NULL();
878         }
879
880         result = arg1 / arg2;
881
882         /*
883          * Overflow check.      The only possible overflow case is for arg1 =
884          * SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN, which can't
885          * be represented on a two's-complement machine.  Most machines produce
886          * SHRT_MIN but it seems some produce zero.
887          */
888         if (arg2 == -1 && arg1 < 0 && result <= 0)
889                 ereport(ERROR,
890                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
891                                  errmsg("smallint out of range")));
892         PG_RETURN_INT16(result);
893 }
894
895 Datum
896 int24pl(PG_FUNCTION_ARGS)
897 {
898         int16           arg1 = PG_GETARG_INT16(0);
899         int32           arg2 = PG_GETARG_INT32(1);
900         int32           result;
901
902         result = arg1 + arg2;
903
904         /*
905          * Overflow check.      If the inputs are of different signs then their sum
906          * cannot overflow.  If the inputs are of the same sign, their sum had
907          * better be that sign too.
908          */
909         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
910                 ereport(ERROR,
911                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
912                                  errmsg("integer out of range")));
913         PG_RETURN_INT32(result);
914 }
915
916 Datum
917 int24mi(PG_FUNCTION_ARGS)
918 {
919         int16           arg1 = PG_GETARG_INT16(0);
920         int32           arg2 = PG_GETARG_INT32(1);
921         int32           result;
922
923         result = arg1 - arg2;
924
925         /*
926          * Overflow check.      If the inputs are of the same sign then their
927          * difference cannot overflow.  If they are of different signs then the
928          * result should be of the same sign as the first input.
929          */
930         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
931                 ereport(ERROR,
932                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
933                                  errmsg("integer out of range")));
934         PG_RETURN_INT32(result);
935 }
936
937 Datum
938 int24mul(PG_FUNCTION_ARGS)
939 {
940         int16           arg1 = PG_GETARG_INT16(0);
941         int32           arg2 = PG_GETARG_INT32(1);
942         int32           result;
943
944         result = arg1 * arg2;
945
946         /*
947          * Overflow check.      We basically check to see if result / arg2 gives arg1
948          * again.  There is one case where this fails: arg2 = 0 (which cannot
949          * overflow).
950          *
951          * Since the division is likely much more expensive than the actual
952          * multiplication, we'd like to skip it where possible.  The best bang for
953          * the buck seems to be to check whether both inputs are in the int16
954          * range; if so, no overflow is possible.
955          */
956         if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
957                 result / arg2 != arg1)
958                 ereport(ERROR,
959                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
960                                  errmsg("integer out of range")));
961         PG_RETURN_INT32(result);
962 }
963
964 Datum
965 int24div(PG_FUNCTION_ARGS)
966 {
967         int16           arg1 = PG_GETARG_INT16(0);
968         int32           arg2 = PG_GETARG_INT32(1);
969
970         if (arg2 == 0)
971         {
972                 ereport(ERROR,
973                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
974                                  errmsg("division by zero")));
975                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
976                 PG_RETURN_NULL();
977         }
978
979         /* No overflow is possible */
980         PG_RETURN_INT32((int32) arg1 / arg2);
981 }
982
983 Datum
984 int42pl(PG_FUNCTION_ARGS)
985 {
986         int32           arg1 = PG_GETARG_INT32(0);
987         int16           arg2 = PG_GETARG_INT16(1);
988         int32           result;
989
990         result = arg1 + arg2;
991
992         /*
993          * Overflow check.      If the inputs are of different signs then their sum
994          * cannot overflow.  If the inputs are of the same sign, their sum had
995          * better be that sign too.
996          */
997         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
998                 ereport(ERROR,
999                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1000                                  errmsg("integer out of range")));
1001         PG_RETURN_INT32(result);
1002 }
1003
1004 Datum
1005 int42mi(PG_FUNCTION_ARGS)
1006 {
1007         int32           arg1 = PG_GETARG_INT32(0);
1008         int16           arg2 = PG_GETARG_INT16(1);
1009         int32           result;
1010
1011         result = arg1 - arg2;
1012
1013         /*
1014          * Overflow check.      If the inputs are of the same sign then their
1015          * difference cannot overflow.  If they are of different signs then the
1016          * result should be of the same sign as the first input.
1017          */
1018         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1019                 ereport(ERROR,
1020                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1021                                  errmsg("integer out of range")));
1022         PG_RETURN_INT32(result);
1023 }
1024
1025 Datum
1026 int42mul(PG_FUNCTION_ARGS)
1027 {
1028         int32           arg1 = PG_GETARG_INT32(0);
1029         int16           arg2 = PG_GETARG_INT16(1);
1030         int32           result;
1031
1032         result = arg1 * arg2;
1033
1034         /*
1035          * Overflow check.      We basically check to see if result / arg1 gives arg2
1036          * again.  There is one case where this fails: arg1 = 0 (which cannot
1037          * overflow).
1038          *
1039          * Since the division is likely much more expensive than the actual
1040          * multiplication, we'd like to skip it where possible.  The best bang for
1041          * the buck seems to be to check whether both inputs are in the int16
1042          * range; if so, no overflow is possible.
1043          */
1044         if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
1045                 result / arg1 != arg2)
1046                 ereport(ERROR,
1047                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1048                                  errmsg("integer out of range")));
1049         PG_RETURN_INT32(result);
1050 }
1051
1052 Datum
1053 int42div(PG_FUNCTION_ARGS)
1054 {
1055         int32           arg1 = PG_GETARG_INT32(0);
1056         int16           arg2 = PG_GETARG_INT16(1);
1057         int32           result;
1058
1059         if (arg2 == 0)
1060         {
1061                 ereport(ERROR,
1062                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1063                                  errmsg("division by zero")));
1064                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1065                 PG_RETURN_NULL();
1066         }
1067
1068         result = arg1 / arg2;
1069
1070         /*
1071          * Overflow check.      The only possible overflow case is for arg1 = INT_MIN,
1072          * arg2 = -1, where the correct result is -INT_MIN, which can't be
1073          * represented on a two's-complement machine.  Most machines produce
1074          * INT_MIN but it seems some produce zero.
1075          */
1076         if (arg2 == -1 && arg1 < 0 && result <= 0)
1077                 ereport(ERROR,
1078                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1079                                  errmsg("integer out of range")));
1080         PG_RETURN_INT32(result);
1081 }
1082
1083 Datum
1084 int4mod(PG_FUNCTION_ARGS)
1085 {
1086         int32           arg1 = PG_GETARG_INT32(0);
1087         int32           arg2 = PG_GETARG_INT32(1);
1088
1089         if (arg2 == 0)
1090         {
1091                 ereport(ERROR,
1092                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1093                                  errmsg("division by zero")));
1094                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1095                 PG_RETURN_NULL();
1096         }
1097
1098         /* SELECT ((-2147483648)::int4) % (-1); causes a floating point exception */
1099         if (arg1 == INT_MIN && arg2 == -1)
1100                 PG_RETURN_INT32(0);
1101
1102         /* No overflow is possible */
1103
1104         PG_RETURN_INT32(arg1 % arg2);
1105 }
1106
1107 Datum
1108 int2mod(PG_FUNCTION_ARGS)
1109 {
1110         int16           arg1 = PG_GETARG_INT16(0);
1111         int16           arg2 = PG_GETARG_INT16(1);
1112
1113         if (arg2 == 0)
1114         {
1115                 ereport(ERROR,
1116                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1117                                  errmsg("division by zero")));
1118                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1119                 PG_RETURN_NULL();
1120         }
1121
1122         /* No overflow is possible */
1123
1124         PG_RETURN_INT16(arg1 % arg2);
1125 }
1126
1127
1128 /* int[24]abs()
1129  * Absolute value
1130  */
1131 Datum
1132 int4abs(PG_FUNCTION_ARGS)
1133 {
1134         int32           arg1 = PG_GETARG_INT32(0);
1135         int32           result;
1136
1137         result = (arg1 < 0) ? -arg1 : arg1;
1138         /* overflow check (needed for INT_MIN) */
1139         if (result < 0)
1140                 ereport(ERROR,
1141                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1142                                  errmsg("integer out of range")));
1143         PG_RETURN_INT32(result);
1144 }
1145
1146 Datum
1147 int2abs(PG_FUNCTION_ARGS)
1148 {
1149         int16           arg1 = PG_GETARG_INT16(0);
1150         int16           result;
1151
1152         result = (arg1 < 0) ? -arg1 : arg1;
1153         /* overflow check (needed for SHRT_MIN) */
1154         if (result < 0)
1155                 ereport(ERROR,
1156                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1157                                  errmsg("smallint out of range")));
1158         PG_RETURN_INT16(result);
1159 }
1160
1161 Datum
1162 int2larger(PG_FUNCTION_ARGS)
1163 {
1164         int16           arg1 = PG_GETARG_INT16(0);
1165         int16           arg2 = PG_GETARG_INT16(1);
1166
1167         PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
1168 }
1169
1170 Datum
1171 int2smaller(PG_FUNCTION_ARGS)
1172 {
1173         int16           arg1 = PG_GETARG_INT16(0);
1174         int16           arg2 = PG_GETARG_INT16(1);
1175
1176         PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
1177 }
1178
1179 Datum
1180 int4larger(PG_FUNCTION_ARGS)
1181 {
1182         int32           arg1 = PG_GETARG_INT32(0);
1183         int32           arg2 = PG_GETARG_INT32(1);
1184
1185         PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
1186 }
1187
1188 Datum
1189 int4smaller(PG_FUNCTION_ARGS)
1190 {
1191         int32           arg1 = PG_GETARG_INT32(0);
1192         int32           arg2 = PG_GETARG_INT32(1);
1193
1194         PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
1195 }
1196
1197 /*
1198  * Bit-pushing operators
1199  *
1200  *              int[24]and              - returns arg1 & arg2
1201  *              int[24]or               - returns arg1 | arg2
1202  *              int[24]xor              - returns arg1 # arg2
1203  *              int[24]not              - returns ~arg1
1204  *              int[24]shl              - returns arg1 << arg2
1205  *              int[24]shr              - returns arg1 >> arg2
1206  */
1207
1208 Datum
1209 int4and(PG_FUNCTION_ARGS)
1210 {
1211         int32           arg1 = PG_GETARG_INT32(0);
1212         int32           arg2 = PG_GETARG_INT32(1);
1213
1214         PG_RETURN_INT32(arg1 & arg2);
1215 }
1216
1217 Datum
1218 int4or(PG_FUNCTION_ARGS)
1219 {
1220         int32           arg1 = PG_GETARG_INT32(0);
1221         int32           arg2 = PG_GETARG_INT32(1);
1222
1223         PG_RETURN_INT32(arg1 | arg2);
1224 }
1225
1226 Datum
1227 int4xor(PG_FUNCTION_ARGS)
1228 {
1229         int32           arg1 = PG_GETARG_INT32(0);
1230         int32           arg2 = PG_GETARG_INT32(1);
1231
1232         PG_RETURN_INT32(arg1 ^ arg2);
1233 }
1234
1235 Datum
1236 int4shl(PG_FUNCTION_ARGS)
1237 {
1238         int32           arg1 = PG_GETARG_INT32(0);
1239         int32           arg2 = PG_GETARG_INT32(1);
1240
1241         PG_RETURN_INT32(arg1 << arg2);
1242 }
1243
1244 Datum
1245 int4shr(PG_FUNCTION_ARGS)
1246 {
1247         int32           arg1 = PG_GETARG_INT32(0);
1248         int32           arg2 = PG_GETARG_INT32(1);
1249
1250         PG_RETURN_INT32(arg1 >> arg2);
1251 }
1252
1253 Datum
1254 int4not(PG_FUNCTION_ARGS)
1255 {
1256         int32           arg1 = PG_GETARG_INT32(0);
1257
1258         PG_RETURN_INT32(~arg1);
1259 }
1260
1261 Datum
1262 int2and(PG_FUNCTION_ARGS)
1263 {
1264         int16           arg1 = PG_GETARG_INT16(0);
1265         int16           arg2 = PG_GETARG_INT16(1);
1266
1267         PG_RETURN_INT16(arg1 & arg2);
1268 }
1269
1270 Datum
1271 int2or(PG_FUNCTION_ARGS)
1272 {
1273         int16           arg1 = PG_GETARG_INT16(0);
1274         int16           arg2 = PG_GETARG_INT16(1);
1275
1276         PG_RETURN_INT16(arg1 | arg2);
1277 }
1278
1279 Datum
1280 int2xor(PG_FUNCTION_ARGS)
1281 {
1282         int16           arg1 = PG_GETARG_INT16(0);
1283         int16           arg2 = PG_GETARG_INT16(1);
1284
1285         PG_RETURN_INT16(arg1 ^ arg2);
1286 }
1287
1288 Datum
1289 int2not(PG_FUNCTION_ARGS)
1290 {
1291         int16           arg1 = PG_GETARG_INT16(0);
1292
1293         PG_RETURN_INT16(~arg1);
1294 }
1295
1296
1297 Datum
1298 int2shl(PG_FUNCTION_ARGS)
1299 {
1300         int16           arg1 = PG_GETARG_INT16(0);
1301         int32           arg2 = PG_GETARG_INT32(1);
1302
1303         PG_RETURN_INT16(arg1 << arg2);
1304 }
1305
1306 Datum
1307 int2shr(PG_FUNCTION_ARGS)
1308 {
1309         int16           arg1 = PG_GETARG_INT16(0);
1310         int32           arg2 = PG_GETARG_INT32(1);
1311
1312         PG_RETURN_INT16(arg1 >> arg2);
1313 }
1314
1315 /*
1316  * non-persistent numeric series generator
1317  */
1318 Datum
1319 generate_series_int4(PG_FUNCTION_ARGS)
1320 {
1321         return generate_series_step_int4(fcinfo);
1322 }
1323
1324 Datum
1325 generate_series_step_int4(PG_FUNCTION_ARGS)
1326 {
1327         FuncCallContext *funcctx;
1328         generate_series_fctx *fctx;
1329         int32           result;
1330         MemoryContext oldcontext;
1331
1332         /* stuff done only on the first call of the function */
1333         if (SRF_IS_FIRSTCALL())
1334         {
1335                 int32           start = PG_GETARG_INT32(0);
1336                 int32           finish = PG_GETARG_INT32(1);
1337                 int32           step = 1;
1338
1339                 /* see if we were given an explicit step size */
1340                 if (PG_NARGS() == 3)
1341                         step = PG_GETARG_INT32(2);
1342                 if (step == 0)
1343                         ereport(ERROR,
1344                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1345                                          errmsg("step size cannot equal zero")));
1346
1347                 /* create a function context for cross-call persistence */
1348                 funcctx = SRF_FIRSTCALL_INIT();
1349
1350                 /*
1351                  * switch to memory context appropriate for multiple function calls
1352                  */
1353                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1354
1355                 /* allocate memory for user context */
1356                 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1357
1358                 /*
1359                  * Use fctx to keep state from call to call. Seed current with the
1360                  * original start value
1361                  */
1362                 fctx->current = start;
1363                 fctx->finish = finish;
1364                 fctx->step = step;
1365
1366                 funcctx->user_fctx = fctx;
1367                 MemoryContextSwitchTo(oldcontext);
1368         }
1369
1370         /* stuff done on every call of the function */
1371         funcctx = SRF_PERCALL_SETUP();
1372
1373         /*
1374          * get the saved state and use current as the result for this iteration
1375          */
1376         fctx = funcctx->user_fctx;
1377         result = fctx->current;
1378
1379         if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1380                 (fctx->step < 0 && fctx->current >= fctx->finish))
1381         {
1382                 /* increment current in preparation for next iteration */
1383                 fctx->current += fctx->step;
1384
1385                 /* do when there is more left to send */
1386                 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
1387         }
1388         else
1389                 /* do when there is no more left */
1390                 SRF_RETURN_DONE(funcctx);
1391 }