LCOV - code coverage report
Current view: top level - src/backend/utils/adt - int8.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19beta1 Lines: 97.8 % 538 526
Test Date: 2026-06-05 18:16:19 Functions: 100.0 % 90 90
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.0-1