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