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