1 /*-------------------------------------------------------------------------
4 * Functions for the built-in integer types (except int8).
6 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/int.c
13 *-------------------------------------------------------------------------
18 * int2in, int2out, int2recv, int2send
19 * int4in, int4out, int4recv, int4send
20 * int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
22 * inteq, intne, intlt, intle, intgt, intge
23 * Arithmetic operators:
24 * intpl, intmi, int4mul, intdiv
26 * Arithmetic operators:
34 #include "catalog/pg_type.h"
36 #include "libpq/pqformat.h"
37 #include "utils/array.h"
38 #include "utils/builtins.h"
41 #define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
43 #define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int2))
50 } generate_series_fctx;
53 /*****************************************************************************
55 *****************************************************************************/
58 * int2in - converts "num" to short
61 int2in(PG_FUNCTION_ARGS)
63 char *num = PG_GETARG_CSTRING(0);
65 PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
69 * int2out - converts short to "num"
72 int2out(PG_FUNCTION_ARGS)
74 int16 arg1 = PG_GETARG_INT16(0);
75 char *result = (char *) palloc(7); /* sign, 5 digits, '\0' */
77 pg_itoa(arg1, result);
78 PG_RETURN_CSTRING(result);
82 * int2recv - converts external binary format to int2
85 int2recv(PG_FUNCTION_ARGS)
87 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
89 PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
93 * int2send - converts int2 to binary format
96 int2send(PG_FUNCTION_ARGS)
98 int16 arg1 = PG_GETARG_INT16(0);
101 pq_begintypsend(&buf);
102 pq_sendint(&buf, arg1, sizeof(int16));
103 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
107 * construct int2vector given a raw array of int2s
109 * If int2s is NULL then caller must fill values[] afterward
112 buildint2vector(const int2 *int2s, int n)
116 result = (int2vector *) palloc0(Int2VectorSize(n));
119 memcpy(result->values, int2s, n * sizeof(int2));
122 * Attach standard array header. For historical reasons, we set the index
123 * lower bound to 0 not 1.
125 SET_VARSIZE(result, Int2VectorSize(n));
127 result->dataoffset = 0; /* never any nulls */
128 result->elemtype = INT2OID;
136 * int2vectorin - converts "num num ..." to internal form
139 int2vectorin(PG_FUNCTION_ARGS)
141 char *intString = PG_GETARG_CSTRING(0);
145 result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
147 for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)
149 while (*intString && isspace((unsigned char) *intString))
151 if (*intString == '\0')
153 result->values[n] = pg_atoi(intString, sizeof(int16), ' ');
154 while (*intString && !isspace((unsigned char) *intString))
157 while (*intString && isspace((unsigned char) *intString))
161 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
162 errmsg("int2vector has too many elements")));
164 SET_VARSIZE(result, Int2VectorSize(n));
166 result->dataoffset = 0; /* never any nulls */
167 result->elemtype = INT2OID;
171 PG_RETURN_POINTER(result);
175 * int2vectorout - converts internal form to "num num ..."
178 int2vectorout(PG_FUNCTION_ARGS)
180 int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
182 nnums = int2Array->dim1;
186 /* assumes sign, 5 digits, ' ' */
187 rp = result = (char *) palloc(nnums * 7 + 1);
188 for (num = 0; num < nnums; num++)
192 pg_itoa(int2Array->values[num], rp);
193 while (*++rp != '\0')
197 PG_RETURN_CSTRING(result);
201 * int2vectorrecv - converts external binary format to int2vector
204 int2vectorrecv(PG_FUNCTION_ARGS)
206 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
207 FunctionCallInfoData locfcinfo;
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
216 InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
217 InvalidOid, NULL, NULL);
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;
226 result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));
228 Assert(!locfcinfo.isnull);
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)
236 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
237 errmsg("invalid int2vector data")));
239 /* check length for consistency with int2vectorin() */
240 if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
242 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
243 errmsg("oidvector has too many elements")));
245 PG_RETURN_POINTER(result);
249 * int2vectorsend - converts int2vector to binary format
252 int2vectorsend(PG_FUNCTION_ARGS)
254 return array_send(fcinfo);
258 * We don't have a complete set of int2vector support routines,
259 * but we need int2vectoreq for catcache indexing.
262 int2vectoreq(PG_FUNCTION_ARGS)
264 int2vector *a = (int2vector *) PG_GETARG_POINTER(0);
265 int2vector *b = (int2vector *) PG_GETARG_POINTER(1);
267 if (a->dim1 != b->dim1)
268 PG_RETURN_BOOL(false);
269 PG_RETURN_BOOL(memcmp(a->values, b->values, a->dim1 * sizeof(int2)) == 0);
273 /*****************************************************************************
275 *****************************************************************************/
278 * int4in - converts "num" to int4
281 int4in(PG_FUNCTION_ARGS)
283 char *num = PG_GETARG_CSTRING(0);
285 PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
289 * int4out - converts int4 to "num"
292 int4out(PG_FUNCTION_ARGS)
294 int32 arg1 = PG_GETARG_INT32(0);
295 char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */
297 pg_ltoa(arg1, result);
298 PG_RETURN_CSTRING(result);
302 * int4recv - converts external binary format to int4
305 int4recv(PG_FUNCTION_ARGS)
307 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
309 PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
313 * int4send - converts int4 to binary format
316 int4send(PG_FUNCTION_ARGS)
318 int32 arg1 = PG_GETARG_INT32(0);
321 pq_begintypsend(&buf);
322 pq_sendint(&buf, arg1, sizeof(int32));
323 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
328 * ===================
329 * CONVERSION ROUTINES
330 * ===================
334 i2toi4(PG_FUNCTION_ARGS)
336 int16 arg1 = PG_GETARG_INT16(0);
338 PG_RETURN_INT32((int32) arg1);
342 i4toi2(PG_FUNCTION_ARGS)
344 int32 arg1 = PG_GETARG_INT32(0);
346 if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
348 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
349 errmsg("smallint out of range")));
351 PG_RETURN_INT16((int16) arg1);
354 /* Cast int4 -> bool */
356 int4_bool(PG_FUNCTION_ARGS)
358 if (PG_GETARG_INT32(0) == 0)
359 PG_RETURN_BOOL(false);
361 PG_RETURN_BOOL(true);
364 /* Cast bool -> int4 */
366 bool_int4(PG_FUNCTION_ARGS)
368 if (PG_GETARG_BOOL(0) == false)
375 * ============================
376 * COMPARISON OPERATOR ROUTINES
377 * ============================
381 * inteq - returns 1 iff arg1 == arg2
382 * intne - returns 1 iff arg1 != arg2
383 * intlt - returns 1 iff arg1 < arg2
384 * intle - returns 1 iff arg1 <= arg2
385 * intgt - returns 1 iff arg1 > arg2
386 * intge - returns 1 iff arg1 >= arg2
390 int4eq(PG_FUNCTION_ARGS)
392 int32 arg1 = PG_GETARG_INT32(0);
393 int32 arg2 = PG_GETARG_INT32(1);
395 PG_RETURN_BOOL(arg1 == arg2);
399 int4ne(PG_FUNCTION_ARGS)
401 int32 arg1 = PG_GETARG_INT32(0);
402 int32 arg2 = PG_GETARG_INT32(1);
404 PG_RETURN_BOOL(arg1 != arg2);
408 int4lt(PG_FUNCTION_ARGS)
410 int32 arg1 = PG_GETARG_INT32(0);
411 int32 arg2 = PG_GETARG_INT32(1);
413 PG_RETURN_BOOL(arg1 < arg2);
417 int4le(PG_FUNCTION_ARGS)
419 int32 arg1 = PG_GETARG_INT32(0);
420 int32 arg2 = PG_GETARG_INT32(1);
422 PG_RETURN_BOOL(arg1 <= arg2);
426 int4gt(PG_FUNCTION_ARGS)
428 int32 arg1 = PG_GETARG_INT32(0);
429 int32 arg2 = PG_GETARG_INT32(1);
431 PG_RETURN_BOOL(arg1 > arg2);
435 int4ge(PG_FUNCTION_ARGS)
437 int32 arg1 = PG_GETARG_INT32(0);
438 int32 arg2 = PG_GETARG_INT32(1);
440 PG_RETURN_BOOL(arg1 >= arg2);
444 int2eq(PG_FUNCTION_ARGS)
446 int16 arg1 = PG_GETARG_INT16(0);
447 int16 arg2 = PG_GETARG_INT16(1);
449 PG_RETURN_BOOL(arg1 == arg2);
453 int2ne(PG_FUNCTION_ARGS)
455 int16 arg1 = PG_GETARG_INT16(0);
456 int16 arg2 = PG_GETARG_INT16(1);
458 PG_RETURN_BOOL(arg1 != arg2);
462 int2lt(PG_FUNCTION_ARGS)
464 int16 arg1 = PG_GETARG_INT16(0);
465 int16 arg2 = PG_GETARG_INT16(1);
467 PG_RETURN_BOOL(arg1 < arg2);
471 int2le(PG_FUNCTION_ARGS)
473 int16 arg1 = PG_GETARG_INT16(0);
474 int16 arg2 = PG_GETARG_INT16(1);
476 PG_RETURN_BOOL(arg1 <= arg2);
480 int2gt(PG_FUNCTION_ARGS)
482 int16 arg1 = PG_GETARG_INT16(0);
483 int16 arg2 = PG_GETARG_INT16(1);
485 PG_RETURN_BOOL(arg1 > arg2);
489 int2ge(PG_FUNCTION_ARGS)
491 int16 arg1 = PG_GETARG_INT16(0);
492 int16 arg2 = PG_GETARG_INT16(1);
494 PG_RETURN_BOOL(arg1 >= arg2);
498 int24eq(PG_FUNCTION_ARGS)
500 int16 arg1 = PG_GETARG_INT16(0);
501 int32 arg2 = PG_GETARG_INT32(1);
503 PG_RETURN_BOOL(arg1 == arg2);
507 int24ne(PG_FUNCTION_ARGS)
509 int16 arg1 = PG_GETARG_INT16(0);
510 int32 arg2 = PG_GETARG_INT32(1);
512 PG_RETURN_BOOL(arg1 != arg2);
516 int24lt(PG_FUNCTION_ARGS)
518 int16 arg1 = PG_GETARG_INT16(0);
519 int32 arg2 = PG_GETARG_INT32(1);
521 PG_RETURN_BOOL(arg1 < arg2);
525 int24le(PG_FUNCTION_ARGS)
527 int16 arg1 = PG_GETARG_INT16(0);
528 int32 arg2 = PG_GETARG_INT32(1);
530 PG_RETURN_BOOL(arg1 <= arg2);
534 int24gt(PG_FUNCTION_ARGS)
536 int16 arg1 = PG_GETARG_INT16(0);
537 int32 arg2 = PG_GETARG_INT32(1);
539 PG_RETURN_BOOL(arg1 > arg2);
543 int24ge(PG_FUNCTION_ARGS)
545 int16 arg1 = PG_GETARG_INT16(0);
546 int32 arg2 = PG_GETARG_INT32(1);
548 PG_RETURN_BOOL(arg1 >= arg2);
552 int42eq(PG_FUNCTION_ARGS)
554 int32 arg1 = PG_GETARG_INT32(0);
555 int16 arg2 = PG_GETARG_INT16(1);
557 PG_RETURN_BOOL(arg1 == arg2);
561 int42ne(PG_FUNCTION_ARGS)
563 int32 arg1 = PG_GETARG_INT32(0);
564 int16 arg2 = PG_GETARG_INT16(1);
566 PG_RETURN_BOOL(arg1 != arg2);
570 int42lt(PG_FUNCTION_ARGS)
572 int32 arg1 = PG_GETARG_INT32(0);
573 int16 arg2 = PG_GETARG_INT16(1);
575 PG_RETURN_BOOL(arg1 < arg2);
579 int42le(PG_FUNCTION_ARGS)
581 int32 arg1 = PG_GETARG_INT32(0);
582 int16 arg2 = PG_GETARG_INT16(1);
584 PG_RETURN_BOOL(arg1 <= arg2);
588 int42gt(PG_FUNCTION_ARGS)
590 int32 arg1 = PG_GETARG_INT32(0);
591 int16 arg2 = PG_GETARG_INT16(1);
593 PG_RETURN_BOOL(arg1 > arg2);
597 int42ge(PG_FUNCTION_ARGS)
599 int32 arg1 = PG_GETARG_INT32(0);
600 int16 arg2 = PG_GETARG_INT16(1);
602 PG_RETURN_BOOL(arg1 >= arg2);
606 * int[24]pl - returns arg1 + arg2
607 * int[24]mi - returns arg1 - arg2
608 * int[24]mul - returns arg1 * arg2
609 * int[24]div - returns arg1 / arg2
613 int4um(PG_FUNCTION_ARGS)
615 int32 arg = PG_GETARG_INT32(0);
619 /* overflow check (needed for INT_MIN) */
620 if (arg != 0 && SAMESIGN(result, arg))
622 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
623 errmsg("integer out of range")));
624 PG_RETURN_INT32(result);
628 int4up(PG_FUNCTION_ARGS)
630 int32 arg = PG_GETARG_INT32(0);
632 PG_RETURN_INT32(arg);
636 int4pl(PG_FUNCTION_ARGS)
638 int32 arg1 = PG_GETARG_INT32(0);
639 int32 arg2 = PG_GETARG_INT32(1);
642 result = arg1 + arg2;
645 * Overflow check. If the inputs are of different signs then their sum
646 * cannot overflow. If the inputs are of the same sign, their sum had
647 * better be that sign too.
649 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
651 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
652 errmsg("integer out of range")));
653 PG_RETURN_INT32(result);
657 int4mi(PG_FUNCTION_ARGS)
659 int32 arg1 = PG_GETARG_INT32(0);
660 int32 arg2 = PG_GETARG_INT32(1);
663 result = arg1 - arg2;
666 * Overflow check. If the inputs are of the same sign then their
667 * difference cannot overflow. If they are of different signs then the
668 * result should be of the same sign as the first input.
670 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
672 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
673 errmsg("integer out of range")));
674 PG_RETURN_INT32(result);
678 int4mul(PG_FUNCTION_ARGS)
680 int32 arg1 = PG_GETARG_INT32(0);
681 int32 arg2 = PG_GETARG_INT32(1);
687 * Win32 doesn't throw a catchable exception for SELECT -2147483648 *
690 if (arg2 == -1 && arg1 == INT_MIN)
692 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
693 errmsg("integer out of range")));
696 result = arg1 * arg2;
699 * Overflow check. We basically check to see if result / arg2 gives arg1
700 * again. There are two cases where this fails: arg2 = 0 (which cannot
701 * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will
702 * overflow and thus incorrectly match).
704 * Since the division is likely much more expensive than the actual
705 * multiplication, we'd like to skip it where possible. The best bang for
706 * the buck seems to be to check whether both inputs are in the int16
707 * range; if so, no overflow is possible.
709 if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
710 arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
712 (result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
714 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
715 errmsg("integer out of range")));
716 PG_RETURN_INT32(result);
720 int4div(PG_FUNCTION_ARGS)
722 int32 arg1 = PG_GETARG_INT32(0);
723 int32 arg2 = PG_GETARG_INT32(1);
729 (errcode(ERRCODE_DIVISION_BY_ZERO),
730 errmsg("division by zero")));
731 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
738 * Win32 doesn't throw a catchable exception for SELECT -2147483648 /
741 if (arg2 == -1 && arg1 == INT_MIN)
743 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
744 errmsg("integer out of range")));
747 result = arg1 / arg2;
750 * Overflow check. The only possible overflow case is for arg1 = INT_MIN,
751 * arg2 = -1, where the correct result is -INT_MIN, which can't be
752 * represented on a two's-complement machine. Most machines produce
753 * INT_MIN but it seems some produce zero.
755 if (arg2 == -1 && arg1 < 0 && result <= 0)
757 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
758 errmsg("integer out of range")));
759 PG_RETURN_INT32(result);
763 int4inc(PG_FUNCTION_ARGS)
765 int32 arg = PG_GETARG_INT32(0);
770 if (arg > 0 && result < 0)
772 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
773 errmsg("integer out of range")));
775 PG_RETURN_INT32(result);
779 int2um(PG_FUNCTION_ARGS)
781 int16 arg = PG_GETARG_INT16(0);
785 /* overflow check (needed for SHRT_MIN) */
786 if (arg != 0 && SAMESIGN(result, arg))
788 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
789 errmsg("smallint out of range")));
790 PG_RETURN_INT16(result);
794 int2up(PG_FUNCTION_ARGS)
796 int16 arg = PG_GETARG_INT16(0);
798 PG_RETURN_INT16(arg);
802 int2pl(PG_FUNCTION_ARGS)
804 int16 arg1 = PG_GETARG_INT16(0);
805 int16 arg2 = PG_GETARG_INT16(1);
808 result = arg1 + arg2;
811 * Overflow check. If the inputs are of different signs then their sum
812 * cannot overflow. If the inputs are of the same sign, their sum had
813 * better be that sign too.
815 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
817 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
818 errmsg("smallint out of range")));
819 PG_RETURN_INT16(result);
823 int2mi(PG_FUNCTION_ARGS)
825 int16 arg1 = PG_GETARG_INT16(0);
826 int16 arg2 = PG_GETARG_INT16(1);
829 result = arg1 - arg2;
832 * Overflow check. If the inputs are of the same sign then their
833 * difference cannot overflow. If they are of different signs then the
834 * result should be of the same sign as the first input.
836 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
838 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
839 errmsg("smallint out of range")));
840 PG_RETURN_INT16(result);
844 int2mul(PG_FUNCTION_ARGS)
846 int16 arg1 = PG_GETARG_INT16(0);
847 int16 arg2 = PG_GETARG_INT16(1);
851 * The most practical way to detect overflow is to do the arithmetic in
852 * int32 (so that the result can't overflow) and then do a range check.
854 result32 = (int32) arg1 *(int32) arg2;
856 if (result32 < SHRT_MIN || result32 > SHRT_MAX)
858 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
859 errmsg("smallint out of range")));
861 PG_RETURN_INT16((int16) result32);
865 int2div(PG_FUNCTION_ARGS)
867 int16 arg1 = PG_GETARG_INT16(0);
868 int16 arg2 = PG_GETARG_INT16(1);
874 (errcode(ERRCODE_DIVISION_BY_ZERO),
875 errmsg("division by zero")));
876 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
880 result = arg1 / arg2;
883 * Overflow check. The only possible overflow case is for arg1 =
884 * SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN, which can't
885 * be represented on a two's-complement machine. Most machines produce
886 * SHRT_MIN but it seems some produce zero.
888 if (arg2 == -1 && arg1 < 0 && result <= 0)
890 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
891 errmsg("smallint out of range")));
892 PG_RETURN_INT16(result);
896 int24pl(PG_FUNCTION_ARGS)
898 int16 arg1 = PG_GETARG_INT16(0);
899 int32 arg2 = PG_GETARG_INT32(1);
902 result = arg1 + arg2;
905 * Overflow check. If the inputs are of different signs then their sum
906 * cannot overflow. If the inputs are of the same sign, their sum had
907 * better be that sign too.
909 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
911 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
912 errmsg("integer out of range")));
913 PG_RETURN_INT32(result);
917 int24mi(PG_FUNCTION_ARGS)
919 int16 arg1 = PG_GETARG_INT16(0);
920 int32 arg2 = PG_GETARG_INT32(1);
923 result = arg1 - arg2;
926 * Overflow check. If the inputs are of the same sign then their
927 * difference cannot overflow. If they are of different signs then the
928 * result should be of the same sign as the first input.
930 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
932 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
933 errmsg("integer out of range")));
934 PG_RETURN_INT32(result);
938 int24mul(PG_FUNCTION_ARGS)
940 int16 arg1 = PG_GETARG_INT16(0);
941 int32 arg2 = PG_GETARG_INT32(1);
944 result = arg1 * arg2;
947 * Overflow check. We basically check to see if result / arg2 gives arg1
948 * again. There is one case where this fails: arg2 = 0 (which cannot
951 * Since the division is likely much more expensive than the actual
952 * multiplication, we'd like to skip it where possible. The best bang for
953 * the buck seems to be to check whether both inputs are in the int16
954 * range; if so, no overflow is possible.
956 if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
957 result / arg2 != arg1)
959 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
960 errmsg("integer out of range")));
961 PG_RETURN_INT32(result);
965 int24div(PG_FUNCTION_ARGS)
967 int16 arg1 = PG_GETARG_INT16(0);
968 int32 arg2 = PG_GETARG_INT32(1);
973 (errcode(ERRCODE_DIVISION_BY_ZERO),
974 errmsg("division by zero")));
975 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
979 /* No overflow is possible */
980 PG_RETURN_INT32((int32) arg1 / arg2);
984 int42pl(PG_FUNCTION_ARGS)
986 int32 arg1 = PG_GETARG_INT32(0);
987 int16 arg2 = PG_GETARG_INT16(1);
990 result = arg1 + arg2;
993 * Overflow check. If the inputs are of different signs then their sum
994 * cannot overflow. If the inputs are of the same sign, their sum had
995 * better be that sign too.
997 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
999 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1000 errmsg("integer out of range")));
1001 PG_RETURN_INT32(result);
1005 int42mi(PG_FUNCTION_ARGS)
1007 int32 arg1 = PG_GETARG_INT32(0);
1008 int16 arg2 = PG_GETARG_INT16(1);
1011 result = arg1 - arg2;
1014 * Overflow check. If the inputs are of the same sign then their
1015 * difference cannot overflow. If they are of different signs then the
1016 * result should be of the same sign as the first input.
1018 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1020 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1021 errmsg("integer out of range")));
1022 PG_RETURN_INT32(result);
1026 int42mul(PG_FUNCTION_ARGS)
1028 int32 arg1 = PG_GETARG_INT32(0);
1029 int16 arg2 = PG_GETARG_INT16(1);
1032 result = arg1 * arg2;
1035 * Overflow check. We basically check to see if result / arg1 gives arg2
1036 * again. There is one case where this fails: arg1 = 0 (which cannot
1039 * Since the division is likely much more expensive than the actual
1040 * multiplication, we'd like to skip it where possible. The best bang for
1041 * the buck seems to be to check whether both inputs are in the int16
1042 * range; if so, no overflow is possible.
1044 if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
1045 result / arg1 != arg2)
1047 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1048 errmsg("integer out of range")));
1049 PG_RETURN_INT32(result);
1053 int42div(PG_FUNCTION_ARGS)
1055 int32 arg1 = PG_GETARG_INT32(0);
1056 int16 arg2 = PG_GETARG_INT16(1);
1062 (errcode(ERRCODE_DIVISION_BY_ZERO),
1063 errmsg("division by zero")));
1064 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1068 result = arg1 / arg2;
1071 * Overflow check. The only possible overflow case is for arg1 = INT_MIN,
1072 * arg2 = -1, where the correct result is -INT_MIN, which can't be
1073 * represented on a two's-complement machine. Most machines produce
1074 * INT_MIN but it seems some produce zero.
1076 if (arg2 == -1 && arg1 < 0 && result <= 0)
1078 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1079 errmsg("integer out of range")));
1080 PG_RETURN_INT32(result);
1084 int4mod(PG_FUNCTION_ARGS)
1086 int32 arg1 = PG_GETARG_INT32(0);
1087 int32 arg2 = PG_GETARG_INT32(1);
1092 (errcode(ERRCODE_DIVISION_BY_ZERO),
1093 errmsg("division by zero")));
1094 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1098 /* SELECT ((-2147483648)::int4) % (-1); causes a floating point exception */
1099 if (arg1 == INT_MIN && arg2 == -1)
1102 /* No overflow is possible */
1104 PG_RETURN_INT32(arg1 % arg2);
1108 int2mod(PG_FUNCTION_ARGS)
1110 int16 arg1 = PG_GETARG_INT16(0);
1111 int16 arg2 = PG_GETARG_INT16(1);
1116 (errcode(ERRCODE_DIVISION_BY_ZERO),
1117 errmsg("division by zero")));
1118 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1122 /* No overflow is possible */
1124 PG_RETURN_INT16(arg1 % arg2);
1132 int4abs(PG_FUNCTION_ARGS)
1134 int32 arg1 = PG_GETARG_INT32(0);
1137 result = (arg1 < 0) ? -arg1 : arg1;
1138 /* overflow check (needed for INT_MIN) */
1141 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1142 errmsg("integer out of range")));
1143 PG_RETURN_INT32(result);
1147 int2abs(PG_FUNCTION_ARGS)
1149 int16 arg1 = PG_GETARG_INT16(0);
1152 result = (arg1 < 0) ? -arg1 : arg1;
1153 /* overflow check (needed for SHRT_MIN) */
1156 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1157 errmsg("smallint out of range")));
1158 PG_RETURN_INT16(result);
1162 int2larger(PG_FUNCTION_ARGS)
1164 int16 arg1 = PG_GETARG_INT16(0);
1165 int16 arg2 = PG_GETARG_INT16(1);
1167 PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
1171 int2smaller(PG_FUNCTION_ARGS)
1173 int16 arg1 = PG_GETARG_INT16(0);
1174 int16 arg2 = PG_GETARG_INT16(1);
1176 PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
1180 int4larger(PG_FUNCTION_ARGS)
1182 int32 arg1 = PG_GETARG_INT32(0);
1183 int32 arg2 = PG_GETARG_INT32(1);
1185 PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
1189 int4smaller(PG_FUNCTION_ARGS)
1191 int32 arg1 = PG_GETARG_INT32(0);
1192 int32 arg2 = PG_GETARG_INT32(1);
1194 PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
1198 * Bit-pushing operators
1200 * int[24]and - returns arg1 & arg2
1201 * int[24]or - returns arg1 | arg2
1202 * int[24]xor - returns arg1 # arg2
1203 * int[24]not - returns ~arg1
1204 * int[24]shl - returns arg1 << arg2
1205 * int[24]shr - returns arg1 >> arg2
1209 int4and(PG_FUNCTION_ARGS)
1211 int32 arg1 = PG_GETARG_INT32(0);
1212 int32 arg2 = PG_GETARG_INT32(1);
1214 PG_RETURN_INT32(arg1 & arg2);
1218 int4or(PG_FUNCTION_ARGS)
1220 int32 arg1 = PG_GETARG_INT32(0);
1221 int32 arg2 = PG_GETARG_INT32(1);
1223 PG_RETURN_INT32(arg1 | arg2);
1227 int4xor(PG_FUNCTION_ARGS)
1229 int32 arg1 = PG_GETARG_INT32(0);
1230 int32 arg2 = PG_GETARG_INT32(1);
1232 PG_RETURN_INT32(arg1 ^ arg2);
1236 int4shl(PG_FUNCTION_ARGS)
1238 int32 arg1 = PG_GETARG_INT32(0);
1239 int32 arg2 = PG_GETARG_INT32(1);
1241 PG_RETURN_INT32(arg1 << arg2);
1245 int4shr(PG_FUNCTION_ARGS)
1247 int32 arg1 = PG_GETARG_INT32(0);
1248 int32 arg2 = PG_GETARG_INT32(1);
1250 PG_RETURN_INT32(arg1 >> arg2);
1254 int4not(PG_FUNCTION_ARGS)
1256 int32 arg1 = PG_GETARG_INT32(0);
1258 PG_RETURN_INT32(~arg1);
1262 int2and(PG_FUNCTION_ARGS)
1264 int16 arg1 = PG_GETARG_INT16(0);
1265 int16 arg2 = PG_GETARG_INT16(1);
1267 PG_RETURN_INT16(arg1 & arg2);
1271 int2or(PG_FUNCTION_ARGS)
1273 int16 arg1 = PG_GETARG_INT16(0);
1274 int16 arg2 = PG_GETARG_INT16(1);
1276 PG_RETURN_INT16(arg1 | arg2);
1280 int2xor(PG_FUNCTION_ARGS)
1282 int16 arg1 = PG_GETARG_INT16(0);
1283 int16 arg2 = PG_GETARG_INT16(1);
1285 PG_RETURN_INT16(arg1 ^ arg2);
1289 int2not(PG_FUNCTION_ARGS)
1291 int16 arg1 = PG_GETARG_INT16(0);
1293 PG_RETURN_INT16(~arg1);
1298 int2shl(PG_FUNCTION_ARGS)
1300 int16 arg1 = PG_GETARG_INT16(0);
1301 int32 arg2 = PG_GETARG_INT32(1);
1303 PG_RETURN_INT16(arg1 << arg2);
1307 int2shr(PG_FUNCTION_ARGS)
1309 int16 arg1 = PG_GETARG_INT16(0);
1310 int32 arg2 = PG_GETARG_INT32(1);
1312 PG_RETURN_INT16(arg1 >> arg2);
1316 * non-persistent numeric series generator
1319 generate_series_int4(PG_FUNCTION_ARGS)
1321 return generate_series_step_int4(fcinfo);
1325 generate_series_step_int4(PG_FUNCTION_ARGS)
1327 FuncCallContext *funcctx;
1328 generate_series_fctx *fctx;
1330 MemoryContext oldcontext;
1332 /* stuff done only on the first call of the function */
1333 if (SRF_IS_FIRSTCALL())
1335 int32 start = PG_GETARG_INT32(0);
1336 int32 finish = PG_GETARG_INT32(1);
1339 /* see if we were given an explicit step size */
1340 if (PG_NARGS() == 3)
1341 step = PG_GETARG_INT32(2);
1344 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1345 errmsg("step size cannot equal zero")));
1347 /* create a function context for cross-call persistence */
1348 funcctx = SRF_FIRSTCALL_INIT();
1351 * switch to memory context appropriate for multiple function calls
1353 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1355 /* allocate memory for user context */
1356 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1359 * Use fctx to keep state from call to call. Seed current with the
1360 * original start value
1362 fctx->current = start;
1363 fctx->finish = finish;
1366 funcctx->user_fctx = fctx;
1367 MemoryContextSwitchTo(oldcontext);
1370 /* stuff done on every call of the function */
1371 funcctx = SRF_PERCALL_SETUP();
1374 * get the saved state and use current as the result for this iteration
1376 fctx = funcctx->user_fctx;
1377 result = fctx->current;
1379 if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1380 (fctx->step < 0 && fctx->current >= fctx->finish))
1382 /* increment current in preparation for next iteration */
1383 fctx->current += fctx->step;
1385 /* do when there is more left to send */
1386 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
1389 /* do when there is no more left */
1390 SRF_RETURN_DONE(funcctx);