LCOV - code coverage report
Current view: top level - src/backend/utils/adt - int8.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 98.3 % 542 533
Test Date: 2026-09-12 06:15:41 Functions: 100.0 % 90 90
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 77.6 % 286 222

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

Generated by: LCOV version 2.0-1