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
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{
117
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 */
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 * validate that an array object meets the restrictions of int2vector
139 *
140 * We need this because there are pathways by which a general int2[] array can
141 * be cast to int2vector, allowing the type's restrictions to be violated.
142 * All code that receives an int2vector as a SQL parameter should check this.
143 */
144static void
146{
147 /*
148 * We insist on ndim == 1 and dataoffset == 0 (that is, no nulls) because
149 * otherwise the array's layout will not be what calling code expects. We
150 * needn't be picky about the index lower bound though. Checking elemtype
151 * is just paranoia.
152 */
153 if (int2Array->ndim != 1 ||
154 int2Array->dataoffset != 0 ||
155 int2Array->elemtype != INT2OID)
158 errmsg("array is not a valid int2vector")));
159}
160
161/*
162 * int2vectorin - converts "num num ..." to internal form
163 */
164Datum
166{
167 char *intString = PG_GETARG_CSTRING(0);
168 Node *escontext = fcinfo->context;
170 int nalloc;
171 int n;
172
173 nalloc = 32; /* arbitrary initial size guess */
175
176 for (n = 0;; n++)
177 {
178 long l;
179 char *endp;
180
181 while (*intString && isspace((unsigned char) *intString))
182 intString++;
183 if (*intString == '\0')
184 break;
185
186 if (n >= nalloc)
187 {
188 nalloc *= 2;
190 }
191
192 errno = 0;
193 l = strtol(intString, &endp, 10);
194
195 if (intString == endp)
196 ereturn(escontext, (Datum) 0,
198 errmsg("invalid input syntax for type %s: \"%s\"",
199 "smallint", intString)));
200
202 ereturn(escontext, (Datum) 0,
204 errmsg("value \"%s\" is out of range for type %s", intString,
205 "smallint")));
206
207 if (*endp && *endp != ' ')
208 ereturn(escontext, (Datum) 0,
210 errmsg("invalid input syntax for type %s: \"%s\"",
211 "smallint", intString)));
212
213 result->values[n] = l;
214 intString = endp;
215 }
216
218 result->ndim = 1;
219 result->dataoffset = 0; /* never any nulls */
220 result->elemtype = INT2OID;
221 result->dim1 = n;
222 result->lbound1 = 0;
223
225}
226
227/*
228 * int2vectorout - converts internal form to "num num ..."
229 */
230Datum
232{
234 int num,
235 nnums;
236 char *rp;
237 char *result;
238
239 /* validate input before fetching dim1 */
241 nnums = int2Array->dim1;
242
243 /* assumes sign, 5 digits, ' ' */
244 rp = result = (char *) palloc(nnums * 7 + 1);
245 for (num = 0; num < nnums; num++)
246 {
247 if (num != 0)
248 *rp++ = ' ';
249 rp += pg_itoa(int2Array->values[num], rp);
250 }
251 *rp = '\0';
253}
254
255/*
256 * int2vectorrecv - converts external binary format to int2vector
257 */
258Datum
260{
264
265 /*
266 * Normally one would call array_recv() using DirectFunctionCall3, but
267 * that does not work since array_recv wants to cache some data using
268 * fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo
269 * parameter.
270 */
271 InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
273
274 locfcinfo->args[0].value = PointerGetDatum(buf);
275 locfcinfo->args[0].isnull = false;
276 locfcinfo->args[1].value = ObjectIdGetDatum(INT2OID);
277 locfcinfo->args[1].isnull = false;
278 locfcinfo->args[2].value = Int32GetDatum(-1);
279 locfcinfo->args[2].isnull = false;
280
282
283 Assert(!locfcinfo->isnull);
284
285 /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
286 if (ARR_NDIM(result) != 1 ||
289 ARR_LBOUND(result)[0] != 0)
292 errmsg("invalid int2vector data")));
293
295}
296
297/*
298 * int2vectorsend - converts int2vector to binary format
299 */
300Datum
302{
303 /* We don't do check_valid_int2vector, since array_send won't care */
304 return array_send(fcinfo);
305}
306
307
308/*****************************************************************************
309 * PUBLIC ROUTINES *
310 *****************************************************************************/
311
312/*
313 * int4in - converts "num" to int4
314 */
315Datum
317{
318 char *num = PG_GETARG_CSTRING(0);
319
320 PG_RETURN_INT32(pg_strtoint32_safe(num, fcinfo->context));
321}
322
323/*
324 * int4out - converts int4 to "num"
325 */
326Datum
328{
330 char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */
331
334}
335
336/*
337 * int4recv - converts external binary format to int4
338 */
339Datum
346
347/*
348 * int4send - converts int4 to binary format
349 */
350Datum
360
361
362/*
363 * ===================
364 * CONVERSION ROUTINES
365 * ===================
366 */
367
368Datum
375
376Datum
378{
380
382 ereturn(fcinfo->context, (Datum) 0,
384 errmsg("smallint out of range")));
385
387}
388
389/* Cast int4 -> bool */
390Datum
392{
393 if (PG_GETARG_INT32(0) == 0)
394 PG_RETURN_BOOL(false);
395 else
396 PG_RETURN_BOOL(true);
397}
398
399/* Cast bool -> int4 */
400Datum
402{
403 if (PG_GETARG_BOOL(0) == false)
405 else
407}
408
409/*
410 * ============================
411 * COMPARISON OPERATOR ROUTINES
412 * ============================
413 */
414
415/*
416 * inteq - returns 1 iff arg1 == arg2
417 * intne - returns 1 iff arg1 != arg2
418 * intlt - returns 1 iff arg1 < arg2
419 * intle - returns 1 iff arg1 <= arg2
420 * intgt - returns 1 iff arg1 > arg2
421 * intge - returns 1 iff arg1 >= arg2
422 */
423
424Datum
432
433Datum
441
442Datum
450
451Datum
459
460Datum
468
469Datum
477
478Datum
486
487Datum
495
496Datum
504
505Datum
513
514Datum
522
523Datum
531
532Datum
540
541Datum
549
550Datum
558
559Datum
567
568Datum
576
577Datum
585
586Datum
594
595Datum
603
604Datum
612
613Datum
621
622Datum
630
631Datum
639
640
641/*----------------------------------------------------------
642 * in_range functions for int4 and int2,
643 * including cross-data-type comparisons.
644 *
645 * Note: we provide separate intN_int8 functions for performance
646 * reasons. This forces also providing intN_int2, else cases with a
647 * smallint offset value would fail to resolve which function to use.
648 * But that's an unlikely situation, so don't duplicate code for it.
649 *---------------------------------------------------------*/
650
651Datum
653{
655 int32 base = PG_GETARG_INT32(1);
656 int32 offset = PG_GETARG_INT32(2);
657 bool sub = PG_GETARG_BOOL(3);
658 bool less = PG_GETARG_BOOL(4);
659 int32 sum;
660
661 if (offset < 0)
664 errmsg("invalid preceding or following size in window function")));
665
666 if (sub)
667 offset = -offset; /* cannot overflow */
668
669 if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
670 {
671 /*
672 * If sub is false, the true sum is surely more than val, so correct
673 * answer is the same as "less". If sub is true, the true sum is
674 * surely less than val, so the answer is "!less".
675 */
676 PG_RETURN_BOOL(sub ? !less : less);
677 }
678
679 if (less)
680 PG_RETURN_BOOL(val <= sum);
681 else
682 PG_RETURN_BOOL(val >= sum);
683}
684
685Datum
687{
688 /* Doesn't seem worth duplicating code for, so just invoke int4_int4 */
694 PG_GETARG_DATUM(4));
695}
696
697Datum
699{
700 /* We must do all the math in int64 */
702 int64 base = (int64) PG_GETARG_INT32(1);
703 int64 offset = PG_GETARG_INT64(2);
704 bool sub = PG_GETARG_BOOL(3);
705 bool less = PG_GETARG_BOOL(4);
706 int64 sum;
707
708 if (offset < 0)
711 errmsg("invalid preceding or following size in window function")));
712
713 if (sub)
714 offset = -offset; /* cannot overflow */
715
716 if (unlikely(pg_add_s64_overflow(base, offset, &sum)))
717 {
718 /*
719 * If sub is false, the true sum is surely more than val, so correct
720 * answer is the same as "less". If sub is true, the true sum is
721 * surely less than val, so the answer is "!less".
722 */
723 PG_RETURN_BOOL(sub ? !less : less);
724 }
725
726 if (less)
727 PG_RETURN_BOOL(val <= sum);
728 else
729 PG_RETURN_BOOL(val >= sum);
730}
731
732Datum
734{
735 /* We must do all the math in int32 */
737 int32 base = (int32) PG_GETARG_INT16(1);
738 int32 offset = PG_GETARG_INT32(2);
739 bool sub = PG_GETARG_BOOL(3);
740 bool less = PG_GETARG_BOOL(4);
741 int32 sum;
742
743 if (offset < 0)
746 errmsg("invalid preceding or following size in window function")));
747
748 if (sub)
749 offset = -offset; /* cannot overflow */
750
751 if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
752 {
753 /*
754 * If sub is false, the true sum is surely more than val, so correct
755 * answer is the same as "less". If sub is true, the true sum is
756 * surely less than val, so the answer is "!less".
757 */
758 PG_RETURN_BOOL(sub ? !less : less);
759 }
760
761 if (less)
762 PG_RETURN_BOOL(val <= sum);
763 else
764 PG_RETURN_BOOL(val >= sum);
765}
766
767Datum
769{
770 /* Doesn't seem worth duplicating code for, so just invoke int2_int4 */
776 PG_GETARG_DATUM(4));
777}
778
779Datum
781{
782 /* Doesn't seem worth duplicating code for, so just invoke int4_int8 */
788 PG_GETARG_DATUM(4));
789}
790
791
792/*
793 * int[24]pl - returns arg1 + arg2
794 * int[24]mi - returns arg1 - arg2
795 * int[24]mul - returns arg1 * arg2
796 * int[24]div - returns arg1 / arg2
797 */
798
799Datum
801{
803
804 if (unlikely(arg == PG_INT32_MIN))
807 errmsg("integer out of range")));
809}
810
811Datum
818
819Datum
832
833Datum
846
847Datum
860
861Datum
863{
867
868 if (arg2 == 0)
869 {
872 errmsg("division by zero")));
873 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
875 }
876
877 /*
878 * INT_MIN / -1 is problematic, since the result can't be represented on a
879 * two's-complement machine. Some machines produce INT_MIN, some produce
880 * zero, some throw an exception. We can dodge the problem by recognizing
881 * that division by -1 is the same as negation.
882 */
883 if (arg2 == -1)
884 {
885 if (unlikely(arg1 == PG_INT32_MIN))
888 errmsg("integer out of range")));
889 result = -arg1;
891 }
892
893 /* No overflow is possible */
894
895 result = arg1 / arg2;
896
898}
899
900Datum
913
914Datum
916{
918
919 if (unlikely(arg == PG_INT16_MIN))
922 errmsg("smallint out of range")));
924}
925
926Datum
933
934Datum
947
948Datum
961
962Datum
976
977Datum
979{
983
984 if (arg2 == 0)
985 {
988 errmsg("division by zero")));
989 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
991 }
992
993 /*
994 * SHRT_MIN / -1 is problematic, since the result can't be represented on
995 * a two's-complement machine. Some machines produce SHRT_MIN, some
996 * produce zero, some throw an exception. We can dodge the problem by
997 * recognizing that division by -1 is the same as negation.
998 */
999 if (arg2 == -1)
1000 {
1001 if (unlikely(arg1 == PG_INT16_MIN))
1002 ereport(ERROR,
1004 errmsg("smallint out of range")));
1005 result = -arg1;
1007 }
1008
1009 /* No overflow is possible */
1010
1011 result = arg1 / arg2;
1012
1014}
1015
1016Datum
1029
1030Datum
1043
1044Datum
1057
1058Datum
1060{
1063
1064 if (unlikely(arg2 == 0))
1065 {
1066 ereport(ERROR,
1068 errmsg("division by zero")));
1069 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1071 }
1072
1073 /* No overflow is possible */
1075}
1076
1077Datum
1090
1091Datum
1104
1105Datum
1118
1119Datum
1121{
1124 int32 result;
1125
1126 if (unlikely(arg2 == 0))
1127 {
1128 ereport(ERROR,
1130 errmsg("division by zero")));
1131 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1133 }
1134
1135 /*
1136 * INT_MIN / -1 is problematic, since the result can't be represented on a
1137 * two's-complement machine. Some machines produce INT_MIN, some produce
1138 * zero, some throw an exception. We can dodge the problem by recognizing
1139 * that division by -1 is the same as negation.
1140 */
1141 if (arg2 == -1)
1142 {
1143 if (unlikely(arg1 == PG_INT32_MIN))
1144 ereport(ERROR,
1146 errmsg("integer out of range")));
1147 result = -arg1;
1149 }
1150
1151 /* No overflow is possible */
1152
1153 result = arg1 / arg2;
1154
1156}
1157
1158Datum
1160{
1163
1164 if (unlikely(arg2 == 0))
1165 {
1166 ereport(ERROR,
1168 errmsg("division by zero")));
1169 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1171 }
1172
1173 /*
1174 * Some machines throw a floating-point exception for INT_MIN % -1, which
1175 * is a bit silly since the correct answer is perfectly well-defined,
1176 * namely zero.
1177 */
1178 if (arg2 == -1)
1179 PG_RETURN_INT32(0);
1180
1181 /* No overflow is possible */
1182
1184}
1185
1186Datum
1188{
1191
1192 if (unlikely(arg2 == 0))
1193 {
1194 ereport(ERROR,
1196 errmsg("division by zero")));
1197 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1199 }
1200
1201 /*
1202 * Some machines throw a floating-point exception for INT_MIN % -1, which
1203 * is a bit silly since the correct answer is perfectly well-defined,
1204 * namely zero. (It's not clear this ever happens when dealing with
1205 * int16, but we might as well have the test for safety.)
1206 */
1207 if (arg2 == -1)
1208 PG_RETURN_INT16(0);
1209
1210 /* No overflow is possible */
1211
1213}
1214
1215
1216/*
1217 * int[24]abs()
1218 * Absolute value
1219 */
1220Datum
1222{
1224 int32 result;
1225
1226 if (unlikely(arg1 == PG_INT32_MIN))
1227 ereport(ERROR,
1229 errmsg("integer out of range")));
1230 result = (arg1 < 0) ? -arg1 : arg1;
1232}
1233
1234Datum
1236{
1238 int16 result;
1239
1240 if (unlikely(arg1 == PG_INT16_MIN))
1241 ereport(ERROR,
1243 errmsg("smallint out of range")));
1244 result = (arg1 < 0) ? -arg1 : arg1;
1246}
1247
1248/*
1249 * Greatest Common Divisor
1250 *
1251 * Returns the largest positive integer that exactly divides both inputs.
1252 * Special cases:
1253 * - gcd(x, 0) = gcd(0, x) = abs(x)
1254 * because 0 is divisible by anything
1255 * - gcd(0, 0) = 0
1256 * complies with the previous definition and is a common convention
1257 *
1258 * Special care must be taken if either input is INT_MIN --- gcd(0, INT_MIN),
1259 * gcd(INT_MIN, 0) and gcd(INT_MIN, INT_MIN) are all equal to abs(INT_MIN),
1260 * which cannot be represented as a 32-bit signed integer.
1261 */
1262static int32
1264{
1265 int32 swap;
1266 int32 a1,
1267 a2;
1268
1269 /*
1270 * Put the greater absolute value in arg1.
1271 *
1272 * This would happen automatically in the loop below, but avoids an
1273 * expensive modulo operation, and simplifies the special-case handling
1274 * for INT_MIN below.
1275 *
1276 * We do this in negative space in order to handle INT_MIN.
1277 */
1278 a1 = (arg1 < 0) ? arg1 : -arg1;
1279 a2 = (arg2 < 0) ? arg2 : -arg2;
1280 if (a1 > a2)
1281 {
1282 swap = arg1;
1283 arg1 = arg2;
1284 arg2 = swap;
1285 }
1286
1287 /* Special care needs to be taken with INT_MIN. See comments above. */
1288 if (arg1 == PG_INT32_MIN)
1289 {
1290 if (arg2 == 0 || arg2 == PG_INT32_MIN)
1291 ereport(ERROR,
1293 errmsg("integer out of range")));
1294
1295 /*
1296 * Some machines throw a floating-point exception for INT_MIN % -1,
1297 * which is a bit silly since the correct answer is perfectly
1298 * well-defined, namely zero. Guard against this and just return the
1299 * result, gcd(INT_MIN, -1) = 1.
1300 */
1301 if (arg2 == -1)
1302 return 1;
1303 }
1304
1305 /* Use the Euclidean algorithm to find the GCD */
1306 while (arg2 != 0)
1307 {
1308 swap = arg2;
1309 arg2 = arg1 % arg2;
1310 arg1 = swap;
1311 }
1312
1313 /*
1314 * Make sure the result is positive. (We know we don't have INT_MIN
1315 * anymore).
1316 */
1317 if (arg1 < 0)
1318 arg1 = -arg1;
1319
1320 return arg1;
1321}
1322
1323Datum
1334
1335/*
1336 * Least Common Multiple
1337 */
1338Datum
1340{
1343 int32 gcd;
1344 int32 result;
1345
1346 /*
1347 * Handle lcm(x, 0) = lcm(0, x) = 0 as a special case. This prevents a
1348 * division-by-zero error below when x is zero, and an overflow error from
1349 * the GCD computation when x = INT_MIN.
1350 */
1351 if (arg1 == 0 || arg2 == 0)
1352 PG_RETURN_INT32(0);
1353
1354 /* lcm(x, y) = abs(x / gcd(x, y) * y) */
1356 arg1 = arg1 / gcd;
1357
1359 ereport(ERROR,
1361 errmsg("integer out of range")));
1362
1363 /* If the result is INT_MIN, it cannot be represented. */
1365 ereport(ERROR,
1367 errmsg("integer out of range")));
1368
1369 if (result < 0)
1370 result = -result;
1371
1373}
1374
1375Datum
1383
1384Datum
1392
1393Datum
1401
1402Datum
1410
1411/*
1412 * Bit-pushing operators
1413 *
1414 * int[24]and - returns arg1 & arg2
1415 * int[24]or - returns arg1 | arg2
1416 * int[24]xor - returns arg1 # arg2
1417 * int[24]not - returns ~arg1
1418 * int[24]shl - returns arg1 << arg2
1419 * int[24]shr - returns arg1 >> arg2
1420 */
1421
1422Datum
1430
1431Datum
1439
1440Datum
1448
1449Datum
1457
1458Datum
1466
1467Datum
1474
1475Datum
1483
1484Datum
1492
1493Datum
1501
1502Datum
1509
1510
1511Datum
1519
1520Datum
1528
1529/*
1530 * non-persistent numeric series generator
1531 */
1532Datum
1537
1538Datum
1540{
1543 int32 result;
1544 MemoryContext oldcontext;
1545
1546 /* stuff done only on the first call of the function */
1547 if (SRF_IS_FIRSTCALL())
1548 {
1550 int32 finish = PG_GETARG_INT32(1);
1551 int32 step = 1;
1552
1553 /* see if we were given an explicit step size */
1554 if (PG_NARGS() == 3)
1555 step = PG_GETARG_INT32(2);
1556 if (step == 0)
1557 ereport(ERROR,
1559 errmsg("step size cannot equal zero")));
1560
1561 /* create a function context for cross-call persistence */
1563
1564 /*
1565 * switch to memory context appropriate for multiple function calls
1566 */
1567 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1568
1569 /* allocate memory for user context */
1571
1572 /*
1573 * Use fctx to keep state from call to call. Seed current with the
1574 * original start value
1575 */
1576 fctx->current = start;
1577 fctx->finish = finish;
1578 fctx->step = step;
1579
1580 funcctx->user_fctx = fctx;
1581 MemoryContextSwitchTo(oldcontext);
1582 }
1583
1584 /* stuff done on every call of the function */
1586
1587 /*
1588 * get the saved state and use current as the result for this iteration
1589 */
1590 fctx = funcctx->user_fctx;
1591 result = fctx->current;
1592
1593 if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1594 (fctx->step < 0 && fctx->current >= fctx->finish))
1595 {
1596 /*
1597 * Increment current in preparation for next iteration. If next-value
1598 * computation overflows, this is the final result.
1599 */
1600 if (pg_add_s32_overflow(fctx->current, fctx->step, &fctx->current))
1601 fctx->step = 0;
1602
1603 /* do when there is more left to send */
1605 }
1606 else
1607 /* do when there is no more left */
1609}
1610
1611/*
1612 * Planner support function for generate_series(int4, int4 [, int4])
1613 */
1614Datum
1616{
1618 Node *ret = NULL;
1619
1621 {
1622 /* Try to estimate the number of rows returned */
1624
1625 if (is_funcclause(req->node)) /* be paranoid */
1626 {
1627 List *args = ((FuncExpr *) req->node)->args;
1628 Node *arg1,
1629 *arg2,
1630 *arg3;
1631
1632 /* We can use estimated argument values here */
1634 arg2 = estimate_expression_value(req->root, lsecond(args));
1635 if (list_length(args) >= 3)
1636 arg3 = estimate_expression_value(req->root, lthird(args));
1637 else
1638 arg3 = NULL;
1639
1640 /*
1641 * If any argument is constant NULL, we can safely assume that
1642 * zero rows are returned. Otherwise, if they're all non-NULL
1643 * constants, we can calculate the number of rows that will be
1644 * returned. Use double arithmetic to avoid overflow hazards.
1645 */
1646 if ((IsA(arg1, Const) &&
1647 ((Const *) arg1)->constisnull) ||
1648 (IsA(arg2, Const) &&
1649 ((Const *) arg2)->constisnull) ||
1650 (arg3 != NULL && IsA(arg3, Const) &&
1651 ((Const *) arg3)->constisnull))
1652 {
1653 req->rows = 0;
1654 ret = (Node *) req;
1655 }
1656 else if (IsA(arg1, Const) &&
1657 IsA(arg2, Const) &&
1658 (arg3 == NULL || IsA(arg3, Const)))
1659 {
1660 double start,
1661 finish,
1662 step;
1663
1665 finish = DatumGetInt32(((Const *) arg2)->constvalue);
1666 step = arg3 ? DatumGetInt32(((Const *) arg3)->constvalue) : 1;
1667
1668 /* This equation works for either sign of step */
1669 if (step != 0)
1670 {
1671 req->rows = floor((finish - start + step) / step);
1672 ret = (Node *) req;
1673 }
1674 }
1675 }
1676 }
1677
1678 PG_RETURN_POINTER(ret);
1679}
#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:943
int64_t int64
Definition c.h:621
int16_t int16
Definition c.h:619
#define PG_INT16_MIN
Definition c.h:669
int32_t int32
Definition c.h:620
#define unlikely(x)
Definition c.h:438
#define PG_INT32_MIN
Definition c.h:672
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition clauses.c:2641
Datum arg
Definition elog.c:1323
int errcode(int sqlerrcode)
Definition elog.c:875
#define ereturn(context, dummy_value,...)
Definition elog.h:280
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
#define palloc_object(type)
Definition fe_memutils.h:89
#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:696
#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:862
Datum int4shl(PG_FUNCTION_ARGS)
Definition int.c:1450
Datum int2vectorrecv(PG_FUNCTION_ARGS)
Definition int.c:259
Datum int2not(PG_FUNCTION_ARGS)
Definition int.c:1503
Datum int4pl(PG_FUNCTION_ARGS)
Definition int.c:820
Datum int2xor(PG_FUNCTION_ARGS)
Definition int.c:1494
Datum generate_series_int4(PG_FUNCTION_ARGS)
Definition int.c:1533
Datum int4recv(PG_FUNCTION_ARGS)
Definition int.c:340
Datum int4um(PG_FUNCTION_ARGS)
Definition int.c:800
Datum int4gt(PG_FUNCTION_ARGS)
Definition int.c:461
Datum int24eq(PG_FUNCTION_ARGS)
Definition int.c:533
Datum int2lt(PG_FUNCTION_ARGS)
Definition int.c:497
Datum int24mi(PG_FUNCTION_ARGS)
Definition int.c:1031
Datum int2out(PG_FUNCTION_ARGS)
Definition int.c:74
Datum int2eq(PG_FUNCTION_ARGS)
Definition int.c:479
Datum int42eq(PG_FUNCTION_ARGS)
Definition int.c:587
Datum int2ge(PG_FUNCTION_ARGS)
Definition int.c:524
Datum int2up(PG_FUNCTION_ARGS)
Definition int.c:927
Datum int4gcd(PG_FUNCTION_ARGS)
Definition int.c:1324
Datum int42ge(PG_FUNCTION_ARGS)
Definition int.c:632
Datum int42mul(PG_FUNCTION_ARGS)
Definition int.c:1106
Datum int24gt(PG_FUNCTION_ARGS)
Definition int.c:569
Datum int2le(PG_FUNCTION_ARGS)
Definition int.c:506
Datum int2abs(PG_FUNCTION_ARGS)
Definition int.c:1235
#define Int2VectorSize(n)
Definition int.c:45
Datum int4lt(PG_FUNCTION_ARGS)
Definition int.c:443
Datum int2um(PG_FUNCTION_ARGS)
Definition int.c:915
Datum int2shl(PG_FUNCTION_ARGS)
Definition int.c:1512
Datum in_range_int2_int8(PG_FUNCTION_ARGS)
Definition int.c:780
Datum int42div(PG_FUNCTION_ARGS)
Definition int.c:1120
static void check_valid_int2vector(const int2vector *int2Array)
Definition int.c:145
Datum int2mi(PG_FUNCTION_ARGS)
Definition int.c:949
Datum int2ne(PG_FUNCTION_ARGS)
Definition int.c:488
Datum int24le(PG_FUNCTION_ARGS)
Definition int.c:560
Datum int2send(PG_FUNCTION_ARGS)
Definition int.c:98
Datum int2mul(PG_FUNCTION_ARGS)
Definition int.c:963
Datum int2smaller(PG_FUNCTION_ARGS)
Definition int.c:1385
Datum int2mod(PG_FUNCTION_ARGS)
Definition int.c:1187
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:1045
Datum int42gt(PG_FUNCTION_ARGS)
Definition int.c:623
Datum int4lcm(PG_FUNCTION_ARGS)
Definition int.c:1339
Datum in_range_int4_int8(PG_FUNCTION_ARGS)
Definition int.c:698
Datum int2div(PG_FUNCTION_ARGS)
Definition int.c:978
Datum in_range_int2_int2(PG_FUNCTION_ARGS)
Definition int.c:768
Datum int4in(PG_FUNCTION_ARGS)
Definition int.c:316
Datum int2shr(PG_FUNCTION_ARGS)
Definition int.c:1521
Datum in_range_int2_int4(PG_FUNCTION_ARGS)
Definition int.c:733
static int32 int4gcd_internal(int32 arg1, int32 arg2)
Definition int.c:1263
Datum int2vectorout(PG_FUNCTION_ARGS)
Definition int.c:231
Datum i4toi2(PG_FUNCTION_ARGS)
Definition int.c:377
Datum int4ge(PG_FUNCTION_ARGS)
Definition int.c:470
Datum int4and(PG_FUNCTION_ARGS)
Definition int.c:1423
Datum int4send(PG_FUNCTION_ARGS)
Definition int.c:351
Datum int24ge(PG_FUNCTION_ARGS)
Definition int.c:578
Datum in_range_int4_int2(PG_FUNCTION_ARGS)
Definition int.c:686
Datum int2vectorin(PG_FUNCTION_ARGS)
Definition int.c:165
Datum bool_int4(PG_FUNCTION_ARGS)
Definition int.c:401
Datum int4inc(PG_FUNCTION_ARGS)
Definition int.c:901
Datum int4shr(PG_FUNCTION_ARGS)
Definition int.c:1459
Datum int4larger(PG_FUNCTION_ARGS)
Definition int.c:1394
Datum int24ne(PG_FUNCTION_ARGS)
Definition int.c:542
Datum int2gt(PG_FUNCTION_ARGS)
Definition int.c:515
Datum int24lt(PG_FUNCTION_ARGS)
Definition int.c:551
Datum int42pl(PG_FUNCTION_ARGS)
Definition int.c:1078
Datum in_range_int4_int4(PG_FUNCTION_ARGS)
Definition int.c:652
Datum int4ne(PG_FUNCTION_ARGS)
Definition int.c:434
Datum int42le(PG_FUNCTION_ARGS)
Definition int.c:614
Datum i2toi4(PG_FUNCTION_ARGS)
Definition int.c:369
Datum int4smaller(PG_FUNCTION_ARGS)
Definition int.c:1403
Datum int24pl(PG_FUNCTION_ARGS)
Definition int.c:1017
Datum int4_bool(PG_FUNCTION_ARGS)
Definition int.c:391
Datum int4mod(PG_FUNCTION_ARGS)
Definition int.c:1159
Datum int24div(PG_FUNCTION_ARGS)
Definition int.c:1059
Datum int4xor(PG_FUNCTION_ARGS)
Definition int.c:1441
Datum generate_series_step_int4(PG_FUNCTION_ARGS)
Definition int.c:1539
Datum int2larger(PG_FUNCTION_ARGS)
Definition int.c:1376
Datum int2and(PG_FUNCTION_ARGS)
Definition int.c:1476
Datum int4not(PG_FUNCTION_ARGS)
Definition int.c:1468
Datum int4abs(PG_FUNCTION_ARGS)
Definition int.c:1221
Datum int4out(PG_FUNCTION_ARGS)
Definition int.c:327
Datum generate_series_int4_support(PG_FUNCTION_ARGS)
Definition int.c:1615
Datum int4mul(PG_FUNCTION_ARGS)
Definition int.c:848
Datum int4eq(PG_FUNCTION_ARGS)
Definition int.c:425
Datum int4le(PG_FUNCTION_ARGS)
Definition int.c:452
Datum int42ne(PG_FUNCTION_ARGS)
Definition int.c:596
Datum int4mi(PG_FUNCTION_ARGS)
Definition int.c:834
Datum int42lt(PG_FUNCTION_ARGS)
Definition int.c:605
Datum int2pl(PG_FUNCTION_ARGS)
Definition int.c:935
Datum int4up(PG_FUNCTION_ARGS)
Definition int.c:812
Datum int2vectorsend(PG_FUNCTION_ARGS)
Definition int.c:301
Datum int2recv(PG_FUNCTION_ARGS)
Definition int.c:87
Datum int42mi(PG_FUNCTION_ARGS)
Definition int.c:1092
Datum int4or(PG_FUNCTION_ARGS)
Definition int.c:1432
Datum int2or(PG_FUNCTION_ARGS)
Definition int.c:1485
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:1635
void * palloc0(Size size)
Definition mcxt.c:1420
void * palloc(Size size)
Definition mcxt.c:1390
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 char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
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 ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define PointerGetDatum(X)
Definition postgres.h:354
#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
static uint32 gcd(uint32 a, uint32 b)
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432