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