Coverage Report

Created: 2026-09-28 06:55

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