1 /*-------------------------------------------------------------------------
2 *
3 * int.c
4 * Functions for the built-in integer types (except int8).
5 *
6 * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/int.c
12 *
13 *-------------------------------------------------------------------------
14 */
15 /*
16 * OLD COMMENTS
17 * I/O routines:
18 * int2in, int2out, int2recv, int2send
19 * int4in, int4out, int4recv, int4send
20 * int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
21 * Boolean operators:
22 * inteq, intne, intlt, intle, intgt, intge
23 * Arithmetic operators:
24 * intpl, intmi, int4mul, intdiv
25 *
26 * Arithmetic operators:
27 * intmod
28 */
29 #include "postgres.h"
30
31 #include <ctype.h>
32 #include <limits.h>
33
34 #include "catalog/pg_type.h"
35 #include "funcapi.h"
36 #include "libpq/pqformat.h"
37 #include "utils/array.h"
38 #include "utils/builtins.h"
39
40
41 #define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
42
43 #define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int16))
44
45 typedef struct
46 {
47 int32 current;
48 int32 finish;
49 int32 step;
50 } generate_series_fctx;
51
52
53 /*****************************************************************************
54 * USER I/O ROUTINES *
55 *****************************************************************************/
56
57 /*
58 * int2in - converts "num" to short
59 */
60 Datum
int2in(PG_FUNCTION_ARGS)61 int2in(PG_FUNCTION_ARGS)
62 {
63 char *num = PG_GETARG_CSTRING(0);
64
65 PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
66 }
67
68 /*
69 * int2out - converts short to "num"
70 */
71 Datum
int2out(PG_FUNCTION_ARGS)72 int2out(PG_FUNCTION_ARGS)
73 {
74 int16 arg1 = PG_GETARG_INT16(0);
75 char *result = (char *) palloc(7); /* sign, 5 digits, '\0' */
76
77 pg_itoa(arg1, result);
78 PG_RETURN_CSTRING(result);
79 }
80
81 /*
82 * int2recv - converts external binary format to int2
83 */
84 Datum
int2recv(PG_FUNCTION_ARGS)85 int2recv(PG_FUNCTION_ARGS)
86 {
87 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
88
89 PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
90 }
91
92 /*
93 * int2send - converts int2 to binary format
94 */
95 Datum
int2send(PG_FUNCTION_ARGS)96 int2send(PG_FUNCTION_ARGS)
97 {
98 int16 arg1 = PG_GETARG_INT16(0);
99 StringInfoData buf;
100
101 pq_begintypsend(&buf);
102 pq_sendint(&buf, arg1, sizeof(int16));
103 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
104 }
105
106 /*
107 * construct int2vector given a raw array of int2s
108 *
109 * If int2s is NULL then caller must fill values[] afterward
110 */
111 int2vector *
buildint2vector(const int16 * int2s,int n)112 buildint2vector(const int16 *int2s, int n)
113 {
114 int2vector *result;
115
116 result = (int2vector *) palloc0(Int2VectorSize(n));
117
118 if (n > 0 && int2s)
119 memcpy(result->values, int2s, n * sizeof(int16));
120
121 /*
122 * Attach standard array header. For historical reasons, we set the index
123 * lower bound to 0 not 1.
124 */
125 SET_VARSIZE(result, Int2VectorSize(n));
126 result->ndim = 1;
127 result->dataoffset = 0; /* never any nulls */
128 result->elemtype = INT2OID;
129 result->dim1 = n;
130 result->lbound1 = 0;
131
132 return result;
133 }
134
135 /*
136 * int2vectorin - converts "num num ..." to internal form
137 */
138 Datum
int2vectorin(PG_FUNCTION_ARGS)139 int2vectorin(PG_FUNCTION_ARGS)
140 {
141 char *intString = PG_GETARG_CSTRING(0);
142 int2vector *result;
143 int n;
144
145 result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
146
147 for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)
148 {
149 while (*intString && isspace((unsigned char) *intString))
150 intString++;
151 if (*intString == '\0')
152 break;
153 result->values[n] = pg_atoi(intString, sizeof(int16), ' ');
154 while (*intString && !isspace((unsigned char) *intString))
155 intString++;
156 }
157 while (*intString && isspace((unsigned char) *intString))
158 intString++;
159 if (*intString)
160 ereport(ERROR,
161 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
162 errmsg("int2vector has too many elements")));
163
164 SET_VARSIZE(result, Int2VectorSize(n));
165 result->ndim = 1;
166 result->dataoffset = 0; /* never any nulls */
167 result->elemtype = INT2OID;
168 result->dim1 = n;
169 result->lbound1 = 0;
170
171 PG_RETURN_POINTER(result);
172 }
173
174 /*
175 * int2vectorout - converts internal form to "num num ..."
176 */
177 Datum
int2vectorout(PG_FUNCTION_ARGS)178 int2vectorout(PG_FUNCTION_ARGS)
179 {
180 int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
181 int num,
182 nnums = int2Array->dim1;
183 char *rp;
184 char *result;
185
186 /* assumes sign, 5 digits, ' ' */
187 rp = result = (char *) palloc(nnums * 7 + 1);
188 for (num = 0; num < nnums; num++)
189 {
190 if (num != 0)
191 *rp++ = ' ';
192 pg_itoa(int2Array->values[num], rp);
193 while (*++rp != '\0')
194 ;
195 }
196 *rp = '\0';
197 PG_RETURN_CSTRING(result);
198 }
199
200 /*
201 * int2vectorrecv - converts external binary format to int2vector
202 */
203 Datum
int2vectorrecv(PG_FUNCTION_ARGS)204 int2vectorrecv(PG_FUNCTION_ARGS)
205 {
206 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
207 FunctionCallInfoData locfcinfo;
208 int2vector *result;
209
210 /*
211 * Normally one would call array_recv() using DirectFunctionCall3, but
212 * that does not work since array_recv wants to cache some data using
213 * fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
214 * parameter.
215 */
216 InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
217 InvalidOid, NULL, NULL);
218
219 locfcinfo.arg[0] = PointerGetDatum(buf);
220 locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
221 locfcinfo.arg[2] = Int32GetDatum(-1);
222 locfcinfo.argnull[0] = false;
223 locfcinfo.argnull[1] = false;
224 locfcinfo.argnull[2] = false;
225
226 result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));
227
228 Assert(!locfcinfo.isnull);
229
230 /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
231 if (ARR_NDIM(result) != 1 ||
232 ARR_HASNULL(result) ||
233 ARR_ELEMTYPE(result) != INT2OID ||
234 ARR_LBOUND(result)[0] != 0)
235 ereport(ERROR,
236 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
237 errmsg("invalid int2vector data")));
238
239 /* check length for consistency with int2vectorin() */
240 if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
241 ereport(ERROR,
242 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
243 errmsg("oidvector has too many elements")));
244
245 PG_RETURN_POINTER(result);
246 }
247
248 /*
249 * int2vectorsend - converts int2vector to binary format
250 */
251 Datum
int2vectorsend(PG_FUNCTION_ARGS)252 int2vectorsend(PG_FUNCTION_ARGS)
253 {
254 return array_send(fcinfo);
255 }
256
257
258 /*****************************************************************************
259 * PUBLIC ROUTINES *
260 *****************************************************************************/
261
262 /*
263 * int4in - converts "num" to int4
264 */
265 Datum
int4in(PG_FUNCTION_ARGS)266 int4in(PG_FUNCTION_ARGS)
267 {
268 char *num = PG_GETARG_CSTRING(0);
269
270 PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
271 }
272
273 /*
274 * int4out - converts int4 to "num"
275 */
276 Datum
int4out(PG_FUNCTION_ARGS)277 int4out(PG_FUNCTION_ARGS)
278 {
279 int32 arg1 = PG_GETARG_INT32(0);
280 char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */
281
282 pg_ltoa(arg1, result);
283 PG_RETURN_CSTRING(result);
284 }
285
286 /*
287 * int4recv - converts external binary format to int4
288 */
289 Datum
int4recv(PG_FUNCTION_ARGS)290 int4recv(PG_FUNCTION_ARGS)
291 {
292 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
293
294 PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
295 }
296
297 /*
298 * int4send - converts int4 to binary format
299 */
300 Datum
int4send(PG_FUNCTION_ARGS)301 int4send(PG_FUNCTION_ARGS)
302 {
303 int32 arg1 = PG_GETARG_INT32(0);
304 StringInfoData buf;
305
306 pq_begintypsend(&buf);
307 pq_sendint(&buf, arg1, sizeof(int32));
308 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
309 }
310
311
312 /*
313 * ===================
314 * CONVERSION ROUTINES
315 * ===================
316 */
317
318 Datum
i2toi4(PG_FUNCTION_ARGS)319 i2toi4(PG_FUNCTION_ARGS)
320 {
321 int16 arg1 = PG_GETARG_INT16(0);
322
323 PG_RETURN_INT32((int32) arg1);
324 }
325
326 Datum
i4toi2(PG_FUNCTION_ARGS)327 i4toi2(PG_FUNCTION_ARGS)
328 {
329 int32 arg1 = PG_GETARG_INT32(0);
330
331 if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
332 ereport(ERROR,
333 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
334 errmsg("smallint out of range")));
335
336 PG_RETURN_INT16((int16) arg1);
337 }
338
339 /* Cast int4 -> bool */
340 Datum
int4_bool(PG_FUNCTION_ARGS)341 int4_bool(PG_FUNCTION_ARGS)
342 {
343 if (PG_GETARG_INT32(0) == 0)
344 PG_RETURN_BOOL(false);
345 else
346 PG_RETURN_BOOL(true);
347 }
348
349 /* Cast bool -> int4 */
350 Datum
bool_int4(PG_FUNCTION_ARGS)351 bool_int4(PG_FUNCTION_ARGS)
352 {
353 if (PG_GETARG_BOOL(0) == false)
354 PG_RETURN_INT32(0);
355 else
356 PG_RETURN_INT32(1);
357 }
358
359 /*
360 * ============================
361 * COMPARISON OPERATOR ROUTINES
362 * ============================
363 */
364
365 /*
366 * inteq - returns 1 iff arg1 == arg2
367 * intne - returns 1 iff arg1 != arg2
368 * intlt - returns 1 iff arg1 < arg2
369 * intle - returns 1 iff arg1 <= arg2
370 * intgt - returns 1 iff arg1 > arg2
371 * intge - returns 1 iff arg1 >= arg2
372 */
373
374 Datum
int4eq(PG_FUNCTION_ARGS)375 int4eq(PG_FUNCTION_ARGS)
376 {
377 int32 arg1 = PG_GETARG_INT32(0);
378 int32 arg2 = PG_GETARG_INT32(1);
379
380 PG_RETURN_BOOL(arg1 == arg2);
381 }
382
383 Datum
int4ne(PG_FUNCTION_ARGS)384 int4ne(PG_FUNCTION_ARGS)
385 {
386 int32 arg1 = PG_GETARG_INT32(0);
387 int32 arg2 = PG_GETARG_INT32(1);
388
389 PG_RETURN_BOOL(arg1 != arg2);
390 }
391
392 Datum
int4lt(PG_FUNCTION_ARGS)393 int4lt(PG_FUNCTION_ARGS)
394 {
395 int32 arg1 = PG_GETARG_INT32(0);
396 int32 arg2 = PG_GETARG_INT32(1);
397
398 PG_RETURN_BOOL(arg1 < arg2);
399 }
400
401 Datum
int4le(PG_FUNCTION_ARGS)402 int4le(PG_FUNCTION_ARGS)
403 {
404 int32 arg1 = PG_GETARG_INT32(0);
405 int32 arg2 = PG_GETARG_INT32(1);
406
407 PG_RETURN_BOOL(arg1 <= arg2);
408 }
409
410 Datum
int4gt(PG_FUNCTION_ARGS)411 int4gt(PG_FUNCTION_ARGS)
412 {
413 int32 arg1 = PG_GETARG_INT32(0);
414 int32 arg2 = PG_GETARG_INT32(1);
415
416 PG_RETURN_BOOL(arg1 > arg2);
417 }
418
419 Datum
int4ge(PG_FUNCTION_ARGS)420 int4ge(PG_FUNCTION_ARGS)
421 {
422 int32 arg1 = PG_GETARG_INT32(0);
423 int32 arg2 = PG_GETARG_INT32(1);
424
425 PG_RETURN_BOOL(arg1 >= arg2);
426 }
427
428 Datum
int2eq(PG_FUNCTION_ARGS)429 int2eq(PG_FUNCTION_ARGS)
430 {
431 int16 arg1 = PG_GETARG_INT16(0);
432 int16 arg2 = PG_GETARG_INT16(1);
433
434 PG_RETURN_BOOL(arg1 == arg2);
435 }
436
437 Datum
int2ne(PG_FUNCTION_ARGS)438 int2ne(PG_FUNCTION_ARGS)
439 {
440 int16 arg1 = PG_GETARG_INT16(0);
441 int16 arg2 = PG_GETARG_INT16(1);
442
443 PG_RETURN_BOOL(arg1 != arg2);
444 }
445
446 Datum
int2lt(PG_FUNCTION_ARGS)447 int2lt(PG_FUNCTION_ARGS)
448 {
449 int16 arg1 = PG_GETARG_INT16(0);
450 int16 arg2 = PG_GETARG_INT16(1);
451
452 PG_RETURN_BOOL(arg1 < arg2);
453 }
454
455 Datum
int2le(PG_FUNCTION_ARGS)456 int2le(PG_FUNCTION_ARGS)
457 {
458 int16 arg1 = PG_GETARG_INT16(0);
459 int16 arg2 = PG_GETARG_INT16(1);
460
461 PG_RETURN_BOOL(arg1 <= arg2);
462 }
463
464 Datum
int2gt(PG_FUNCTION_ARGS)465 int2gt(PG_FUNCTION_ARGS)
466 {
467 int16 arg1 = PG_GETARG_INT16(0);
468 int16 arg2 = PG_GETARG_INT16(1);
469
470 PG_RETURN_BOOL(arg1 > arg2);
471 }
472
473 Datum
int2ge(PG_FUNCTION_ARGS)474 int2ge(PG_FUNCTION_ARGS)
475 {
476 int16 arg1 = PG_GETARG_INT16(0);
477 int16 arg2 = PG_GETARG_INT16(1);
478
479 PG_RETURN_BOOL(arg1 >= arg2);
480 }
481
482 Datum
int24eq(PG_FUNCTION_ARGS)483 int24eq(PG_FUNCTION_ARGS)
484 {
485 int16 arg1 = PG_GETARG_INT16(0);
486 int32 arg2 = PG_GETARG_INT32(1);
487
488 PG_RETURN_BOOL(arg1 == arg2);
489 }
490
491 Datum
int24ne(PG_FUNCTION_ARGS)492 int24ne(PG_FUNCTION_ARGS)
493 {
494 int16 arg1 = PG_GETARG_INT16(0);
495 int32 arg2 = PG_GETARG_INT32(1);
496
497 PG_RETURN_BOOL(arg1 != arg2);
498 }
499
500 Datum
int24lt(PG_FUNCTION_ARGS)501 int24lt(PG_FUNCTION_ARGS)
502 {
503 int16 arg1 = PG_GETARG_INT16(0);
504 int32 arg2 = PG_GETARG_INT32(1);
505
506 PG_RETURN_BOOL(arg1 < arg2);
507 }
508
509 Datum
int24le(PG_FUNCTION_ARGS)510 int24le(PG_FUNCTION_ARGS)
511 {
512 int16 arg1 = PG_GETARG_INT16(0);
513 int32 arg2 = PG_GETARG_INT32(1);
514
515 PG_RETURN_BOOL(arg1 <= arg2);
516 }
517
518 Datum
int24gt(PG_FUNCTION_ARGS)519 int24gt(PG_FUNCTION_ARGS)
520 {
521 int16 arg1 = PG_GETARG_INT16(0);
522 int32 arg2 = PG_GETARG_INT32(1);
523
524 PG_RETURN_BOOL(arg1 > arg2);
525 }
526
527 Datum
int24ge(PG_FUNCTION_ARGS)528 int24ge(PG_FUNCTION_ARGS)
529 {
530 int16 arg1 = PG_GETARG_INT16(0);
531 int32 arg2 = PG_GETARG_INT32(1);
532
533 PG_RETURN_BOOL(arg1 >= arg2);
534 }
535
536 Datum
int42eq(PG_FUNCTION_ARGS)537 int42eq(PG_FUNCTION_ARGS)
538 {
539 int32 arg1 = PG_GETARG_INT32(0);
540 int16 arg2 = PG_GETARG_INT16(1);
541
542 PG_RETURN_BOOL(arg1 == arg2);
543 }
544
545 Datum
int42ne(PG_FUNCTION_ARGS)546 int42ne(PG_FUNCTION_ARGS)
547 {
548 int32 arg1 = PG_GETARG_INT32(0);
549 int16 arg2 = PG_GETARG_INT16(1);
550
551 PG_RETURN_BOOL(arg1 != arg2);
552 }
553
554 Datum
int42lt(PG_FUNCTION_ARGS)555 int42lt(PG_FUNCTION_ARGS)
556 {
557 int32 arg1 = PG_GETARG_INT32(0);
558 int16 arg2 = PG_GETARG_INT16(1);
559
560 PG_RETURN_BOOL(arg1 < arg2);
561 }
562
563 Datum
int42le(PG_FUNCTION_ARGS)564 int42le(PG_FUNCTION_ARGS)
565 {
566 int32 arg1 = PG_GETARG_INT32(0);
567 int16 arg2 = PG_GETARG_INT16(1);
568
569 PG_RETURN_BOOL(arg1 <= arg2);
570 }
571
572 Datum
int42gt(PG_FUNCTION_ARGS)573 int42gt(PG_FUNCTION_ARGS)
574 {
575 int32 arg1 = PG_GETARG_INT32(0);
576 int16 arg2 = PG_GETARG_INT16(1);
577
578 PG_RETURN_BOOL(arg1 > arg2);
579 }
580
581 Datum
int42ge(PG_FUNCTION_ARGS)582 int42ge(PG_FUNCTION_ARGS)
583 {
584 int32 arg1 = PG_GETARG_INT32(0);
585 int16 arg2 = PG_GETARG_INT16(1);
586
587 PG_RETURN_BOOL(arg1 >= arg2);
588 }
589
590 /*
591 * int[24]pl - returns arg1 + arg2
592 * int[24]mi - returns arg1 - arg2
593 * int[24]mul - returns arg1 * arg2
594 * int[24]div - returns arg1 / arg2
595 */
596
597 Datum
int4um(PG_FUNCTION_ARGS)598 int4um(PG_FUNCTION_ARGS)
599 {
600 int32 arg = PG_GETARG_INT32(0);
601 int32 result;
602
603 result = -arg;
604 /* overflow check (needed for INT_MIN) */
605 if (arg != 0 && SAMESIGN(result, arg))
606 ereport(ERROR,
607 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
608 errmsg("integer out of range")));
609 PG_RETURN_INT32(result);
610 }
611
612 Datum
int4up(PG_FUNCTION_ARGS)613 int4up(PG_FUNCTION_ARGS)
614 {
615 int32 arg = PG_GETARG_INT32(0);
616
617 PG_RETURN_INT32(arg);
618 }
619
620 Datum
int4pl(PG_FUNCTION_ARGS)621 int4pl(PG_FUNCTION_ARGS)
622 {
623 int32 arg1 = PG_GETARG_INT32(0);
624 int32 arg2 = PG_GETARG_INT32(1);
625 int32 result;
626
627 result = arg1 + arg2;
628
629 /*
630 * Overflow check. If the inputs are of different signs then their sum
631 * cannot overflow. If the inputs are of the same sign, their sum had
632 * better be that sign too.
633 */
634 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
635 ereport(ERROR,
636 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
637 errmsg("integer out of range")));
638 PG_RETURN_INT32(result);
639 }
640
641 Datum
int4mi(PG_FUNCTION_ARGS)642 int4mi(PG_FUNCTION_ARGS)
643 {
644 int32 arg1 = PG_GETARG_INT32(0);
645 int32 arg2 = PG_GETARG_INT32(1);
646 int32 result;
647
648 result = arg1 - arg2;
649
650 /*
651 * Overflow check. If the inputs are of the same sign then their
652 * difference cannot overflow. If they are of different signs then the
653 * result should be of the same sign as the first input.
654 */
655 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
656 ereport(ERROR,
657 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
658 errmsg("integer out of range")));
659 PG_RETURN_INT32(result);
660 }
661
662 Datum
int4mul(PG_FUNCTION_ARGS)663 int4mul(PG_FUNCTION_ARGS)
664 {
665 int32 arg1 = PG_GETARG_INT32(0);
666 int32 arg2 = PG_GETARG_INT32(1);
667 int32 result;
668
669 result = arg1 * arg2;
670
671 /*
672 * Overflow check. We basically check to see if result / arg2 gives arg1
673 * again. There are two cases where this fails: arg2 = 0 (which cannot
674 * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will
675 * overflow and thus incorrectly match).
676 *
677 * Since the division is likely much more expensive than the actual
678 * multiplication, we'd like to skip it where possible. The best bang for
679 * the buck seems to be to check whether both inputs are in the int16
680 * range; if so, no overflow is possible.
681 */
682 if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
683 arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
684 arg2 != 0 &&
685 ((arg2 == -1 && arg1 < 0 && result < 0) ||
686 result / arg2 != arg1))
687 ereport(ERROR,
688 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
689 errmsg("integer out of range")));
690 PG_RETURN_INT32(result);
691 }
692
693 Datum
int4div(PG_FUNCTION_ARGS)694 int4div(PG_FUNCTION_ARGS)
695 {
696 int32 arg1 = PG_GETARG_INT32(0);
697 int32 arg2 = PG_GETARG_INT32(1);
698 int32 result;
699
700 if (arg2 == 0)
701 {
702 ereport(ERROR,
703 (errcode(ERRCODE_DIVISION_BY_ZERO),
704 errmsg("division by zero")));
705 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
706 PG_RETURN_NULL();
707 }
708
709 /*
710 * INT_MIN / -1 is problematic, since the result can't be represented on a
711 * two's-complement machine. Some machines produce INT_MIN, some produce
712 * zero, some throw an exception. We can dodge the problem by recognizing
713 * that division by -1 is the same as negation.
714 */
715 if (arg2 == -1)
716 {
717 result = -arg1;
718 /* overflow check (needed for INT_MIN) */
719 if (arg1 != 0 && SAMESIGN(result, arg1))
720 ereport(ERROR,
721 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
722 errmsg("integer out of range")));
723 PG_RETURN_INT32(result);
724 }
725
726 /* No overflow is possible */
727
728 result = arg1 / arg2;
729
730 PG_RETURN_INT32(result);
731 }
732
733 Datum
int4inc(PG_FUNCTION_ARGS)734 int4inc(PG_FUNCTION_ARGS)
735 {
736 int32 arg = PG_GETARG_INT32(0);
737 int32 result;
738
739 result = arg + 1;
740 /* Overflow check */
741 if (arg > 0 && result < 0)
742 ereport(ERROR,
743 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
744 errmsg("integer out of range")));
745
746 PG_RETURN_INT32(result);
747 }
748
749 Datum
int2um(PG_FUNCTION_ARGS)750 int2um(PG_FUNCTION_ARGS)
751 {
752 int16 arg = PG_GETARG_INT16(0);
753 int16 result;
754
755 result = -arg;
756 /* overflow check (needed for SHRT_MIN) */
757 if (arg != 0 && SAMESIGN(result, arg))
758 ereport(ERROR,
759 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
760 errmsg("smallint out of range")));
761 PG_RETURN_INT16(result);
762 }
763
764 Datum
int2up(PG_FUNCTION_ARGS)765 int2up(PG_FUNCTION_ARGS)
766 {
767 int16 arg = PG_GETARG_INT16(0);
768
769 PG_RETURN_INT16(arg);
770 }
771
772 Datum
int2pl(PG_FUNCTION_ARGS)773 int2pl(PG_FUNCTION_ARGS)
774 {
775 int16 arg1 = PG_GETARG_INT16(0);
776 int16 arg2 = PG_GETARG_INT16(1);
777 int16 result;
778
779 result = arg1 + arg2;
780
781 /*
782 * Overflow check. If the inputs are of different signs then their sum
783 * cannot overflow. If the inputs are of the same sign, their sum had
784 * better be that sign too.
785 */
786 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
787 ereport(ERROR,
788 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
789 errmsg("smallint out of range")));
790 PG_RETURN_INT16(result);
791 }
792
793 Datum
int2mi(PG_FUNCTION_ARGS)794 int2mi(PG_FUNCTION_ARGS)
795 {
796 int16 arg1 = PG_GETARG_INT16(0);
797 int16 arg2 = PG_GETARG_INT16(1);
798 int16 result;
799
800 result = arg1 - arg2;
801
802 /*
803 * Overflow check. If the inputs are of the same sign then their
804 * difference cannot overflow. If they are of different signs then the
805 * result should be of the same sign as the first input.
806 */
807 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
808 ereport(ERROR,
809 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
810 errmsg("smallint out of range")));
811 PG_RETURN_INT16(result);
812 }
813
814 Datum
int2mul(PG_FUNCTION_ARGS)815 int2mul(PG_FUNCTION_ARGS)
816 {
817 int16 arg1 = PG_GETARG_INT16(0);
818 int16 arg2 = PG_GETARG_INT16(1);
819 int32 result32;
820
821 /*
822 * The most practical way to detect overflow is to do the arithmetic in
823 * int32 (so that the result can't overflow) and then do a range check.
824 */
825 result32 = (int32) arg1 * (int32) arg2;
826
827 if (result32 < SHRT_MIN || result32 > SHRT_MAX)
828 ereport(ERROR,
829 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
830 errmsg("smallint out of range")));
831
832 PG_RETURN_INT16((int16) result32);
833 }
834
835 Datum
int2div(PG_FUNCTION_ARGS)836 int2div(PG_FUNCTION_ARGS)
837 {
838 int16 arg1 = PG_GETARG_INT16(0);
839 int16 arg2 = PG_GETARG_INT16(1);
840 int16 result;
841
842 if (arg2 == 0)
843 {
844 ereport(ERROR,
845 (errcode(ERRCODE_DIVISION_BY_ZERO),
846 errmsg("division by zero")));
847 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
848 PG_RETURN_NULL();
849 }
850
851 /*
852 * SHRT_MIN / -1 is problematic, since the result can't be represented on
853 * a two's-complement machine. Some machines produce SHRT_MIN, some
854 * produce zero, some throw an exception. We can dodge the problem by
855 * recognizing that division by -1 is the same as negation.
856 */
857 if (arg2 == -1)
858 {
859 result = -arg1;
860 /* overflow check (needed for SHRT_MIN) */
861 if (arg1 != 0 && SAMESIGN(result, arg1))
862 ereport(ERROR,
863 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
864 errmsg("smallint out of range")));
865 PG_RETURN_INT16(result);
866 }
867
868 /* No overflow is possible */
869
870 result = arg1 / arg2;
871
872 PG_RETURN_INT16(result);
873 }
874
875 Datum
int24pl(PG_FUNCTION_ARGS)876 int24pl(PG_FUNCTION_ARGS)
877 {
878 int16 arg1 = PG_GETARG_INT16(0);
879 int32 arg2 = PG_GETARG_INT32(1);
880 int32 result;
881
882 result = arg1 + arg2;
883
884 /*
885 * Overflow check. If the inputs are of different signs then their sum
886 * cannot overflow. If the inputs are of the same sign, their sum had
887 * better be that sign too.
888 */
889 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
890 ereport(ERROR,
891 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
892 errmsg("integer out of range")));
893 PG_RETURN_INT32(result);
894 }
895
896 Datum
int24mi(PG_FUNCTION_ARGS)897 int24mi(PG_FUNCTION_ARGS)
898 {
899 int16 arg1 = PG_GETARG_INT16(0);
900 int32 arg2 = PG_GETARG_INT32(1);
901 int32 result;
902
903 result = arg1 - arg2;
904
905 /*
906 * Overflow check. If the inputs are of the same sign then their
907 * difference cannot overflow. If they are of different signs then the
908 * result should be of the same sign as the first input.
909 */
910 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
911 ereport(ERROR,
912 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
913 errmsg("integer out of range")));
914 PG_RETURN_INT32(result);
915 }
916
917 Datum
int24mul(PG_FUNCTION_ARGS)918 int24mul(PG_FUNCTION_ARGS)
919 {
920 int16 arg1 = PG_GETARG_INT16(0);
921 int32 arg2 = PG_GETARG_INT32(1);
922 int32 result;
923
924 result = arg1 * arg2;
925
926 /*
927 * Overflow check. We basically check to see if result / arg2 gives arg1
928 * again. There is one case where this fails: arg2 = 0 (which cannot
929 * overflow).
930 *
931 * Since the division is likely much more expensive than the actual
932 * multiplication, we'd like to skip it where possible. The best bang for
933 * the buck seems to be to check whether both inputs are in the int16
934 * range; if so, no overflow is possible.
935 */
936 if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
937 result / arg2 != arg1)
938 ereport(ERROR,
939 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
940 errmsg("integer out of range")));
941 PG_RETURN_INT32(result);
942 }
943
944 Datum
int24div(PG_FUNCTION_ARGS)945 int24div(PG_FUNCTION_ARGS)
946 {
947 int16 arg1 = PG_GETARG_INT16(0);
948 int32 arg2 = PG_GETARG_INT32(1);
949
950 if (arg2 == 0)
951 {
952 ereport(ERROR,
953 (errcode(ERRCODE_DIVISION_BY_ZERO),
954 errmsg("division by zero")));
955 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
956 PG_RETURN_NULL();
957 }
958
959 /* No overflow is possible */
960 PG_RETURN_INT32((int32) arg1 / arg2);
961 }
962
963 Datum
int42pl(PG_FUNCTION_ARGS)964 int42pl(PG_FUNCTION_ARGS)
965 {
966 int32 arg1 = PG_GETARG_INT32(0);
967 int16 arg2 = PG_GETARG_INT16(1);
968 int32 result;
969
970 result = arg1 + arg2;
971
972 /*
973 * Overflow check. If the inputs are of different signs then their sum
974 * cannot overflow. If the inputs are of the same sign, their sum had
975 * better be that sign too.
976 */
977 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
978 ereport(ERROR,
979 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
980 errmsg("integer out of range")));
981 PG_RETURN_INT32(result);
982 }
983
984 Datum
int42mi(PG_FUNCTION_ARGS)985 int42mi(PG_FUNCTION_ARGS)
986 {
987 int32 arg1 = PG_GETARG_INT32(0);
988 int16 arg2 = PG_GETARG_INT16(1);
989 int32 result;
990
991 result = arg1 - arg2;
992
993 /*
994 * Overflow check. If the inputs are of the same sign then their
995 * difference cannot overflow. If they are of different signs then the
996 * result should be of the same sign as the first input.
997 */
998 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
999 ereport(ERROR,
1000 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1001 errmsg("integer out of range")));
1002 PG_RETURN_INT32(result);
1003 }
1004
1005 Datum
int42mul(PG_FUNCTION_ARGS)1006 int42mul(PG_FUNCTION_ARGS)
1007 {
1008 int32 arg1 = PG_GETARG_INT32(0);
1009 int16 arg2 = PG_GETARG_INT16(1);
1010 int32 result;
1011
1012 result = arg1 * arg2;
1013
1014 /*
1015 * Overflow check. We basically check to see if result / arg1 gives arg2
1016 * again. There is one case where this fails: arg1 = 0 (which cannot
1017 * overflow).
1018 *
1019 * Since the division is likely much more expensive than the actual
1020 * multiplication, we'd like to skip it where possible. The best bang for
1021 * the buck seems to be to check whether both inputs are in the int16
1022 * range; if so, no overflow is possible.
1023 */
1024 if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
1025 result / arg1 != arg2)
1026 ereport(ERROR,
1027 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1028 errmsg("integer out of range")));
1029 PG_RETURN_INT32(result);
1030 }
1031
1032 Datum
int42div(PG_FUNCTION_ARGS)1033 int42div(PG_FUNCTION_ARGS)
1034 {
1035 int32 arg1 = PG_GETARG_INT32(0);
1036 int16 arg2 = PG_GETARG_INT16(1);
1037 int32 result;
1038
1039 if (arg2 == 0)
1040 {
1041 ereport(ERROR,
1042 (errcode(ERRCODE_DIVISION_BY_ZERO),
1043 errmsg("division by zero")));
1044 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1045 PG_RETURN_NULL();
1046 }
1047
1048 /*
1049 * INT_MIN / -1 is problematic, since the result can't be represented on a
1050 * two's-complement machine. Some machines produce INT_MIN, some produce
1051 * zero, some throw an exception. We can dodge the problem by recognizing
1052 * that division by -1 is the same as negation.
1053 */
1054 if (arg2 == -1)
1055 {
1056 result = -arg1;
1057 /* overflow check (needed for INT_MIN) */
1058 if (arg1 != 0 && SAMESIGN(result, arg1))
1059 ereport(ERROR,
1060 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1061 errmsg("integer out of range")));
1062 PG_RETURN_INT32(result);
1063 }
1064
1065 /* No overflow is possible */
1066
1067 result = arg1 / arg2;
1068
1069 PG_RETURN_INT32(result);
1070 }
1071
1072 Datum
int4mod(PG_FUNCTION_ARGS)1073 int4mod(PG_FUNCTION_ARGS)
1074 {
1075 int32 arg1 = PG_GETARG_INT32(0);
1076 int32 arg2 = PG_GETARG_INT32(1);
1077
1078 if (arg2 == 0)
1079 {
1080 ereport(ERROR,
1081 (errcode(ERRCODE_DIVISION_BY_ZERO),
1082 errmsg("division by zero")));
1083 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1084 PG_RETURN_NULL();
1085 }
1086
1087 /*
1088 * Some machines throw a floating-point exception for INT_MIN % -1, which
1089 * is a bit silly since the correct answer is perfectly well-defined,
1090 * namely zero.
1091 */
1092 if (arg2 == -1)
1093 PG_RETURN_INT32(0);
1094
1095 /* No overflow is possible */
1096
1097 PG_RETURN_INT32(arg1 % arg2);
1098 }
1099
1100 Datum
int2mod(PG_FUNCTION_ARGS)1101 int2mod(PG_FUNCTION_ARGS)
1102 {
1103 int16 arg1 = PG_GETARG_INT16(0);
1104 int16 arg2 = PG_GETARG_INT16(1);
1105
1106 if (arg2 == 0)
1107 {
1108 ereport(ERROR,
1109 (errcode(ERRCODE_DIVISION_BY_ZERO),
1110 errmsg("division by zero")));
1111 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1112 PG_RETURN_NULL();
1113 }
1114
1115 /*
1116 * Some machines throw a floating-point exception for INT_MIN % -1, which
1117 * is a bit silly since the correct answer is perfectly well-defined,
1118 * namely zero. (It's not clear this ever happens when dealing with
1119 * int16, but we might as well have the test for safety.)
1120 */
1121 if (arg2 == -1)
1122 PG_RETURN_INT16(0);
1123
1124 /* No overflow is possible */
1125
1126 PG_RETURN_INT16(arg1 % arg2);
1127 }
1128
1129
1130 /* int[24]abs()
1131 * Absolute value
1132 */
1133 Datum
int4abs(PG_FUNCTION_ARGS)1134 int4abs(PG_FUNCTION_ARGS)
1135 {
1136 int32 arg1 = PG_GETARG_INT32(0);
1137 int32 result;
1138
1139 result = (arg1 < 0) ? -arg1 : arg1;
1140 /* overflow check (needed for INT_MIN) */
1141 if (result < 0)
1142 ereport(ERROR,
1143 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1144 errmsg("integer out of range")));
1145 PG_RETURN_INT32(result);
1146 }
1147
1148 Datum
int2abs(PG_FUNCTION_ARGS)1149 int2abs(PG_FUNCTION_ARGS)
1150 {
1151 int16 arg1 = PG_GETARG_INT16(0);
1152 int16 result;
1153
1154 result = (arg1 < 0) ? -arg1 : arg1;
1155 /* overflow check (needed for SHRT_MIN) */
1156 if (result < 0)
1157 ereport(ERROR,
1158 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1159 errmsg("smallint out of range")));
1160 PG_RETURN_INT16(result);
1161 }
1162
1163 Datum
int2larger(PG_FUNCTION_ARGS)1164 int2larger(PG_FUNCTION_ARGS)
1165 {
1166 int16 arg1 = PG_GETARG_INT16(0);
1167 int16 arg2 = PG_GETARG_INT16(1);
1168
1169 PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
1170 }
1171
1172 Datum
int2smaller(PG_FUNCTION_ARGS)1173 int2smaller(PG_FUNCTION_ARGS)
1174 {
1175 int16 arg1 = PG_GETARG_INT16(0);
1176 int16 arg2 = PG_GETARG_INT16(1);
1177
1178 PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
1179 }
1180
1181 Datum
int4larger(PG_FUNCTION_ARGS)1182 int4larger(PG_FUNCTION_ARGS)
1183 {
1184 int32 arg1 = PG_GETARG_INT32(0);
1185 int32 arg2 = PG_GETARG_INT32(1);
1186
1187 PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
1188 }
1189
1190 Datum
int4smaller(PG_FUNCTION_ARGS)1191 int4smaller(PG_FUNCTION_ARGS)
1192 {
1193 int32 arg1 = PG_GETARG_INT32(0);
1194 int32 arg2 = PG_GETARG_INT32(1);
1195
1196 PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
1197 }
1198
1199 /*
1200 * Bit-pushing operators
1201 *
1202 * int[24]and - returns arg1 & arg2
1203 * int[24]or - returns arg1 | arg2
1204 * int[24]xor - returns arg1 # arg2
1205 * int[24]not - returns ~arg1
1206 * int[24]shl - returns arg1 << arg2
1207 * int[24]shr - returns arg1 >> arg2
1208 */
1209
1210 Datum
int4and(PG_FUNCTION_ARGS)1211 int4and(PG_FUNCTION_ARGS)
1212 {
1213 int32 arg1 = PG_GETARG_INT32(0);
1214 int32 arg2 = PG_GETARG_INT32(1);
1215
1216 PG_RETURN_INT32(arg1 & arg2);
1217 }
1218
1219 Datum
int4or(PG_FUNCTION_ARGS)1220 int4or(PG_FUNCTION_ARGS)
1221 {
1222 int32 arg1 = PG_GETARG_INT32(0);
1223 int32 arg2 = PG_GETARG_INT32(1);
1224
1225 PG_RETURN_INT32(arg1 | arg2);
1226 }
1227
1228 Datum
int4xor(PG_FUNCTION_ARGS)1229 int4xor(PG_FUNCTION_ARGS)
1230 {
1231 int32 arg1 = PG_GETARG_INT32(0);
1232 int32 arg2 = PG_GETARG_INT32(1);
1233
1234 PG_RETURN_INT32(arg1 ^ arg2);
1235 }
1236
1237 Datum
int4shl(PG_FUNCTION_ARGS)1238 int4shl(PG_FUNCTION_ARGS)
1239 {
1240 int32 arg1 = PG_GETARG_INT32(0);
1241 int32 arg2 = PG_GETARG_INT32(1);
1242
1243 PG_RETURN_INT32(arg1 << arg2);
1244 }
1245
1246 Datum
int4shr(PG_FUNCTION_ARGS)1247 int4shr(PG_FUNCTION_ARGS)
1248 {
1249 int32 arg1 = PG_GETARG_INT32(0);
1250 int32 arg2 = PG_GETARG_INT32(1);
1251
1252 PG_RETURN_INT32(arg1 >> arg2);
1253 }
1254
1255 Datum
int4not(PG_FUNCTION_ARGS)1256 int4not(PG_FUNCTION_ARGS)
1257 {
1258 int32 arg1 = PG_GETARG_INT32(0);
1259
1260 PG_RETURN_INT32(~arg1);
1261 }
1262
1263 Datum
int2and(PG_FUNCTION_ARGS)1264 int2and(PG_FUNCTION_ARGS)
1265 {
1266 int16 arg1 = PG_GETARG_INT16(0);
1267 int16 arg2 = PG_GETARG_INT16(1);
1268
1269 PG_RETURN_INT16(arg1 & arg2);
1270 }
1271
1272 Datum
int2or(PG_FUNCTION_ARGS)1273 int2or(PG_FUNCTION_ARGS)
1274 {
1275 int16 arg1 = PG_GETARG_INT16(0);
1276 int16 arg2 = PG_GETARG_INT16(1);
1277
1278 PG_RETURN_INT16(arg1 | arg2);
1279 }
1280
1281 Datum
int2xor(PG_FUNCTION_ARGS)1282 int2xor(PG_FUNCTION_ARGS)
1283 {
1284 int16 arg1 = PG_GETARG_INT16(0);
1285 int16 arg2 = PG_GETARG_INT16(1);
1286
1287 PG_RETURN_INT16(arg1 ^ arg2);
1288 }
1289
1290 Datum
int2not(PG_FUNCTION_ARGS)1291 int2not(PG_FUNCTION_ARGS)
1292 {
1293 int16 arg1 = PG_GETARG_INT16(0);
1294
1295 PG_RETURN_INT16(~arg1);
1296 }
1297
1298
1299 Datum
int2shl(PG_FUNCTION_ARGS)1300 int2shl(PG_FUNCTION_ARGS)
1301 {
1302 int16 arg1 = PG_GETARG_INT16(0);
1303 int32 arg2 = PG_GETARG_INT32(1);
1304
1305 PG_RETURN_INT16(arg1 << arg2);
1306 }
1307
1308 Datum
int2shr(PG_FUNCTION_ARGS)1309 int2shr(PG_FUNCTION_ARGS)
1310 {
1311 int16 arg1 = PG_GETARG_INT16(0);
1312 int32 arg2 = PG_GETARG_INT32(1);
1313
1314 PG_RETURN_INT16(arg1 >> arg2);
1315 }
1316
1317 /*
1318 * non-persistent numeric series generator
1319 */
1320 Datum
generate_series_int4(PG_FUNCTION_ARGS)1321 generate_series_int4(PG_FUNCTION_ARGS)
1322 {
1323 return generate_series_step_int4(fcinfo);
1324 }
1325
1326 Datum
generate_series_step_int4(PG_FUNCTION_ARGS)1327 generate_series_step_int4(PG_FUNCTION_ARGS)
1328 {
1329 FuncCallContext *funcctx;
1330 generate_series_fctx *fctx;
1331 int32 result;
1332 MemoryContext oldcontext;
1333
1334 /* stuff done only on the first call of the function */
1335 if (SRF_IS_FIRSTCALL())
1336 {
1337 int32 start = PG_GETARG_INT32(0);
1338 int32 finish = PG_GETARG_INT32(1);
1339 int32 step = 1;
1340
1341 /* see if we were given an explicit step size */
1342 if (PG_NARGS() == 3)
1343 step = PG_GETARG_INT32(2);
1344 if (step == 0)
1345 ereport(ERROR,
1346 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1347 errmsg("step size cannot equal zero")));
1348
1349 /* create a function context for cross-call persistence */
1350 funcctx = SRF_FIRSTCALL_INIT();
1351
1352 /*
1353 * switch to memory context appropriate for multiple function calls
1354 */
1355 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1356
1357 /* allocate memory for user context */
1358 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1359
1360 /*
1361 * Use fctx to keep state from call to call. Seed current with the
1362 * original start value
1363 */
1364 fctx->current = start;
1365 fctx->finish = finish;
1366 fctx->step = step;
1367
1368 funcctx->user_fctx = fctx;
1369 MemoryContextSwitchTo(oldcontext);
1370 }
1371
1372 /* stuff done on every call of the function */
1373 funcctx = SRF_PERCALL_SETUP();
1374
1375 /*
1376 * get the saved state and use current as the result for this iteration
1377 */
1378 fctx = funcctx->user_fctx;
1379 result = fctx->current;
1380
1381 if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1382 (fctx->step < 0 && fctx->current >= fctx->finish))
1383 {
1384 /* increment current in preparation for next iteration */
1385 fctx->current += fctx->step;
1386
1387 /* if next-value computation overflows, this is the final result */
1388 if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
1389 fctx->step = 0;
1390
1391 /* do when there is more left to send */
1392 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
1393 }
1394 else
1395 /* do when there is no more left */
1396 SRF_RETURN_DONE(funcctx);
1397 }
1398