LCOV - code coverage report
Current view: top level - src/backend/utils/adt - int8.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 97.8 % 538 526
Test Date: 2026-07-03 19:57:34 Functions: 100.0 % 90 90
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 76.8 % 276 212

             Branch data     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                 :       81782 : int8in(PG_FUNCTION_ARGS)
      52                 :             : {
      53                 :       81782 :     char       *num = PG_GETARG_CSTRING(0);
      54                 :             : 
      55                 :       81782 :     PG_RETURN_INT64(pg_strtoint64_safe(num, fcinfo->context));
      56                 :             : }
      57                 :             : 
      58                 :             : 
      59                 :             : /*
      60                 :             :  * int8out()
      61                 :             :  */
      62                 :             : Datum
      63                 :      174372 : int8out(PG_FUNCTION_ARGS)
      64                 :             : {
      65                 :      174372 :     int64       val = PG_GETARG_INT64(0);
      66                 :             :     char        buf[MAXINT8LEN + 1];
      67                 :             :     char       *result;
      68                 :             :     int         len;
      69                 :             : 
      70                 :      174372 :     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                 :      174372 :     result = palloc(len);
      77                 :      174372 :     memcpy(result, buf, len);
      78                 :      174372 :     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                 :        2429 : int8send(PG_FUNCTION_ARGS)
      97                 :             : {
      98                 :        2429 :     int64       arg1 = PG_GETARG_INT64(0);
      99                 :             :     StringInfoData buf;
     100                 :             : 
     101                 :        2429 :     pq_begintypsend(&buf);
     102                 :        2429 :     pq_sendint64(&buf, arg1);
     103                 :        2429 :     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                 :      231217 : int8eq(PG_FUNCTION_ARGS)
     117                 :             : {
     118                 :      231217 :     int64       val1 = PG_GETARG_INT64(0);
     119                 :      231217 :     int64       val2 = PG_GETARG_INT64(1);
     120                 :             : 
     121                 :      231217 :     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                 :      350151 : int8lt(PG_FUNCTION_ARGS)
     135                 :             : {
     136                 :      350151 :     int64       val1 = PG_GETARG_INT64(0);
     137                 :      350151 :     int64       val2 = PG_GETARG_INT64(1);
     138                 :             : 
     139                 :      350151 :     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                 :      117596 : int84eq(PG_FUNCTION_ARGS)
     175                 :             : {
     176                 :      117596 :     int64       val1 = PG_GETARG_INT64(0);
     177                 :      117596 :     int32       val2 = PG_GETARG_INT32(1);
     178                 :             : 
     179                 :      117596 :     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                 :       93627 : int84gt(PG_FUNCTION_ARGS)
     202                 :             : {
     203                 :       93627 :     int64       val1 = PG_GETARG_INT64(0);
     204                 :       93627 :     int32       val2 = PG_GETARG_INT32(1);
     205                 :             : 
     206                 :       93627 :     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                 :        6683 : int84ge(PG_FUNCTION_ARGS)
     220                 :             : {
     221                 :        6683 :     int64       val1 = PG_GETARG_INT64(0);
     222                 :        6683 :     int32       val2 = PG_GETARG_INT32(1);
     223                 :             : 
     224                 :        6683 :     PG_RETURN_BOOL(val1 >= val2);
     225                 :             : }
     226                 :             : 
     227                 :             : /*
     228                 :             :  * int48relop()
     229                 :             :  * Is 32-bit val1 relop 64-bit val2?
     230                 :             :  */
     231                 :             : Datum
     232                 :      103523 : int48eq(PG_FUNCTION_ARGS)
     233                 :             : {
     234                 :      103523 :     int32       val1 = PG_GETARG_INT32(0);
     235                 :      103523 :     int64       val2 = PG_GETARG_INT64(1);
     236                 :             : 
     237                 :      103523 :     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                 :        2381 : int28ne(PG_FUNCTION_ARGS)
     358                 :             : {
     359                 :        2381 :     int16       val1 = PG_GETARG_INT16(0);
     360                 :        2381 :     int64       val2 = PG_GETARG_INT64(1);
     361                 :             : 
     362                 :        2381 :     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                 :      169963 : int8pl(PG_FUNCTION_ARGS)
     470                 :             : {
     471                 :      169963 :     int64       arg1 = PG_GETARG_INT64(0);
     472                 :      169963 :     int64       arg2 = PG_GETARG_INT64(1);
     473                 :             :     int64       result;
     474                 :             : 
     475         [ +  + ]:      169963 :     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                 :      169955 :     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                 :    14551327 : int8inc(PG_FUNCTION_ARGS)
     729                 :             : {
     730                 :    14551327 :     int64       arg = PG_GETARG_INT64(0);
     731                 :             :     int64       result;
     732                 :             : 
     733         [ -  + ]:    14551327 :     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                 :    14551327 :     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                 :      796884 : int8inc_any(PG_FUNCTION_ARGS)
     767                 :             : {
     768                 :      796884 :     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                 :       14738 : int8inc_support(PG_FUNCTION_ARGS)
     789                 :             : {
     790                 :       14738 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
     791                 :             : 
     792         [ +  + ]:       14738 :     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         [ +  + ]:       14673 :     if (IsA(rawreq, SupportRequestSimplifyAggref))
     824                 :             :     {
     825                 :       14243 :         SupportRequestSimplifyAggref *req = (SupportRequestSimplifyAggref *) rawreq;
     826                 :       14243 :         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   [ +  +  +  - ]:       14243 :         if (agg->aggfnoid == F_COUNT_ANY && list_length(agg->args) == 1)
     836                 :             :         {
     837                 :        1315 :             TargetEntry *tle = (TargetEntry *) linitial(agg->args);
     838                 :        1315 :             Expr       *arg = tle->expr;
     839                 :             : 
     840                 :             :             /* Check for unsupported cases */
     841   [ +  +  +  + ]:        1315 :             if (agg->aggdistinct != NIL || agg->aggorder != NIL ||
     842         [ +  + ]:        1073 :                 agg->agglevelsup != 0)
     843                 :         252 :                 PG_RETURN_POINTER(NULL);
     844                 :             : 
     845                 :             :             /* If the arg isn't NULLable, do the conversion */
     846         [ +  + ]:        1063 :             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                 :         404 :                 newagg = makeNode(Aggref);
     856                 :         404 :                 memcpy(newagg, agg, sizeof(Aggref));
     857                 :         404 :                 newagg->aggfnoid = F_COUNT_;
     858                 :             : 
     859                 :             :                 /* count(*) has no args */
     860                 :         404 :                 newagg->aggargtypes = NULL;
     861                 :         404 :                 newagg->args = NULL;
     862                 :         404 :                 newagg->aggstar = true;
     863                 :         404 :                 newagg->location = -1;
     864                 :             : 
     865                 :         404 :                 PG_RETURN_POINTER(newagg);
     866                 :             :             }
     867                 :             :         }
     868                 :             :     }
     869                 :             : 
     870                 :       14017 :     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                 :     1443842 : int48(PG_FUNCTION_ARGS)
    1252                 :             : {
    1253                 :     1443842 :     int32       arg = PG_GETARG_INT32(0);
    1254                 :             : 
    1255                 :     1443842 :     PG_RETURN_INT64((int64) arg);
    1256                 :             : }
    1257                 :             : 
    1258                 :             : Datum
    1259                 :      221405 : int84(PG_FUNCTION_ARGS)
    1260                 :             : {
    1261                 :      221405 :     int64       arg = PG_GETARG_INT64(0);
    1262                 :             : 
    1263   [ +  -  +  + ]:      221405 :     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                 :      221400 :     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