]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/int8.c
Silence compiler warnings about possibly unset variables.
[postgresql] / src / backend / utils / adt / int8.c
1 /*-------------------------------------------------------------------------
2  *
3  * int8.c
4  *        Internal 64-bit integer operations
5  *
6  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        src/backend/utils/adt/int8.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
16 #include <ctype.h>
17 #include <limits.h>
18 #include <math.h>
19
20 #include "funcapi.h"
21 #include "libpq/pqformat.h"
22 #include "utils/int8.h"
23 #include "utils/builtins.h"
24
25
26 #define MAXINT8LEN              25
27
28 #define SAMESIGN(a,b)   (((a) < 0) == ((b) < 0))
29
30 typedef struct
31 {
32         int64           current;
33         int64           finish;
34         int64           step;
35 } generate_series_fctx;
36
37
38 /***********************************************************************
39  **
40  **             Routines for 64-bit integers.
41  **
42  ***********************************************************************/
43
44 /*----------------------------------------------------------
45  * Formatting and conversion routines.
46  *---------------------------------------------------------*/
47
48 /*
49  * scanint8 --- try to parse a string into an int8.
50  *
51  * If errorOK is false, ereport a useful error message if the string is bad.
52  * If errorOK is true, just return "false" for bad input.
53  */
54 bool
55 scanint8(const char *str, bool errorOK, int64 *result)
56 {
57         const char *ptr = str;
58         int64           tmp = 0;
59         int                     sign = 1;
60
61         /*
62          * Do our own scan, rather than relying on sscanf which might be broken
63          * for long long.
64          */
65
66         /* skip leading spaces */
67         while (*ptr && isspace((unsigned char) *ptr))
68                 ptr++;
69
70         /* handle sign */
71         if (*ptr == '-')
72         {
73                 ptr++;
74
75                 /*
76                  * Do an explicit check for INT64_MIN.  Ugly though this is, it's
77                  * cleaner than trying to get the loop below to handle it portably.
78                  */
79                 if (strncmp(ptr, "9223372036854775808", 19) == 0)
80                 {
81                         tmp = -INT64CONST(0x7fffffffffffffff) - 1;
82                         ptr += 19;
83                         goto gotdigits;
84                 }
85                 sign = -1;
86         }
87         else if (*ptr == '+')
88                 ptr++;
89
90         /* require at least one digit */
91         if (!isdigit((unsigned char) *ptr))
92         {
93                 if (errorOK)
94                         return false;
95                 else
96                         ereport(ERROR,
97                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
98                                          errmsg("invalid input syntax for integer: \"%s\"",
99                                                         str)));
100         }
101
102         /* process digits */
103         while (*ptr && isdigit((unsigned char) *ptr))
104         {
105                 int64           newtmp = tmp * 10 + (*ptr++ - '0');
106
107                 if ((newtmp / 10) != tmp)               /* overflow? */
108                 {
109                         if (errorOK)
110                                 return false;
111                         else
112                                 ereport(ERROR,
113                                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
114                                            errmsg("value \"%s\" is out of range for type bigint",
115                                                           str)));
116                 }
117                 tmp = newtmp;
118         }
119
120 gotdigits:
121
122         /* allow trailing whitespace, but not other trailing chars */
123         while (*ptr != '\0' && isspace((unsigned char) *ptr))
124                 ptr++;
125
126         if (*ptr != '\0')
127         {
128                 if (errorOK)
129                         return false;
130                 else
131                         ereport(ERROR,
132                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
133                                          errmsg("invalid input syntax for integer: \"%s\"",
134                                                         str)));
135         }
136
137         *result = (sign < 0) ? -tmp : tmp;
138
139         return true;
140 }
141
142 /* int8in()
143  */
144 Datum
145 int8in(PG_FUNCTION_ARGS)
146 {
147         char       *str = PG_GETARG_CSTRING(0);
148         int64           result;
149
150         (void) scanint8(str, false, &result);
151         PG_RETURN_INT64(result);
152 }
153
154
155 /* int8out()
156  */
157 Datum
158 int8out(PG_FUNCTION_ARGS)
159 {
160         int64           val = PG_GETARG_INT64(0);
161         char            buf[MAXINT8LEN + 1];
162         char       *result;
163
164         pg_lltoa(val, buf);
165         result = pstrdup(buf);
166         PG_RETURN_CSTRING(result);
167 }
168
169 /*
170  *              int8recv                        - converts external binary format to int8
171  */
172 Datum
173 int8recv(PG_FUNCTION_ARGS)
174 {
175         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
176
177         PG_RETURN_INT64(pq_getmsgint64(buf));
178 }
179
180 /*
181  *              int8send                        - converts int8 to binary format
182  */
183 Datum
184 int8send(PG_FUNCTION_ARGS)
185 {
186         int64           arg1 = PG_GETARG_INT64(0);
187         StringInfoData buf;
188
189         pq_begintypsend(&buf);
190         pq_sendint64(&buf, arg1);
191         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
192 }
193
194
195 /*----------------------------------------------------------
196  *      Relational operators for int8s, including cross-data-type comparisons.
197  *---------------------------------------------------------*/
198
199 /* int8relop()
200  * Is val1 relop val2?
201  */
202 Datum
203 int8eq(PG_FUNCTION_ARGS)
204 {
205         int64           val1 = PG_GETARG_INT64(0);
206         int64           val2 = PG_GETARG_INT64(1);
207
208         PG_RETURN_BOOL(val1 == val2);
209 }
210
211 Datum
212 int8ne(PG_FUNCTION_ARGS)
213 {
214         int64           val1 = PG_GETARG_INT64(0);
215         int64           val2 = PG_GETARG_INT64(1);
216
217         PG_RETURN_BOOL(val1 != val2);
218 }
219
220 Datum
221 int8lt(PG_FUNCTION_ARGS)
222 {
223         int64           val1 = PG_GETARG_INT64(0);
224         int64           val2 = PG_GETARG_INT64(1);
225
226         PG_RETURN_BOOL(val1 < val2);
227 }
228
229 Datum
230 int8gt(PG_FUNCTION_ARGS)
231 {
232         int64           val1 = PG_GETARG_INT64(0);
233         int64           val2 = PG_GETARG_INT64(1);
234
235         PG_RETURN_BOOL(val1 > val2);
236 }
237
238 Datum
239 int8le(PG_FUNCTION_ARGS)
240 {
241         int64           val1 = PG_GETARG_INT64(0);
242         int64           val2 = PG_GETARG_INT64(1);
243
244         PG_RETURN_BOOL(val1 <= val2);
245 }
246
247 Datum
248 int8ge(PG_FUNCTION_ARGS)
249 {
250         int64           val1 = PG_GETARG_INT64(0);
251         int64           val2 = PG_GETARG_INT64(1);
252
253         PG_RETURN_BOOL(val1 >= val2);
254 }
255
256 /* int84relop()
257  * Is 64-bit val1 relop 32-bit val2?
258  */
259 Datum
260 int84eq(PG_FUNCTION_ARGS)
261 {
262         int64           val1 = PG_GETARG_INT64(0);
263         int32           val2 = PG_GETARG_INT32(1);
264
265         PG_RETURN_BOOL(val1 == val2);
266 }
267
268 Datum
269 int84ne(PG_FUNCTION_ARGS)
270 {
271         int64           val1 = PG_GETARG_INT64(0);
272         int32           val2 = PG_GETARG_INT32(1);
273
274         PG_RETURN_BOOL(val1 != val2);
275 }
276
277 Datum
278 int84lt(PG_FUNCTION_ARGS)
279 {
280         int64           val1 = PG_GETARG_INT64(0);
281         int32           val2 = PG_GETARG_INT32(1);
282
283         PG_RETURN_BOOL(val1 < val2);
284 }
285
286 Datum
287 int84gt(PG_FUNCTION_ARGS)
288 {
289         int64           val1 = PG_GETARG_INT64(0);
290         int32           val2 = PG_GETARG_INT32(1);
291
292         PG_RETURN_BOOL(val1 > val2);
293 }
294
295 Datum
296 int84le(PG_FUNCTION_ARGS)
297 {
298         int64           val1 = PG_GETARG_INT64(0);
299         int32           val2 = PG_GETARG_INT32(1);
300
301         PG_RETURN_BOOL(val1 <= val2);
302 }
303
304 Datum
305 int84ge(PG_FUNCTION_ARGS)
306 {
307         int64           val1 = PG_GETARG_INT64(0);
308         int32           val2 = PG_GETARG_INT32(1);
309
310         PG_RETURN_BOOL(val1 >= val2);
311 }
312
313 /* int48relop()
314  * Is 32-bit val1 relop 64-bit val2?
315  */
316 Datum
317 int48eq(PG_FUNCTION_ARGS)
318 {
319         int32           val1 = PG_GETARG_INT32(0);
320         int64           val2 = PG_GETARG_INT64(1);
321
322         PG_RETURN_BOOL(val1 == val2);
323 }
324
325 Datum
326 int48ne(PG_FUNCTION_ARGS)
327 {
328         int32           val1 = PG_GETARG_INT32(0);
329         int64           val2 = PG_GETARG_INT64(1);
330
331         PG_RETURN_BOOL(val1 != val2);
332 }
333
334 Datum
335 int48lt(PG_FUNCTION_ARGS)
336 {
337         int32           val1 = PG_GETARG_INT32(0);
338         int64           val2 = PG_GETARG_INT64(1);
339
340         PG_RETURN_BOOL(val1 < val2);
341 }
342
343 Datum
344 int48gt(PG_FUNCTION_ARGS)
345 {
346         int32           val1 = PG_GETARG_INT32(0);
347         int64           val2 = PG_GETARG_INT64(1);
348
349         PG_RETURN_BOOL(val1 > val2);
350 }
351
352 Datum
353 int48le(PG_FUNCTION_ARGS)
354 {
355         int32           val1 = PG_GETARG_INT32(0);
356         int64           val2 = PG_GETARG_INT64(1);
357
358         PG_RETURN_BOOL(val1 <= val2);
359 }
360
361 Datum
362 int48ge(PG_FUNCTION_ARGS)
363 {
364         int32           val1 = PG_GETARG_INT32(0);
365         int64           val2 = PG_GETARG_INT64(1);
366
367         PG_RETURN_BOOL(val1 >= val2);
368 }
369
370 /* int82relop()
371  * Is 64-bit val1 relop 16-bit val2?
372  */
373 Datum
374 int82eq(PG_FUNCTION_ARGS)
375 {
376         int64           val1 = PG_GETARG_INT64(0);
377         int16           val2 = PG_GETARG_INT16(1);
378
379         PG_RETURN_BOOL(val1 == val2);
380 }
381
382 Datum
383 int82ne(PG_FUNCTION_ARGS)
384 {
385         int64           val1 = PG_GETARG_INT64(0);
386         int16           val2 = PG_GETARG_INT16(1);
387
388         PG_RETURN_BOOL(val1 != val2);
389 }
390
391 Datum
392 int82lt(PG_FUNCTION_ARGS)
393 {
394         int64           val1 = PG_GETARG_INT64(0);
395         int16           val2 = PG_GETARG_INT16(1);
396
397         PG_RETURN_BOOL(val1 < val2);
398 }
399
400 Datum
401 int82gt(PG_FUNCTION_ARGS)
402 {
403         int64           val1 = PG_GETARG_INT64(0);
404         int16           val2 = PG_GETARG_INT16(1);
405
406         PG_RETURN_BOOL(val1 > val2);
407 }
408
409 Datum
410 int82le(PG_FUNCTION_ARGS)
411 {
412         int64           val1 = PG_GETARG_INT64(0);
413         int16           val2 = PG_GETARG_INT16(1);
414
415         PG_RETURN_BOOL(val1 <= val2);
416 }
417
418 Datum
419 int82ge(PG_FUNCTION_ARGS)
420 {
421         int64           val1 = PG_GETARG_INT64(0);
422         int16           val2 = PG_GETARG_INT16(1);
423
424         PG_RETURN_BOOL(val1 >= val2);
425 }
426
427 /* int28relop()
428  * Is 16-bit val1 relop 64-bit val2?
429  */
430 Datum
431 int28eq(PG_FUNCTION_ARGS)
432 {
433         int16           val1 = PG_GETARG_INT16(0);
434         int64           val2 = PG_GETARG_INT64(1);
435
436         PG_RETURN_BOOL(val1 == val2);
437 }
438
439 Datum
440 int28ne(PG_FUNCTION_ARGS)
441 {
442         int16           val1 = PG_GETARG_INT16(0);
443         int64           val2 = PG_GETARG_INT64(1);
444
445         PG_RETURN_BOOL(val1 != val2);
446 }
447
448 Datum
449 int28lt(PG_FUNCTION_ARGS)
450 {
451         int16           val1 = PG_GETARG_INT16(0);
452         int64           val2 = PG_GETARG_INT64(1);
453
454         PG_RETURN_BOOL(val1 < val2);
455 }
456
457 Datum
458 int28gt(PG_FUNCTION_ARGS)
459 {
460         int16           val1 = PG_GETARG_INT16(0);
461         int64           val2 = PG_GETARG_INT64(1);
462
463         PG_RETURN_BOOL(val1 > val2);
464 }
465
466 Datum
467 int28le(PG_FUNCTION_ARGS)
468 {
469         int16           val1 = PG_GETARG_INT16(0);
470         int64           val2 = PG_GETARG_INT64(1);
471
472         PG_RETURN_BOOL(val1 <= val2);
473 }
474
475 Datum
476 int28ge(PG_FUNCTION_ARGS)
477 {
478         int16           val1 = PG_GETARG_INT16(0);
479         int64           val2 = PG_GETARG_INT64(1);
480
481         PG_RETURN_BOOL(val1 >= val2);
482 }
483
484
485 /*----------------------------------------------------------
486  *      Arithmetic operators on 64-bit integers.
487  *---------------------------------------------------------*/
488
489 Datum
490 int8um(PG_FUNCTION_ARGS)
491 {
492         int64           arg = PG_GETARG_INT64(0);
493         int64           result;
494
495         result = -arg;
496         /* overflow check (needed for INT64_MIN) */
497         if (arg != 0 && SAMESIGN(result, arg))
498                 ereport(ERROR,
499                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
500                                  errmsg("bigint out of range")));
501         PG_RETURN_INT64(result);
502 }
503
504 Datum
505 int8up(PG_FUNCTION_ARGS)
506 {
507         int64           arg = PG_GETARG_INT64(0);
508
509         PG_RETURN_INT64(arg);
510 }
511
512 Datum
513 int8pl(PG_FUNCTION_ARGS)
514 {
515         int64           arg1 = PG_GETARG_INT64(0);
516         int64           arg2 = PG_GETARG_INT64(1);
517         int64           result;
518
519         result = arg1 + arg2;
520
521         /*
522          * Overflow check.      If the inputs are of different signs then their sum
523          * cannot overflow.  If the inputs are of the same sign, their sum had
524          * better be that sign too.
525          */
526         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
527                 ereport(ERROR,
528                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
529                                  errmsg("bigint out of range")));
530         PG_RETURN_INT64(result);
531 }
532
533 Datum
534 int8mi(PG_FUNCTION_ARGS)
535 {
536         int64           arg1 = PG_GETARG_INT64(0);
537         int64           arg2 = PG_GETARG_INT64(1);
538         int64           result;
539
540         result = arg1 - arg2;
541
542         /*
543          * Overflow check.      If the inputs are of the same sign then their
544          * difference cannot overflow.  If they are of different signs then the
545          * result should be of the same sign as the first input.
546          */
547         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
548                 ereport(ERROR,
549                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
550                                  errmsg("bigint out of range")));
551         PG_RETURN_INT64(result);
552 }
553
554 Datum
555 int8mul(PG_FUNCTION_ARGS)
556 {
557         int64           arg1 = PG_GETARG_INT64(0);
558         int64           arg2 = PG_GETARG_INT64(1);
559         int64           result;
560
561         result = arg1 * arg2;
562
563         /*
564          * Overflow check.      We basically check to see if result / arg2 gives arg1
565          * again.  There are two cases where this fails: arg2 = 0 (which cannot
566          * overflow) and arg1 = INT64_MIN, arg2 = -1 (where the division itself
567          * will overflow and thus incorrectly match).
568          *
569          * Since the division is likely much more expensive than the actual
570          * multiplication, we'd like to skip it where possible.  The best bang for
571          * the buck seems to be to check whether both inputs are in the int32
572          * range; if so, no overflow is possible.
573          */
574         if (arg1 != (int64) ((int32) arg1) || arg2 != (int64) ((int32) arg2))
575         {
576                 if (arg2 != 0 &&
577                         ((arg2 == -1 && arg1 < 0 && result < 0) ||
578                          result / arg2 != arg1))
579                         ereport(ERROR,
580                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
581                                          errmsg("bigint out of range")));
582         }
583         PG_RETURN_INT64(result);
584 }
585
586 Datum
587 int8div(PG_FUNCTION_ARGS)
588 {
589         int64           arg1 = PG_GETARG_INT64(0);
590         int64           arg2 = PG_GETARG_INT64(1);
591         int64           result;
592
593         if (arg2 == 0)
594         {
595                 ereport(ERROR,
596                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
597                                  errmsg("division by zero")));
598                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
599                 PG_RETURN_NULL();
600         }
601
602         /*
603          * INT64_MIN / -1 is problematic, since the result can't be represented on
604          * a two's-complement machine.  Some machines produce INT64_MIN, some
605          * produce zero, some throw an exception.  We can dodge the problem by
606          * recognizing that division by -1 is the same as negation.
607          */
608         if (arg2 == -1)
609         {
610                 result = -arg1;
611                 /* overflow check (needed for INT64_MIN) */
612                 if (arg1 != 0 && SAMESIGN(result, arg1))
613                         ereport(ERROR,
614                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
615                                          errmsg("bigint out of range")));
616                 PG_RETURN_INT64(result);
617         }
618
619         /* No overflow is possible */
620
621         result = arg1 / arg2;
622
623         PG_RETURN_INT64(result);
624 }
625
626 /* int8abs()
627  * Absolute value
628  */
629 Datum
630 int8abs(PG_FUNCTION_ARGS)
631 {
632         int64           arg1 = PG_GETARG_INT64(0);
633         int64           result;
634
635         result = (arg1 < 0) ? -arg1 : arg1;
636         /* overflow check (needed for INT64_MIN) */
637         if (result < 0)
638                 ereport(ERROR,
639                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
640                                  errmsg("bigint out of range")));
641         PG_RETURN_INT64(result);
642 }
643
644 /* int8mod()
645  * Modulo operation.
646  */
647 Datum
648 int8mod(PG_FUNCTION_ARGS)
649 {
650         int64           arg1 = PG_GETARG_INT64(0);
651         int64           arg2 = PG_GETARG_INT64(1);
652
653         if (arg2 == 0)
654         {
655                 ereport(ERROR,
656                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
657                                  errmsg("division by zero")));
658                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
659                 PG_RETURN_NULL();
660         }
661
662         /*
663          * Some machines throw a floating-point exception for INT64_MIN % -1,
664          * which is a bit silly since the correct answer is perfectly
665          * well-defined, namely zero.
666          */
667         if (arg2 == -1)
668                 PG_RETURN_INT64(0);
669
670         /* No overflow is possible */
671
672         PG_RETURN_INT64(arg1 % arg2);
673 }
674
675
676 Datum
677 int8inc(PG_FUNCTION_ARGS)
678 {
679         /*
680          * When int8 is pass-by-reference, we provide this special case to avoid
681          * palloc overhead for COUNT(): when called as an aggregate, we know that
682          * the argument is modifiable local storage, so just update it in-place.
683          * (If int8 is pass-by-value, then of course this is useless as well as
684          * incorrect, so just ifdef it out.)
685          */
686 #ifndef USE_FLOAT8_BYVAL                /* controls int8 too */
687         if (AggCheckCallContext(fcinfo, NULL))
688         {
689                 int64      *arg = (int64 *) PG_GETARG_POINTER(0);
690                 int64           result;
691
692                 result = *arg + 1;
693                 /* Overflow check */
694                 if (result < 0 && *arg > 0)
695                         ereport(ERROR,
696                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
697                                          errmsg("bigint out of range")));
698
699                 *arg = result;
700                 PG_RETURN_POINTER(arg);
701         }
702         else
703 #endif
704         {
705                 /* Not called as an aggregate, so just do it the dumb way */
706                 int64           arg = PG_GETARG_INT64(0);
707                 int64           result;
708
709                 result = arg + 1;
710                 /* Overflow check */
711                 if (result < 0 && arg > 0)
712                         ereport(ERROR,
713                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
714                                          errmsg("bigint out of range")));
715
716                 PG_RETURN_INT64(result);
717         }
718 }
719
720 /*
721  * These functions are exactly like int8inc but are used for aggregates that
722  * count only non-null values.  Since the functions are declared strict,
723  * the null checks happen before we ever get here, and all we need do is
724  * increment the state value.  We could actually make these pg_proc entries
725  * point right at int8inc, but then the opr_sanity regression test would
726  * complain about mismatched entries for a built-in function.
727  */
728
729 Datum
730 int8inc_any(PG_FUNCTION_ARGS)
731 {
732         return int8inc(fcinfo);
733 }
734
735 Datum
736 int8inc_float8_float8(PG_FUNCTION_ARGS)
737 {
738         return int8inc(fcinfo);
739 }
740
741
742 Datum
743 int8larger(PG_FUNCTION_ARGS)
744 {
745         int64           arg1 = PG_GETARG_INT64(0);
746         int64           arg2 = PG_GETARG_INT64(1);
747         int64           result;
748
749         result = ((arg1 > arg2) ? arg1 : arg2);
750
751         PG_RETURN_INT64(result);
752 }
753
754 Datum
755 int8smaller(PG_FUNCTION_ARGS)
756 {
757         int64           arg1 = PG_GETARG_INT64(0);
758         int64           arg2 = PG_GETARG_INT64(1);
759         int64           result;
760
761         result = ((arg1 < arg2) ? arg1 : arg2);
762
763         PG_RETURN_INT64(result);
764 }
765
766 Datum
767 int84pl(PG_FUNCTION_ARGS)
768 {
769         int64           arg1 = PG_GETARG_INT64(0);
770         int32           arg2 = PG_GETARG_INT32(1);
771         int64           result;
772
773         result = arg1 + arg2;
774
775         /*
776          * Overflow check.      If the inputs are of different signs then their sum
777          * cannot overflow.  If the inputs are of the same sign, their sum had
778          * better be that sign too.
779          */
780         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
781                 ereport(ERROR,
782                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
783                                  errmsg("bigint out of range")));
784         PG_RETURN_INT64(result);
785 }
786
787 Datum
788 int84mi(PG_FUNCTION_ARGS)
789 {
790         int64           arg1 = PG_GETARG_INT64(0);
791         int32           arg2 = PG_GETARG_INT32(1);
792         int64           result;
793
794         result = arg1 - arg2;
795
796         /*
797          * Overflow check.      If the inputs are of the same sign then their
798          * difference cannot overflow.  If they are of different signs then the
799          * result should be of the same sign as the first input.
800          */
801         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
802                 ereport(ERROR,
803                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
804                                  errmsg("bigint out of range")));
805         PG_RETURN_INT64(result);
806 }
807
808 Datum
809 int84mul(PG_FUNCTION_ARGS)
810 {
811         int64           arg1 = PG_GETARG_INT64(0);
812         int32           arg2 = PG_GETARG_INT32(1);
813         int64           result;
814
815         result = arg1 * arg2;
816
817         /*
818          * Overflow check.      We basically check to see if result / arg1 gives arg2
819          * again.  There is one case where this fails: arg1 = 0 (which cannot
820          * overflow).
821          *
822          * Since the division is likely much more expensive than the actual
823          * multiplication, we'd like to skip it where possible.  The best bang for
824          * the buck seems to be to check whether both inputs are in the int32
825          * range; if so, no overflow is possible.
826          */
827         if (arg1 != (int64) ((int32) arg1) &&
828                 result / arg1 != arg2)
829                 ereport(ERROR,
830                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
831                                  errmsg("bigint out of range")));
832         PG_RETURN_INT64(result);
833 }
834
835 Datum
836 int84div(PG_FUNCTION_ARGS)
837 {
838         int64           arg1 = PG_GETARG_INT64(0);
839         int32           arg2 = PG_GETARG_INT32(1);
840         int64           result;
841
842         if (arg2 == 0)
843         {
844                 ereport(ERROR,
845                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
846                                  errmsg("division by zero")));
847                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
848                 PG_RETURN_NULL();
849         }
850
851         /*
852          * INT64_MIN / -1 is problematic, since the result can't be represented on
853          * a two's-complement machine.  Some machines produce INT64_MIN, some
854          * produce zero, some throw an exception.  We can dodge the problem by
855          * recognizing that division by -1 is the same as negation.
856          */
857         if (arg2 == -1)
858         {
859                 result = -arg1;
860                 /* overflow check (needed for INT64_MIN) */
861                 if (arg1 != 0 && SAMESIGN(result, arg1))
862                         ereport(ERROR,
863                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
864                                          errmsg("bigint out of range")));
865                 PG_RETURN_INT64(result);
866         }
867
868         /* No overflow is possible */
869
870         result = arg1 / arg2;
871
872         PG_RETURN_INT64(result);
873 }
874
875 Datum
876 int48pl(PG_FUNCTION_ARGS)
877 {
878         int32           arg1 = PG_GETARG_INT32(0);
879         int64           arg2 = PG_GETARG_INT64(1);
880         int64           result;
881
882         result = arg1 + arg2;
883
884         /*
885          * Overflow check.      If the inputs are of different signs then their sum
886          * cannot overflow.  If the inputs are of the same sign, their sum had
887          * better be that sign too.
888          */
889         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
890                 ereport(ERROR,
891                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
892                                  errmsg("bigint out of range")));
893         PG_RETURN_INT64(result);
894 }
895
896 Datum
897 int48mi(PG_FUNCTION_ARGS)
898 {
899         int32           arg1 = PG_GETARG_INT32(0);
900         int64           arg2 = PG_GETARG_INT64(1);
901         int64           result;
902
903         result = arg1 - arg2;
904
905         /*
906          * Overflow check.      If the inputs are of the same sign then their
907          * difference cannot overflow.  If they are of different signs then the
908          * result should be of the same sign as the first input.
909          */
910         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
911                 ereport(ERROR,
912                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
913                                  errmsg("bigint out of range")));
914         PG_RETURN_INT64(result);
915 }
916
917 Datum
918 int48mul(PG_FUNCTION_ARGS)
919 {
920         int32           arg1 = PG_GETARG_INT32(0);
921         int64           arg2 = PG_GETARG_INT64(1);
922         int64           result;
923
924         result = arg1 * arg2;
925
926         /*
927          * Overflow check.      We basically check to see if result / arg2 gives arg1
928          * again.  There is one case where this fails: arg2 = 0 (which cannot
929          * overflow).
930          *
931          * Since the division is likely much more expensive than the actual
932          * multiplication, we'd like to skip it where possible.  The best bang for
933          * the buck seems to be to check whether both inputs are in the int32
934          * range; if so, no overflow is possible.
935          */
936         if (arg2 != (int64) ((int32) arg2) &&
937                 result / arg2 != arg1)
938                 ereport(ERROR,
939                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
940                                  errmsg("bigint out of range")));
941         PG_RETURN_INT64(result);
942 }
943
944 Datum
945 int48div(PG_FUNCTION_ARGS)
946 {
947         int32           arg1 = PG_GETARG_INT32(0);
948         int64           arg2 = PG_GETARG_INT64(1);
949
950         if (arg2 == 0)
951         {
952                 ereport(ERROR,
953                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
954                                  errmsg("division by zero")));
955                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
956                 PG_RETURN_NULL();
957         }
958
959         /* No overflow is possible */
960         PG_RETURN_INT64((int64) arg1 / arg2);
961 }
962
963 Datum
964 int82pl(PG_FUNCTION_ARGS)
965 {
966         int64           arg1 = PG_GETARG_INT64(0);
967         int16           arg2 = PG_GETARG_INT16(1);
968         int64           result;
969
970         result = arg1 + arg2;
971
972         /*
973          * Overflow check.      If the inputs are of different signs then their sum
974          * cannot overflow.  If the inputs are of the same sign, their sum had
975          * better be that sign too.
976          */
977         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
978                 ereport(ERROR,
979                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
980                                  errmsg("bigint out of range")));
981         PG_RETURN_INT64(result);
982 }
983
984 Datum
985 int82mi(PG_FUNCTION_ARGS)
986 {
987         int64           arg1 = PG_GETARG_INT64(0);
988         int16           arg2 = PG_GETARG_INT16(1);
989         int64           result;
990
991         result = arg1 - arg2;
992
993         /*
994          * Overflow check.      If the inputs are of the same sign then their
995          * difference cannot overflow.  If they are of different signs then the
996          * result should be of the same sign as the first input.
997          */
998         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
999                 ereport(ERROR,
1000                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1001                                  errmsg("bigint out of range")));
1002         PG_RETURN_INT64(result);
1003 }
1004
1005 Datum
1006 int82mul(PG_FUNCTION_ARGS)
1007 {
1008         int64           arg1 = PG_GETARG_INT64(0);
1009         int16           arg2 = PG_GETARG_INT16(1);
1010         int64           result;
1011
1012         result = arg1 * arg2;
1013
1014         /*
1015          * Overflow check.      We basically check to see if result / arg1 gives arg2
1016          * again.  There is one case where this fails: arg1 = 0 (which cannot
1017          * overflow).
1018          *
1019          * Since the division is likely much more expensive than the actual
1020          * multiplication, we'd like to skip it where possible.  The best bang for
1021          * the buck seems to be to check whether both inputs are in the int32
1022          * range; if so, no overflow is possible.
1023          */
1024         if (arg1 != (int64) ((int32) arg1) &&
1025                 result / arg1 != arg2)
1026                 ereport(ERROR,
1027                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1028                                  errmsg("bigint out of range")));
1029         PG_RETURN_INT64(result);
1030 }
1031
1032 Datum
1033 int82div(PG_FUNCTION_ARGS)
1034 {
1035         int64           arg1 = PG_GETARG_INT64(0);
1036         int16           arg2 = PG_GETARG_INT16(1);
1037         int64           result;
1038
1039         if (arg2 == 0)
1040         {
1041                 ereport(ERROR,
1042                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1043                                  errmsg("division by zero")));
1044                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1045                 PG_RETURN_NULL();
1046         }
1047
1048         /*
1049          * INT64_MIN / -1 is problematic, since the result can't be represented on
1050          * a two's-complement machine.  Some machines produce INT64_MIN, some
1051          * produce zero, some throw an exception.  We can dodge the problem by
1052          * recognizing that division by -1 is the same as negation.
1053          */
1054         if (arg2 == -1)
1055         {
1056                 result = -arg1;
1057                 /* overflow check (needed for INT64_MIN) */
1058                 if (arg1 != 0 && SAMESIGN(result, arg1))
1059                         ereport(ERROR,
1060                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1061                                          errmsg("bigint out of range")));
1062                 PG_RETURN_INT64(result);
1063         }
1064
1065         /* No overflow is possible */
1066
1067         result = arg1 / arg2;
1068
1069         PG_RETURN_INT64(result);
1070 }
1071
1072 Datum
1073 int28pl(PG_FUNCTION_ARGS)
1074 {
1075         int16           arg1 = PG_GETARG_INT16(0);
1076         int64           arg2 = PG_GETARG_INT64(1);
1077         int64           result;
1078
1079         result = arg1 + arg2;
1080
1081         /*
1082          * Overflow check.      If the inputs are of different signs then their sum
1083          * cannot overflow.  If the inputs are of the same sign, their sum had
1084          * better be that sign too.
1085          */
1086         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1087                 ereport(ERROR,
1088                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1089                                  errmsg("bigint out of range")));
1090         PG_RETURN_INT64(result);
1091 }
1092
1093 Datum
1094 int28mi(PG_FUNCTION_ARGS)
1095 {
1096         int16           arg1 = PG_GETARG_INT16(0);
1097         int64           arg2 = PG_GETARG_INT64(1);
1098         int64           result;
1099
1100         result = arg1 - arg2;
1101
1102         /*
1103          * Overflow check.      If the inputs are of the same sign then their
1104          * difference cannot overflow.  If they are of different signs then the
1105          * result should be of the same sign as the first input.
1106          */
1107         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1108                 ereport(ERROR,
1109                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1110                                  errmsg("bigint out of range")));
1111         PG_RETURN_INT64(result);
1112 }
1113
1114 Datum
1115 int28mul(PG_FUNCTION_ARGS)
1116 {
1117         int16           arg1 = PG_GETARG_INT16(0);
1118         int64           arg2 = PG_GETARG_INT64(1);
1119         int64           result;
1120
1121         result = arg1 * arg2;
1122
1123         /*
1124          * Overflow check.      We basically check to see if result / arg2 gives arg1
1125          * again.  There is one case where this fails: arg2 = 0 (which cannot
1126          * overflow).
1127          *
1128          * Since the division is likely much more expensive than the actual
1129          * multiplication, we'd like to skip it where possible.  The best bang for
1130          * the buck seems to be to check whether both inputs are in the int32
1131          * range; if so, no overflow is possible.
1132          */
1133         if (arg2 != (int64) ((int32) arg2) &&
1134                 result / arg2 != arg1)
1135                 ereport(ERROR,
1136                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1137                                  errmsg("bigint out of range")));
1138         PG_RETURN_INT64(result);
1139 }
1140
1141 Datum
1142 int28div(PG_FUNCTION_ARGS)
1143 {
1144         int16           arg1 = PG_GETARG_INT16(0);
1145         int64           arg2 = PG_GETARG_INT64(1);
1146
1147         if (arg2 == 0)
1148         {
1149                 ereport(ERROR,
1150                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
1151                                  errmsg("division by zero")));
1152                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1153                 PG_RETURN_NULL();
1154         }
1155
1156         /* No overflow is possible */
1157         PG_RETURN_INT64((int64) arg1 / arg2);
1158 }
1159
1160 /* Binary arithmetics
1161  *
1162  *              int8and         - returns arg1 & arg2
1163  *              int8or          - returns arg1 | arg2
1164  *              int8xor         - returns arg1 # arg2
1165  *              int8not         - returns ~arg1
1166  *              int8shl         - returns arg1 << arg2
1167  *              int8shr         - returns arg1 >> arg2
1168  */
1169
1170 Datum
1171 int8and(PG_FUNCTION_ARGS)
1172 {
1173         int64           arg1 = PG_GETARG_INT64(0);
1174         int64           arg2 = PG_GETARG_INT64(1);
1175
1176         PG_RETURN_INT64(arg1 & arg2);
1177 }
1178
1179 Datum
1180 int8or(PG_FUNCTION_ARGS)
1181 {
1182         int64           arg1 = PG_GETARG_INT64(0);
1183         int64           arg2 = PG_GETARG_INT64(1);
1184
1185         PG_RETURN_INT64(arg1 | arg2);
1186 }
1187
1188 Datum
1189 int8xor(PG_FUNCTION_ARGS)
1190 {
1191         int64           arg1 = PG_GETARG_INT64(0);
1192         int64           arg2 = PG_GETARG_INT64(1);
1193
1194         PG_RETURN_INT64(arg1 ^ arg2);
1195 }
1196
1197 Datum
1198 int8not(PG_FUNCTION_ARGS)
1199 {
1200         int64           arg1 = PG_GETARG_INT64(0);
1201
1202         PG_RETURN_INT64(~arg1);
1203 }
1204
1205 Datum
1206 int8shl(PG_FUNCTION_ARGS)
1207 {
1208         int64           arg1 = PG_GETARG_INT64(0);
1209         int32           arg2 = PG_GETARG_INT32(1);
1210
1211         PG_RETURN_INT64(arg1 << arg2);
1212 }
1213
1214 Datum
1215 int8shr(PG_FUNCTION_ARGS)
1216 {
1217         int64           arg1 = PG_GETARG_INT64(0);
1218         int32           arg2 = PG_GETARG_INT32(1);
1219
1220         PG_RETURN_INT64(arg1 >> arg2);
1221 }
1222
1223 /*----------------------------------------------------------
1224  *      Conversion operators.
1225  *---------------------------------------------------------*/
1226
1227 Datum
1228 int48(PG_FUNCTION_ARGS)
1229 {
1230         int32           arg = PG_GETARG_INT32(0);
1231
1232         PG_RETURN_INT64((int64) arg);
1233 }
1234
1235 Datum
1236 int84(PG_FUNCTION_ARGS)
1237 {
1238         int64           arg = PG_GETARG_INT64(0);
1239         int32           result;
1240
1241         result = (int32) arg;
1242
1243         /* Test for overflow by reverse-conversion. */
1244         if ((int64) result != arg)
1245                 ereport(ERROR,
1246                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1247                                  errmsg("integer out of range")));
1248
1249         PG_RETURN_INT32(result);
1250 }
1251
1252 Datum
1253 int28(PG_FUNCTION_ARGS)
1254 {
1255         int16           arg = PG_GETARG_INT16(0);
1256
1257         PG_RETURN_INT64((int64) arg);
1258 }
1259
1260 Datum
1261 int82(PG_FUNCTION_ARGS)
1262 {
1263         int64           arg = PG_GETARG_INT64(0);
1264         int16           result;
1265
1266         result = (int16) arg;
1267
1268         /* Test for overflow by reverse-conversion. */
1269         if ((int64) result != arg)
1270                 ereport(ERROR,
1271                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1272                                  errmsg("smallint out of range")));
1273
1274         PG_RETURN_INT16(result);
1275 }
1276
1277 Datum
1278 i8tod(PG_FUNCTION_ARGS)
1279 {
1280         int64           arg = PG_GETARG_INT64(0);
1281         float8          result;
1282
1283         result = arg;
1284
1285         PG_RETURN_FLOAT8(result);
1286 }
1287
1288 /* dtoi8()
1289  * Convert float8 to 8-byte integer.
1290  */
1291 Datum
1292 dtoi8(PG_FUNCTION_ARGS)
1293 {
1294         float8          arg = PG_GETARG_FLOAT8(0);
1295         int64           result;
1296
1297         /* Round arg to nearest integer (but it's still in float form) */
1298         arg = rint(arg);
1299
1300         /*
1301          * Does it fit in an int64?  Avoid assuming that we have handy constants
1302          * defined for the range boundaries, instead test for overflow by
1303          * reverse-conversion.
1304          */
1305         result = (int64) arg;
1306
1307         if ((float8) result != arg)
1308                 ereport(ERROR,
1309                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1310                                  errmsg("bigint out of range")));
1311
1312         PG_RETURN_INT64(result);
1313 }
1314
1315 Datum
1316 i8tof(PG_FUNCTION_ARGS)
1317 {
1318         int64           arg = PG_GETARG_INT64(0);
1319         float4          result;
1320
1321         result = arg;
1322
1323         PG_RETURN_FLOAT4(result);
1324 }
1325
1326 /* ftoi8()
1327  * Convert float4 to 8-byte integer.
1328  */
1329 Datum
1330 ftoi8(PG_FUNCTION_ARGS)
1331 {
1332         float4          arg = PG_GETARG_FLOAT4(0);
1333         int64           result;
1334         float8          darg;
1335
1336         /* Round arg to nearest integer (but it's still in float form) */
1337         darg = rint(arg);
1338
1339         /*
1340          * Does it fit in an int64?  Avoid assuming that we have handy constants
1341          * defined for the range boundaries, instead test for overflow by
1342          * reverse-conversion.
1343          */
1344         result = (int64) darg;
1345
1346         if ((float8) result != darg)
1347                 ereport(ERROR,
1348                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1349                                  errmsg("bigint out of range")));
1350
1351         PG_RETURN_INT64(result);
1352 }
1353
1354 Datum
1355 i8tooid(PG_FUNCTION_ARGS)
1356 {
1357         int64           arg = PG_GETARG_INT64(0);
1358         Oid                     result;
1359
1360         result = (Oid) arg;
1361
1362         /* Test for overflow by reverse-conversion. */
1363         if ((int64) result != arg)
1364                 ereport(ERROR,
1365                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1366                                  errmsg("OID out of range")));
1367
1368         PG_RETURN_OID(result);
1369 }
1370
1371 Datum
1372 oidtoi8(PG_FUNCTION_ARGS)
1373 {
1374         Oid                     arg = PG_GETARG_OID(0);
1375
1376         PG_RETURN_INT64((int64) arg);
1377 }
1378
1379 /*
1380  * non-persistent numeric series generator
1381  */
1382 Datum
1383 generate_series_int8(PG_FUNCTION_ARGS)
1384 {
1385         return generate_series_step_int8(fcinfo);
1386 }
1387
1388 Datum
1389 generate_series_step_int8(PG_FUNCTION_ARGS)
1390 {
1391         FuncCallContext *funcctx;
1392         generate_series_fctx *fctx;
1393         int64           result;
1394         MemoryContext oldcontext;
1395
1396         /* stuff done only on the first call of the function */
1397         if (SRF_IS_FIRSTCALL())
1398         {
1399                 int64           start = PG_GETARG_INT64(0);
1400                 int64           finish = PG_GETARG_INT64(1);
1401                 int64           step = 1;
1402
1403                 /* see if we were given an explicit step size */
1404                 if (PG_NARGS() == 3)
1405                         step = PG_GETARG_INT64(2);
1406                 if (step == 0)
1407                         ereport(ERROR,
1408                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1409                                          errmsg("step size cannot equal zero")));
1410
1411                 /* create a function context for cross-call persistence */
1412                 funcctx = SRF_FIRSTCALL_INIT();
1413
1414                 /*
1415                  * switch to memory context appropriate for multiple function calls
1416                  */
1417                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1418
1419                 /* allocate memory for user context */
1420                 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1421
1422                 /*
1423                  * Use fctx to keep state from call to call. Seed current with the
1424                  * original start value
1425                  */
1426                 fctx->current = start;
1427                 fctx->finish = finish;
1428                 fctx->step = step;
1429
1430                 funcctx->user_fctx = fctx;
1431                 MemoryContextSwitchTo(oldcontext);
1432         }
1433
1434         /* stuff done on every call of the function */
1435         funcctx = SRF_PERCALL_SETUP();
1436
1437         /*
1438          * get the saved state and use current as the result for this iteration
1439          */
1440         fctx = funcctx->user_fctx;
1441         result = fctx->current;
1442
1443         if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1444                 (fctx->step < 0 && fctx->current >= fctx->finish))
1445         {
1446                 /* increment current in preparation for next iteration */
1447                 fctx->current += fctx->step;
1448
1449                 /* if next-value computation overflows, this is the final result */
1450                 if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
1451                         fctx->step = 0;
1452
1453                 /* do when there is more left to send */
1454                 SRF_RETURN_NEXT(funcctx, Int64GetDatum(result));
1455         }
1456         else
1457                 /* do when there is no more left */
1458                 SRF_RETURN_DONE(funcctx);
1459 }