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

Generated by: LCOV version 1.13