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