OSDN Git Service

pgindent run for 8.2.
[pg-rex/syncrep.git] / src / backend / utils / adt / int8.c
1 /*-------------------------------------------------------------------------
2  *
3  * int8.c
4  *        Internal 64-bit integer operations
5  *
6  * Portions Copyright (c) 1996-2006, 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.62 2006/10/04 00:29:59 momjian 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.
579          */
580         if (!(arg1 == (int64) ((int32) arg1) &&
581                   arg2 == (int64) ((int32) arg2)) &&
582                 arg2 != 0 &&
583                 (result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
584                 ereport(ERROR,
585                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
586                                  errmsg("bigint out of range")));
587         PG_RETURN_INT64(result);
588 }
589
590 Datum
591 int8div(PG_FUNCTION_ARGS)
592 {
593         int64           arg1 = PG_GETARG_INT64(0);
594         int64           arg2 = PG_GETARG_INT64(1);
595         int64           result;
596
597         if (arg2 == 0)
598                 ereport(ERROR,
599                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
600                                  errmsg("division by zero")));
601
602         result = arg1 / arg2;
603
604         /*
605          * Overflow check.      The only possible overflow case is for arg1 =
606          * INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which
607          * can't be represented on a two's-complement machine.
608          */
609         if (arg2 == -1 && arg1 < 0 && result < 0)
610                 ereport(ERROR,
611                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
612                                  errmsg("bigint out of range")));
613         PG_RETURN_INT64(result);
614 }
615
616 /* int8abs()
617  * Absolute value
618  */
619 Datum
620 int8abs(PG_FUNCTION_ARGS)
621 {
622         int64           arg1 = PG_GETARG_INT64(0);
623         int64           result;
624
625         result = (arg1 < 0) ? -arg1 : arg1;
626         /* overflow check (needed for INT64_MIN) */
627         if (result < 0)
628                 ereport(ERROR,
629                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
630                                  errmsg("bigint out of range")));
631         PG_RETURN_INT64(result);
632 }
633
634 /* int8mod()
635  * Modulo operation.
636  */
637 Datum
638 int8mod(PG_FUNCTION_ARGS)
639 {
640         int64           arg1 = PG_GETARG_INT64(0);
641         int64           arg2 = PG_GETARG_INT64(1);
642
643         if (arg2 == 0)
644                 ereport(ERROR,
645                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
646                                  errmsg("division by zero")));
647         /* No overflow is possible */
648
649         PG_RETURN_INT64(arg1 % arg2);
650 }
651
652
653 Datum
654 int8inc(PG_FUNCTION_ARGS)
655 {
656         if (fcinfo->context && IsA(fcinfo->context, AggState))
657         {
658                 /*
659                  * Special case to avoid palloc overhead for COUNT(): when called from
660                  * nodeAgg, we know that the argument is modifiable local storage, so
661                  * just update it in-place.
662                  *
663                  * Note: this assumes int8 is a pass-by-ref type; if we ever support
664                  * pass-by-val int8, this should be ifdef'd out when int8 is
665                  * pass-by-val.
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         {
682                 /* Not called by nodeAgg, so just do it the dumb way */
683                 int64           arg = PG_GETARG_INT64(0);
684                 int64           result;
685
686                 result = arg + 1;
687                 /* Overflow check */
688                 if (result < 0 && arg > 0)
689                         ereport(ERROR,
690                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
691                                          errmsg("bigint out of range")));
692
693                 PG_RETURN_INT64(result);
694         }
695 }
696
697 /*
698  * These functions are exactly like int8inc but are used for aggregates that
699  * count only non-null values.  Since the functions are declared strict,
700  * the null checks happen before we ever get here, and all we need do is
701  * increment the state value.  We could actually make these pg_proc entries
702  * point right at int8inc, but then the opr_sanity regression test would
703  * complain about mismatched entries for a built-in function.
704  */
705
706 Datum
707 int8inc_any(PG_FUNCTION_ARGS)
708 {
709         return int8inc(fcinfo);
710 }
711
712 Datum
713 int8inc_float8_float8(PG_FUNCTION_ARGS)
714 {
715         return int8inc(fcinfo);
716 }
717
718
719 Datum
720 int8larger(PG_FUNCTION_ARGS)
721 {
722         int64           arg1 = PG_GETARG_INT64(0);
723         int64           arg2 = PG_GETARG_INT64(1);
724         int64           result;
725
726         result = ((arg1 > arg2) ? arg1 : arg2);
727
728         PG_RETURN_INT64(result);
729 }
730
731 Datum
732 int8smaller(PG_FUNCTION_ARGS)
733 {
734         int64           arg1 = PG_GETARG_INT64(0);
735         int64           arg2 = PG_GETARG_INT64(1);
736         int64           result;
737
738         result = ((arg1 < arg2) ? arg1 : arg2);
739
740         PG_RETURN_INT64(result);
741 }
742
743 Datum
744 int84pl(PG_FUNCTION_ARGS)
745 {
746         int64           arg1 = PG_GETARG_INT64(0);
747         int32           arg2 = PG_GETARG_INT32(1);
748         int64           result;
749
750         result = arg1 + arg2;
751
752         /*
753          * Overflow check.      If the inputs are of different signs then their sum
754          * cannot overflow.  If the inputs are of the same sign, their sum had
755          * better be that sign too.
756          */
757         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
758                 ereport(ERROR,
759                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
760                                  errmsg("bigint out of range")));
761         PG_RETURN_INT64(result);
762 }
763
764 Datum
765 int84mi(PG_FUNCTION_ARGS)
766 {
767         int64           arg1 = PG_GETARG_INT64(0);
768         int32           arg2 = PG_GETARG_INT32(1);
769         int64           result;
770
771         result = arg1 - arg2;
772
773         /*
774          * Overflow check.      If the inputs are of the same sign then their
775          * difference cannot overflow.  If they are of different signs then the
776          * result should be of the same sign as the first input.
777          */
778         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
779                 ereport(ERROR,
780                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
781                                  errmsg("bigint out of range")));
782         PG_RETURN_INT64(result);
783 }
784
785 Datum
786 int84mul(PG_FUNCTION_ARGS)
787 {
788         int64           arg1 = PG_GETARG_INT64(0);
789         int32           arg2 = PG_GETARG_INT32(1);
790         int64           result;
791
792         result = arg1 * arg2;
793
794         /*
795          * Overflow check.      We basically check to see if result / arg1 gives arg2
796          * again.  There is one case where this fails: arg1 = 0 (which cannot
797          * overflow).
798          *
799          * Since the division is likely much more expensive than the actual
800          * multiplication, we'd like to skip it where possible.  The best bang for
801          * the buck seems to be to check whether both inputs are in the int32
802          * range; if so, no overflow is possible.
803          */
804         if (arg1 != (int64) ((int32) arg1) &&
805                 result / arg1 != arg2)
806                 ereport(ERROR,
807                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
808                                  errmsg("bigint out of range")));
809         PG_RETURN_INT64(result);
810 }
811
812 Datum
813 int84div(PG_FUNCTION_ARGS)
814 {
815         int64           arg1 = PG_GETARG_INT64(0);
816         int32           arg2 = PG_GETARG_INT32(1);
817         int64           result;
818
819         if (arg2 == 0)
820                 ereport(ERROR,
821                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
822                                  errmsg("division by zero")));
823
824         result = arg1 / arg2;
825
826         /*
827          * Overflow check.      The only possible overflow case is for arg1 =
828          * INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which
829          * can't be represented on a two's-complement machine.
830          */
831         if (arg2 == -1 && arg1 < 0 && result < 0)
832                 ereport(ERROR,
833                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
834                                  errmsg("bigint out of range")));
835         PG_RETURN_INT64(result);
836 }
837
838 Datum
839 int48pl(PG_FUNCTION_ARGS)
840 {
841         int32           arg1 = PG_GETARG_INT32(0);
842         int64           arg2 = PG_GETARG_INT64(1);
843         int64           result;
844
845         result = arg1 + arg2;
846
847         /*
848          * Overflow check.      If the inputs are of different signs then their sum
849          * cannot overflow.  If the inputs are of the same sign, their sum had
850          * better be that sign too.
851          */
852         if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
853                 ereport(ERROR,
854                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
855                                  errmsg("bigint out of range")));
856         PG_RETURN_INT64(result);
857 }
858
859 Datum
860 int48mi(PG_FUNCTION_ARGS)
861 {
862         int32           arg1 = PG_GETARG_INT32(0);
863         int64           arg2 = PG_GETARG_INT64(1);
864         int64           result;
865
866         result = arg1 - arg2;
867
868         /*
869          * Overflow check.      If the inputs are of the same sign then their
870          * difference cannot overflow.  If they are of different signs then the
871          * result should be of the same sign as the first input.
872          */
873         if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
874                 ereport(ERROR,
875                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
876                                  errmsg("bigint out of range")));
877         PG_RETURN_INT64(result);
878 }
879
880 Datum
881 int48mul(PG_FUNCTION_ARGS)
882 {
883         int32           arg1 = PG_GETARG_INT32(0);
884         int64           arg2 = PG_GETARG_INT64(1);
885         int64           result;
886
887         result = arg1 * arg2;
888
889         /*
890          * Overflow check.      We basically check to see if result / arg2 gives arg1
891          * again.  There is one case where this fails: arg2 = 0 (which cannot
892          * overflow).
893          *
894          * Since the division is likely much more expensive than the actual
895          * multiplication, we'd like to skip it where possible.  The best bang for
896          * the buck seems to be to check whether both inputs are in the int32
897          * range; if so, no overflow is possible.
898          */
899         if (arg2 != (int64) ((int32) arg2) &&
900                 result / arg2 != arg1)
901                 ereport(ERROR,
902                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
903                                  errmsg("bigint out of range")));
904         PG_RETURN_INT64(result);
905 }
906
907 Datum
908 int48div(PG_FUNCTION_ARGS)
909 {
910         int32           arg1 = PG_GETARG_INT32(0);
911         int64           arg2 = PG_GETARG_INT64(1);
912
913         if (arg2 == 0)
914                 ereport(ERROR,
915                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
916                                  errmsg("division by zero")));
917         /* No overflow is possible */
918         PG_RETURN_INT64((int64) arg1 / arg2);
919 }
920
921 /* Binary arithmetics
922  *
923  *              int8and         - returns arg1 & arg2
924  *              int8or          - returns arg1 | arg2
925  *              int8xor         - returns arg1 # arg2
926  *              int8not         - returns ~arg1
927  *              int8shl         - returns arg1 << arg2
928  *              int8shr         - returns arg1 >> arg2
929  */
930
931 Datum
932 int8and(PG_FUNCTION_ARGS)
933 {
934         int64           arg1 = PG_GETARG_INT64(0);
935         int64           arg2 = PG_GETARG_INT64(1);
936
937         PG_RETURN_INT64(arg1 & arg2);
938 }
939
940 Datum
941 int8or(PG_FUNCTION_ARGS)
942 {
943         int64           arg1 = PG_GETARG_INT64(0);
944         int64           arg2 = PG_GETARG_INT64(1);
945
946         PG_RETURN_INT64(arg1 | arg2);
947 }
948
949 Datum
950 int8xor(PG_FUNCTION_ARGS)
951 {
952         int64           arg1 = PG_GETARG_INT64(0);
953         int64           arg2 = PG_GETARG_INT64(1);
954
955         PG_RETURN_INT64(arg1 ^ arg2);
956 }
957
958 Datum
959 int8not(PG_FUNCTION_ARGS)
960 {
961         int64           arg1 = PG_GETARG_INT64(0);
962
963         PG_RETURN_INT64(~arg1);
964 }
965
966 Datum
967 int8shl(PG_FUNCTION_ARGS)
968 {
969         int64           arg1 = PG_GETARG_INT64(0);
970         int32           arg2 = PG_GETARG_INT32(1);
971
972         PG_RETURN_INT64(arg1 << arg2);
973 }
974
975 Datum
976 int8shr(PG_FUNCTION_ARGS)
977 {
978         int64           arg1 = PG_GETARG_INT64(0);
979         int32           arg2 = PG_GETARG_INT32(1);
980
981         PG_RETURN_INT64(arg1 >> arg2);
982 }
983
984 /*----------------------------------------------------------
985  *      Conversion operators.
986  *---------------------------------------------------------*/
987
988 Datum
989 int48(PG_FUNCTION_ARGS)
990 {
991         int32           arg = PG_GETARG_INT32(0);
992
993         PG_RETURN_INT64((int64) arg);
994 }
995
996 Datum
997 int84(PG_FUNCTION_ARGS)
998 {
999         int64           arg = PG_GETARG_INT64(0);
1000         int32           result;
1001
1002         result = (int32) arg;
1003
1004         /* Test for overflow by reverse-conversion. */
1005         if ((int64) result != arg)
1006                 ereport(ERROR,
1007                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1008                                  errmsg("integer out of range")));
1009
1010         PG_RETURN_INT32(result);
1011 }
1012
1013 Datum
1014 int28(PG_FUNCTION_ARGS)
1015 {
1016         int16           arg = PG_GETARG_INT16(0);
1017
1018         PG_RETURN_INT64((int64) arg);
1019 }
1020
1021 Datum
1022 int82(PG_FUNCTION_ARGS)
1023 {
1024         int64           arg = PG_GETARG_INT64(0);
1025         int16           result;
1026
1027         result = (int16) arg;
1028
1029         /* Test for overflow by reverse-conversion. */
1030         if ((int64) result != arg)
1031                 ereport(ERROR,
1032                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1033                                  errmsg("smallint out of range")));
1034
1035         PG_RETURN_INT16(result);
1036 }
1037
1038 Datum
1039 i8tod(PG_FUNCTION_ARGS)
1040 {
1041         int64           arg = PG_GETARG_INT64(0);
1042         float8          result;
1043
1044         result = arg;
1045
1046         PG_RETURN_FLOAT8(result);
1047 }
1048
1049 /* dtoi8()
1050  * Convert float8 to 8-byte integer.
1051  */
1052 Datum
1053 dtoi8(PG_FUNCTION_ARGS)
1054 {
1055         float8          arg = PG_GETARG_FLOAT8(0);
1056         int64           result;
1057
1058         /* Round arg to nearest integer (but it's still in float form) */
1059         arg = rint(arg);
1060
1061         /*
1062          * Does it fit in an int64?  Avoid assuming that we have handy constants
1063          * defined for the range boundaries, instead test for overflow by
1064          * reverse-conversion.
1065          */
1066         result = (int64) arg;
1067
1068         if ((float8) result != arg)
1069                 ereport(ERROR,
1070                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1071                                  errmsg("bigint out of range")));
1072
1073         PG_RETURN_INT64(result);
1074 }
1075
1076 Datum
1077 i8tof(PG_FUNCTION_ARGS)
1078 {
1079         int64           arg = PG_GETARG_INT64(0);
1080         float4          result;
1081
1082         result = arg;
1083
1084         PG_RETURN_FLOAT4(result);
1085 }
1086
1087 /* ftoi8()
1088  * Convert float4 to 8-byte integer.
1089  */
1090 Datum
1091 ftoi8(PG_FUNCTION_ARGS)
1092 {
1093         float4          arg = PG_GETARG_FLOAT4(0);
1094         int64           result;
1095         float8          darg;
1096
1097         /* Round arg to nearest integer (but it's still in float form) */
1098         darg = rint(arg);
1099
1100         /*
1101          * Does it fit in an int64?  Avoid assuming that we have handy constants
1102          * defined for the range boundaries, instead test for overflow by
1103          * reverse-conversion.
1104          */
1105         result = (int64) darg;
1106
1107         if ((float8) result != darg)
1108                 ereport(ERROR,
1109                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1110                                  errmsg("bigint out of range")));
1111
1112         PG_RETURN_INT64(result);
1113 }
1114
1115 Datum
1116 i8tooid(PG_FUNCTION_ARGS)
1117 {
1118         int64           arg = PG_GETARG_INT64(0);
1119         Oid                     result;
1120
1121         result = (Oid) arg;
1122
1123         /* Test for overflow by reverse-conversion. */
1124         if ((int64) result != arg)
1125                 ereport(ERROR,
1126                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1127                                  errmsg("OID out of range")));
1128
1129         PG_RETURN_OID(result);
1130 }
1131
1132 Datum
1133 oidtoi8(PG_FUNCTION_ARGS)
1134 {
1135         Oid                     arg = PG_GETARG_OID(0);
1136
1137         PG_RETURN_INT64((int64) arg);
1138 }
1139
1140 Datum
1141 text_int8(PG_FUNCTION_ARGS)
1142 {
1143         text       *str = PG_GETARG_TEXT_P(0);
1144         int                     len;
1145         char       *s;
1146         Datum           result;
1147
1148         len = (VARSIZE(str) - VARHDRSZ);
1149         s = palloc(len + 1);
1150         memcpy(s, VARDATA(str), len);
1151         *(s + len) = '\0';
1152
1153         result = DirectFunctionCall1(int8in, CStringGetDatum(s));
1154
1155         pfree(s);
1156
1157         return result;
1158 }
1159
1160 Datum
1161 int8_text(PG_FUNCTION_ARGS)
1162 {
1163         /* arg is int64, but easier to leave it as Datum */
1164         Datum           arg = PG_GETARG_DATUM(0);
1165         char       *s;
1166         int                     len;
1167         text       *result;
1168
1169         s = DatumGetCString(DirectFunctionCall1(int8out, arg));
1170         len = strlen(s);
1171
1172         result = (text *) palloc(VARHDRSZ + len);
1173
1174         VARATT_SIZEP(result) = len + VARHDRSZ;
1175         memcpy(VARDATA(result), s, len);
1176
1177         pfree(s);
1178
1179         PG_RETURN_TEXT_P(result);
1180 }
1181
1182 /*
1183  * non-persistent numeric series generator
1184  */
1185 Datum
1186 generate_series_int8(PG_FUNCTION_ARGS)
1187 {
1188         return generate_series_step_int8(fcinfo);
1189 }
1190
1191 Datum
1192 generate_series_step_int8(PG_FUNCTION_ARGS)
1193 {
1194         FuncCallContext *funcctx;
1195         generate_series_fctx *fctx;
1196         int64           result;
1197         MemoryContext oldcontext;
1198
1199         /* stuff done only on the first call of the function */
1200         if (SRF_IS_FIRSTCALL())
1201         {
1202                 int64           start = PG_GETARG_INT64(0);
1203                 int64           finish = PG_GETARG_INT64(1);
1204                 int64           step = 1;
1205
1206                 /* see if we were given an explicit step size */
1207                 if (PG_NARGS() == 3)
1208                         step = PG_GETARG_INT64(2);
1209                 if (step == 0)
1210                         ereport(ERROR,
1211                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1212                                          errmsg("step size may not equal zero")));
1213
1214                 /* create a function context for cross-call persistence */
1215                 funcctx = SRF_FIRSTCALL_INIT();
1216
1217                 /*
1218                  * switch to memory context appropriate for multiple function calls
1219                  */
1220                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1221
1222                 /* allocate memory for user context */
1223                 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1224
1225                 /*
1226                  * Use fctx to keep state from call to call. Seed current with the
1227                  * original start value
1228                  */
1229                 fctx->current = start;
1230                 fctx->finish = finish;
1231                 fctx->step = step;
1232
1233                 funcctx->user_fctx = fctx;
1234                 MemoryContextSwitchTo(oldcontext);
1235         }
1236
1237         /* stuff done on every call of the function */
1238         funcctx = SRF_PERCALL_SETUP();
1239
1240         /*
1241          * get the saved state and use current as the result for this iteration
1242          */
1243         fctx = funcctx->user_fctx;
1244         result = fctx->current;
1245
1246         if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1247                 (fctx->step < 0 && fctx->current >= fctx->finish))
1248         {
1249                 /* increment current in preparation for next iteration */
1250                 fctx->current += fctx->step;
1251
1252                 /* do when there is more left to send */
1253                 SRF_RETURN_NEXT(funcctx, Int64GetDatum(result));
1254         }
1255         else
1256                 /* do when there is no more left */
1257                 SRF_RETURN_DONE(funcctx);
1258 }