1 /*-------------------------------------------------------------------------
4 * Functions for the built-in integer types (except int8).
6 * Portions Copyright (c) 1996-2014, 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(int16))
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 int16 *int2s, int n)
116 result = (int2vector *) palloc0(Int2VectorSize(n));
119 memcpy(result->values, int2s, n * sizeof(int16));
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(int16)) == 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);
684 result = arg1 * arg2;
687 * Overflow check. We basically check to see if result / arg2 gives arg1
688 * again. There are two cases where this fails: arg2 = 0 (which cannot
689 * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will
690 * overflow and thus incorrectly match).
692 * Since the division is likely much more expensive than the actual
693 * multiplication, we'd like to skip it where possible. The best bang for
694 * the buck seems to be to check whether both inputs are in the int16
695 * range; if so, no overflow is possible.
697 if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
698 arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
700 ((arg2 == -1 && arg1 < 0 && result < 0) ||
701 result / arg2 != arg1))
703 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
704 errmsg("integer out of range")));
705 PG_RETURN_INT32(result);
709 int4div(PG_FUNCTION_ARGS)
711 int32 arg1 = PG_GETARG_INT32(0);
712 int32 arg2 = PG_GETARG_INT32(1);
718 (errcode(ERRCODE_DIVISION_BY_ZERO),
719 errmsg("division by zero")));
720 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
725 * INT_MIN / -1 is problematic, since the result can't be represented on a
726 * two's-complement machine. Some machines produce INT_MIN, some produce
727 * zero, some throw an exception. We can dodge the problem by recognizing
728 * that division by -1 is the same as negation.
733 /* overflow check (needed for INT_MIN) */
734 if (arg1 != 0 && SAMESIGN(result, arg1))
736 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
737 errmsg("integer out of range")));
738 PG_RETURN_INT32(result);
741 /* No overflow is possible */
743 result = arg1 / arg2;
745 PG_RETURN_INT32(result);
749 int4inc(PG_FUNCTION_ARGS)
751 int32 arg = PG_GETARG_INT32(0);
756 if (arg > 0 && result < 0)
758 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
759 errmsg("integer out of range")));
761 PG_RETURN_INT32(result);
765 int2um(PG_FUNCTION_ARGS)
767 int16 arg = PG_GETARG_INT16(0);
771 /* overflow check (needed for SHRT_MIN) */
772 if (arg != 0 && SAMESIGN(result, arg))
774 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
775 errmsg("smallint out of range")));
776 PG_RETURN_INT16(result);
780 int2up(PG_FUNCTION_ARGS)
782 int16 arg = PG_GETARG_INT16(0);
784 PG_RETURN_INT16(arg);
788 int2pl(PG_FUNCTION_ARGS)
790 int16 arg1 = PG_GETARG_INT16(0);
791 int16 arg2 = PG_GETARG_INT16(1);
794 result = arg1 + arg2;
797 * Overflow check. If the inputs are of different signs then their sum
798 * cannot overflow. If the inputs are of the same sign, their sum had
799 * better be that sign too.
801 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
803 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
804 errmsg("smallint out of range")));
805 PG_RETURN_INT16(result);
809 int2mi(PG_FUNCTION_ARGS)
811 int16 arg1 = PG_GETARG_INT16(0);
812 int16 arg2 = PG_GETARG_INT16(1);
815 result = arg1 - arg2;
818 * Overflow check. If the inputs are of the same sign then their
819 * difference cannot overflow. If they are of different signs then the
820 * result should be of the same sign as the first input.
822 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
824 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
825 errmsg("smallint out of range")));
826 PG_RETURN_INT16(result);
830 int2mul(PG_FUNCTION_ARGS)
832 int16 arg1 = PG_GETARG_INT16(0);
833 int16 arg2 = PG_GETARG_INT16(1);
837 * The most practical way to detect overflow is to do the arithmetic in
838 * int32 (so that the result can't overflow) and then do a range check.
840 result32 = (int32) arg1 *(int32) arg2;
842 if (result32 < SHRT_MIN || result32 > SHRT_MAX)
844 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
845 errmsg("smallint out of range")));
847 PG_RETURN_INT16((int16) result32);
851 int2div(PG_FUNCTION_ARGS)
853 int16 arg1 = PG_GETARG_INT16(0);
854 int16 arg2 = PG_GETARG_INT16(1);
860 (errcode(ERRCODE_DIVISION_BY_ZERO),
861 errmsg("division by zero")));
862 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
867 * SHRT_MIN / -1 is problematic, since the result can't be represented on
868 * a two's-complement machine. Some machines produce SHRT_MIN, some
869 * produce zero, some throw an exception. We can dodge the problem by
870 * recognizing that division by -1 is the same as negation.
875 /* overflow check (needed for SHRT_MIN) */
876 if (arg1 != 0 && SAMESIGN(result, arg1))
878 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
879 errmsg("smallint out of range")));
880 PG_RETURN_INT16(result);
883 /* No overflow is possible */
885 result = arg1 / arg2;
887 PG_RETURN_INT16(result);
891 int24pl(PG_FUNCTION_ARGS)
893 int16 arg1 = PG_GETARG_INT16(0);
894 int32 arg2 = PG_GETARG_INT32(1);
897 result = arg1 + arg2;
900 * Overflow check. If the inputs are of different signs then their sum
901 * cannot overflow. If the inputs are of the same sign, their sum had
902 * better be that sign too.
904 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
906 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
907 errmsg("integer out of range")));
908 PG_RETURN_INT32(result);
912 int24mi(PG_FUNCTION_ARGS)
914 int16 arg1 = PG_GETARG_INT16(0);
915 int32 arg2 = PG_GETARG_INT32(1);
918 result = arg1 - arg2;
921 * Overflow check. If the inputs are of the same sign then their
922 * difference cannot overflow. If they are of different signs then the
923 * result should be of the same sign as the first input.
925 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
927 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
928 errmsg("integer out of range")));
929 PG_RETURN_INT32(result);
933 int24mul(PG_FUNCTION_ARGS)
935 int16 arg1 = PG_GETARG_INT16(0);
936 int32 arg2 = PG_GETARG_INT32(1);
939 result = arg1 * arg2;
942 * Overflow check. We basically check to see if result / arg2 gives arg1
943 * again. There is one case where this fails: arg2 = 0 (which cannot
946 * Since the division is likely much more expensive than the actual
947 * multiplication, we'd like to skip it where possible. The best bang for
948 * the buck seems to be to check whether both inputs are in the int16
949 * range; if so, no overflow is possible.
951 if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
952 result / arg2 != arg1)
954 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
955 errmsg("integer out of range")));
956 PG_RETURN_INT32(result);
960 int24div(PG_FUNCTION_ARGS)
962 int16 arg1 = PG_GETARG_INT16(0);
963 int32 arg2 = PG_GETARG_INT32(1);
968 (errcode(ERRCODE_DIVISION_BY_ZERO),
969 errmsg("division by zero")));
970 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
974 /* No overflow is possible */
975 PG_RETURN_INT32((int32) arg1 / arg2);
979 int42pl(PG_FUNCTION_ARGS)
981 int32 arg1 = PG_GETARG_INT32(0);
982 int16 arg2 = PG_GETARG_INT16(1);
985 result = arg1 + arg2;
988 * Overflow check. If the inputs are of different signs then their sum
989 * cannot overflow. If the inputs are of the same sign, their sum had
990 * better be that sign too.
992 if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
994 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
995 errmsg("integer out of range")));
996 PG_RETURN_INT32(result);
1000 int42mi(PG_FUNCTION_ARGS)
1002 int32 arg1 = PG_GETARG_INT32(0);
1003 int16 arg2 = PG_GETARG_INT16(1);
1006 result = arg1 - arg2;
1009 * Overflow check. If the inputs are of the same sign then their
1010 * difference cannot overflow. If they are of different signs then the
1011 * result should be of the same sign as the first input.
1013 if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
1015 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1016 errmsg("integer out of range")));
1017 PG_RETURN_INT32(result);
1021 int42mul(PG_FUNCTION_ARGS)
1023 int32 arg1 = PG_GETARG_INT32(0);
1024 int16 arg2 = PG_GETARG_INT16(1);
1027 result = arg1 * arg2;
1030 * Overflow check. We basically check to see if result / arg1 gives arg2
1031 * again. There is one case where this fails: arg1 = 0 (which cannot
1034 * Since the division is likely much more expensive than the actual
1035 * multiplication, we'd like to skip it where possible. The best bang for
1036 * the buck seems to be to check whether both inputs are in the int16
1037 * range; if so, no overflow is possible.
1039 if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
1040 result / arg1 != arg2)
1042 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1043 errmsg("integer out of range")));
1044 PG_RETURN_INT32(result);
1048 int42div(PG_FUNCTION_ARGS)
1050 int32 arg1 = PG_GETARG_INT32(0);
1051 int16 arg2 = PG_GETARG_INT16(1);
1057 (errcode(ERRCODE_DIVISION_BY_ZERO),
1058 errmsg("division by zero")));
1059 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1064 * INT_MIN / -1 is problematic, since the result can't be represented on a
1065 * two's-complement machine. Some machines produce INT_MIN, some produce
1066 * zero, some throw an exception. We can dodge the problem by recognizing
1067 * that division by -1 is the same as negation.
1072 /* overflow check (needed for INT_MIN) */
1073 if (arg1 != 0 && SAMESIGN(result, arg1))
1075 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1076 errmsg("integer out of range")));
1077 PG_RETURN_INT32(result);
1080 /* No overflow is possible */
1082 result = arg1 / arg2;
1084 PG_RETURN_INT32(result);
1088 int4mod(PG_FUNCTION_ARGS)
1090 int32 arg1 = PG_GETARG_INT32(0);
1091 int32 arg2 = PG_GETARG_INT32(1);
1096 (errcode(ERRCODE_DIVISION_BY_ZERO),
1097 errmsg("division by zero")));
1098 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1103 * Some machines throw a floating-point exception for INT_MIN % -1, which
1104 * is a bit silly since the correct answer is perfectly well-defined,
1110 /* No overflow is possible */
1112 PG_RETURN_INT32(arg1 % arg2);
1116 int2mod(PG_FUNCTION_ARGS)
1118 int16 arg1 = PG_GETARG_INT16(0);
1119 int16 arg2 = PG_GETARG_INT16(1);
1124 (errcode(ERRCODE_DIVISION_BY_ZERO),
1125 errmsg("division by zero")));
1126 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1131 * Some machines throw a floating-point exception for INT_MIN % -1, which
1132 * is a bit silly since the correct answer is perfectly well-defined,
1133 * namely zero. (It's not clear this ever happens when dealing with
1134 * int16, but we might as well have the test for safety.)
1139 /* No overflow is possible */
1141 PG_RETURN_INT16(arg1 % arg2);
1149 int4abs(PG_FUNCTION_ARGS)
1151 int32 arg1 = PG_GETARG_INT32(0);
1154 result = (arg1 < 0) ? -arg1 : arg1;
1155 /* overflow check (needed for INT_MIN) */
1158 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1159 errmsg("integer out of range")));
1160 PG_RETURN_INT32(result);
1164 int2abs(PG_FUNCTION_ARGS)
1166 int16 arg1 = PG_GETARG_INT16(0);
1169 result = (arg1 < 0) ? -arg1 : arg1;
1170 /* overflow check (needed for SHRT_MIN) */
1173 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1174 errmsg("smallint out of range")));
1175 PG_RETURN_INT16(result);
1179 int2larger(PG_FUNCTION_ARGS)
1181 int16 arg1 = PG_GETARG_INT16(0);
1182 int16 arg2 = PG_GETARG_INT16(1);
1184 PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
1188 int2smaller(PG_FUNCTION_ARGS)
1190 int16 arg1 = PG_GETARG_INT16(0);
1191 int16 arg2 = PG_GETARG_INT16(1);
1193 PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
1197 int4larger(PG_FUNCTION_ARGS)
1199 int32 arg1 = PG_GETARG_INT32(0);
1200 int32 arg2 = PG_GETARG_INT32(1);
1202 PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
1206 int4smaller(PG_FUNCTION_ARGS)
1208 int32 arg1 = PG_GETARG_INT32(0);
1209 int32 arg2 = PG_GETARG_INT32(1);
1211 PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
1215 * Bit-pushing operators
1217 * int[24]and - returns arg1 & arg2
1218 * int[24]or - returns arg1 | arg2
1219 * int[24]xor - returns arg1 # arg2
1220 * int[24]not - returns ~arg1
1221 * int[24]shl - returns arg1 << arg2
1222 * int[24]shr - returns arg1 >> arg2
1226 int4and(PG_FUNCTION_ARGS)
1228 int32 arg1 = PG_GETARG_INT32(0);
1229 int32 arg2 = PG_GETARG_INT32(1);
1231 PG_RETURN_INT32(arg1 & arg2);
1235 int4or(PG_FUNCTION_ARGS)
1237 int32 arg1 = PG_GETARG_INT32(0);
1238 int32 arg2 = PG_GETARG_INT32(1);
1240 PG_RETURN_INT32(arg1 | arg2);
1244 int4xor(PG_FUNCTION_ARGS)
1246 int32 arg1 = PG_GETARG_INT32(0);
1247 int32 arg2 = PG_GETARG_INT32(1);
1249 PG_RETURN_INT32(arg1 ^ arg2);
1253 int4shl(PG_FUNCTION_ARGS)
1255 int32 arg1 = PG_GETARG_INT32(0);
1256 int32 arg2 = PG_GETARG_INT32(1);
1258 PG_RETURN_INT32(arg1 << arg2);
1262 int4shr(PG_FUNCTION_ARGS)
1264 int32 arg1 = PG_GETARG_INT32(0);
1265 int32 arg2 = PG_GETARG_INT32(1);
1267 PG_RETURN_INT32(arg1 >> arg2);
1271 int4not(PG_FUNCTION_ARGS)
1273 int32 arg1 = PG_GETARG_INT32(0);
1275 PG_RETURN_INT32(~arg1);
1279 int2and(PG_FUNCTION_ARGS)
1281 int16 arg1 = PG_GETARG_INT16(0);
1282 int16 arg2 = PG_GETARG_INT16(1);
1284 PG_RETURN_INT16(arg1 & arg2);
1288 int2or(PG_FUNCTION_ARGS)
1290 int16 arg1 = PG_GETARG_INT16(0);
1291 int16 arg2 = PG_GETARG_INT16(1);
1293 PG_RETURN_INT16(arg1 | arg2);
1297 int2xor(PG_FUNCTION_ARGS)
1299 int16 arg1 = PG_GETARG_INT16(0);
1300 int16 arg2 = PG_GETARG_INT16(1);
1302 PG_RETURN_INT16(arg1 ^ arg2);
1306 int2not(PG_FUNCTION_ARGS)
1308 int16 arg1 = PG_GETARG_INT16(0);
1310 PG_RETURN_INT16(~arg1);
1315 int2shl(PG_FUNCTION_ARGS)
1317 int16 arg1 = PG_GETARG_INT16(0);
1318 int32 arg2 = PG_GETARG_INT32(1);
1320 PG_RETURN_INT16(arg1 << arg2);
1324 int2shr(PG_FUNCTION_ARGS)
1326 int16 arg1 = PG_GETARG_INT16(0);
1327 int32 arg2 = PG_GETARG_INT32(1);
1329 PG_RETURN_INT16(arg1 >> arg2);
1333 * non-persistent numeric series generator
1336 generate_series_int4(PG_FUNCTION_ARGS)
1338 return generate_series_step_int4(fcinfo);
1342 generate_series_step_int4(PG_FUNCTION_ARGS)
1344 FuncCallContext *funcctx;
1345 generate_series_fctx *fctx;
1347 MemoryContext oldcontext;
1349 /* stuff done only on the first call of the function */
1350 if (SRF_IS_FIRSTCALL())
1352 int32 start = PG_GETARG_INT32(0);
1353 int32 finish = PG_GETARG_INT32(1);
1356 /* see if we were given an explicit step size */
1357 if (PG_NARGS() == 3)
1358 step = PG_GETARG_INT32(2);
1361 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1362 errmsg("step size cannot equal zero")));
1364 /* create a function context for cross-call persistence */
1365 funcctx = SRF_FIRSTCALL_INIT();
1368 * switch to memory context appropriate for multiple function calls
1370 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1372 /* allocate memory for user context */
1373 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1376 * Use fctx to keep state from call to call. Seed current with the
1377 * original start value
1379 fctx->current = start;
1380 fctx->finish = finish;
1383 funcctx->user_fctx = fctx;
1384 MemoryContextSwitchTo(oldcontext);
1387 /* stuff done on every call of the function */
1388 funcctx = SRF_PERCALL_SETUP();
1391 * get the saved state and use current as the result for this iteration
1393 fctx = funcctx->user_fctx;
1394 result = fctx->current;
1396 if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1397 (fctx->step < 0 && fctx->current >= fctx->finish))
1399 /* increment current in preparation for next iteration */
1400 fctx->current += fctx->step;
1402 /* if next-value computation overflows, this is the final result */
1403 if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
1406 /* do when there is more left to send */
1407 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
1410 /* do when there is no more left */
1411 SRF_RETURN_DONE(funcctx);