Coverage Report

Created: 2025-08-12 06:43

/src/postgres/src/backend/utils/adt/int8.c
Line
Count
Source (jump to first uncovered line)
1
/*-------------------------------------------------------------------------
2
 *
3
 * int8.c
4
 *    Internal 64-bit integer operations
5
 *
6
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 * IDENTIFICATION
10
 *    src/backend/utils/adt/int8.c
11
 *
12
 *-------------------------------------------------------------------------
13
 */
14
#include "postgres.h"
15
16
#include <ctype.h>
17
#include <limits.h>
18
#include <math.h>
19
20
#include "common/int.h"
21
#include "funcapi.h"
22
#include "libpq/pqformat.h"
23
#include "nodes/nodeFuncs.h"
24
#include "nodes/supportnodes.h"
25
#include "optimizer/optimizer.h"
26
#include "utils/builtins.h"
27
28
29
typedef struct
30
{
31
  int64   current;
32
  int64   finish;
33
  int64   step;
34
} generate_series_fctx;
35
36
37
/***********************************************************************
38
 **
39
 **   Routines for 64-bit integers.
40
 **
41
 ***********************************************************************/
42
43
/*----------------------------------------------------------
44
 * Formatting and conversion routines.
45
 *---------------------------------------------------------*/
46
47
/* int8in()
48
 */
49
Datum
50
int8in(PG_FUNCTION_ARGS)
51
0
{
52
0
  char     *num = PG_GETARG_CSTRING(0);
53
54
0
  PG_RETURN_INT64(pg_strtoint64_safe(num, fcinfo->context));
55
0
}
56
57
58
/* int8out()
59
 */
60
Datum
61
int8out(PG_FUNCTION_ARGS)
62
0
{
63
0
  int64   val = PG_GETARG_INT64(0);
64
0
  char    buf[MAXINT8LEN + 1];
65
0
  char     *result;
66
0
  int     len;
67
68
0
  len = pg_lltoa(val, buf) + 1;
69
70
  /*
71
   * Since the length is already known, we do a manual palloc() and memcpy()
72
   * to avoid the strlen() call that would otherwise be done in pstrdup().
73
   */
74
0
  result = palloc(len);
75
0
  memcpy(result, buf, len);
76
0
  PG_RETURN_CSTRING(result);
77
0
}
78
79
/*
80
 *    int8recv      - converts external binary format to int8
81
 */
82
Datum
83
int8recv(PG_FUNCTION_ARGS)
84
0
{
85
0
  StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
86
87
0
  PG_RETURN_INT64(pq_getmsgint64(buf));
88
0
}
89
90
/*
91
 *    int8send      - converts int8 to binary format
92
 */
93
Datum
94
int8send(PG_FUNCTION_ARGS)
95
0
{
96
0
  int64   arg1 = PG_GETARG_INT64(0);
97
0
  StringInfoData buf;
98
99
0
  pq_begintypsend(&buf);
100
0
  pq_sendint64(&buf, arg1);
101
0
  PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
102
0
}
103
104
105
/*----------------------------------------------------------
106
 *  Relational operators for int8s, including cross-data-type comparisons.
107
 *---------------------------------------------------------*/
108
109
/* int8relop()
110
 * Is val1 relop val2?
111
 */
112
Datum
113
int8eq(PG_FUNCTION_ARGS)
114
0
{
115
0
  int64   val1 = PG_GETARG_INT64(0);
116
0
  int64   val2 = PG_GETARG_INT64(1);
117
118
0
  PG_RETURN_BOOL(val1 == val2);
119
0
}
120
121
Datum
122
int8ne(PG_FUNCTION_ARGS)
123
0
{
124
0
  int64   val1 = PG_GETARG_INT64(0);
125
0
  int64   val2 = PG_GETARG_INT64(1);
126
127
0
  PG_RETURN_BOOL(val1 != val2);
128
0
}
129
130
Datum
131
int8lt(PG_FUNCTION_ARGS)
132
0
{
133
0
  int64   val1 = PG_GETARG_INT64(0);
134
0
  int64   val2 = PG_GETARG_INT64(1);
135
136
0
  PG_RETURN_BOOL(val1 < val2);
137
0
}
138
139
Datum
140
int8gt(PG_FUNCTION_ARGS)
141
0
{
142
0
  int64   val1 = PG_GETARG_INT64(0);
143
0
  int64   val2 = PG_GETARG_INT64(1);
144
145
0
  PG_RETURN_BOOL(val1 > val2);
146
0
}
147
148
Datum
149
int8le(PG_FUNCTION_ARGS)
150
0
{
151
0
  int64   val1 = PG_GETARG_INT64(0);
152
0
  int64   val2 = PG_GETARG_INT64(1);
153
154
0
  PG_RETURN_BOOL(val1 <= val2);
155
0
}
156
157
Datum
158
int8ge(PG_FUNCTION_ARGS)
159
0
{
160
0
  int64   val1 = PG_GETARG_INT64(0);
161
0
  int64   val2 = PG_GETARG_INT64(1);
162
163
0
  PG_RETURN_BOOL(val1 >= val2);
164
0
}
165
166
/* int84relop()
167
 * Is 64-bit val1 relop 32-bit val2?
168
 */
169
Datum
170
int84eq(PG_FUNCTION_ARGS)
171
0
{
172
0
  int64   val1 = PG_GETARG_INT64(0);
173
0
  int32   val2 = PG_GETARG_INT32(1);
174
175
0
  PG_RETURN_BOOL(val1 == val2);
176
0
}
177
178
Datum
179
int84ne(PG_FUNCTION_ARGS)
180
0
{
181
0
  int64   val1 = PG_GETARG_INT64(0);
182
0
  int32   val2 = PG_GETARG_INT32(1);
183
184
0
  PG_RETURN_BOOL(val1 != val2);
185
0
}
186
187
Datum
188
int84lt(PG_FUNCTION_ARGS)
189
0
{
190
0
  int64   val1 = PG_GETARG_INT64(0);
191
0
  int32   val2 = PG_GETARG_INT32(1);
192
193
0
  PG_RETURN_BOOL(val1 < val2);
194
0
}
195
196
Datum
197
int84gt(PG_FUNCTION_ARGS)
198
0
{
199
0
  int64   val1 = PG_GETARG_INT64(0);
200
0
  int32   val2 = PG_GETARG_INT32(1);
201
202
0
  PG_RETURN_BOOL(val1 > val2);
203
0
}
204
205
Datum
206
int84le(PG_FUNCTION_ARGS)
207
0
{
208
0
  int64   val1 = PG_GETARG_INT64(0);
209
0
  int32   val2 = PG_GETARG_INT32(1);
210
211
0
  PG_RETURN_BOOL(val1 <= val2);
212
0
}
213
214
Datum
215
int84ge(PG_FUNCTION_ARGS)
216
0
{
217
0
  int64   val1 = PG_GETARG_INT64(0);
218
0
  int32   val2 = PG_GETARG_INT32(1);
219
220
0
  PG_RETURN_BOOL(val1 >= val2);
221
0
}
222
223
/* int48relop()
224
 * Is 32-bit val1 relop 64-bit val2?
225
 */
226
Datum
227
int48eq(PG_FUNCTION_ARGS)
228
0
{
229
0
  int32   val1 = PG_GETARG_INT32(0);
230
0
  int64   val2 = PG_GETARG_INT64(1);
231
232
0
  PG_RETURN_BOOL(val1 == val2);
233
0
}
234
235
Datum
236
int48ne(PG_FUNCTION_ARGS)
237
0
{
238
0
  int32   val1 = PG_GETARG_INT32(0);
239
0
  int64   val2 = PG_GETARG_INT64(1);
240
241
0
  PG_RETURN_BOOL(val1 != val2);
242
0
}
243
244
Datum
245
int48lt(PG_FUNCTION_ARGS)
246
0
{
247
0
  int32   val1 = PG_GETARG_INT32(0);
248
0
  int64   val2 = PG_GETARG_INT64(1);
249
250
0
  PG_RETURN_BOOL(val1 < val2);
251
0
}
252
253
Datum
254
int48gt(PG_FUNCTION_ARGS)
255
0
{
256
0
  int32   val1 = PG_GETARG_INT32(0);
257
0
  int64   val2 = PG_GETARG_INT64(1);
258
259
0
  PG_RETURN_BOOL(val1 > val2);
260
0
}
261
262
Datum
263
int48le(PG_FUNCTION_ARGS)
264
0
{
265
0
  int32   val1 = PG_GETARG_INT32(0);
266
0
  int64   val2 = PG_GETARG_INT64(1);
267
268
0
  PG_RETURN_BOOL(val1 <= val2);
269
0
}
270
271
Datum
272
int48ge(PG_FUNCTION_ARGS)
273
0
{
274
0
  int32   val1 = PG_GETARG_INT32(0);
275
0
  int64   val2 = PG_GETARG_INT64(1);
276
277
0
  PG_RETURN_BOOL(val1 >= val2);
278
0
}
279
280
/* int82relop()
281
 * Is 64-bit val1 relop 16-bit val2?
282
 */
283
Datum
284
int82eq(PG_FUNCTION_ARGS)
285
0
{
286
0
  int64   val1 = PG_GETARG_INT64(0);
287
0
  int16   val2 = PG_GETARG_INT16(1);
288
289
0
  PG_RETURN_BOOL(val1 == val2);
290
0
}
291
292
Datum
293
int82ne(PG_FUNCTION_ARGS)
294
0
{
295
0
  int64   val1 = PG_GETARG_INT64(0);
296
0
  int16   val2 = PG_GETARG_INT16(1);
297
298
0
  PG_RETURN_BOOL(val1 != val2);
299
0
}
300
301
Datum
302
int82lt(PG_FUNCTION_ARGS)
303
0
{
304
0
  int64   val1 = PG_GETARG_INT64(0);
305
0
  int16   val2 = PG_GETARG_INT16(1);
306
307
0
  PG_RETURN_BOOL(val1 < val2);
308
0
}
309
310
Datum
311
int82gt(PG_FUNCTION_ARGS)
312
0
{
313
0
  int64   val1 = PG_GETARG_INT64(0);
314
0
  int16   val2 = PG_GETARG_INT16(1);
315
316
0
  PG_RETURN_BOOL(val1 > val2);
317
0
}
318
319
Datum
320
int82le(PG_FUNCTION_ARGS)
321
0
{
322
0
  int64   val1 = PG_GETARG_INT64(0);
323
0
  int16   val2 = PG_GETARG_INT16(1);
324
325
0
  PG_RETURN_BOOL(val1 <= val2);
326
0
}
327
328
Datum
329
int82ge(PG_FUNCTION_ARGS)
330
0
{
331
0
  int64   val1 = PG_GETARG_INT64(0);
332
0
  int16   val2 = PG_GETARG_INT16(1);
333
334
0
  PG_RETURN_BOOL(val1 >= val2);
335
0
}
336
337
/* int28relop()
338
 * Is 16-bit val1 relop 64-bit val2?
339
 */
340
Datum
341
int28eq(PG_FUNCTION_ARGS)
342
0
{
343
0
  int16   val1 = PG_GETARG_INT16(0);
344
0
  int64   val2 = PG_GETARG_INT64(1);
345
346
0
  PG_RETURN_BOOL(val1 == val2);
347
0
}
348
349
Datum
350
int28ne(PG_FUNCTION_ARGS)
351
0
{
352
0
  int16   val1 = PG_GETARG_INT16(0);
353
0
  int64   val2 = PG_GETARG_INT64(1);
354
355
0
  PG_RETURN_BOOL(val1 != val2);
356
0
}
357
358
Datum
359
int28lt(PG_FUNCTION_ARGS)
360
0
{
361
0
  int16   val1 = PG_GETARG_INT16(0);
362
0
  int64   val2 = PG_GETARG_INT64(1);
363
364
0
  PG_RETURN_BOOL(val1 < val2);
365
0
}
366
367
Datum
368
int28gt(PG_FUNCTION_ARGS)
369
0
{
370
0
  int16   val1 = PG_GETARG_INT16(0);
371
0
  int64   val2 = PG_GETARG_INT64(1);
372
373
0
  PG_RETURN_BOOL(val1 > val2);
374
0
}
375
376
Datum
377
int28le(PG_FUNCTION_ARGS)
378
0
{
379
0
  int16   val1 = PG_GETARG_INT16(0);
380
0
  int64   val2 = PG_GETARG_INT64(1);
381
382
0
  PG_RETURN_BOOL(val1 <= val2);
383
0
}
384
385
Datum
386
int28ge(PG_FUNCTION_ARGS)
387
0
{
388
0
  int16   val1 = PG_GETARG_INT16(0);
389
0
  int64   val2 = PG_GETARG_INT64(1);
390
391
0
  PG_RETURN_BOOL(val1 >= val2);
392
0
}
393
394
/*
395
 * in_range support function for int8.
396
 *
397
 * Note: we needn't supply int8_int4 or int8_int2 variants, as implicit
398
 * coercion of the offset value takes care of those scenarios just as well.
399
 */
400
Datum
401
in_range_int8_int8(PG_FUNCTION_ARGS)
402
0
{
403
0
  int64   val = PG_GETARG_INT64(0);
404
0
  int64   base = PG_GETARG_INT64(1);
405
0
  int64   offset = PG_GETARG_INT64(2);
406
0
  bool    sub = PG_GETARG_BOOL(3);
407
0
  bool    less = PG_GETARG_BOOL(4);
408
0
  int64   sum;
409
410
0
  if (offset < 0)
411
0
    ereport(ERROR,
412
0
        (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
413
0
         errmsg("invalid preceding or following size in window function")));
414
415
0
  if (sub)
416
0
    offset = -offset;   /* cannot overflow */
417
418
0
  if (unlikely(pg_add_s64_overflow(base, offset, &sum)))
419
0
  {
420
    /*
421
     * If sub is false, the true sum is surely more than val, so correct
422
     * answer is the same as "less".  If sub is true, the true sum is
423
     * surely less than val, so the answer is "!less".
424
     */
425
0
    PG_RETURN_BOOL(sub ? !less : less);
426
0
  }
427
428
0
  if (less)
429
0
    PG_RETURN_BOOL(val <= sum);
430
0
  else
431
0
    PG_RETURN_BOOL(val >= sum);
432
0
}
433
434
435
/*----------------------------------------------------------
436
 *  Arithmetic operators on 64-bit integers.
437
 *---------------------------------------------------------*/
438
439
Datum
440
int8um(PG_FUNCTION_ARGS)
441
0
{
442
0
  int64   arg = PG_GETARG_INT64(0);
443
0
  int64   result;
444
445
0
  if (unlikely(arg == PG_INT64_MIN))
446
0
    ereport(ERROR,
447
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
448
0
         errmsg("bigint out of range")));
449
0
  result = -arg;
450
0
  PG_RETURN_INT64(result);
451
0
}
452
453
Datum
454
int8up(PG_FUNCTION_ARGS)
455
0
{
456
0
  int64   arg = PG_GETARG_INT64(0);
457
458
0
  PG_RETURN_INT64(arg);
459
0
}
460
461
Datum
462
int8pl(PG_FUNCTION_ARGS)
463
0
{
464
0
  int64   arg1 = PG_GETARG_INT64(0);
465
0
  int64   arg2 = PG_GETARG_INT64(1);
466
0
  int64   result;
467
468
0
  if (unlikely(pg_add_s64_overflow(arg1, arg2, &result)))
469
0
    ereport(ERROR,
470
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
471
0
         errmsg("bigint out of range")));
472
0
  PG_RETURN_INT64(result);
473
0
}
474
475
Datum
476
int8mi(PG_FUNCTION_ARGS)
477
0
{
478
0
  int64   arg1 = PG_GETARG_INT64(0);
479
0
  int64   arg2 = PG_GETARG_INT64(1);
480
0
  int64   result;
481
482
0
  if (unlikely(pg_sub_s64_overflow(arg1, arg2, &result)))
483
0
    ereport(ERROR,
484
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
485
0
         errmsg("bigint out of range")));
486
0
  PG_RETURN_INT64(result);
487
0
}
488
489
Datum
490
int8mul(PG_FUNCTION_ARGS)
491
0
{
492
0
  int64   arg1 = PG_GETARG_INT64(0);
493
0
  int64   arg2 = PG_GETARG_INT64(1);
494
0
  int64   result;
495
496
0
  if (unlikely(pg_mul_s64_overflow(arg1, arg2, &result)))
497
0
    ereport(ERROR,
498
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
499
0
         errmsg("bigint out of range")));
500
0
  PG_RETURN_INT64(result);
501
0
}
502
503
Datum
504
int8div(PG_FUNCTION_ARGS)
505
0
{
506
0
  int64   arg1 = PG_GETARG_INT64(0);
507
0
  int64   arg2 = PG_GETARG_INT64(1);
508
0
  int64   result;
509
510
0
  if (arg2 == 0)
511
0
  {
512
0
    ereport(ERROR,
513
0
        (errcode(ERRCODE_DIVISION_BY_ZERO),
514
0
         errmsg("division by zero")));
515
    /* ensure compiler realizes we mustn't reach the division (gcc bug) */
516
0
    PG_RETURN_NULL();
517
0
  }
518
519
  /*
520
   * INT64_MIN / -1 is problematic, since the result can't be represented on
521
   * a two's-complement machine.  Some machines produce INT64_MIN, some
522
   * produce zero, some throw an exception.  We can dodge the problem by
523
   * recognizing that division by -1 is the same as negation.
524
   */
525
0
  if (arg2 == -1)
526
0
  {
527
0
    if (unlikely(arg1 == PG_INT64_MIN))
528
0
      ereport(ERROR,
529
0
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
530
0
           errmsg("bigint out of range")));
531
0
    result = -arg1;
532
0
    PG_RETURN_INT64(result);
533
0
  }
534
535
  /* No overflow is possible */
536
537
0
  result = arg1 / arg2;
538
539
0
  PG_RETURN_INT64(result);
540
0
}
541
542
/* int8abs()
543
 * Absolute value
544
 */
545
Datum
546
int8abs(PG_FUNCTION_ARGS)
547
0
{
548
0
  int64   arg1 = PG_GETARG_INT64(0);
549
0
  int64   result;
550
551
0
  if (unlikely(arg1 == PG_INT64_MIN))
552
0
    ereport(ERROR,
553
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
554
0
         errmsg("bigint out of range")));
555
0
  result = (arg1 < 0) ? -arg1 : arg1;
556
0
  PG_RETURN_INT64(result);
557
0
}
558
559
/* int8mod()
560
 * Modulo operation.
561
 */
562
Datum
563
int8mod(PG_FUNCTION_ARGS)
564
0
{
565
0
  int64   arg1 = PG_GETARG_INT64(0);
566
0
  int64   arg2 = PG_GETARG_INT64(1);
567
568
0
  if (unlikely(arg2 == 0))
569
0
  {
570
0
    ereport(ERROR,
571
0
        (errcode(ERRCODE_DIVISION_BY_ZERO),
572
0
         errmsg("division by zero")));
573
    /* ensure compiler realizes we mustn't reach the division (gcc bug) */
574
0
    PG_RETURN_NULL();
575
0
  }
576
577
  /*
578
   * Some machines throw a floating-point exception for INT64_MIN % -1,
579
   * which is a bit silly since the correct answer is perfectly
580
   * well-defined, namely zero.
581
   */
582
0
  if (arg2 == -1)
583
0
    PG_RETURN_INT64(0);
584
585
  /* No overflow is possible */
586
587
0
  PG_RETURN_INT64(arg1 % arg2);
588
0
}
589
590
/*
591
 * Greatest Common Divisor
592
 *
593
 * Returns the largest positive integer that exactly divides both inputs.
594
 * Special cases:
595
 *   - gcd(x, 0) = gcd(0, x) = abs(x)
596
 *      because 0 is divisible by anything
597
 *   - gcd(0, 0) = 0
598
 *      complies with the previous definition and is a common convention
599
 *
600
 * Special care must be taken if either input is INT64_MIN ---
601
 * gcd(0, INT64_MIN), gcd(INT64_MIN, 0) and gcd(INT64_MIN, INT64_MIN) are
602
 * all equal to abs(INT64_MIN), which cannot be represented as a 64-bit signed
603
 * integer.
604
 */
605
static int64
606
int8gcd_internal(int64 arg1, int64 arg2)
607
0
{
608
0
  int64   swap;
609
0
  int64   a1,
610
0
        a2;
611
612
  /*
613
   * Put the greater absolute value in arg1.
614
   *
615
   * This would happen automatically in the loop below, but avoids an
616
   * expensive modulo operation, and simplifies the special-case handling
617
   * for INT64_MIN below.
618
   *
619
   * We do this in negative space in order to handle INT64_MIN.
620
   */
621
0
  a1 = (arg1 < 0) ? arg1 : -arg1;
622
0
  a2 = (arg2 < 0) ? arg2 : -arg2;
623
0
  if (a1 > a2)
624
0
  {
625
0
    swap = arg1;
626
0
    arg1 = arg2;
627
0
    arg2 = swap;
628
0
  }
629
630
  /* Special care needs to be taken with INT64_MIN.  See comments above. */
631
0
  if (arg1 == PG_INT64_MIN)
632
0
  {
633
0
    if (arg2 == 0 || arg2 == PG_INT64_MIN)
634
0
      ereport(ERROR,
635
0
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
636
0
           errmsg("bigint out of range")));
637
638
    /*
639
     * Some machines throw a floating-point exception for INT64_MIN % -1,
640
     * which is a bit silly since the correct answer is perfectly
641
     * well-defined, namely zero.  Guard against this and just return the
642
     * result, gcd(INT64_MIN, -1) = 1.
643
     */
644
0
    if (arg2 == -1)
645
0
      return 1;
646
0
  }
647
648
  /* Use the Euclidean algorithm to find the GCD */
649
0
  while (arg2 != 0)
650
0
  {
651
0
    swap = arg2;
652
0
    arg2 = arg1 % arg2;
653
0
    arg1 = swap;
654
0
  }
655
656
  /*
657
   * Make sure the result is positive. (We know we don't have INT64_MIN
658
   * anymore).
659
   */
660
0
  if (arg1 < 0)
661
0
    arg1 = -arg1;
662
663
0
  return arg1;
664
0
}
665
666
Datum
667
int8gcd(PG_FUNCTION_ARGS)
668
0
{
669
0
  int64   arg1 = PG_GETARG_INT64(0);
670
0
  int64   arg2 = PG_GETARG_INT64(1);
671
0
  int64   result;
672
673
0
  result = int8gcd_internal(arg1, arg2);
674
675
0
  PG_RETURN_INT64(result);
676
0
}
677
678
/*
679
 * Least Common Multiple
680
 */
681
Datum
682
int8lcm(PG_FUNCTION_ARGS)
683
0
{
684
0
  int64   arg1 = PG_GETARG_INT64(0);
685
0
  int64   arg2 = PG_GETARG_INT64(1);
686
0
  int64   gcd;
687
0
  int64   result;
688
689
  /*
690
   * Handle lcm(x, 0) = lcm(0, x) = 0 as a special case.  This prevents a
691
   * division-by-zero error below when x is zero, and an overflow error from
692
   * the GCD computation when x = INT64_MIN.
693
   */
694
0
  if (arg1 == 0 || arg2 == 0)
695
0
    PG_RETURN_INT64(0);
696
697
  /* lcm(x, y) = abs(x / gcd(x, y) * y) */
698
0
  gcd = int8gcd_internal(arg1, arg2);
699
0
  arg1 = arg1 / gcd;
700
701
0
  if (unlikely(pg_mul_s64_overflow(arg1, arg2, &result)))
702
0
    ereport(ERROR,
703
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
704
0
         errmsg("bigint out of range")));
705
706
  /* If the result is INT64_MIN, it cannot be represented. */
707
0
  if (unlikely(result == PG_INT64_MIN))
708
0
    ereport(ERROR,
709
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
710
0
         errmsg("bigint out of range")));
711
712
0
  if (result < 0)
713
0
    result = -result;
714
715
0
  PG_RETURN_INT64(result);
716
0
}
717
718
Datum
719
int8inc(PG_FUNCTION_ARGS)
720
0
{
721
  /*
722
   * When int8 is pass-by-reference, we provide this special case to avoid
723
   * palloc overhead for COUNT(): when called as an aggregate, we know that
724
   * the argument is modifiable local storage, so just update it in-place.
725
   * (If int8 is pass-by-value, then of course this is useless as well as
726
   * incorrect, so just ifdef it out.)
727
   */
728
#ifndef USE_FLOAT8_BYVAL    /* controls int8 too */
729
  if (AggCheckCallContext(fcinfo, NULL))
730
  {
731
    int64    *arg = (int64 *) PG_GETARG_POINTER(0);
732
733
    if (unlikely(pg_add_s64_overflow(*arg, 1, arg)))
734
      ereport(ERROR,
735
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
736
           errmsg("bigint out of range")));
737
738
    PG_RETURN_POINTER(arg);
739
  }
740
  else
741
#endif
742
0
  {
743
    /* Not called as an aggregate, so just do it the dumb way */
744
0
    int64   arg = PG_GETARG_INT64(0);
745
0
    int64   result;
746
747
0
    if (unlikely(pg_add_s64_overflow(arg, 1, &result)))
748
0
      ereport(ERROR,
749
0
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
750
0
           errmsg("bigint out of range")));
751
752
0
    PG_RETURN_INT64(result);
753
0
  }
754
0
}
755
756
Datum
757
int8dec(PG_FUNCTION_ARGS)
758
0
{
759
  /*
760
   * When int8 is pass-by-reference, we provide this special case to avoid
761
   * palloc overhead for COUNT(): when called as an aggregate, we know that
762
   * the argument is modifiable local storage, so just update it in-place.
763
   * (If int8 is pass-by-value, then of course this is useless as well as
764
   * incorrect, so just ifdef it out.)
765
   */
766
#ifndef USE_FLOAT8_BYVAL    /* controls int8 too */
767
  if (AggCheckCallContext(fcinfo, NULL))
768
  {
769
    int64    *arg = (int64 *) PG_GETARG_POINTER(0);
770
771
    if (unlikely(pg_sub_s64_overflow(*arg, 1, arg)))
772
      ereport(ERROR,
773
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
774
           errmsg("bigint out of range")));
775
    PG_RETURN_POINTER(arg);
776
  }
777
  else
778
#endif
779
0
  {
780
    /* Not called as an aggregate, so just do it the dumb way */
781
0
    int64   arg = PG_GETARG_INT64(0);
782
0
    int64   result;
783
784
0
    if (unlikely(pg_sub_s64_overflow(arg, 1, &result)))
785
0
      ereport(ERROR,
786
0
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
787
0
           errmsg("bigint out of range")));
788
789
0
    PG_RETURN_INT64(result);
790
0
  }
791
0
}
792
793
794
/*
795
 * These functions are exactly like int8inc/int8dec but are used for
796
 * aggregates that count only non-null values.  Since the functions are
797
 * declared strict, the null checks happen before we ever get here, and all we
798
 * need do is increment the state value.  We could actually make these pg_proc
799
 * entries point right at int8inc/int8dec, but then the opr_sanity regression
800
 * test would complain about mismatched entries for a built-in function.
801
 */
802
803
Datum
804
int8inc_any(PG_FUNCTION_ARGS)
805
0
{
806
0
  return int8inc(fcinfo);
807
0
}
808
809
Datum
810
int8inc_float8_float8(PG_FUNCTION_ARGS)
811
0
{
812
0
  return int8inc(fcinfo);
813
0
}
814
815
Datum
816
int8dec_any(PG_FUNCTION_ARGS)
817
0
{
818
0
  return int8dec(fcinfo);
819
0
}
820
821
/*
822
 * int8inc_support
823
 *    prosupport function for int8inc() and int8inc_any()
824
 */
825
Datum
826
int8inc_support(PG_FUNCTION_ARGS)
827
0
{
828
0
  Node     *rawreq = (Node *) PG_GETARG_POINTER(0);
829
830
0
  if (IsA(rawreq, SupportRequestWFuncMonotonic))
831
0
  {
832
0
    SupportRequestWFuncMonotonic *req = (SupportRequestWFuncMonotonic *) rawreq;
833
0
    MonotonicFunction monotonic = MONOTONICFUNC_NONE;
834
0
    int     frameOptions = req->window_clause->frameOptions;
835
836
    /* No ORDER BY clause then all rows are peers */
837
0
    if (req->window_clause->orderClause == NIL)
838
0
      monotonic = MONOTONICFUNC_BOTH;
839
0
    else
840
0
    {
841
      /*
842
       * Otherwise take into account the frame options.  When the frame
843
       * bound is the start of the window then the resulting value can
844
       * never decrease, therefore is monotonically increasing
845
       */
846
0
      if (frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING)
847
0
        monotonic |= MONOTONICFUNC_INCREASING;
848
849
      /*
850
       * Likewise, if the frame bound is the end of the window then the
851
       * resulting value can never decrease.
852
       */
853
0
      if (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING)
854
0
        monotonic |= MONOTONICFUNC_DECREASING;
855
0
    }
856
857
0
    req->monotonic = monotonic;
858
0
    PG_RETURN_POINTER(req);
859
0
  }
860
861
0
  PG_RETURN_POINTER(NULL);
862
0
}
863
864
865
Datum
866
int8larger(PG_FUNCTION_ARGS)
867
0
{
868
0
  int64   arg1 = PG_GETARG_INT64(0);
869
0
  int64   arg2 = PG_GETARG_INT64(1);
870
0
  int64   result;
871
872
0
  result = ((arg1 > arg2) ? arg1 : arg2);
873
874
0
  PG_RETURN_INT64(result);
875
0
}
876
877
Datum
878
int8smaller(PG_FUNCTION_ARGS)
879
0
{
880
0
  int64   arg1 = PG_GETARG_INT64(0);
881
0
  int64   arg2 = PG_GETARG_INT64(1);
882
0
  int64   result;
883
884
0
  result = ((arg1 < arg2) ? arg1 : arg2);
885
886
0
  PG_RETURN_INT64(result);
887
0
}
888
889
Datum
890
int84pl(PG_FUNCTION_ARGS)
891
0
{
892
0
  int64   arg1 = PG_GETARG_INT64(0);
893
0
  int32   arg2 = PG_GETARG_INT32(1);
894
0
  int64   result;
895
896
0
  if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result)))
897
0
    ereport(ERROR,
898
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
899
0
         errmsg("bigint out of range")));
900
0
  PG_RETURN_INT64(result);
901
0
}
902
903
Datum
904
int84mi(PG_FUNCTION_ARGS)
905
0
{
906
0
  int64   arg1 = PG_GETARG_INT64(0);
907
0
  int32   arg2 = PG_GETARG_INT32(1);
908
0
  int64   result;
909
910
0
  if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result)))
911
0
    ereport(ERROR,
912
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
913
0
         errmsg("bigint out of range")));
914
0
  PG_RETURN_INT64(result);
915
0
}
916
917
Datum
918
int84mul(PG_FUNCTION_ARGS)
919
0
{
920
0
  int64   arg1 = PG_GETARG_INT64(0);
921
0
  int32   arg2 = PG_GETARG_INT32(1);
922
0
  int64   result;
923
924
0
  if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result)))
925
0
    ereport(ERROR,
926
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
927
0
         errmsg("bigint out of range")));
928
0
  PG_RETURN_INT64(result);
929
0
}
930
931
Datum
932
int84div(PG_FUNCTION_ARGS)
933
0
{
934
0
  int64   arg1 = PG_GETARG_INT64(0);
935
0
  int32   arg2 = PG_GETARG_INT32(1);
936
0
  int64   result;
937
938
0
  if (arg2 == 0)
939
0
  {
940
0
    ereport(ERROR,
941
0
        (errcode(ERRCODE_DIVISION_BY_ZERO),
942
0
         errmsg("division by zero")));
943
    /* ensure compiler realizes we mustn't reach the division (gcc bug) */
944
0
    PG_RETURN_NULL();
945
0
  }
946
947
  /*
948
   * INT64_MIN / -1 is problematic, since the result can't be represented on
949
   * a two's-complement machine.  Some machines produce INT64_MIN, some
950
   * produce zero, some throw an exception.  We can dodge the problem by
951
   * recognizing that division by -1 is the same as negation.
952
   */
953
0
  if (arg2 == -1)
954
0
  {
955
0
    if (unlikely(arg1 == PG_INT64_MIN))
956
0
      ereport(ERROR,
957
0
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
958
0
           errmsg("bigint out of range")));
959
0
    result = -arg1;
960
0
    PG_RETURN_INT64(result);
961
0
  }
962
963
  /* No overflow is possible */
964
965
0
  result = arg1 / arg2;
966
967
0
  PG_RETURN_INT64(result);
968
0
}
969
970
Datum
971
int48pl(PG_FUNCTION_ARGS)
972
0
{
973
0
  int32   arg1 = PG_GETARG_INT32(0);
974
0
  int64   arg2 = PG_GETARG_INT64(1);
975
0
  int64   result;
976
977
0
  if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result)))
978
0
    ereport(ERROR,
979
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
980
0
         errmsg("bigint out of range")));
981
0
  PG_RETURN_INT64(result);
982
0
}
983
984
Datum
985
int48mi(PG_FUNCTION_ARGS)
986
0
{
987
0
  int32   arg1 = PG_GETARG_INT32(0);
988
0
  int64   arg2 = PG_GETARG_INT64(1);
989
0
  int64   result;
990
991
0
  if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result)))
992
0
    ereport(ERROR,
993
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
994
0
         errmsg("bigint out of range")));
995
0
  PG_RETURN_INT64(result);
996
0
}
997
998
Datum
999
int48mul(PG_FUNCTION_ARGS)
1000
0
{
1001
0
  int32   arg1 = PG_GETARG_INT32(0);
1002
0
  int64   arg2 = PG_GETARG_INT64(1);
1003
0
  int64   result;
1004
1005
0
  if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result)))
1006
0
    ereport(ERROR,
1007
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1008
0
         errmsg("bigint out of range")));
1009
0
  PG_RETURN_INT64(result);
1010
0
}
1011
1012
Datum
1013
int48div(PG_FUNCTION_ARGS)
1014
0
{
1015
0
  int32   arg1 = PG_GETARG_INT32(0);
1016
0
  int64   arg2 = PG_GETARG_INT64(1);
1017
1018
0
  if (unlikely(arg2 == 0))
1019
0
  {
1020
0
    ereport(ERROR,
1021
0
        (errcode(ERRCODE_DIVISION_BY_ZERO),
1022
0
         errmsg("division by zero")));
1023
    /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1024
0
    PG_RETURN_NULL();
1025
0
  }
1026
1027
  /* No overflow is possible */
1028
0
  PG_RETURN_INT64((int64) arg1 / arg2);
1029
0
}
1030
1031
Datum
1032
int82pl(PG_FUNCTION_ARGS)
1033
0
{
1034
0
  int64   arg1 = PG_GETARG_INT64(0);
1035
0
  int16   arg2 = PG_GETARG_INT16(1);
1036
0
  int64   result;
1037
1038
0
  if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result)))
1039
0
    ereport(ERROR,
1040
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1041
0
         errmsg("bigint out of range")));
1042
0
  PG_RETURN_INT64(result);
1043
0
}
1044
1045
Datum
1046
int82mi(PG_FUNCTION_ARGS)
1047
0
{
1048
0
  int64   arg1 = PG_GETARG_INT64(0);
1049
0
  int16   arg2 = PG_GETARG_INT16(1);
1050
0
  int64   result;
1051
1052
0
  if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result)))
1053
0
    ereport(ERROR,
1054
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1055
0
         errmsg("bigint out of range")));
1056
0
  PG_RETURN_INT64(result);
1057
0
}
1058
1059
Datum
1060
int82mul(PG_FUNCTION_ARGS)
1061
0
{
1062
0
  int64   arg1 = PG_GETARG_INT64(0);
1063
0
  int16   arg2 = PG_GETARG_INT16(1);
1064
0
  int64   result;
1065
1066
0
  if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result)))
1067
0
    ereport(ERROR,
1068
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1069
0
         errmsg("bigint out of range")));
1070
0
  PG_RETURN_INT64(result);
1071
0
}
1072
1073
Datum
1074
int82div(PG_FUNCTION_ARGS)
1075
0
{
1076
0
  int64   arg1 = PG_GETARG_INT64(0);
1077
0
  int16   arg2 = PG_GETARG_INT16(1);
1078
0
  int64   result;
1079
1080
0
  if (unlikely(arg2 == 0))
1081
0
  {
1082
0
    ereport(ERROR,
1083
0
        (errcode(ERRCODE_DIVISION_BY_ZERO),
1084
0
         errmsg("division by zero")));
1085
    /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1086
0
    PG_RETURN_NULL();
1087
0
  }
1088
1089
  /*
1090
   * INT64_MIN / -1 is problematic, since the result can't be represented on
1091
   * a two's-complement machine.  Some machines produce INT64_MIN, some
1092
   * produce zero, some throw an exception.  We can dodge the problem by
1093
   * recognizing that division by -1 is the same as negation.
1094
   */
1095
0
  if (arg2 == -1)
1096
0
  {
1097
0
    if (unlikely(arg1 == PG_INT64_MIN))
1098
0
      ereport(ERROR,
1099
0
          (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1100
0
           errmsg("bigint out of range")));
1101
0
    result = -arg1;
1102
0
    PG_RETURN_INT64(result);
1103
0
  }
1104
1105
  /* No overflow is possible */
1106
1107
0
  result = arg1 / arg2;
1108
1109
0
  PG_RETURN_INT64(result);
1110
0
}
1111
1112
Datum
1113
int28pl(PG_FUNCTION_ARGS)
1114
0
{
1115
0
  int16   arg1 = PG_GETARG_INT16(0);
1116
0
  int64   arg2 = PG_GETARG_INT64(1);
1117
0
  int64   result;
1118
1119
0
  if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result)))
1120
0
    ereport(ERROR,
1121
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1122
0
         errmsg("bigint out of range")));
1123
0
  PG_RETURN_INT64(result);
1124
0
}
1125
1126
Datum
1127
int28mi(PG_FUNCTION_ARGS)
1128
0
{
1129
0
  int16   arg1 = PG_GETARG_INT16(0);
1130
0
  int64   arg2 = PG_GETARG_INT64(1);
1131
0
  int64   result;
1132
1133
0
  if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result)))
1134
0
    ereport(ERROR,
1135
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1136
0
         errmsg("bigint out of range")));
1137
0
  PG_RETURN_INT64(result);
1138
0
}
1139
1140
Datum
1141
int28mul(PG_FUNCTION_ARGS)
1142
0
{
1143
0
  int16   arg1 = PG_GETARG_INT16(0);
1144
0
  int64   arg2 = PG_GETARG_INT64(1);
1145
0
  int64   result;
1146
1147
0
  if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result)))
1148
0
    ereport(ERROR,
1149
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1150
0
         errmsg("bigint out of range")));
1151
0
  PG_RETURN_INT64(result);
1152
0
}
1153
1154
Datum
1155
int28div(PG_FUNCTION_ARGS)
1156
0
{
1157
0
  int16   arg1 = PG_GETARG_INT16(0);
1158
0
  int64   arg2 = PG_GETARG_INT64(1);
1159
1160
0
  if (unlikely(arg2 == 0))
1161
0
  {
1162
0
    ereport(ERROR,
1163
0
        (errcode(ERRCODE_DIVISION_BY_ZERO),
1164
0
         errmsg("division by zero")));
1165
    /* ensure compiler realizes we mustn't reach the division (gcc bug) */
1166
0
    PG_RETURN_NULL();
1167
0
  }
1168
1169
  /* No overflow is possible */
1170
0
  PG_RETURN_INT64((int64) arg1 / arg2);
1171
0
}
1172
1173
/* Binary arithmetics
1174
 *
1175
 *    int8and   - returns arg1 & arg2
1176
 *    int8or    - returns arg1 | arg2
1177
 *    int8xor   - returns arg1 # arg2
1178
 *    int8not   - returns ~arg1
1179
 *    int8shl   - returns arg1 << arg2
1180
 *    int8shr   - returns arg1 >> arg2
1181
 */
1182
1183
Datum
1184
int8and(PG_FUNCTION_ARGS)
1185
0
{
1186
0
  int64   arg1 = PG_GETARG_INT64(0);
1187
0
  int64   arg2 = PG_GETARG_INT64(1);
1188
1189
0
  PG_RETURN_INT64(arg1 & arg2);
1190
0
}
1191
1192
Datum
1193
int8or(PG_FUNCTION_ARGS)
1194
0
{
1195
0
  int64   arg1 = PG_GETARG_INT64(0);
1196
0
  int64   arg2 = PG_GETARG_INT64(1);
1197
1198
0
  PG_RETURN_INT64(arg1 | arg2);
1199
0
}
1200
1201
Datum
1202
int8xor(PG_FUNCTION_ARGS)
1203
0
{
1204
0
  int64   arg1 = PG_GETARG_INT64(0);
1205
0
  int64   arg2 = PG_GETARG_INT64(1);
1206
1207
0
  PG_RETURN_INT64(arg1 ^ arg2);
1208
0
}
1209
1210
Datum
1211
int8not(PG_FUNCTION_ARGS)
1212
0
{
1213
0
  int64   arg1 = PG_GETARG_INT64(0);
1214
1215
0
  PG_RETURN_INT64(~arg1);
1216
0
}
1217
1218
Datum
1219
int8shl(PG_FUNCTION_ARGS)
1220
0
{
1221
0
  int64   arg1 = PG_GETARG_INT64(0);
1222
0
  int32   arg2 = PG_GETARG_INT32(1);
1223
1224
0
  PG_RETURN_INT64(arg1 << arg2);
1225
0
}
1226
1227
Datum
1228
int8shr(PG_FUNCTION_ARGS)
1229
0
{
1230
0
  int64   arg1 = PG_GETARG_INT64(0);
1231
0
  int32   arg2 = PG_GETARG_INT32(1);
1232
1233
0
  PG_RETURN_INT64(arg1 >> arg2);
1234
0
}
1235
1236
/*----------------------------------------------------------
1237
 *  Conversion operators.
1238
 *---------------------------------------------------------*/
1239
1240
Datum
1241
int48(PG_FUNCTION_ARGS)
1242
0
{
1243
0
  int32   arg = PG_GETARG_INT32(0);
1244
1245
0
  PG_RETURN_INT64((int64) arg);
1246
0
}
1247
1248
Datum
1249
int84(PG_FUNCTION_ARGS)
1250
0
{
1251
0
  int64   arg = PG_GETARG_INT64(0);
1252
1253
0
  if (unlikely(arg < PG_INT32_MIN) || unlikely(arg > PG_INT32_MAX))
1254
0
    ereport(ERROR,
1255
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1256
0
         errmsg("integer out of range")));
1257
1258
0
  PG_RETURN_INT32((int32) arg);
1259
0
}
1260
1261
Datum
1262
int28(PG_FUNCTION_ARGS)
1263
0
{
1264
0
  int16   arg = PG_GETARG_INT16(0);
1265
1266
0
  PG_RETURN_INT64((int64) arg);
1267
0
}
1268
1269
Datum
1270
int82(PG_FUNCTION_ARGS)
1271
0
{
1272
0
  int64   arg = PG_GETARG_INT64(0);
1273
1274
0
  if (unlikely(arg < PG_INT16_MIN) || unlikely(arg > PG_INT16_MAX))
1275
0
    ereport(ERROR,
1276
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1277
0
         errmsg("smallint out of range")));
1278
1279
0
  PG_RETURN_INT16((int16) arg);
1280
0
}
1281
1282
Datum
1283
i8tod(PG_FUNCTION_ARGS)
1284
0
{
1285
0
  int64   arg = PG_GETARG_INT64(0);
1286
0
  float8    result;
1287
1288
0
  result = arg;
1289
1290
0
  PG_RETURN_FLOAT8(result);
1291
0
}
1292
1293
/* dtoi8()
1294
 * Convert float8 to 8-byte integer.
1295
 */
1296
Datum
1297
dtoi8(PG_FUNCTION_ARGS)
1298
0
{
1299
0
  float8    num = PG_GETARG_FLOAT8(0);
1300
1301
  /*
1302
   * Get rid of any fractional part in the input.  This is so we don't fail
1303
   * on just-out-of-range values that would round into range.  Note
1304
   * assumption that rint() will pass through a NaN or Inf unchanged.
1305
   */
1306
0
  num = rint(num);
1307
1308
  /* Range check */
1309
0
  if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT64(num)))
1310
0
    ereport(ERROR,
1311
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1312
0
         errmsg("bigint out of range")));
1313
1314
0
  PG_RETURN_INT64((int64) num);
1315
0
}
1316
1317
Datum
1318
i8tof(PG_FUNCTION_ARGS)
1319
0
{
1320
0
  int64   arg = PG_GETARG_INT64(0);
1321
0
  float4    result;
1322
1323
0
  result = arg;
1324
1325
0
  PG_RETURN_FLOAT4(result);
1326
0
}
1327
1328
/* ftoi8()
1329
 * Convert float4 to 8-byte integer.
1330
 */
1331
Datum
1332
ftoi8(PG_FUNCTION_ARGS)
1333
0
{
1334
0
  float4    num = PG_GETARG_FLOAT4(0);
1335
1336
  /*
1337
   * Get rid of any fractional part in the input.  This is so we don't fail
1338
   * on just-out-of-range values that would round into range.  Note
1339
   * assumption that rint() will pass through a NaN or Inf unchanged.
1340
   */
1341
0
  num = rint(num);
1342
1343
  /* Range check */
1344
0
  if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT64(num)))
1345
0
    ereport(ERROR,
1346
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1347
0
         errmsg("bigint out of range")));
1348
1349
0
  PG_RETURN_INT64((int64) num);
1350
0
}
1351
1352
Datum
1353
i8tooid(PG_FUNCTION_ARGS)
1354
0
{
1355
0
  int64   arg = PG_GETARG_INT64(0);
1356
1357
0
  if (unlikely(arg < 0) || unlikely(arg > PG_UINT32_MAX))
1358
0
    ereport(ERROR,
1359
0
        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1360
0
         errmsg("OID out of range")));
1361
1362
0
  PG_RETURN_OID((Oid) arg);
1363
0
}
1364
1365
Datum
1366
oidtoi8(PG_FUNCTION_ARGS)
1367
0
{
1368
0
  Oid     arg = PG_GETARG_OID(0);
1369
1370
0
  PG_RETURN_INT64((int64) arg);
1371
0
}
1372
1373
/*
1374
 * non-persistent numeric series generator
1375
 */
1376
Datum
1377
generate_series_int8(PG_FUNCTION_ARGS)
1378
0
{
1379
0
  return generate_series_step_int8(fcinfo);
1380
0
}
1381
1382
Datum
1383
generate_series_step_int8(PG_FUNCTION_ARGS)
1384
0
{
1385
0
  FuncCallContext *funcctx;
1386
0
  generate_series_fctx *fctx;
1387
0
  int64   result;
1388
0
  MemoryContext oldcontext;
1389
1390
  /* stuff done only on the first call of the function */
1391
0
  if (SRF_IS_FIRSTCALL())
1392
0
  {
1393
0
    int64   start = PG_GETARG_INT64(0);
1394
0
    int64   finish = PG_GETARG_INT64(1);
1395
0
    int64   step = 1;
1396
1397
    /* see if we were given an explicit step size */
1398
0
    if (PG_NARGS() == 3)
1399
0
      step = PG_GETARG_INT64(2);
1400
0
    if (step == 0)
1401
0
      ereport(ERROR,
1402
0
          (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1403
0
           errmsg("step size cannot equal zero")));
1404
1405
    /* create a function context for cross-call persistence */
1406
0
    funcctx = SRF_FIRSTCALL_INIT();
1407
1408
    /*
1409
     * switch to memory context appropriate for multiple function calls
1410
     */
1411
0
    oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1412
1413
    /* allocate memory for user context */
1414
0
    fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
1415
1416
    /*
1417
     * Use fctx to keep state from call to call. Seed current with the
1418
     * original start value
1419
     */
1420
0
    fctx->current = start;
1421
0
    fctx->finish = finish;
1422
0
    fctx->step = step;
1423
1424
0
    funcctx->user_fctx = fctx;
1425
0
    MemoryContextSwitchTo(oldcontext);
1426
0
  }
1427
1428
  /* stuff done on every call of the function */
1429
0
  funcctx = SRF_PERCALL_SETUP();
1430
1431
  /*
1432
   * get the saved state and use current as the result for this iteration
1433
   */
1434
0
  fctx = funcctx->user_fctx;
1435
0
  result = fctx->current;
1436
1437
0
  if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
1438
0
    (fctx->step < 0 && fctx->current >= fctx->finish))
1439
0
  {
1440
    /*
1441
     * Increment current in preparation for next iteration. If next-value
1442
     * computation overflows, this is the final result.
1443
     */
1444
0
    if (pg_add_s64_overflow(fctx->current, fctx->step, &fctx->current))
1445
0
      fctx->step = 0;
1446
1447
    /* do when there is more left to send */
1448
0
    SRF_RETURN_NEXT(funcctx, Int64GetDatum(result));
1449
0
  }
1450
0
  else
1451
    /* do when there is no more left */
1452
0
    SRF_RETURN_DONE(funcctx);
1453
0
}
1454
1455
/*
1456
 * Planner support function for generate_series(int8, int8 [, int8])
1457
 */
1458
Datum
1459
generate_series_int8_support(PG_FUNCTION_ARGS)
1460
0
{
1461
0
  Node     *rawreq = (Node *) PG_GETARG_POINTER(0);
1462
0
  Node     *ret = NULL;
1463
1464
0
  if (IsA(rawreq, SupportRequestRows))
1465
0
  {
1466
    /* Try to estimate the number of rows returned */
1467
0
    SupportRequestRows *req = (SupportRequestRows *) rawreq;
1468
1469
0
    if (is_funcclause(req->node)) /* be paranoid */
1470
0
    {
1471
0
      List     *args = ((FuncExpr *) req->node)->args;
1472
0
      Node     *arg1,
1473
0
             *arg2,
1474
0
             *arg3;
1475
1476
      /* We can use estimated argument values here */
1477
0
      arg1 = estimate_expression_value(req->root, linitial(args));
1478
0
      arg2 = estimate_expression_value(req->root, lsecond(args));
1479
0
      if (list_length(args) >= 3)
1480
0
        arg3 = estimate_expression_value(req->root, lthird(args));
1481
0
      else
1482
0
        arg3 = NULL;
1483
1484
      /*
1485
       * If any argument is constant NULL, we can safely assume that
1486
       * zero rows are returned.  Otherwise, if they're all non-NULL
1487
       * constants, we can calculate the number of rows that will be
1488
       * returned.  Use double arithmetic to avoid overflow hazards.
1489
       */
1490
0
      if ((IsA(arg1, Const) &&
1491
0
         ((Const *) arg1)->constisnull) ||
1492
0
        (IsA(arg2, Const) &&
1493
0
         ((Const *) arg2)->constisnull) ||
1494
0
        (arg3 != NULL && IsA(arg3, Const) &&
1495
0
         ((Const *) arg3)->constisnull))
1496
0
      {
1497
0
        req->rows = 0;
1498
0
        ret = (Node *) req;
1499
0
      }
1500
0
      else if (IsA(arg1, Const) &&
1501
0
           IsA(arg2, Const) &&
1502
0
           (arg3 == NULL || IsA(arg3, Const)))
1503
0
      {
1504
0
        double    start,
1505
0
              finish,
1506
0
              step;
1507
1508
0
        start = DatumGetInt64(((Const *) arg1)->constvalue);
1509
0
        finish = DatumGetInt64(((Const *) arg2)->constvalue);
1510
0
        step = arg3 ? DatumGetInt64(((Const *) arg3)->constvalue) : 1;
1511
1512
        /* This equation works for either sign of step */
1513
0
        if (step != 0)
1514
0
        {
1515
0
          req->rows = floor((finish - start + step) / step);
1516
0
          ret = (Node *) req;
1517
0
        }
1518
0
      }
1519
0
    }
1520
0
  }
1521
1522
0
  PG_RETURN_POINTER(ret);
1523
0
}