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