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