PostgreSQL Source Code git master
Loading...
Searching...
No Matches
int.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * int.c
4 * Functions for the built-in integer types (except int8).
5 *
6 * Portions Copyright (c) 1996-2026, 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#include <math.h>
34
35#include "catalog/pg_type.h"
36#include "common/int.h"
37#include "funcapi.h"
38#include "libpq/pqformat.h"
39#include "nodes/nodeFuncs.h"
40#include "nodes/supportnodes.h"
41#include "optimizer/optimizer.h"
42#include "utils/array.h"
43#include "utils/builtins.h"
44
45#define Int2VectorSize(n) (offsetof(int2vector, values) + (n) * sizeof(int16))
46
53
54
55/*****************************************************************************
56 * USER I/O ROUTINES *
57 *****************************************************************************/
58
59/*
60 * int2in - converts "num" to short
61 */
64{
65 char *num = PG_GETARG_CSTRING(0);
66
67 PG_RETURN_INT16(pg_strtoint16_safe(num, fcinfo->context));
68}
69
70/*
71 * int2out - converts short to "num"
72 */
75{
77 char *result = (char *) palloc(7); /* sign, 5 digits, '\0' */
78
79 pg_itoa(arg1, result);
80 PG_RETURN_CSTRING(result);
81}
82
83/*
84 * int2recv - converts external binary format to int2
85 */
93
94/*
95 * int2send - converts int2 to binary format
96 */
107
108/*
109 * construct int2vector given a raw array of int2s
110 *
111 * If int2s is NULL then caller must fill values[] afterward
112 */
115{
116 int2vector *result;
117
118 result = (int2vector *) palloc0(Int2VectorSize(n));
119
120 if (n > 0 && int2s)
121 memcpy(result->values, int2s, n * sizeof(int16));
122
123 /*
124 * Attach standard array header. For historical reasons, we set the index
125 * lower bound to 0 not 1.
126 */
127 SET_VARSIZE(result, Int2VectorSize(n));
128 result->ndim = 1;
129 result->dataoffset = 0; /* never any nulls */
130 result->elemtype = INT2OID;
131 result->dim1 = n;
132 result->lbound1 = 0;
133
134 return result;
135}
136
137/*
138 * int2vectorin - converts "num num ..." to internal form
139 */
140Datum
142{
143 char *intString = PG_GETARG_CSTRING(0);
144 Node *escontext = fcinfo->context;
145 int2vector *result;
146 int nalloc;
147 int n;
148
149 nalloc = 32; /* arbitrary initial size guess */
151
152 for (n = 0;; n++)
153 {
154 long l;
155 char *endp;
156
157 while (*intString && isspace((unsigned char) *intString))
158 intString++;
159 if (*intString == '\0')
160 break;
161
162 if (n >= nalloc)
163 {
164 nalloc *= 2;
165 result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
166 }
167
168 errno = 0;
169 l = strtol(intString, &endp, 10);
170
171 if (intString == endp)
172 ereturn(escontext, (Datum) 0,
174 errmsg("invalid input syntax for type %s: \"%s\"",
175 "smallint", intString)));
176
178 ereturn(escontext, (Datum) 0,
180 errmsg("value \"%s\" is out of range for type %s", intString,
181 "smallint")));
182
183 if (*endp && *endp != ' ')
184 ereturn(escontext, (Datum) 0,
186 errmsg("invalid input syntax for type %s: \"%s\"",
187 "smallint", intString)));
188
189 result->values[n] = l;
190 intString = endp;
191 }
192
193 SET_VARSIZE(result, Int2VectorSize(n));
194 result->ndim = 1;
195 result->dataoffset = 0; /* never any nulls */
196 result->elemtype = INT2OID;
197 result->dim1 = n;
198 result->lbound1 = 0;
199
200 PG_RETURN_POINTER(result);
201}
202
203/*
204 * int2vectorout - converts internal form to "num num ..."
205 */
206Datum
208{
210 int num,
212 char *rp;
213 char *result;
214
215 /* assumes sign, 5 digits, ' ' */
216 rp = result = (char *) palloc(nnums * 7 + 1);
217 for (num = 0; num < nnums; num++)
218 {
219 if (num != 0)
220 *rp++ = ' ';
221 rp += pg_itoa(int2Array->values[num], rp);
222 }
223 *rp = '\0';
224 PG_RETURN_CSTRING(result);
225}
226
227/*
228 * int2vectorrecv - converts external binary format to int2vector
229 */
230Datum
232{
235 int2vector *result;
236
237 /*
238 * Normally one would call array_recv() using DirectFunctionCall3, but
239 * that does not work since array_recv wants to cache some data using
240 * fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
241 * parameter.
242 */
243 InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
245
246 locfcinfo->args[0].value = PointerGetDatum(buf);
247 locfcinfo->args[0].isnull = false;
248 locfcinfo->args[1].value = ObjectIdGetDatum(INT2OID);
249 locfcinfo->args[1].isnull = false;
250 locfcinfo->args[2].value = Int32GetDatum(-1);
251 locfcinfo->args[2].isnull = false;
252
254
255 Assert(!locfcinfo->isnull);
256
257 /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
258 if (ARR_NDIM(result) != 1 ||
259 ARR_HASNULL(result) ||
260 ARR_ELEMTYPE(result) != INT2OID ||
261 ARR_LBOUND(result)[0] != 0)
264 errmsg("invalid int2vector data")));
265
266 PG_RETURN_POINTER(result);
267}
268
269/*
270 * int2vectorsend - converts int2vector to binary format
271 */
272Datum
274{
275 return array_send(fcinfo);
276}
277
278
279/*****************************************************************************
280 * PUBLIC ROUTINES *
281 *****************************************************************************/
282
283/*
284 * int4in - converts "num" to int4
285 */
286Datum
288{
289 char *num = PG_GETARG_CSTRING(0);
290
291 PG_RETURN_INT32(pg_strtoint32_safe(num, fcinfo->context));
292}
293
294/*
295 * int4out - converts int4 to "num"
296 */
297Datum
299{
301 char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */
302
303 pg_ltoa(arg1, result);
304 PG_RETURN_CSTRING(result);
305}
306
307/*
308 * int4recv - converts external binary format to int4
309 */
310Datum
317
318/*
319 * int4send - converts int4 to binary format
320 */
321Datum
331
332
333/*
334 * ===================
335 * CONVERSION ROUTINES
336 * ===================
337 */
338
339Datum
346
347Datum
349{
351
355 errmsg("smallint out of range")));
356
358}
359
360/* Cast int4 -> bool */
361Datum
363{
364 if (PG_GETARG_INT32(0) == 0)
365 PG_RETURN_BOOL(false);
366 else
367 PG_RETURN_BOOL(true);
368}
369
370/* Cast bool -> int4 */
371Datum
373{
374 if (PG_GETARG_BOOL(0) == false)
376 else
378}
379
380/*
381 * ============================
382 * COMPARISON OPERATOR ROUTINES
383 * ============================
384 */
385
386/*
387 * inteq - returns 1 iff arg1 == arg2
388 * intne - returns 1 iff arg1 != arg2
389 * intlt - returns 1 iff arg1 < arg2
390 * intle - returns 1 iff arg1 <= arg2
391 * intgt - returns 1 iff arg1 > arg2
392 * intge - returns 1 iff arg1 >= arg2
393 */
394
395Datum
403
404Datum
412
413Datum
421
422Datum
430
431Datum
439
440Datum
448
449Datum
457
458Datum
466
467Datum
475
476Datum
484
485Datum
493
494Datum
502
503Datum
511
512Datum
520
521Datum
529
530Datum
538
539Datum
547
548Datum
556
557Datum
565
566Datum
574
575Datum
583
584Datum
592
593Datum
601
602Datum
610
611
612/*----------------------------------------------------------
613 * in_range functions for int4 and int2,
614 * including cross-data-type comparisons.
615 *
616 * Note: we provide separate intN_int8 functions for performance
617 * reasons. This forces also providing intN_int2, else cases with a
618 * smallint offset value would fail to resolve which function to use.
619 * But that's an unlikely situation, so don't duplicate code for it.
620 *---------------------------------------------------------*/
621
622Datum
624{
626 int32 base = PG_GETARG_INT32(1);
627 int32 offset = PG_GETARG_INT32(2);
628 bool sub = PG_GETARG_BOOL(3);
629 bool less = PG_GETARG_BOOL(4);
630 int32 sum;
631
632 if (offset < 0)
635 errmsg("invalid preceding or following size in window function")));
636
637 if (sub)
638 offset = -offset; /* cannot overflow */
639
640 if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
641 {
642 /*
643 * If sub is false, the true sum is surely more than val, so correct
644 * answer is the same as "less". If sub is true, the true sum is
645 * surely less than val, so the answer is "!less".
646 */
647 PG_RETURN_BOOL(sub ? !less : less);
648 }
649
650 if (less)
651 PG_RETURN_BOOL(val <= sum);
652 else
653 PG_RETURN_BOOL(val >= sum);
654}
655
656Datum
658{
659 /* Doesn't seem worth duplicating code for, so just invoke int4_int4 */
665 PG_GETARG_DATUM(4));
666}
667
668Datum
670{
671 /* We must do all the math in int64 */
673 int64 base = (int64) PG_GETARG_INT32(1);
674 int64 offset = PG_GETARG_INT64(2);
675 bool sub = PG_GETARG_BOOL(3);
676 bool less = PG_GETARG_BOOL(4);
677 int64 sum;
678
679 if (offset < 0)
682 errmsg("invalid preceding or following size in window function")));
683
684 if (sub)
685 offset = -offset; /* cannot overflow */
686
687 if (unlikely(pg_add_s64_overflow(base, offset, &sum)))
688 {
689 /*
690 * If sub is false, the true sum is surely more than val, so correct
691 * answer is the same as "less". If sub is true, the true sum is
692 * surely less than val, so the answer is "!less".
693 */
694 PG_RETURN_BOOL(sub ? !less : less);
695 }
696
697 if (less)
698 PG_RETURN_BOOL(val <= sum);
699 else
700 PG_RETURN_BOOL(val >= sum);
701}
702
703Datum
705{
706 /* We must do all the math in int32 */
708 int32 base = (int32) PG_GETARG_INT16(1);
709 int32 offset = PG_GETARG_INT32(2);
710 bool sub = PG_GETARG_BOOL(3);
711 bool less = PG_GETARG_BOOL(4);
712 int32 sum;
713
714 if (offset < 0)
717 errmsg("invalid preceding or following size in window function")));
718
719 if (sub)
720 offset = -offset; /* cannot overflow */
721
722 if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
723 {
724 /*
725 * If sub is false, the true sum is surely more than val, so correct
726 * answer is the same as "less". If sub is true, the true sum is
727 * surely less than val, so the answer is "!less".
728 */
729 PG_RETURN_BOOL(sub ? !less : less);
730 }
731
732 if (less)
733 PG_RETURN_BOOL(val <= sum);
734 else
735 PG_RETURN_BOOL(val >= sum);
736}
737
738Datum
740{
741 /* Doesn't seem worth duplicating code for, so just invoke int2_int4 */
747 PG_GETARG_DATUM(4));
748}
749
750Datum
752{
753 /* Doesn't seem worth duplicating code for, so just invoke int4_int8 */
759 PG_GETARG_DATUM(4));
760}
761
762
763/*
764 * int[24]pl - returns arg1 + arg2
765 * int[24]mi - returns arg1 - arg2
766 * int[24]mul - returns arg1 * arg2
767 * int[24]div - returns arg1 / arg2
768 */
769
770Datum
772{
774
775 if (unlikely(arg == PG_INT32_MIN))
778 errmsg("integer out of range")));
780}
781
782Datum
789
790Datum
792{
795 int32 result;
796
797 if (unlikely(pg_add_s32_overflow(arg1, arg2, &result)))
800 errmsg("integer out of range")));
801 PG_RETURN_INT32(result);
802}
803
804Datum
806{
809 int32 result;
810
811 if (unlikely(pg_sub_s32_overflow(arg1, arg2, &result)))
814 errmsg("integer out of range")));
815 PG_RETURN_INT32(result);
816}
817
818Datum
820{
823 int32 result;
824
825 if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
828 errmsg("integer out of range")));
829 PG_RETURN_INT32(result);
830}
831
832Datum
834{
837 int32 result;
838
839 if (arg2 == 0)
840 {
843 errmsg("division by zero")));
844 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
846 }
847
848 /*
849 * INT_MIN / -1 is problematic, since the result can't be represented on a
850 * two's-complement machine. Some machines produce INT_MIN, some produce
851 * zero, some throw an exception. We can dodge the problem by recognizing
852 * that division by -1 is the same as negation.
853 */
854 if (arg2 == -1)
855 {
856 if (unlikely(arg1 == PG_INT32_MIN))
859 errmsg("integer out of range")));
860 result = -arg1;
861 PG_RETURN_INT32(result);
862 }
863
864 /* No overflow is possible */
865
866 result = arg1 / arg2;
867
868 PG_RETURN_INT32(result);
869}
870
871Datum
873{
875 int32 result;
876
877 if (unlikely(pg_add_s32_overflow(arg, 1, &result)))
880 errmsg("integer out of range")));
881
882 PG_RETURN_INT32(result);
883}
884
885Datum
887{
889
890 if (unlikely(arg == PG_INT16_MIN))
893 errmsg("smallint out of range")));
895}
896
897Datum
904
905Datum
907{
910 int16 result;
911
912 if (unlikely(pg_add_s16_overflow(arg1, arg2, &result)))
915 errmsg("smallint out of range")));
916 PG_RETURN_INT16(result);
917}
918
919Datum
921{
924 int16 result;
925
926 if (unlikely(pg_sub_s16_overflow(arg1, arg2, &result)))
929 errmsg("smallint out of range")));
930 PG_RETURN_INT16(result);
931}
932
933Datum
935{
938 int16 result;
939
940 if (unlikely(pg_mul_s16_overflow(arg1, arg2, &result)))
943 errmsg("smallint out of range")));
944
945 PG_RETURN_INT16(result);
946}
947
948Datum
950{
953 int16 result;
954
955 if (arg2 == 0)
956 {
959 errmsg("division by zero")));
960 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
962 }
963
964 /*
965 * SHRT_MIN / -1 is problematic, since the result can't be represented on
966 * a two's-complement machine. Some machines produce SHRT_MIN, some
967 * produce zero, some throw an exception. We can dodge the problem by
968 * recognizing that division by -1 is the same as negation.
969 */
970 if (arg2 == -1)
971 {
972 if (unlikely(arg1 == PG_INT16_MIN))
975 errmsg("smallint out of range")));
976 result = -arg1;
977 PG_RETURN_INT16(result);
978 }
979
980 /* No overflow is possible */
981
982 result = arg1 / arg2;
983
984 PG_RETURN_INT16(result);
985}
986
987Datum
989{
992 int32 result;
993
994 if (unlikely(pg_add_s32_overflow((int32) arg1, arg2, &result)))
997 errmsg("integer out of range")));
998 PG_RETURN_INT32(result);
999}
1000
1001Datum
1003{
1006 int32 result;
1007
1008 if (unlikely(pg_sub_s32_overflow((int32) arg1, arg2, &result)))
1009 ereport(ERROR,
1011 errmsg("integer out of range")));
1012 PG_RETURN_INT32(result);
1013}
1014
1015Datum
1017{
1020 int32 result;
1021
1022 if (unlikely(pg_mul_s32_overflow((int32) arg1, arg2, &result)))
1023 ereport(ERROR,
1025 errmsg("integer out of range")));
1026 PG_RETURN_INT32(result);
1027}
1028
1029Datum
1031{
1034
1035 if (unlikely(arg2 == 0))
1036 {
1037 ereport(ERROR,
1039 errmsg("division by zero")));
1040 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1042 }
1043
1044 /* No overflow is possible */
1046}
1047
1048Datum
1050{
1053 int32 result;
1054
1055 if (unlikely(pg_add_s32_overflow(arg1, (int32) arg2, &result)))
1056 ereport(ERROR,
1058 errmsg("integer out of range")));
1059 PG_RETURN_INT32(result);
1060}
1061
1062Datum
1064{
1067 int32 result;
1068
1069 if (unlikely(pg_sub_s32_overflow(arg1, (int32) arg2, &result)))
1070 ereport(ERROR,
1072 errmsg("integer out of range")));
1073 PG_RETURN_INT32(result);
1074}
1075
1076Datum
1078{
1081 int32 result;
1082
1083 if (unlikely(pg_mul_s32_overflow(arg1, (int32) arg2, &result)))
1084 ereport(ERROR,
1086 errmsg("integer out of range")));
1087 PG_RETURN_INT32(result);
1088}
1089
1090Datum
1092{
1095 int32 result;
1096
1097 if (unlikely(arg2 == 0))
1098 {
1099 ereport(ERROR,
1101 errmsg("division by zero")));
1102 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1104 }
1105
1106 /*
1107 * INT_MIN / -1 is problematic, since the result can't be represented on a
1108 * two's-complement machine. Some machines produce INT_MIN, some produce
1109 * zero, some throw an exception. We can dodge the problem by recognizing
1110 * that division by -1 is the same as negation.
1111 */
1112 if (arg2 == -1)
1113 {
1114 if (unlikely(arg1 == PG_INT32_MIN))
1115 ereport(ERROR,
1117 errmsg("integer out of range")));
1118 result = -arg1;
1119 PG_RETURN_INT32(result);
1120 }
1121
1122 /* No overflow is possible */
1123
1124 result = arg1 / arg2;
1125
1126 PG_RETURN_INT32(result);
1127}
1128
1129Datum
1131{
1134
1135 if (unlikely(arg2 == 0))
1136 {
1137 ereport(ERROR,
1139 errmsg("division by zero")));
1140 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1142 }
1143
1144 /*
1145 * Some machines throw a floating-point exception for INT_MIN % -1, which
1146 * is a bit silly since the correct answer is perfectly well-defined,
1147 * namely zero.
1148 */
1149 if (arg2 == -1)
1150 PG_RETURN_INT32(0);
1151
1152 /* No overflow is possible */
1153
1155}
1156
1157Datum
1159{
1162
1163 if (unlikely(arg2 == 0))
1164 {
1165 ereport(ERROR,
1167 errmsg("division by zero")));
1168 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1170 }
1171
1172 /*
1173 * Some machines throw a floating-point exception for INT_MIN % -1, which
1174 * is a bit silly since the correct answer is perfectly well-defined,
1175 * namely zero. (It's not clear this ever happens when dealing with
1176 * int16, but we might as well have the test for safety.)
1177 */
1178 if (arg2 == -1)
1179 PG_RETURN_INT16(0);
1180
1181 /* No overflow is possible */
1182
1184}
1185
1186
1187/* int[24]abs()
1188 * Absolute value
1189 */
1190Datum
1192{
1194 int32 result;
1195
1196 if (unlikely(arg1 == PG_INT32_MIN))
1197 ereport(ERROR,
1199 errmsg("integer out of range")));
1200 result = (arg1 < 0) ? -arg1 : arg1;
1201 PG_RETURN_INT32(result);
1202}
1203
1204Datum
1206{
1208 int16 result;
1209
1210 if (unlikely(arg1 == PG_INT16_MIN))
1211 ereport(ERROR,
1213 errmsg("smallint out of range")));
1214 result = (arg1 < 0) ? -arg1 : arg1;
1215 PG_RETURN_INT16(result);
1216}
1217
1218/*
1219 * Greatest Common Divisor
1220 *
1221 * Returns the largest positive integer that exactly divides both inputs.
1222 * Special cases:
1223 * - gcd(x, 0) = gcd(0, x) = abs(x)
1224 * because 0 is divisible by anything
1225 * - gcd(0, 0) = 0
1226 * complies with the previous definition and is a common convention
1227 *
1228 * Special care must be taken if either input is INT_MIN --- gcd(0, INT_MIN),
1229 * gcd(INT_MIN, 0) and gcd(INT_MIN, INT_MIN) are all equal to abs(INT_MIN),
1230 * which cannot be represented as a 32-bit signed integer.
1231 */
1232static int32
1234{
1235 int32 swap;
1236 int32 a1,
1237 a2;
1238
1239 /*
1240 * Put the greater absolute value in arg1.
1241 *
1242 * This would happen automatically in the loop below, but avoids an
1243 * expensive modulo operation, and simplifies the special-case handling
1244 * for INT_MIN below.
1245 *
1246 * We do this in negative space in order to handle INT_MIN.
1247 */
1248 a1 = (arg1 < 0) ? arg1 : -arg1;
1249 a2 = (arg2 < 0) ? arg2 : -arg2;
1250 if (a1 > a2)
1251 {
1252 swap = arg1;
1253 arg1 = arg2;
1254 arg2 = swap;
1255 }
1256
1257 /* Special care needs to be taken with INT_MIN. See comments above. */
1258 if (arg1 == PG_INT32_MIN)
1259 {
1260 if (arg2 == 0 || arg2 == PG_INT32_MIN)
1261 ereport(ERROR,
1263 errmsg("integer out of range")));
1264
1265 /*
1266 * Some machines throw a floating-point exception for INT_MIN % -1,
1267 * which is a bit silly since the correct answer is perfectly
1268 * well-defined, namely zero. Guard against this and just return the
1269 * result, gcd(INT_MIN, -1) = 1.
1270 */
1271 if (arg2 == -1)
1272 return 1;
1273 }
1274
1275 /* Use the Euclidean algorithm to find the GCD */
1276 while (arg2 != 0)
1277 {
1278 swap = arg2;
1279 arg2 = arg1 % arg2;
1280 arg1 = swap;
1281 }
1282
1283 /*
1284 * Make sure the result is positive. (We know we don't have INT_MIN
1285 * anymore).
1286 */
1287 if (arg1 < 0)
1288 arg1 = -arg1;
1289
1290 return arg1;
1291}
1292
1293Datum
1295{
1298 int32 result;
1299
1300 result = int4gcd_internal(arg1, arg2);
1301
1302 PG_RETURN_INT32(result);
1303}
1304
1305/*
1306 * Least Common Multiple
1307 */
1308Datum
1310{
1313 int32 gcd;
1314 int32 result;
1315
1316 /*
1317 * Handle lcm(x, 0) = lcm(0, x) = 0 as a special case. This prevents a
1318 * division-by-zero error below when x is zero, and an overflow error from
1319 * the GCD computation when x = INT_MIN.
1320 */
1321 if (arg1 == 0 || arg2 == 0)
1322 PG_RETURN_INT32(0);
1323
1324 /* lcm(x, y) = abs(x / gcd(x, y) * y) */
1326 arg1 = arg1 / gcd;
1327
1328 if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
1329 ereport(ERROR,
1331 errmsg("integer out of range")));
1332
1333 /* If the result is INT_MIN, it cannot be represented. */
1334 if (unlikely(result == PG_INT32_MIN))
1335 ereport(ERROR,
1337 errmsg("integer out of range")));
1338
1339 if (result < 0)
1340 result = -result;
1341
1342 PG_RETURN_INT32(result);
1343}
1344
1345Datum
1353
1354Datum
1362
1363Datum
1371
1372Datum
1380
1381/*
1382 * Bit-pushing operators
1383 *
1384 * int[24]and - returns arg1 & arg2
1385 * int[24]or - returns arg1 | arg2
1386 * int[24]xor - returns arg1 # arg2
1387 * int[24]not - returns ~arg1
1388 * int[24]shl - returns arg1 << arg2
1389 * int[24]shr - returns arg1 >> arg2
1390 */
1391
1392Datum
1400
1401Datum
1409
1410Datum
1418
1419Datum
1427
1428Datum
1436
1437Datum
1444
1445Datum
1453
1454Datum
1462
1463Datum
1471
1472Datum
1479
1480
1481Datum
1489
1490Datum
1498
1499/*
1500 * non-persistent numeric series generator
1501 */
1502Datum
1507
1508Datum
1510{
1513 int32 result;
1514 MemoryContext oldcontext;
1515
1516 /* stuff done only on the first call of the function */
1517 if (SRF_IS_FIRSTCALL())
1518 {
1520 int32 finish = PG_GETARG_INT32(1);
1521 int32 step = 1;
1522
1523 /* see if we were given an explicit step size */
1524 if (PG_NARGS() == 3)
1525 step = PG_GETARG_INT32(2);
1526 if (step == 0)
1527 ereport(ERROR,
1529 errmsg("step size cannot equal zero")));
1530
1531 /* create a function context for cross-call persistence */
1533
1534 /*
1535 * switch to memory context appropriate for multiple function calls
1536 */
1537 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1538
1539 /* allocate memory for user context */
1541
1542 /*
1543 * Use fctx to keep state from call to call. Seed current with the
1544 * original start value
1545 */
1546 fctx->current = start;
1547 fctx->finish = finish;
1548 fctx->step = step;
1549
1550 funcctx->user_fctx = fctx;
1551 MemoryContextSwitchTo(oldcontext);
1552 }
1553
1554 /* stuff done on every call of the function */
1556
1557 /*
1558 * get the saved state and use current as the result for this iteration
1559 */
1560 fctx = funcctx->user_fctx;
1561 result = fctx->current;
1562
1563 if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1564 (fctx->step < 0 && fctx->current >= fctx->finish))
1565 {
1566 /*
1567 * Increment current in preparation for next iteration. If next-value
1568 * computation overflows, this is the final result.
1569 */
1570 if (pg_add_s32_overflow(fctx->current, fctx->step, &fctx->current))
1571 fctx->step = 0;
1572
1573 /* do when there is more left to send */
1575 }
1576 else
1577 /* do when there is no more left */
1579}
1580
1581/*
1582 * Planner support function for generate_series(int4, int4 [, int4])
1583 */
1584Datum
1586{
1588 Node *ret = NULL;
1589
1591 {
1592 /* Try to estimate the number of rows returned */
1594
1595 if (is_funcclause(req->node)) /* be paranoid */
1596 {
1597 List *args = ((FuncExpr *) req->node)->args;
1598 Node *arg1,
1599 *arg2,
1600 *arg3;
1601
1602 /* We can use estimated argument values here */
1604 arg2 = estimate_expression_value(req->root, lsecond(args));
1605 if (list_length(args) >= 3)
1606 arg3 = estimate_expression_value(req->root, lthird(args));
1607 else
1608 arg3 = NULL;
1609
1610 /*
1611 * If any argument is constant NULL, we can safely assume that
1612 * zero rows are returned. Otherwise, if they're all non-NULL
1613 * constants, we can calculate the number of rows that will be
1614 * returned. Use double arithmetic to avoid overflow hazards.
1615 */
1616 if ((IsA(arg1, Const) &&
1617 ((Const *) arg1)->constisnull) ||
1618 (IsA(arg2, Const) &&
1619 ((Const *) arg2)->constisnull) ||
1620 (arg3 != NULL && IsA(arg3, Const) &&
1621 ((Const *) arg3)->constisnull))
1622 {
1623 req->rows = 0;
1624 ret = (Node *) req;
1625 }
1626 else if (IsA(arg1, Const) &&
1627 IsA(arg2, Const) &&
1628 (arg3 == NULL || IsA(arg3, Const)))
1629 {
1630 double start,
1631 finish,
1632 step;
1633
1635 finish = DatumGetInt32(((Const *) arg2)->constvalue);
1636 step = arg3 ? DatumGetInt32(((Const *) arg3)->constvalue) : 1;
1637
1638 /* This equation works for either sign of step */
1639 if (step != 0)
1640 {
1641 req->rows = floor((finish - start + step) / step);
1642 ret = (Node *) req;
1643 }
1644 }
1645 }
1646 }
1647
1648 PG_RETURN_POINTER(ret);
1649}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_HASNULL(a)
Definition array.h:291
#define ARR_LBOUND(a)
Definition array.h:296
Datum array_recv(PG_FUNCTION_ARGS)
Datum array_send(PG_FUNCTION_ARGS)
#define Assert(condition)
Definition c.h:873
int64_t int64
Definition c.h:543
int16_t int16
Definition c.h:541
#define PG_INT16_MIN
Definition c.h:599
int32_t int32
Definition c.h:542
#define unlikely(x)
Definition c.h:412
#define PG_INT32_MIN
Definition c.h:602
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition clauses.c:2408
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ereturn(context, dummy_value,...)
Definition elog.h:278
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
#define palloc_object(type)
Definition fe_memutils.h:74
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition fmgr.h:150
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define LOCAL_FCINFO(name, nargs)
Definition fmgr.h:110
#define PG_NARGS()
Definition fmgr.h:203
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_RETURN_INT16(x)
Definition fmgr.h:357
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5)
Definition fmgr.h:692
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_GETARG_INT16(n)
Definition fmgr.h:271
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
return str start
static const FormData_pg_attribute a1
Definition heap.c:144
static const FormData_pg_attribute a2
Definition heap.c:157
long val
Definition informix.c:689
Datum int4div(PG_FUNCTION_ARGS)
Definition int.c:833
Datum int4shl(PG_FUNCTION_ARGS)
Definition int.c:1420
Datum int2vectorrecv(PG_FUNCTION_ARGS)
Definition int.c:231
Datum int2not(PG_FUNCTION_ARGS)
Definition int.c:1473
Datum int4pl(PG_FUNCTION_ARGS)
Definition int.c:791
Datum int2xor(PG_FUNCTION_ARGS)
Definition int.c:1464
Datum generate_series_int4(PG_FUNCTION_ARGS)
Definition int.c:1503
Datum int4recv(PG_FUNCTION_ARGS)
Definition int.c:311
Datum int4um(PG_FUNCTION_ARGS)
Definition int.c:771
Datum int4gt(PG_FUNCTION_ARGS)
Definition int.c:432
Datum int24eq(PG_FUNCTION_ARGS)
Definition int.c:504
Datum int2lt(PG_FUNCTION_ARGS)
Definition int.c:468
Datum int24mi(PG_FUNCTION_ARGS)
Definition int.c:1002
Datum int2out(PG_FUNCTION_ARGS)
Definition int.c:74
Datum int2eq(PG_FUNCTION_ARGS)
Definition int.c:450
Datum int42eq(PG_FUNCTION_ARGS)
Definition int.c:558
Datum int2ge(PG_FUNCTION_ARGS)
Definition int.c:495
Datum int2up(PG_FUNCTION_ARGS)
Definition int.c:898
Datum int4gcd(PG_FUNCTION_ARGS)
Definition int.c:1294
Datum int42ge(PG_FUNCTION_ARGS)
Definition int.c:603
Datum int42mul(PG_FUNCTION_ARGS)
Definition int.c:1077
Datum int24gt(PG_FUNCTION_ARGS)
Definition int.c:540
Datum int2le(PG_FUNCTION_ARGS)
Definition int.c:477
Datum int2abs(PG_FUNCTION_ARGS)
Definition int.c:1205
#define Int2VectorSize(n)
Definition int.c:45
Datum int4lt(PG_FUNCTION_ARGS)
Definition int.c:414
Datum int2um(PG_FUNCTION_ARGS)
Definition int.c:886
Datum int2shl(PG_FUNCTION_ARGS)
Definition int.c:1482
Datum in_range_int2_int8(PG_FUNCTION_ARGS)
Definition int.c:751
Datum int42div(PG_FUNCTION_ARGS)
Definition int.c:1091
Datum int2mi(PG_FUNCTION_ARGS)
Definition int.c:920
Datum int2ne(PG_FUNCTION_ARGS)
Definition int.c:459
Datum int24le(PG_FUNCTION_ARGS)
Definition int.c:531
Datum int2send(PG_FUNCTION_ARGS)
Definition int.c:98
Datum int2mul(PG_FUNCTION_ARGS)
Definition int.c:934
Datum int2smaller(PG_FUNCTION_ARGS)
Definition int.c:1355
Datum int2mod(PG_FUNCTION_ARGS)
Definition int.c:1158
int2vector * buildint2vector(const int16 *int2s, int n)
Definition int.c:114
Datum int2in(PG_FUNCTION_ARGS)
Definition int.c:63
Datum int24mul(PG_FUNCTION_ARGS)
Definition int.c:1016
Datum int42gt(PG_FUNCTION_ARGS)
Definition int.c:594
Datum int4lcm(PG_FUNCTION_ARGS)
Definition int.c:1309
Datum in_range_int4_int8(PG_FUNCTION_ARGS)
Definition int.c:669
Datum int2div(PG_FUNCTION_ARGS)
Definition int.c:949
Datum in_range_int2_int2(PG_FUNCTION_ARGS)
Definition int.c:739
Datum int4in(PG_FUNCTION_ARGS)
Definition int.c:287
Datum int2shr(PG_FUNCTION_ARGS)
Definition int.c:1491
Datum in_range_int2_int4(PG_FUNCTION_ARGS)
Definition int.c:704
static int32 int4gcd_internal(int32 arg1, int32 arg2)
Definition int.c:1233
Datum int2vectorout(PG_FUNCTION_ARGS)
Definition int.c:207
Datum i4toi2(PG_FUNCTION_ARGS)
Definition int.c:348
Datum int4ge(PG_FUNCTION_ARGS)
Definition int.c:441
Datum int4and(PG_FUNCTION_ARGS)
Definition int.c:1393
Datum int4send(PG_FUNCTION_ARGS)
Definition int.c:322
Datum int24ge(PG_FUNCTION_ARGS)
Definition int.c:549
Datum in_range_int4_int2(PG_FUNCTION_ARGS)
Definition int.c:657
Datum int2vectorin(PG_FUNCTION_ARGS)
Definition int.c:141
Datum bool_int4(PG_FUNCTION_ARGS)
Definition int.c:372
Datum int4inc(PG_FUNCTION_ARGS)
Definition int.c:872
Datum int4shr(PG_FUNCTION_ARGS)
Definition int.c:1429
Datum int4larger(PG_FUNCTION_ARGS)
Definition int.c:1364
Datum int24ne(PG_FUNCTION_ARGS)
Definition int.c:513
Datum int2gt(PG_FUNCTION_ARGS)
Definition int.c:486
Datum int24lt(PG_FUNCTION_ARGS)
Definition int.c:522
Datum int42pl(PG_FUNCTION_ARGS)
Definition int.c:1049
Datum in_range_int4_int4(PG_FUNCTION_ARGS)
Definition int.c:623
Datum int4ne(PG_FUNCTION_ARGS)
Definition int.c:405
Datum int42le(PG_FUNCTION_ARGS)
Definition int.c:585
Datum i2toi4(PG_FUNCTION_ARGS)
Definition int.c:340
Datum int4smaller(PG_FUNCTION_ARGS)
Definition int.c:1373
Datum int24pl(PG_FUNCTION_ARGS)
Definition int.c:988
Datum int4_bool(PG_FUNCTION_ARGS)
Definition int.c:362
Datum int4mod(PG_FUNCTION_ARGS)
Definition int.c:1130
Datum int24div(PG_FUNCTION_ARGS)
Definition int.c:1030
Datum int4xor(PG_FUNCTION_ARGS)
Definition int.c:1411
Datum generate_series_step_int4(PG_FUNCTION_ARGS)
Definition int.c:1509
Datum int2larger(PG_FUNCTION_ARGS)
Definition int.c:1346
Datum int2and(PG_FUNCTION_ARGS)
Definition int.c:1446
Datum int4not(PG_FUNCTION_ARGS)
Definition int.c:1438
Datum int4abs(PG_FUNCTION_ARGS)
Definition int.c:1191
Datum int4out(PG_FUNCTION_ARGS)
Definition int.c:298
Datum generate_series_int4_support(PG_FUNCTION_ARGS)
Definition int.c:1585
Datum int4mul(PG_FUNCTION_ARGS)
Definition int.c:819
Datum int4eq(PG_FUNCTION_ARGS)
Definition int.c:396
Datum int4le(PG_FUNCTION_ARGS)
Definition int.c:423
Datum int42ne(PG_FUNCTION_ARGS)
Definition int.c:567
Datum int4mi(PG_FUNCTION_ARGS)
Definition int.c:805
Datum int42lt(PG_FUNCTION_ARGS)
Definition int.c:576
Datum int2pl(PG_FUNCTION_ARGS)
Definition int.c:906
Datum int4up(PG_FUNCTION_ARGS)
Definition int.c:783
Datum int2vectorsend(PG_FUNCTION_ARGS)
Definition int.c:273
Datum int2recv(PG_FUNCTION_ARGS)
Definition int.c:87
Datum int42mi(PG_FUNCTION_ARGS)
Definition int.c:1063
Datum int4or(PG_FUNCTION_ARGS)
Definition int.c:1402
Datum int2or(PG_FUNCTION_ARGS)
Definition int.c:1455
static bool pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
Definition int.h:85
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:187
static bool pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
Definition int.h:103
static bool pg_add_s16_overflow(int16 a, int16 b, int16 *result)
Definition int.h:67
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:169
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition int.h:235
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:151
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
void * palloc0(Size size)
Definition mcxt.c:1417
void * palloc(Size size)
Definition mcxt.c:1387
static bool is_funcclause(const void *clause)
Definition nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition nodes.h:164
int pg_ltoa(int32 value, char *a)
Definition numutils.c:1119
int32 pg_strtoint32_safe(const char *s, Node *escontext)
Definition numutils.c:388
int pg_itoa(int16 i, char *a)
Definition numutils.c:1041
int16 pg_strtoint16_safe(const char *s, Node *escontext)
Definition numutils.c:127
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
void * arg
static int list_length(const List *l)
Definition pg_list.h:152
#define lthird(l)
Definition pg_list.h:188
#define linitial(l)
Definition pg_list.h:178
#define lsecond(l)
Definition pg_list.h:183
static char buf[DEFAULT_XLOG_SEG_SIZE]
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
static int32 DatumGetInt32(Datum X)
Definition postgres.h:212
#define InvalidOid
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
static void pq_sendint32(StringInfo buf, uint32 i)
Definition pqformat.h:144
static void pq_sendint16(StringInfo buf, uint16 i)
Definition pqformat.h:136
static int fb(int x)
struct StringInfoData * StringInfo
Definition string.h:15
Definition pg_list.h:54
Definition nodes.h:135
int ndim
Definition c.h:736
int dim1
Definition c.h:739
Oid elemtype
Definition c.h:738
int16 values[FLEXIBLE_ARRAY_MEMBER]
Definition c.h:741
int32 dataoffset
Definition c.h:737
int lbound1
Definition c.h:740
static uint32 gcd(uint32 a, uint32 b)
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432