LCOV - code coverage report
Current view: top level - src/backend/utils/adt - int.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 85.9 % 744 639
Test Date: 2026-01-26 10:56:24 Functions: 87.2 % 94 82
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 59.8 % 363 217

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * int.c
       4                 :             :  *        Functions for the built-in integer types (except int8).
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/utils/adt/int.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : /*
      16                 :             :  * OLD COMMENTS
      17                 :             :  *              I/O routines:
      18                 :             :  *               int2in, int2out, int2recv, int2send
      19                 :             :  *               int4in, int4out, int4recv, int4send
      20                 :             :  *               int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
      21                 :             :  *              Boolean operators:
      22                 :             :  *               inteq, intne, intlt, intle, intgt, intge
      23                 :             :  *              Arithmetic operators:
      24                 :             :  *               intpl, intmi, int4mul, intdiv
      25                 :             :  *
      26                 :             :  *              Arithmetic operators:
      27                 :             :  *               intmod
      28                 :             :  */
      29                 :             : #include "postgres.h"
      30                 :             : 
      31                 :             : #include <ctype.h>
      32                 :             : #include <limits.h>
      33                 :             : #include <math.h>
      34                 :             : 
      35                 :             : #include "catalog/pg_type.h"
      36                 :             : #include "common/int.h"
      37                 :             : #include "funcapi.h"
      38                 :             : #include "libpq/pqformat.h"
      39                 :             : #include "nodes/nodeFuncs.h"
      40                 :             : #include "nodes/supportnodes.h"
      41                 :             : #include "optimizer/optimizer.h"
      42                 :             : #include "utils/array.h"
      43                 :             : #include "utils/builtins.h"
      44                 :             : 
      45                 :             : #define Int2VectorSize(n)       (offsetof(int2vector, values) + (n) * sizeof(int16))
      46                 :             : 
      47                 :             : typedef struct
      48                 :             : {
      49                 :             :         int32           current;
      50                 :             :         int32           finish;
      51                 :             :         int32           step;
      52                 :             : } generate_series_fctx;
      53                 :             : 
      54                 :             : 
      55                 :             : /*****************************************************************************
      56                 :             :  *       USER I/O ROUTINES                                                                                                               *
      57                 :             :  *****************************************************************************/
      58                 :             : 
      59                 :             : /*
      60                 :             :  *              int2in                  - converts "num" to short
      61                 :             :  */
      62                 :             : Datum
      63                 :        9799 : int2in(PG_FUNCTION_ARGS)
      64                 :             : {
      65                 :        9799 :         char       *num = PG_GETARG_CSTRING(0);
      66                 :             : 
      67                 :       19598 :         PG_RETURN_INT16(pg_strtoint16_safe(num, fcinfo->context));
      68                 :        9799 : }
      69                 :             : 
      70                 :             : /*
      71                 :             :  *              int2out                 - converts short to "num"
      72                 :             :  */
      73                 :             : Datum
      74                 :        5691 : int2out(PG_FUNCTION_ARGS)
      75                 :             : {
      76                 :        5691 :         int16           arg1 = PG_GETARG_INT16(0);
      77                 :        5691 :         char       *result = (char *) palloc(7);        /* sign, 5 digits, '\0' */
      78                 :             : 
      79                 :        5691 :         pg_itoa(arg1, result);
      80                 :       11382 :         PG_RETURN_CSTRING(result);
      81                 :        5691 : }
      82                 :             : 
      83                 :             : /*
      84                 :             :  *              int2recv                        - converts external binary format to int2
      85                 :             :  */
      86                 :             : Datum
      87                 :           0 : int2recv(PG_FUNCTION_ARGS)
      88                 :             : {
      89                 :           0 :         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
      90                 :             : 
      91                 :           0 :         PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
      92                 :           0 : }
      93                 :             : 
      94                 :             : /*
      95                 :             :  *              int2send                        - converts int2 to binary format
      96                 :             :  */
      97                 :             : Datum
      98                 :           2 : int2send(PG_FUNCTION_ARGS)
      99                 :             : {
     100                 :           2 :         int16           arg1 = PG_GETARG_INT16(0);
     101                 :           2 :         StringInfoData buf;
     102                 :             : 
     103                 :           2 :         pq_begintypsend(&buf);
     104                 :           2 :         pq_sendint16(&buf, arg1);
     105                 :           4 :         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     106                 :           2 : }
     107                 :             : 
     108                 :             : /*
     109                 :             :  * construct int2vector given a raw array of int2s
     110                 :             :  *
     111                 :             :  * If int2s is NULL then caller must fill values[] afterward
     112                 :             :  */
     113                 :             : int2vector *
     114                 :       10300 : buildint2vector(const int16 *int2s, int n)
     115                 :             : {
     116                 :       10300 :         int2vector *result;
     117                 :             : 
     118                 :       10300 :         result = (int2vector *) palloc0(Int2VectorSize(n));
     119                 :             : 
     120   [ +  +  +  + ]:       10300 :         if (n > 0 && int2s)
     121                 :        4487 :                 memcpy(result->values, int2s, n * sizeof(int16));
     122                 :             : 
     123                 :             :         /*
     124                 :             :          * Attach standard array header.  For historical reasons, we set the index
     125                 :             :          * lower bound to 0 not 1.
     126                 :             :          */
     127                 :       10300 :         SET_VARSIZE(result, Int2VectorSize(n));
     128                 :       10300 :         result->ndim = 1;
     129                 :       10300 :         result->dataoffset = 0;              /* never any nulls */
     130                 :       10300 :         result->elemtype = INT2OID;
     131                 :       10300 :         result->dim1 = n;
     132                 :       10300 :         result->lbound1 = 0;
     133                 :             : 
     134                 :       20600 :         return result;
     135                 :       10300 : }
     136                 :             : 
     137                 :             : /*
     138                 :             :  *              int2vectorin                    - converts "num num ..." to internal form
     139                 :             :  */
     140                 :             : Datum
     141                 :          19 : int2vectorin(PG_FUNCTION_ARGS)
     142                 :             : {
     143                 :          19 :         char       *intString = PG_GETARG_CSTRING(0);
     144                 :          19 :         Node       *escontext = fcinfo->context;
     145                 :          19 :         int2vector *result;
     146                 :          19 :         int                     nalloc;
     147                 :          19 :         int                     n;
     148                 :             : 
     149                 :          19 :         nalloc = 32;                            /* arbitrary initial size guess */
     150                 :          19 :         result = (int2vector *) palloc0(Int2VectorSize(nalloc));
     151                 :             : 
     152                 :          64 :         for (n = 0;; n++)
     153                 :             :         {
     154                 :          64 :                 long            l;
     155                 :          64 :                 char       *endp;
     156                 :             : 
     157   [ +  +  +  + ]:          95 :                 while (*intString && isspace((unsigned char) *intString))
     158                 :          31 :                         intString++;
     159         [ +  + ]:          64 :                 if (*intString == '\0')
     160                 :          17 :                         break;
     161                 :             : 
     162         [ +  - ]:          47 :                 if (n >= nalloc)
     163                 :             :                 {
     164                 :           0 :                         nalloc *= 2;
     165                 :           0 :                         result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
     166                 :           0 :                 }
     167                 :             : 
     168                 :          47 :                 errno = 0;
     169                 :          47 :                 l = strtol(intString, &endp, 10);
     170                 :             : 
     171         [ +  + ]:          47 :                 if (intString == endp)
     172         [ -  + ]:           1 :                         ereturn(escontext, (Datum) 0,
     173                 :             :                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     174                 :             :                                          errmsg("invalid input syntax for type %s: \"%s\"",
     175                 :             :                                                         "smallint", intString)));
     176                 :             : 
     177   [ +  -  +  -  :          46 :                 if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX)
                   +  + ]
     178         [ -  + ]:           1 :                         ereturn(escontext, (Datum) 0,
     179                 :             :                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     180                 :             :                                          errmsg("value \"%s\" is out of range for type %s", intString,
     181                 :             :                                                         "smallint")));
     182                 :             : 
     183   [ +  +  +  - ]:          45 :                 if (*endp && *endp != ' ')
     184         [ #  # ]:           0 :                         ereturn(escontext, (Datum) 0,
     185                 :             :                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     186                 :             :                                          errmsg("invalid input syntax for type %s: \"%s\"",
     187                 :             :                                                         "smallint", intString)));
     188                 :             : 
     189                 :          45 :                 result->values[n] = l;
     190                 :          45 :                 intString = endp;
     191      [ +  +  + ]:          64 :         }
     192                 :             : 
     193                 :          17 :         SET_VARSIZE(result, Int2VectorSize(n));
     194                 :          17 :         result->ndim = 1;
     195                 :          17 :         result->dataoffset = 0;              /* never any nulls */
     196                 :          17 :         result->elemtype = INT2OID;
     197                 :          17 :         result->dim1 = n;
     198                 :          17 :         result->lbound1 = 0;
     199                 :             : 
     200                 :          17 :         PG_RETURN_POINTER(result);
     201                 :          19 : }
     202                 :             : 
     203                 :             : /*
     204                 :             :  *              int2vectorout           - converts internal form to "num num ..."
     205                 :             :  */
     206                 :             : Datum
     207                 :          23 : int2vectorout(PG_FUNCTION_ARGS)
     208                 :             : {
     209                 :          23 :         int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
     210                 :          23 :         int                     num,
     211                 :          23 :                                 nnums = int2Array->dim1;
     212                 :          23 :         char       *rp;
     213                 :          23 :         char       *result;
     214                 :             : 
     215                 :             :         /* assumes sign, 5 digits, ' ' */
     216                 :          23 :         rp = result = (char *) palloc(nnums * 7 + 1);
     217         [ +  + ]:          90 :         for (num = 0; num < nnums; num++)
     218                 :             :         {
     219         [ +  + ]:          67 :                 if (num != 0)
     220                 :          44 :                         *rp++ = ' ';
     221                 :          67 :                 rp += pg_itoa(int2Array->values[num], rp);
     222                 :          67 :         }
     223                 :          23 :         *rp = '\0';
     224                 :          46 :         PG_RETURN_CSTRING(result);
     225                 :          23 : }
     226                 :             : 
     227                 :             : /*
     228                 :             :  *              int2vectorrecv                  - converts external binary format to int2vector
     229                 :             :  */
     230                 :             : Datum
     231                 :           0 : int2vectorrecv(PG_FUNCTION_ARGS)
     232                 :             : {
     233                 :           0 :         LOCAL_FCINFO(locfcinfo, 3);
     234                 :           0 :         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
     235                 :           0 :         int2vector *result;
     236                 :             : 
     237                 :             :         /*
     238                 :             :          * Normally one would call array_recv() using DirectFunctionCall3, but
     239                 :             :          * that does not work since array_recv wants to cache some data using
     240                 :             :          * fcinfo->flinfo->fn_extra.  So we need to pass it our own flinfo
     241                 :             :          * parameter.
     242                 :             :          */
     243                 :           0 :         InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
     244                 :             :                                                          InvalidOid, NULL, NULL);
     245                 :             : 
     246                 :           0 :         locfcinfo->args[0].value = PointerGetDatum(buf);
     247                 :           0 :         locfcinfo->args[0].isnull = false;
     248                 :           0 :         locfcinfo->args[1].value = ObjectIdGetDatum(INT2OID);
     249                 :           0 :         locfcinfo->args[1].isnull = false;
     250                 :           0 :         locfcinfo->args[2].value = Int32GetDatum(-1);
     251                 :           0 :         locfcinfo->args[2].isnull = false;
     252                 :             : 
     253                 :           0 :         result = (int2vector *) DatumGetPointer(array_recv(locfcinfo));
     254                 :             : 
     255         [ #  # ]:           0 :         Assert(!locfcinfo->isnull);
     256                 :             : 
     257                 :             :         /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
     258         [ #  # ]:           0 :         if (ARR_NDIM(result) != 1 ||
     259                 :           0 :                 ARR_HASNULL(result) ||
     260                 :           0 :                 ARR_ELEMTYPE(result) != INT2OID ||
     261                 :           0 :                 ARR_LBOUND(result)[0] != 0)
     262   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     263                 :             :                                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
     264                 :             :                                  errmsg("invalid int2vector data")));
     265                 :             : 
     266                 :           0 :         PG_RETURN_POINTER(result);
     267                 :           0 : }
     268                 :             : 
     269                 :             : /*
     270                 :             :  *              int2vectorsend                  - converts int2vector to binary format
     271                 :             :  */
     272                 :             : Datum
     273                 :           0 : int2vectorsend(PG_FUNCTION_ARGS)
     274                 :             : {
     275                 :           0 :         return array_send(fcinfo);
     276                 :             : }
     277                 :             : 
     278                 :             : 
     279                 :             : /*****************************************************************************
     280                 :             :  *       PUBLIC ROUTINES                                                                                                                 *
     281                 :             :  *****************************************************************************/
     282                 :             : 
     283                 :             : /*
     284                 :             :  *              int4in                  - converts "num" to int4
     285                 :             :  */
     286                 :             : Datum
     287                 :      339308 : int4in(PG_FUNCTION_ARGS)
     288                 :             : {
     289                 :      339308 :         char       *num = PG_GETARG_CSTRING(0);
     290                 :             : 
     291                 :      678616 :         PG_RETURN_INT32(pg_strtoint32_safe(num, fcinfo->context));
     292                 :      339308 : }
     293                 :             : 
     294                 :             : /*
     295                 :             :  *              int4out                 - converts int4 to "num"
     296                 :             :  */
     297                 :             : Datum
     298                 :      710208 : int4out(PG_FUNCTION_ARGS)
     299                 :             : {
     300                 :      710208 :         int32           arg1 = PG_GETARG_INT32(0);
     301                 :      710208 :         char       *result = (char *) palloc(12);       /* sign, 10 digits, '\0' */
     302                 :             : 
     303                 :      710208 :         pg_ltoa(arg1, result);
     304                 :     1420416 :         PG_RETURN_CSTRING(result);
     305                 :      710208 : }
     306                 :             : 
     307                 :             : /*
     308                 :             :  *              int4recv                        - converts external binary format to int4
     309                 :             :  */
     310                 :             : Datum
     311                 :         344 : int4recv(PG_FUNCTION_ARGS)
     312                 :             : {
     313                 :         344 :         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
     314                 :             : 
     315                 :         688 :         PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
     316                 :         344 : }
     317                 :             : 
     318                 :             : /*
     319                 :             :  *              int4send                        - converts int4 to binary format
     320                 :             :  */
     321                 :             : Datum
     322                 :         182 : int4send(PG_FUNCTION_ARGS)
     323                 :             : {
     324                 :         182 :         int32           arg1 = PG_GETARG_INT32(0);
     325                 :         182 :         StringInfoData buf;
     326                 :             : 
     327                 :         182 :         pq_begintypsend(&buf);
     328                 :         182 :         pq_sendint32(&buf, arg1);
     329                 :         364 :         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     330                 :         182 : }
     331                 :             : 
     332                 :             : 
     333                 :             : /*
     334                 :             :  *              ===================
     335                 :             :  *              CONVERSION ROUTINES
     336                 :             :  *              ===================
     337                 :             :  */
     338                 :             : 
     339                 :             : Datum
     340                 :        5112 : i2toi4(PG_FUNCTION_ARGS)
     341                 :             : {
     342                 :        5112 :         int16           arg1 = PG_GETARG_INT16(0);
     343                 :             : 
     344                 :       10224 :         PG_RETURN_INT32((int32) arg1);
     345                 :        5112 : }
     346                 :             : 
     347                 :             : Datum
     348                 :         517 : i4toi2(PG_FUNCTION_ARGS)
     349                 :             : {
     350                 :         517 :         int32           arg1 = PG_GETARG_INT32(0);
     351                 :             : 
     352         [ +  + ]:         517 :         if (unlikely(arg1 < SHRT_MIN) || unlikely(arg1 > SHRT_MAX))
     353   [ +  -  +  - ]:           4 :                 ereport(ERROR,
     354                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     355                 :             :                                  errmsg("smallint out of range")));
     356                 :             : 
     357                 :        1026 :         PG_RETURN_INT16((int16) arg1);
     358                 :         513 : }
     359                 :             : 
     360                 :             : /* Cast int4 -> bool */
     361                 :             : Datum
     362                 :           5 : int4_bool(PG_FUNCTION_ARGS)
     363                 :             : {
     364         [ +  + ]:           5 :         if (PG_GETARG_INT32(0) == 0)
     365                 :           2 :                 PG_RETURN_BOOL(false);
     366                 :             :         else
     367                 :           3 :                 PG_RETURN_BOOL(true);
     368                 :           5 : }
     369                 :             : 
     370                 :             : /* Cast bool -> int4 */
     371                 :             : Datum
     372                 :         127 : bool_int4(PG_FUNCTION_ARGS)
     373                 :             : {
     374         [ +  + ]:         127 :         if (PG_GETARG_BOOL(0) == false)
     375                 :          19 :                 PG_RETURN_INT32(0);
     376                 :             :         else
     377                 :         108 :                 PG_RETURN_INT32(1);
     378                 :         127 : }
     379                 :             : 
     380                 :             : /*
     381                 :             :  *              ============================
     382                 :             :  *              COMPARISON OPERATOR ROUTINES
     383                 :             :  *              ============================
     384                 :             :  */
     385                 :             : 
     386                 :             : /*
     387                 :             :  *              inteq                   - returns 1 iff arg1 == arg2
     388                 :             :  *              intne                   - returns 1 iff arg1 != arg2
     389                 :             :  *              intlt                   - returns 1 iff arg1 < arg2
     390                 :             :  *              intle                   - returns 1 iff arg1 <= arg2
     391                 :             :  *              intgt                   - returns 1 iff arg1 > arg2
     392                 :             :  *              intge                   - returns 1 iff arg1 >= arg2
     393                 :             :  */
     394                 :             : 
     395                 :             : Datum
     396                 :    12397076 : int4eq(PG_FUNCTION_ARGS)
     397                 :             : {
     398                 :    12397076 :         int32           arg1 = PG_GETARG_INT32(0);
     399                 :    12397076 :         int32           arg2 = PG_GETARG_INT32(1);
     400                 :             : 
     401                 :    24794152 :         PG_RETURN_BOOL(arg1 == arg2);
     402                 :    12397076 : }
     403                 :             : 
     404                 :             : Datum
     405                 :       66781 : int4ne(PG_FUNCTION_ARGS)
     406                 :             : {
     407                 :       66781 :         int32           arg1 = PG_GETARG_INT32(0);
     408                 :       66781 :         int32           arg2 = PG_GETARG_INT32(1);
     409                 :             : 
     410                 :      133562 :         PG_RETURN_BOOL(arg1 != arg2);
     411                 :       66781 : }
     412                 :             : 
     413                 :             : Datum
     414                 :    37331683 : int4lt(PG_FUNCTION_ARGS)
     415                 :             : {
     416                 :    37331683 :         int32           arg1 = PG_GETARG_INT32(0);
     417                 :    37331683 :         int32           arg2 = PG_GETARG_INT32(1);
     418                 :             : 
     419                 :    74663366 :         PG_RETURN_BOOL(arg1 < arg2);
     420                 :    37331683 : }
     421                 :             : 
     422                 :             : Datum
     423                 :      224286 : int4le(PG_FUNCTION_ARGS)
     424                 :             : {
     425                 :      224286 :         int32           arg1 = PG_GETARG_INT32(0);
     426                 :      224286 :         int32           arg2 = PG_GETARG_INT32(1);
     427                 :             : 
     428                 :      448572 :         PG_RETURN_BOOL(arg1 <= arg2);
     429                 :      224286 : }
     430                 :             : 
     431                 :             : Datum
     432                 :      767374 : int4gt(PG_FUNCTION_ARGS)
     433                 :             : {
     434                 :      767374 :         int32           arg1 = PG_GETARG_INT32(0);
     435                 :      767374 :         int32           arg2 = PG_GETARG_INT32(1);
     436                 :             : 
     437                 :     1534748 :         PG_RETURN_BOOL(arg1 > arg2);
     438                 :      767374 : }
     439                 :             : 
     440                 :             : Datum
     441                 :       83320 : int4ge(PG_FUNCTION_ARGS)
     442                 :             : {
     443                 :       83320 :         int32           arg1 = PG_GETARG_INT32(0);
     444                 :       83320 :         int32           arg2 = PG_GETARG_INT32(1);
     445                 :             : 
     446                 :      166640 :         PG_RETURN_BOOL(arg1 >= arg2);
     447                 :       83320 : }
     448                 :             : 
     449                 :             : Datum
     450                 :      107815 : int2eq(PG_FUNCTION_ARGS)
     451                 :             : {
     452                 :      107815 :         int16           arg1 = PG_GETARG_INT16(0);
     453                 :      107815 :         int16           arg2 = PG_GETARG_INT16(1);
     454                 :             : 
     455                 :      215630 :         PG_RETURN_BOOL(arg1 == arg2);
     456                 :      107815 : }
     457                 :             : 
     458                 :             : Datum
     459                 :        5289 : int2ne(PG_FUNCTION_ARGS)
     460                 :             : {
     461                 :        5289 :         int16           arg1 = PG_GETARG_INT16(0);
     462                 :        5289 :         int16           arg2 = PG_GETARG_INT16(1);
     463                 :             : 
     464                 :       10578 :         PG_RETURN_BOOL(arg1 != arg2);
     465                 :        5289 : }
     466                 :             : 
     467                 :             : Datum
     468                 :      100894 : int2lt(PG_FUNCTION_ARGS)
     469                 :             : {
     470                 :      100894 :         int16           arg1 = PG_GETARG_INT16(0);
     471                 :      100894 :         int16           arg2 = PG_GETARG_INT16(1);
     472                 :             : 
     473                 :      201788 :         PG_RETURN_BOOL(arg1 < arg2);
     474                 :      100894 : }
     475                 :             : 
     476                 :             : Datum
     477                 :         731 : int2le(PG_FUNCTION_ARGS)
     478                 :             : {
     479                 :         731 :         int16           arg1 = PG_GETARG_INT16(0);
     480                 :         731 :         int16           arg2 = PG_GETARG_INT16(1);
     481                 :             : 
     482                 :        1462 :         PG_RETURN_BOOL(arg1 <= arg2);
     483                 :         731 : }
     484                 :             : 
     485                 :             : Datum
     486                 :      282448 : int2gt(PG_FUNCTION_ARGS)
     487                 :             : {
     488                 :      282448 :         int16           arg1 = PG_GETARG_INT16(0);
     489                 :      282448 :         int16           arg2 = PG_GETARG_INT16(1);
     490                 :             : 
     491                 :      564896 :         PG_RETURN_BOOL(arg1 > arg2);
     492                 :      282448 : }
     493                 :             : 
     494                 :             : Datum
     495                 :         619 : int2ge(PG_FUNCTION_ARGS)
     496                 :             : {
     497                 :         619 :         int16           arg1 = PG_GETARG_INT16(0);
     498                 :         619 :         int16           arg2 = PG_GETARG_INT16(1);
     499                 :             : 
     500                 :        1238 :         PG_RETURN_BOOL(arg1 >= arg2);
     501                 :         619 : }
     502                 :             : 
     503                 :             : Datum
     504                 :       14914 : int24eq(PG_FUNCTION_ARGS)
     505                 :             : {
     506                 :       14914 :         int16           arg1 = PG_GETARG_INT16(0);
     507                 :       14914 :         int32           arg2 = PG_GETARG_INT32(1);
     508                 :             : 
     509                 :       29828 :         PG_RETURN_BOOL(arg1 == arg2);
     510                 :       14914 : }
     511                 :             : 
     512                 :             : Datum
     513                 :       12521 : int24ne(PG_FUNCTION_ARGS)
     514                 :             : {
     515                 :       12521 :         int16           arg1 = PG_GETARG_INT16(0);
     516                 :       12521 :         int32           arg2 = PG_GETARG_INT32(1);
     517                 :             : 
     518                 :       25042 :         PG_RETURN_BOOL(arg1 != arg2);
     519                 :       12521 : }
     520                 :             : 
     521                 :             : Datum
     522                 :       17708 : int24lt(PG_FUNCTION_ARGS)
     523                 :             : {
     524                 :       17708 :         int16           arg1 = PG_GETARG_INT16(0);
     525                 :       17708 :         int32           arg2 = PG_GETARG_INT32(1);
     526                 :             : 
     527                 :       35416 :         PG_RETURN_BOOL(arg1 < arg2);
     528                 :       17708 : }
     529                 :             : 
     530                 :             : Datum
     531                 :        4835 : int24le(PG_FUNCTION_ARGS)
     532                 :             : {
     533                 :        4835 :         int16           arg1 = PG_GETARG_INT16(0);
     534                 :        4835 :         int32           arg2 = PG_GETARG_INT32(1);
     535                 :             : 
     536                 :        9670 :         PG_RETURN_BOOL(arg1 <= arg2);
     537                 :        4835 : }
     538                 :             : 
     539                 :             : Datum
     540                 :       91987 : int24gt(PG_FUNCTION_ARGS)
     541                 :             : {
     542                 :       91987 :         int16           arg1 = PG_GETARG_INT16(0);
     543                 :       91987 :         int32           arg2 = PG_GETARG_INT32(1);
     544                 :             : 
     545                 :      183974 :         PG_RETURN_BOOL(arg1 > arg2);
     546                 :       91987 : }
     547                 :             : 
     548                 :             : Datum
     549                 :        1406 : int24ge(PG_FUNCTION_ARGS)
     550                 :             : {
     551                 :        1406 :         int16           arg1 = PG_GETARG_INT16(0);
     552                 :        1406 :         int32           arg2 = PG_GETARG_INT32(1);
     553                 :             : 
     554                 :        2812 :         PG_RETURN_BOOL(arg1 >= arg2);
     555                 :        1406 : }
     556                 :             : 
     557                 :             : Datum
     558                 :        3956 : int42eq(PG_FUNCTION_ARGS)
     559                 :             : {
     560                 :        3956 :         int32           arg1 = PG_GETARG_INT32(0);
     561                 :        3956 :         int16           arg2 = PG_GETARG_INT16(1);
     562                 :             : 
     563                 :        7912 :         PG_RETURN_BOOL(arg1 == arg2);
     564                 :        3956 : }
     565                 :             : 
     566                 :             : Datum
     567                 :           5 : int42ne(PG_FUNCTION_ARGS)
     568                 :             : {
     569                 :           5 :         int32           arg1 = PG_GETARG_INT32(0);
     570                 :           5 :         int16           arg2 = PG_GETARG_INT16(1);
     571                 :             : 
     572                 :          10 :         PG_RETURN_BOOL(arg1 != arg2);
     573                 :           5 : }
     574                 :             : 
     575                 :             : Datum
     576                 :        2476 : int42lt(PG_FUNCTION_ARGS)
     577                 :             : {
     578                 :        2476 :         int32           arg1 = PG_GETARG_INT32(0);
     579                 :        2476 :         int16           arg2 = PG_GETARG_INT16(1);
     580                 :             : 
     581                 :        4952 :         PG_RETURN_BOOL(arg1 < arg2);
     582                 :        2476 : }
     583                 :             : 
     584                 :             : Datum
     585                 :        2519 : int42le(PG_FUNCTION_ARGS)
     586                 :             : {
     587                 :        2519 :         int32           arg1 = PG_GETARG_INT32(0);
     588                 :        2519 :         int16           arg2 = PG_GETARG_INT16(1);
     589                 :             : 
     590                 :        5038 :         PG_RETURN_BOOL(arg1 <= arg2);
     591                 :        2519 : }
     592                 :             : 
     593                 :             : Datum
     594                 :         538 : int42gt(PG_FUNCTION_ARGS)
     595                 :             : {
     596                 :         538 :         int32           arg1 = PG_GETARG_INT32(0);
     597                 :         538 :         int16           arg2 = PG_GETARG_INT16(1);
     598                 :             : 
     599                 :        1076 :         PG_RETURN_BOOL(arg1 > arg2);
     600                 :         538 : }
     601                 :             : 
     602                 :             : Datum
     603                 :         576 : int42ge(PG_FUNCTION_ARGS)
     604                 :             : {
     605                 :         576 :         int32           arg1 = PG_GETARG_INT32(0);
     606                 :         576 :         int16           arg2 = PG_GETARG_INT16(1);
     607                 :             : 
     608                 :        1152 :         PG_RETURN_BOOL(arg1 >= arg2);
     609                 :         576 : }
     610                 :             : 
     611                 :             : 
     612                 :             : /*----------------------------------------------------------
     613                 :             :  *      in_range functions for int4 and int2,
     614                 :             :  *      including cross-data-type comparisons.
     615                 :             :  *
     616                 :             :  *      Note: we provide separate intN_int8 functions for performance
     617                 :             :  *      reasons.  This forces also providing intN_int2, else cases with a
     618                 :             :  *      smallint offset value would fail to resolve which function to use.
     619                 :             :  *      But that's an unlikely situation, so don't duplicate code for it.
     620                 :             :  *---------------------------------------------------------*/
     621                 :             : 
     622                 :             : Datum
     623                 :         533 : in_range_int4_int4(PG_FUNCTION_ARGS)
     624                 :             : {
     625                 :         533 :         int32           val = PG_GETARG_INT32(0);
     626                 :         533 :         int32           base = PG_GETARG_INT32(1);
     627                 :         533 :         int32           offset = PG_GETARG_INT32(2);
     628                 :         533 :         bool            sub = PG_GETARG_BOOL(3);
     629                 :         533 :         bool            less = PG_GETARG_BOOL(4);
     630                 :         533 :         int32           sum;
     631                 :             : 
     632         [ +  + ]:         533 :         if (offset < 0)
     633   [ +  -  +  - ]:           2 :                 ereport(ERROR,
     634                 :             :                                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     635                 :             :                                  errmsg("invalid preceding or following size in window function")));
     636                 :             : 
     637         [ +  + ]:         531 :         if (sub)
     638                 :         240 :                 offset = -offset;               /* cannot overflow */
     639                 :             : 
     640         [ +  + ]:         531 :         if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
     641                 :             :         {
     642                 :             :                 /*
     643                 :             :                  * If sub is false, the true sum is surely more than val, so correct
     644                 :             :                  * answer is the same as "less".  If sub is true, the true sum is
     645                 :             :                  * surely less than val, so the answer is "!less".
     646                 :             :                  */
     647         [ +  + ]:           6 :                 PG_RETURN_BOOL(sub ? !less : less);
     648                 :             :         }
     649                 :             : 
     650         [ +  + ]:         525 :         if (less)
     651                 :         310 :                 PG_RETURN_BOOL(val <= sum);
     652                 :             :         else
     653                 :         215 :                 PG_RETURN_BOOL(val >= sum);
     654                 :         531 : }
     655                 :             : 
     656                 :             : Datum
     657                 :         151 : in_range_int4_int2(PG_FUNCTION_ARGS)
     658                 :             : {
     659                 :             :         /* Doesn't seem worth duplicating code for, so just invoke int4_int4 */
     660                 :         151 :         return DirectFunctionCall5(in_range_int4_int4,
     661                 :             :                                                            PG_GETARG_DATUM(0),
     662                 :             :                                                            PG_GETARG_DATUM(1),
     663                 :             :                                                            Int32GetDatum((int32) PG_GETARG_INT16(2)),
     664                 :             :                                                            PG_GETARG_DATUM(3),
     665                 :             :                                                            PG_GETARG_DATUM(4));
     666                 :             : }
     667                 :             : 
     668                 :             : Datum
     669                 :         127 : in_range_int4_int8(PG_FUNCTION_ARGS)
     670                 :             : {
     671                 :             :         /* We must do all the math in int64 */
     672                 :         127 :         int64           val = (int64) PG_GETARG_INT32(0);
     673                 :         127 :         int64           base = (int64) PG_GETARG_INT32(1);
     674                 :         127 :         int64           offset = PG_GETARG_INT64(2);
     675                 :         127 :         bool            sub = PG_GETARG_BOOL(3);
     676                 :         127 :         bool            less = PG_GETARG_BOOL(4);
     677                 :         127 :         int64           sum;
     678                 :             : 
     679         [ +  - ]:         127 :         if (offset < 0)
     680   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     681                 :             :                                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     682                 :             :                                  errmsg("invalid preceding or following size in window function")));
     683                 :             : 
     684         [ +  + ]:         127 :         if (sub)
     685                 :         115 :                 offset = -offset;               /* cannot overflow */
     686                 :             : 
     687         [ -  + ]:         127 :         if (unlikely(pg_add_s64_overflow(base, offset, &sum)))
     688                 :             :         {
     689                 :             :                 /*
     690                 :             :                  * If sub is false, the true sum is surely more than val, so correct
     691                 :             :                  * answer is the same as "less".  If sub is true, the true sum is
     692                 :             :                  * surely less than val, so the answer is "!less".
     693                 :             :                  */
     694         [ #  # ]:           0 :                 PG_RETURN_BOOL(sub ? !less : less);
     695                 :             :         }
     696                 :             : 
     697         [ +  + ]:         127 :         if (less)
     698                 :          12 :                 PG_RETURN_BOOL(val <= sum);
     699                 :             :         else
     700                 :         115 :                 PG_RETURN_BOOL(val >= sum);
     701                 :         127 : }
     702                 :             : 
     703                 :             : Datum
     704                 :           6 : in_range_int2_int4(PG_FUNCTION_ARGS)
     705                 :             : {
     706                 :             :         /* We must do all the math in int32 */
     707                 :           6 :         int32           val = (int32) PG_GETARG_INT16(0);
     708                 :           6 :         int32           base = (int32) PG_GETARG_INT16(1);
     709                 :           6 :         int32           offset = PG_GETARG_INT32(2);
     710                 :           6 :         bool            sub = PG_GETARG_BOOL(3);
     711                 :           6 :         bool            less = PG_GETARG_BOOL(4);
     712                 :           6 :         int32           sum;
     713                 :             : 
     714         [ +  - ]:           6 :         if (offset < 0)
     715   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     716                 :             :                                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     717                 :             :                                  errmsg("invalid preceding or following size in window function")));
     718                 :             : 
     719         [ +  + ]:           6 :         if (sub)
     720                 :           3 :                 offset = -offset;               /* cannot overflow */
     721                 :             : 
     722         [ +  - ]:           6 :         if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
     723                 :             :         {
     724                 :             :                 /*
     725                 :             :                  * If sub is false, the true sum is surely more than val, so correct
     726                 :             :                  * answer is the same as "less".  If sub is true, the true sum is
     727                 :             :                  * surely less than val, so the answer is "!less".
     728                 :             :                  */
     729         [ +  + ]:           6 :                 PG_RETURN_BOOL(sub ? !less : less);
     730                 :             :         }
     731                 :             : 
     732         [ #  # ]:           0 :         if (less)
     733                 :           0 :                 PG_RETURN_BOOL(val <= sum);
     734                 :             :         else
     735                 :           0 :                 PG_RETURN_BOOL(val >= sum);
     736                 :           6 : }
     737                 :             : 
     738                 :             : Datum
     739                 :           0 : in_range_int2_int2(PG_FUNCTION_ARGS)
     740                 :             : {
     741                 :             :         /* Doesn't seem worth duplicating code for, so just invoke int2_int4 */
     742                 :           0 :         return DirectFunctionCall5(in_range_int2_int4,
     743                 :             :                                                            PG_GETARG_DATUM(0),
     744                 :             :                                                            PG_GETARG_DATUM(1),
     745                 :             :                                                            Int32GetDatum((int32) PG_GETARG_INT16(2)),
     746                 :             :                                                            PG_GETARG_DATUM(3),
     747                 :             :                                                            PG_GETARG_DATUM(4));
     748                 :             : }
     749                 :             : 
     750                 :             : Datum
     751                 :           0 : in_range_int2_int8(PG_FUNCTION_ARGS)
     752                 :             : {
     753                 :             :         /* Doesn't seem worth duplicating code for, so just invoke int4_int8 */
     754                 :           0 :         return DirectFunctionCall5(in_range_int4_int8,
     755                 :             :                                                            Int32GetDatum((int32) PG_GETARG_INT16(0)),
     756                 :             :                                                            Int32GetDatum((int32) PG_GETARG_INT16(1)),
     757                 :             :                                                            PG_GETARG_DATUM(2),
     758                 :             :                                                            PG_GETARG_DATUM(3),
     759                 :             :                                                            PG_GETARG_DATUM(4));
     760                 :             : }
     761                 :             : 
     762                 :             : 
     763                 :             : /*
     764                 :             :  *              int[24]pl               - returns arg1 + arg2
     765                 :             :  *              int[24]mi               - returns arg1 - arg2
     766                 :             :  *              int[24]mul              - returns arg1 * arg2
     767                 :             :  *              int[24]div              - returns arg1 / arg2
     768                 :             :  */
     769                 :             : 
     770                 :             : Datum
     771                 :        4497 : int4um(PG_FUNCTION_ARGS)
     772                 :             : {
     773                 :        4497 :         int32           arg = PG_GETARG_INT32(0);
     774                 :             : 
     775         [ +  - ]:        4497 :         if (unlikely(arg == PG_INT32_MIN))
     776   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     777                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     778                 :             :                                  errmsg("integer out of range")));
     779                 :        8994 :         PG_RETURN_INT32(-arg);
     780                 :        4497 : }
     781                 :             : 
     782                 :             : Datum
     783                 :           1 : int4up(PG_FUNCTION_ARGS)
     784                 :             : {
     785                 :           1 :         int32           arg = PG_GETARG_INT32(0);
     786                 :             : 
     787                 :           2 :         PG_RETURN_INT32(arg);
     788                 :           1 : }
     789                 :             : 
     790                 :             : Datum
     791                 :     1320880 : int4pl(PG_FUNCTION_ARGS)
     792                 :             : {
     793                 :     1320880 :         int32           arg1 = PG_GETARG_INT32(0);
     794                 :     1320880 :         int32           arg2 = PG_GETARG_INT32(1);
     795                 :     1320880 :         int32           result;
     796                 :             : 
     797         [ +  + ]:     1320880 :         if (unlikely(pg_add_s32_overflow(arg1, arg2, &result)))
     798   [ +  -  +  - ]:           1 :                 ereport(ERROR,
     799                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     800                 :             :                                  errmsg("integer out of range")));
     801                 :     2641758 :         PG_RETURN_INT32(result);
     802                 :     1320879 : }
     803                 :             : 
     804                 :             : Datum
     805                 :      439307 : int4mi(PG_FUNCTION_ARGS)
     806                 :             : {
     807                 :      439307 :         int32           arg1 = PG_GETARG_INT32(0);
     808                 :      439307 :         int32           arg2 = PG_GETARG_INT32(1);
     809                 :      439307 :         int32           result;
     810                 :             : 
     811         [ +  + ]:      439307 :         if (unlikely(pg_sub_s32_overflow(arg1, arg2, &result)))
     812   [ +  -  +  - ]:           1 :                 ereport(ERROR,
     813                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     814                 :             :                                  errmsg("integer out of range")));
     815                 :      878612 :         PG_RETURN_INT32(result);
     816                 :      439306 : }
     817                 :             : 
     818                 :             : Datum
     819                 :      434216 : int4mul(PG_FUNCTION_ARGS)
     820                 :             : {
     821                 :      434216 :         int32           arg1 = PG_GETARG_INT32(0);
     822                 :      434216 :         int32           arg2 = PG_GETARG_INT32(1);
     823                 :      434216 :         int32           result;
     824                 :             : 
     825         [ +  + ]:      434216 :         if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
     826   [ +  -  +  - ]:           4 :                 ereport(ERROR,
     827                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     828                 :             :                                  errmsg("integer out of range")));
     829                 :      868424 :         PG_RETURN_INT32(result);
     830                 :      434212 : }
     831                 :             : 
     832                 :             : Datum
     833                 :      213447 : int4div(PG_FUNCTION_ARGS)
     834                 :             : {
     835                 :      213447 :         int32           arg1 = PG_GETARG_INT32(0);
     836                 :      213447 :         int32           arg2 = PG_GETARG_INT32(1);
     837                 :      213447 :         int32           result;
     838                 :             : 
     839         [ +  + ]:      213447 :         if (arg2 == 0)
     840                 :             :         {
     841   [ +  -  +  - ]:          41 :                 ereport(ERROR,
     842                 :             :                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     843                 :             :                                  errmsg("division by zero")));
     844                 :             :                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     845                 :           0 :                 PG_RETURN_NULL();
     846                 :           0 :         }
     847                 :             : 
     848                 :             :         /*
     849                 :             :          * INT_MIN / -1 is problematic, since the result can't be represented on a
     850                 :             :          * two's-complement machine.  Some machines produce INT_MIN, some produce
     851                 :             :          * zero, some throw an exception.  We can dodge the problem by recognizing
     852                 :             :          * that division by -1 is the same as negation.
     853                 :             :          */
     854         [ +  + ]:      213406 :         if (arg2 == -1)
     855                 :             :         {
     856         [ -  + ]:           1 :                 if (unlikely(arg1 == PG_INT32_MIN))
     857   [ +  -  +  - ]:           1 :                         ereport(ERROR,
     858                 :             :                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     859                 :             :                                          errmsg("integer out of range")));
     860                 :           0 :                 result = -arg1;
     861                 :           0 :                 PG_RETURN_INT32(result);
     862                 :             :         }
     863                 :             : 
     864                 :             :         /* No overflow is possible */
     865                 :             : 
     866                 :      213405 :         result = arg1 / arg2;
     867                 :             : 
     868                 :      213405 :         PG_RETURN_INT32(result);
     869                 :      213405 : }
     870                 :             : 
     871                 :             : Datum
     872                 :           0 : int4inc(PG_FUNCTION_ARGS)
     873                 :             : {
     874                 :           0 :         int32           arg = PG_GETARG_INT32(0);
     875                 :           0 :         int32           result;
     876                 :             : 
     877         [ #  # ]:           0 :         if (unlikely(pg_add_s32_overflow(arg, 1, &result)))
     878   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     879                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     880                 :             :                                  errmsg("integer out of range")));
     881                 :             : 
     882                 :           0 :         PG_RETURN_INT32(result);
     883                 :           0 : }
     884                 :             : 
     885                 :             : Datum
     886                 :           2 : int2um(PG_FUNCTION_ARGS)
     887                 :             : {
     888                 :           2 :         int16           arg = PG_GETARG_INT16(0);
     889                 :             : 
     890         [ +  - ]:           2 :         if (unlikely(arg == PG_INT16_MIN))
     891   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     892                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     893                 :             :                                  errmsg("smallint out of range")));
     894                 :           4 :         PG_RETURN_INT16(-arg);
     895                 :           2 : }
     896                 :             : 
     897                 :             : Datum
     898                 :           0 : int2up(PG_FUNCTION_ARGS)
     899                 :             : {
     900                 :           0 :         int16           arg = PG_GETARG_INT16(0);
     901                 :             : 
     902                 :           0 :         PG_RETURN_INT16(arg);
     903                 :           0 : }
     904                 :             : 
     905                 :             : Datum
     906                 :           9 : int2pl(PG_FUNCTION_ARGS)
     907                 :             : {
     908                 :           9 :         int16           arg1 = PG_GETARG_INT16(0);
     909                 :           9 :         int16           arg2 = PG_GETARG_INT16(1);
     910                 :           9 :         int16           result;
     911                 :             : 
     912         [ +  + ]:           9 :         if (unlikely(pg_add_s16_overflow(arg1, arg2, &result)))
     913   [ +  -  +  - ]:           1 :                 ereport(ERROR,
     914                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     915                 :             :                                  errmsg("smallint out of range")));
     916                 :          16 :         PG_RETURN_INT16(result);
     917                 :           8 : }
     918                 :             : 
     919                 :             : Datum
     920                 :          20 : int2mi(PG_FUNCTION_ARGS)
     921                 :             : {
     922                 :          20 :         int16           arg1 = PG_GETARG_INT16(0);
     923                 :          20 :         int16           arg2 = PG_GETARG_INT16(1);
     924                 :          20 :         int16           result;
     925                 :             : 
     926         [ +  + ]:          20 :         if (unlikely(pg_sub_s16_overflow(arg1, arg2, &result)))
     927   [ +  -  +  - ]:           1 :                 ereport(ERROR,
     928                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     929                 :             :                                  errmsg("smallint out of range")));
     930                 :          38 :         PG_RETURN_INT16(result);
     931                 :          19 : }
     932                 :             : 
     933                 :             : Datum
     934                 :           9 : int2mul(PG_FUNCTION_ARGS)
     935                 :             : {
     936                 :           9 :         int16           arg1 = PG_GETARG_INT16(0);
     937                 :           9 :         int16           arg2 = PG_GETARG_INT16(1);
     938                 :           9 :         int16           result;
     939                 :             : 
     940         [ +  + ]:           9 :         if (unlikely(pg_mul_s16_overflow(arg1, arg2, &result)))
     941   [ +  -  +  - ]:           2 :                 ereport(ERROR,
     942                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     943                 :             :                                  errmsg("smallint out of range")));
     944                 :             : 
     945                 :          14 :         PG_RETURN_INT16(result);
     946                 :           7 : }
     947                 :             : 
     948                 :             : Datum
     949                 :           7 : int2div(PG_FUNCTION_ARGS)
     950                 :             : {
     951                 :           7 :         int16           arg1 = PG_GETARG_INT16(0);
     952                 :           7 :         int16           arg2 = PG_GETARG_INT16(1);
     953                 :           7 :         int16           result;
     954                 :             : 
     955         [ +  - ]:           7 :         if (arg2 == 0)
     956                 :             :         {
     957   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     958                 :             :                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     959                 :             :                                  errmsg("division by zero")));
     960                 :             :                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     961                 :           0 :                 PG_RETURN_NULL();
     962                 :           0 :         }
     963                 :             : 
     964                 :             :         /*
     965                 :             :          * SHRT_MIN / -1 is problematic, since the result can't be represented on
     966                 :             :          * a two's-complement machine.  Some machines produce SHRT_MIN, some
     967                 :             :          * produce zero, some throw an exception.  We can dodge the problem by
     968                 :             :          * recognizing that division by -1 is the same as negation.
     969                 :             :          */
     970         [ +  + ]:           7 :         if (arg2 == -1)
     971                 :             :         {
     972         [ -  + ]:           1 :                 if (unlikely(arg1 == PG_INT16_MIN))
     973   [ +  -  +  - ]:           1 :                         ereport(ERROR,
     974                 :             :                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     975                 :             :                                          errmsg("smallint out of range")));
     976                 :           0 :                 result = -arg1;
     977                 :           0 :                 PG_RETURN_INT16(result);
     978                 :             :         }
     979                 :             : 
     980                 :             :         /* No overflow is possible */
     981                 :             : 
     982                 :           6 :         result = arg1 / arg2;
     983                 :             : 
     984                 :           6 :         PG_RETURN_INT16(result);
     985                 :           6 : }
     986                 :             : 
     987                 :             : Datum
     988                 :         376 : int24pl(PG_FUNCTION_ARGS)
     989                 :             : {
     990                 :         376 :         int16           arg1 = PG_GETARG_INT16(0);
     991                 :         376 :         int32           arg2 = PG_GETARG_INT32(1);
     992                 :         376 :         int32           result;
     993                 :             : 
     994         [ +  - ]:         376 :         if (unlikely(pg_add_s32_overflow((int32) arg1, arg2, &result)))
     995   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     996                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     997                 :             :                                  errmsg("integer out of range")));
     998                 :         752 :         PG_RETURN_INT32(result);
     999                 :         376 : }
    1000                 :             : 
    1001                 :             : Datum
    1002                 :        4312 : int24mi(PG_FUNCTION_ARGS)
    1003                 :             : {
    1004                 :        4312 :         int16           arg1 = PG_GETARG_INT16(0);
    1005                 :        4312 :         int32           arg2 = PG_GETARG_INT32(1);
    1006                 :        4312 :         int32           result;
    1007                 :             : 
    1008         [ +  - ]:        4312 :         if (unlikely(pg_sub_s32_overflow((int32) arg1, arg2, &result)))
    1009   [ #  #  #  # ]:           0 :                 ereport(ERROR,
    1010                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1011                 :             :                                  errmsg("integer out of range")));
    1012                 :        8624 :         PG_RETURN_INT32(result);
    1013                 :        4312 : }
    1014                 :             : 
    1015                 :             : Datum
    1016                 :           6 : int24mul(PG_FUNCTION_ARGS)
    1017                 :             : {
    1018                 :           6 :         int16           arg1 = PG_GETARG_INT16(0);
    1019                 :           6 :         int32           arg2 = PG_GETARG_INT32(1);
    1020                 :           6 :         int32           result;
    1021                 :             : 
    1022         [ +  - ]:           6 :         if (unlikely(pg_mul_s32_overflow((int32) arg1, arg2, &result)))
    1023   [ #  #  #  # ]:           0 :                 ereport(ERROR,
    1024                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1025                 :             :                                  errmsg("integer out of range")));
    1026                 :          12 :         PG_RETURN_INT32(result);
    1027                 :           6 : }
    1028                 :             : 
    1029                 :             : Datum
    1030                 :           7 : int24div(PG_FUNCTION_ARGS)
    1031                 :             : {
    1032                 :           7 :         int16           arg1 = PG_GETARG_INT16(0);
    1033                 :           7 :         int32           arg2 = PG_GETARG_INT32(1);
    1034                 :             : 
    1035         [ +  + ]:           7 :         if (unlikely(arg2 == 0))
    1036                 :             :         {
    1037   [ +  -  +  - ]:           1 :                 ereport(ERROR,
    1038                 :             :                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1039                 :             :                                  errmsg("division by zero")));
    1040                 :             :                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1041                 :           0 :                 PG_RETURN_NULL();
    1042                 :           0 :         }
    1043                 :             : 
    1044                 :             :         /* No overflow is possible */
    1045                 :           6 :         PG_RETURN_INT32((int32) arg1 / arg2);
    1046                 :           6 : }
    1047                 :             : 
    1048                 :             : Datum
    1049                 :           8 : int42pl(PG_FUNCTION_ARGS)
    1050                 :             : {
    1051                 :           8 :         int32           arg1 = PG_GETARG_INT32(0);
    1052                 :           8 :         int16           arg2 = PG_GETARG_INT16(1);
    1053                 :           8 :         int32           result;
    1054                 :             : 
    1055         [ +  + ]:           8 :         if (unlikely(pg_add_s32_overflow(arg1, (int32) arg2, &result)))
    1056   [ +  -  +  - ]:           1 :                 ereport(ERROR,
    1057                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1058                 :             :                                  errmsg("integer out of range")));
    1059                 :          14 :         PG_RETURN_INT32(result);
    1060                 :           7 : }
    1061                 :             : 
    1062                 :             : Datum
    1063                 :           9 : int42mi(PG_FUNCTION_ARGS)
    1064                 :             : {
    1065                 :           9 :         int32           arg1 = PG_GETARG_INT32(0);
    1066                 :           9 :         int16           arg2 = PG_GETARG_INT16(1);
    1067                 :           9 :         int32           result;
    1068                 :             : 
    1069         [ +  + ]:           9 :         if (unlikely(pg_sub_s32_overflow(arg1, (int32) arg2, &result)))
    1070   [ +  -  +  - ]:           1 :                 ereport(ERROR,
    1071                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1072                 :             :                                  errmsg("integer out of range")));
    1073                 :          16 :         PG_RETURN_INT32(result);
    1074                 :           8 : }
    1075                 :             : 
    1076                 :             : Datum
    1077                 :           9 : int42mul(PG_FUNCTION_ARGS)
    1078                 :             : {
    1079                 :           9 :         int32           arg1 = PG_GETARG_INT32(0);
    1080                 :           9 :         int16           arg2 = PG_GETARG_INT16(1);
    1081                 :           9 :         int32           result;
    1082                 :             : 
    1083         [ +  + ]:           9 :         if (unlikely(pg_mul_s32_overflow(arg1, (int32) arg2, &result)))
    1084   [ +  -  +  - ]:           2 :                 ereport(ERROR,
    1085                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1086                 :             :                                  errmsg("integer out of range")));
    1087                 :          14 :         PG_RETURN_INT32(result);
    1088                 :           7 : }
    1089                 :             : 
    1090                 :             : Datum
    1091                 :           8 : int42div(PG_FUNCTION_ARGS)
    1092                 :             : {
    1093                 :           8 :         int32           arg1 = PG_GETARG_INT32(0);
    1094                 :           8 :         int16           arg2 = PG_GETARG_INT16(1);
    1095                 :           8 :         int32           result;
    1096                 :             : 
    1097         [ +  + ]:           8 :         if (unlikely(arg2 == 0))
    1098                 :             :         {
    1099   [ +  -  +  - ]:           1 :                 ereport(ERROR,
    1100                 :             :                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1101                 :             :                                  errmsg("division by zero")));
    1102                 :             :                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1103                 :           0 :                 PG_RETURN_NULL();
    1104                 :           0 :         }
    1105                 :             : 
    1106                 :             :         /*
    1107                 :             :          * INT_MIN / -1 is problematic, since the result can't be represented on a
    1108                 :             :          * two's-complement machine.  Some machines produce INT_MIN, some produce
    1109                 :             :          * zero, some throw an exception.  We can dodge the problem by recognizing
    1110                 :             :          * that division by -1 is the same as negation.
    1111                 :             :          */
    1112         [ +  + ]:           7 :         if (arg2 == -1)
    1113                 :             :         {
    1114         [ -  + ]:           1 :                 if (unlikely(arg1 == PG_INT32_MIN))
    1115   [ +  -  +  - ]:           1 :                         ereport(ERROR,
    1116                 :             :                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1117                 :             :                                          errmsg("integer out of range")));
    1118                 :           0 :                 result = -arg1;
    1119                 :           0 :                 PG_RETURN_INT32(result);
    1120                 :             :         }
    1121                 :             : 
    1122                 :             :         /* No overflow is possible */
    1123                 :             : 
    1124                 :           6 :         result = arg1 / arg2;
    1125                 :             : 
    1126                 :           6 :         PG_RETURN_INT32(result);
    1127                 :           6 : }
    1128                 :             : 
    1129                 :             : Datum
    1130                 :     1372101 : int4mod(PG_FUNCTION_ARGS)
    1131                 :             : {
    1132                 :     1372101 :         int32           arg1 = PG_GETARG_INT32(0);
    1133                 :     1372101 :         int32           arg2 = PG_GETARG_INT32(1);
    1134                 :             : 
    1135         [ +  - ]:     1372101 :         if (unlikely(arg2 == 0))
    1136                 :             :         {
    1137   [ #  #  #  # ]:           0 :                 ereport(ERROR,
    1138                 :             :                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1139                 :             :                                  errmsg("division by zero")));
    1140                 :             :                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1141                 :           0 :                 PG_RETURN_NULL();
    1142                 :           0 :         }
    1143                 :             : 
    1144                 :             :         /*
    1145                 :             :          * Some machines throw a floating-point exception for INT_MIN % -1, which
    1146                 :             :          * is a bit silly since the correct answer is perfectly well-defined,
    1147                 :             :          * namely zero.
    1148                 :             :          */
    1149         [ +  + ]:     1372101 :         if (arg2 == -1)
    1150                 :           2 :                 PG_RETURN_INT32(0);
    1151                 :             : 
    1152                 :             :         /* No overflow is possible */
    1153                 :             : 
    1154                 :     1372099 :         PG_RETURN_INT32(arg1 % arg2);
    1155                 :     1372101 : }
    1156                 :             : 
    1157                 :             : Datum
    1158                 :           6 : int2mod(PG_FUNCTION_ARGS)
    1159                 :             : {
    1160                 :           6 :         int16           arg1 = PG_GETARG_INT16(0);
    1161                 :           6 :         int16           arg2 = PG_GETARG_INT16(1);
    1162                 :             : 
    1163         [ +  - ]:           6 :         if (unlikely(arg2 == 0))
    1164                 :             :         {
    1165   [ #  #  #  # ]:           0 :                 ereport(ERROR,
    1166                 :             :                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1167                 :             :                                  errmsg("division by zero")));
    1168                 :             :                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1169                 :           0 :                 PG_RETURN_NULL();
    1170                 :           0 :         }
    1171                 :             : 
    1172                 :             :         /*
    1173                 :             :          * Some machines throw a floating-point exception for INT_MIN % -1, which
    1174                 :             :          * is a bit silly since the correct answer is perfectly well-defined,
    1175                 :             :          * namely zero.  (It's not clear this ever happens when dealing with
    1176                 :             :          * int16, but we might as well have the test for safety.)
    1177                 :             :          */
    1178         [ +  + ]:           6 :         if (arg2 == -1)
    1179                 :           1 :                 PG_RETURN_INT16(0);
    1180                 :             : 
    1181                 :             :         /* No overflow is possible */
    1182                 :             : 
    1183                 :           5 :         PG_RETURN_INT16(arg1 % arg2);
    1184                 :           6 : }
    1185                 :             : 
    1186                 :             : 
    1187                 :             : /* int[24]abs()
    1188                 :             :  * Absolute value
    1189                 :             :  */
    1190                 :             : Datum
    1191                 :       20221 : int4abs(PG_FUNCTION_ARGS)
    1192                 :             : {
    1193                 :       20221 :         int32           arg1 = PG_GETARG_INT32(0);
    1194                 :       20221 :         int32           result;
    1195                 :             : 
    1196         [ +  - ]:       20221 :         if (unlikely(arg1 == PG_INT32_MIN))
    1197   [ #  #  #  # ]:           0 :                 ereport(ERROR,
    1198                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1199                 :             :                                  errmsg("integer out of range")));
    1200         [ +  + ]:       20221 :         result = (arg1 < 0) ? -arg1 : arg1;
    1201                 :       40442 :         PG_RETURN_INT32(result);
    1202                 :       20221 : }
    1203                 :             : 
    1204                 :             : Datum
    1205                 :           5 : int2abs(PG_FUNCTION_ARGS)
    1206                 :             : {
    1207                 :           5 :         int16           arg1 = PG_GETARG_INT16(0);
    1208                 :           5 :         int16           result;
    1209                 :             : 
    1210         [ +  - ]:           5 :         if (unlikely(arg1 == PG_INT16_MIN))
    1211   [ #  #  #  # ]:           0 :                 ereport(ERROR,
    1212                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1213                 :             :                                  errmsg("smallint out of range")));
    1214         [ +  + ]:           5 :         result = (arg1 < 0) ? -arg1 : arg1;
    1215                 :          10 :         PG_RETURN_INT16(result);
    1216                 :           5 : }
    1217                 :             : 
    1218                 :             : /*
    1219                 :             :  * Greatest Common Divisor
    1220                 :             :  *
    1221                 :             :  * Returns the largest positive integer that exactly divides both inputs.
    1222                 :             :  * Special cases:
    1223                 :             :  *   - gcd(x, 0) = gcd(0, x) = abs(x)
    1224                 :             :  *              because 0 is divisible by anything
    1225                 :             :  *   - gcd(0, 0) = 0
    1226                 :             :  *              complies with the previous definition and is a common convention
    1227                 :             :  *
    1228                 :             :  * Special care must be taken if either input is INT_MIN --- gcd(0, INT_MIN),
    1229                 :             :  * gcd(INT_MIN, 0) and gcd(INT_MIN, INT_MIN) are all equal to abs(INT_MIN),
    1230                 :             :  * which cannot be represented as a 32-bit signed integer.
    1231                 :             :  */
    1232                 :             : static int32
    1233                 :          44 : int4gcd_internal(int32 arg1, int32 arg2)
    1234                 :             : {
    1235                 :          44 :         int32           swap;
    1236                 :          44 :         int32           a1,
    1237                 :             :                                 a2;
    1238                 :             : 
    1239                 :             :         /*
    1240                 :             :          * Put the greater absolute value in arg1.
    1241                 :             :          *
    1242                 :             :          * This would happen automatically in the loop below, but avoids an
    1243                 :             :          * expensive modulo operation, and simplifies the special-case handling
    1244                 :             :          * for INT_MIN below.
    1245                 :             :          *
    1246                 :             :          * We do this in negative space in order to handle INT_MIN.
    1247                 :             :          */
    1248         [ +  + ]:          44 :         a1 = (arg1 < 0) ? arg1 : -arg1;
    1249         [ +  + ]:          44 :         a2 = (arg2 < 0) ? arg2 : -arg2;
    1250         [ +  + ]:          44 :         if (a1 > a2)
    1251                 :             :         {
    1252                 :          16 :                 swap = arg1;
    1253                 :          16 :                 arg1 = arg2;
    1254                 :          16 :                 arg2 = swap;
    1255                 :          16 :         }
    1256                 :             : 
    1257                 :             :         /* Special care needs to be taken with INT_MIN.  See comments above. */
    1258         [ +  + ]:          44 :         if (arg1 == PG_INT32_MIN)
    1259                 :             :         {
    1260         [ +  + ]:          15 :                 if (arg2 == 0 || arg2 == PG_INT32_MIN)
    1261   [ +  -  +  - ]:           2 :                         ereport(ERROR,
    1262                 :             :                                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1263                 :             :                                          errmsg("integer out of range")));
    1264                 :             : 
    1265                 :             :                 /*
    1266                 :             :                  * Some machines throw a floating-point exception for INT_MIN % -1,
    1267                 :             :                  * which is a bit silly since the correct answer is perfectly
    1268                 :             :                  * well-defined, namely zero.  Guard against this and just return the
    1269                 :             :                  * result, gcd(INT_MIN, -1) = 1.
    1270                 :             :                  */
    1271         [ +  + ]:          13 :                 if (arg2 == -1)
    1272                 :           2 :                         return 1;
    1273                 :          11 :         }
    1274                 :             : 
    1275                 :             :         /* Use the Euclidean algorithm to find the GCD */
    1276         [ +  + ]:         157 :         while (arg2 != 0)
    1277                 :             :         {
    1278                 :         117 :                 swap = arg2;
    1279                 :         117 :                 arg2 = arg1 % arg2;
    1280                 :         117 :                 arg1 = swap;
    1281                 :             :         }
    1282                 :             : 
    1283                 :             :         /*
    1284                 :             :          * Make sure the result is positive. (We know we don't have INT_MIN
    1285                 :             :          * anymore).
    1286                 :             :          */
    1287         [ +  + ]:          40 :         if (arg1 < 0)
    1288                 :          17 :                 arg1 = -arg1;
    1289                 :             : 
    1290                 :          40 :         return arg1;
    1291                 :          42 : }
    1292                 :             : 
    1293                 :             : Datum
    1294                 :          30 : int4gcd(PG_FUNCTION_ARGS)
    1295                 :             : {
    1296                 :          30 :         int32           arg1 = PG_GETARG_INT32(0);
    1297                 :          30 :         int32           arg2 = PG_GETARG_INT32(1);
    1298                 :          30 :         int32           result;
    1299                 :             : 
    1300                 :          30 :         result = int4gcd_internal(arg1, arg2);
    1301                 :             : 
    1302                 :          60 :         PG_RETURN_INT32(result);
    1303                 :          30 : }
    1304                 :             : 
    1305                 :             : /*
    1306                 :             :  * Least Common Multiple
    1307                 :             :  */
    1308                 :             : Datum
    1309                 :          26 : int4lcm(PG_FUNCTION_ARGS)
    1310                 :             : {
    1311                 :          26 :         int32           arg1 = PG_GETARG_INT32(0);
    1312                 :          26 :         int32           arg2 = PG_GETARG_INT32(1);
    1313                 :          26 :         int32           gcd;
    1314                 :          26 :         int32           result;
    1315                 :             : 
    1316                 :             :         /*
    1317                 :             :          * Handle lcm(x, 0) = lcm(0, x) = 0 as a special case.  This prevents a
    1318                 :             :          * division-by-zero error below when x is zero, and an overflow error from
    1319                 :             :          * the GCD computation when x = INT_MIN.
    1320                 :             :          */
    1321   [ +  +  +  + ]:          26 :         if (arg1 == 0 || arg2 == 0)
    1322                 :          12 :                 PG_RETURN_INT32(0);
    1323                 :             : 
    1324                 :             :         /* lcm(x, y) = abs(x / gcd(x, y) * y) */
    1325                 :          14 :         gcd = int4gcd_internal(arg1, arg2);
    1326                 :          14 :         arg1 = arg1 / gcd;
    1327                 :             : 
    1328         [ +  + ]:          14 :         if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
    1329   [ +  -  +  - ]:           1 :                 ereport(ERROR,
    1330                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1331                 :             :                                  errmsg("integer out of range")));
    1332                 :             : 
    1333                 :             :         /* If the result is INT_MIN, it cannot be represented. */
    1334         [ +  + ]:          13 :         if (unlikely(result == PG_INT32_MIN))
    1335   [ +  -  +  - ]:           1 :                 ereport(ERROR,
    1336                 :             :                                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1337                 :             :                                  errmsg("integer out of range")));
    1338                 :             : 
    1339         [ +  + ]:          12 :         if (result < 0)
    1340                 :           6 :                 result = -result;
    1341                 :             : 
    1342                 :          12 :         PG_RETURN_INT32(result);
    1343                 :          24 : }
    1344                 :             : 
    1345                 :             : Datum
    1346                 :          67 : int2larger(PG_FUNCTION_ARGS)
    1347                 :             : {
    1348                 :          67 :         int16           arg1 = PG_GETARG_INT16(0);
    1349                 :          67 :         int16           arg2 = PG_GETARG_INT16(1);
    1350                 :             : 
    1351         [ +  + ]:          67 :         PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
    1352                 :          67 : }
    1353                 :             : 
    1354                 :             : Datum
    1355                 :           0 : int2smaller(PG_FUNCTION_ARGS)
    1356                 :             : {
    1357                 :           0 :         int16           arg1 = PG_GETARG_INT16(0);
    1358                 :           0 :         int16           arg2 = PG_GETARG_INT16(1);
    1359                 :             : 
    1360         [ #  # ]:           0 :         PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
    1361                 :           0 : }
    1362                 :             : 
    1363                 :             : Datum
    1364                 :      151273 : int4larger(PG_FUNCTION_ARGS)
    1365                 :             : {
    1366                 :      151273 :         int32           arg1 = PG_GETARG_INT32(0);
    1367                 :      151273 :         int32           arg2 = PG_GETARG_INT32(1);
    1368                 :             : 
    1369         [ +  + ]:      151273 :         PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
    1370                 :      151273 : }
    1371                 :             : 
    1372                 :             : Datum
    1373                 :       88610 : int4smaller(PG_FUNCTION_ARGS)
    1374                 :             : {
    1375                 :       88610 :         int32           arg1 = PG_GETARG_INT32(0);
    1376                 :       88610 :         int32           arg2 = PG_GETARG_INT32(1);
    1377                 :             : 
    1378         [ +  + ]:       88610 :         PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
    1379                 :       88610 : }
    1380                 :             : 
    1381                 :             : /*
    1382                 :             :  * Bit-pushing operators
    1383                 :             :  *
    1384                 :             :  *              int[24]and              - returns arg1 & arg2
    1385                 :             :  *              int[24]or               - returns arg1 | arg2
    1386                 :             :  *              int[24]xor              - returns arg1 # arg2
    1387                 :             :  *              int[24]not              - returns ~arg1
    1388                 :             :  *              int[24]shl              - returns arg1 << arg2
    1389                 :             :  *              int[24]shr              - returns arg1 >> arg2
    1390                 :             :  */
    1391                 :             : 
    1392                 :             : Datum
    1393                 :         822 : int4and(PG_FUNCTION_ARGS)
    1394                 :             : {
    1395                 :         822 :         int32           arg1 = PG_GETARG_INT32(0);
    1396                 :         822 :         int32           arg2 = PG_GETARG_INT32(1);
    1397                 :             : 
    1398                 :        1644 :         PG_RETURN_INT32(arg1 & arg2);
    1399                 :         822 : }
    1400                 :             : 
    1401                 :             : Datum
    1402                 :           3 : int4or(PG_FUNCTION_ARGS)
    1403                 :             : {
    1404                 :           3 :         int32           arg1 = PG_GETARG_INT32(0);
    1405                 :           3 :         int32           arg2 = PG_GETARG_INT32(1);
    1406                 :             : 
    1407                 :           6 :         PG_RETURN_INT32(arg1 | arg2);
    1408                 :           3 : }
    1409                 :             : 
    1410                 :             : Datum
    1411                 :           3 : int4xor(PG_FUNCTION_ARGS)
    1412                 :             : {
    1413                 :           3 :         int32           arg1 = PG_GETARG_INT32(0);
    1414                 :           3 :         int32           arg2 = PG_GETARG_INT32(1);
    1415                 :             : 
    1416                 :           6 :         PG_RETURN_INT32(arg1 ^ arg2);
    1417                 :           3 : }
    1418                 :             : 
    1419                 :             : Datum
    1420                 :         258 : int4shl(PG_FUNCTION_ARGS)
    1421                 :             : {
    1422                 :         258 :         int32           arg1 = PG_GETARG_INT32(0);
    1423                 :         258 :         int32           arg2 = PG_GETARG_INT32(1);
    1424                 :             : 
    1425                 :         516 :         PG_RETURN_INT32(arg1 << arg2);
    1426                 :         258 : }
    1427                 :             : 
    1428                 :             : Datum
    1429                 :           0 : int4shr(PG_FUNCTION_ARGS)
    1430                 :             : {
    1431                 :           0 :         int32           arg1 = PG_GETARG_INT32(0);
    1432                 :           0 :         int32           arg2 = PG_GETARG_INT32(1);
    1433                 :             : 
    1434                 :           0 :         PG_RETURN_INT32(arg1 >> arg2);
    1435                 :           0 : }
    1436                 :             : 
    1437                 :             : Datum
    1438                 :           0 : int4not(PG_FUNCTION_ARGS)
    1439                 :             : {
    1440                 :           0 :         int32           arg1 = PG_GETARG_INT32(0);
    1441                 :             : 
    1442                 :           0 :         PG_RETURN_INT32(~arg1);
    1443                 :           0 : }
    1444                 :             : 
    1445                 :             : Datum
    1446                 :           4 : int2and(PG_FUNCTION_ARGS)
    1447                 :             : {
    1448                 :           4 :         int16           arg1 = PG_GETARG_INT16(0);
    1449                 :           4 :         int16           arg2 = PG_GETARG_INT16(1);
    1450                 :             : 
    1451                 :           8 :         PG_RETURN_INT16(arg1 & arg2);
    1452                 :           4 : }
    1453                 :             : 
    1454                 :             : Datum
    1455                 :           4 : int2or(PG_FUNCTION_ARGS)
    1456                 :             : {
    1457                 :           4 :         int16           arg1 = PG_GETARG_INT16(0);
    1458                 :           4 :         int16           arg2 = PG_GETARG_INT16(1);
    1459                 :             : 
    1460                 :           8 :         PG_RETURN_INT16(arg1 | arg2);
    1461                 :           4 : }
    1462                 :             : 
    1463                 :             : Datum
    1464                 :           4 : int2xor(PG_FUNCTION_ARGS)
    1465                 :             : {
    1466                 :           4 :         int16           arg1 = PG_GETARG_INT16(0);
    1467                 :           4 :         int16           arg2 = PG_GETARG_INT16(1);
    1468                 :             : 
    1469                 :           8 :         PG_RETURN_INT16(arg1 ^ arg2);
    1470                 :           4 : }
    1471                 :             : 
    1472                 :             : Datum
    1473                 :           0 : int2not(PG_FUNCTION_ARGS)
    1474                 :             : {
    1475                 :           0 :         int16           arg1 = PG_GETARG_INT16(0);
    1476                 :             : 
    1477                 :           0 :         PG_RETURN_INT16(~arg1);
    1478                 :           0 : }
    1479                 :             : 
    1480                 :             : 
    1481                 :             : Datum
    1482                 :           2 : int2shl(PG_FUNCTION_ARGS)
    1483                 :             : {
    1484                 :           2 :         int16           arg1 = PG_GETARG_INT16(0);
    1485                 :           2 :         int32           arg2 = PG_GETARG_INT32(1);
    1486                 :             : 
    1487                 :           4 :         PG_RETURN_INT16(arg1 << arg2);
    1488                 :           2 : }
    1489                 :             : 
    1490                 :             : Datum
    1491                 :           0 : int2shr(PG_FUNCTION_ARGS)
    1492                 :             : {
    1493                 :           0 :         int16           arg1 = PG_GETARG_INT16(0);
    1494                 :           0 :         int32           arg2 = PG_GETARG_INT32(1);
    1495                 :             : 
    1496                 :           0 :         PG_RETURN_INT16(arg1 >> arg2);
    1497                 :           0 : }
    1498                 :             : 
    1499                 :             : /*
    1500                 :             :  * non-persistent numeric series generator
    1501                 :             :  */
    1502                 :             : Datum
    1503                 :     1686198 : generate_series_int4(PG_FUNCTION_ARGS)
    1504                 :             : {
    1505                 :     1686198 :         return generate_series_step_int4(fcinfo);
    1506                 :             : }
    1507                 :             : 
    1508                 :             : Datum
    1509                 :     1713727 : generate_series_step_int4(PG_FUNCTION_ARGS)
    1510                 :             : {
    1511                 :     1713727 :         FuncCallContext *funcctx;
    1512                 :     1713727 :         generate_series_fctx *fctx;
    1513                 :     1713727 :         int32           result;
    1514                 :     1713727 :         MemoryContext oldcontext;
    1515                 :             : 
    1516                 :             :         /* stuff done only on the first call of the function */
    1517         [ +  + ]:     1713727 :         if (SRF_IS_FIRSTCALL())
    1518                 :             :         {
    1519                 :       11377 :                 int32           start = PG_GETARG_INT32(0);
    1520                 :       11377 :                 int32           finish = PG_GETARG_INT32(1);
    1521                 :       11377 :                 int32           step = 1;
    1522                 :             : 
    1523                 :             :                 /* see if we were given an explicit step size */
    1524         [ +  + ]:       11377 :                 if (PG_NARGS() == 3)
    1525                 :          51 :                         step = PG_GETARG_INT32(2);
    1526         [ +  - ]:       11377 :                 if (step == 0)
    1527   [ #  #  #  # ]:           0 :                         ereport(ERROR,
    1528                 :             :                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1529                 :             :                                          errmsg("step size cannot equal zero")));
    1530                 :             : 
    1531                 :             :                 /* create a function context for cross-call persistence */
    1532                 :       11377 :                 funcctx = SRF_FIRSTCALL_INIT();
    1533                 :             : 
    1534                 :             :                 /*
    1535                 :             :                  * switch to memory context appropriate for multiple function calls
    1536                 :             :                  */
    1537                 :       11377 :                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1538                 :             : 
    1539                 :             :                 /* allocate memory for user context */
    1540                 :       11377 :                 fctx = palloc_object(generate_series_fctx);
    1541                 :             : 
    1542                 :             :                 /*
    1543                 :             :                  * Use fctx to keep state from call to call. Seed current with the
    1544                 :             :                  * original start value
    1545                 :             :                  */
    1546                 :       11377 :                 fctx->current = start;
    1547                 :       11377 :                 fctx->finish = finish;
    1548                 :       11377 :                 fctx->step = step;
    1549                 :             : 
    1550                 :       11377 :                 funcctx->user_fctx = fctx;
    1551                 :       11377 :                 MemoryContextSwitchTo(oldcontext);
    1552                 :       11377 :         }
    1553                 :             : 
    1554                 :             :         /* stuff done on every call of the function */
    1555                 :     1713727 :         funcctx = SRF_PERCALL_SETUP();
    1556                 :             : 
    1557                 :             :         /*
    1558                 :             :          * get the saved state and use current as the result for this iteration
    1559                 :             :          */
    1560                 :     1713727 :         fctx = funcctx->user_fctx;
    1561                 :     1713727 :         result = fctx->current;
    1562                 :             : 
    1563   [ +  -  +  + ]:     1713727 :         if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
    1564         [ -  + ]:       11369 :                 (fctx->step < 0 && fctx->current >= fctx->finish))
    1565                 :             :         {
    1566                 :             :                 /*
    1567                 :             :                  * Increment current in preparation for next iteration. If next-value
    1568                 :             :                  * computation overflows, this is the final result.
    1569                 :             :                  */
    1570         [ +  - ]:     1702358 :                 if (pg_add_s32_overflow(fctx->current, fctx->step, &fctx->current))
    1571                 :           0 :                         fctx->step = 0;
    1572                 :             : 
    1573                 :             :                 /* do when there is more left to send */
    1574                 :     1702358 :                 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
    1575                 :           0 :         }
    1576                 :             :         else
    1577                 :             :                 /* do when there is no more left */
    1578         [ +  - ]:       11369 :                 SRF_RETURN_DONE(funcctx);
    1579         [ -  + ]:     1713727 : }
    1580                 :             : 
    1581                 :             : /*
    1582                 :             :  * Planner support function for generate_series(int4, int4 [, int4])
    1583                 :             :  */
    1584                 :             : Datum
    1585                 :        6011 : generate_series_int4_support(PG_FUNCTION_ARGS)
    1586                 :             : {
    1587                 :        6011 :         Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1588                 :        6011 :         Node       *ret = NULL;
    1589                 :             : 
    1590         [ +  + ]:        6011 :         if (IsA(rawreq, SupportRequestRows))
    1591                 :             :         {
    1592                 :             :                 /* Try to estimate the number of rows returned */
    1593                 :        3559 :                 SupportRequestRows *req = (SupportRequestRows *) rawreq;
    1594                 :             : 
    1595         [ +  + ]:        3559 :                 if (is_funcclause(req->node))        /* be paranoid */
    1596                 :             :                 {
    1597                 :        1545 :                         List       *args = ((FuncExpr *) req->node)->args;
    1598                 :        1545 :                         Node       *arg1,
    1599                 :             :                                            *arg2,
    1600                 :             :                                            *arg3;
    1601                 :             : 
    1602                 :             :                         /* We can use estimated argument values here */
    1603                 :        1545 :                         arg1 = estimate_expression_value(req->root, linitial(args));
    1604                 :        1545 :                         arg2 = estimate_expression_value(req->root, lsecond(args));
    1605         [ +  + ]:        1545 :                         if (list_length(args) >= 3)
    1606                 :          55 :                                 arg3 = estimate_expression_value(req->root, lthird(args));
    1607                 :             :                         else
    1608                 :        1490 :                                 arg3 = NULL;
    1609                 :             : 
    1610                 :             :                         /*
    1611                 :             :                          * If any argument is constant NULL, we can safely assume that
    1612                 :             :                          * zero rows are returned.  Otherwise, if they're all non-NULL
    1613                 :             :                          * constants, we can calculate the number of rows that will be
    1614                 :             :                          * returned.  Use double arithmetic to avoid overflow hazards.
    1615                 :             :                          */
    1616         [ +  + ]:        1545 :                         if ((IsA(arg1, Const) &&
    1617         [ +  + ]:        1532 :                                  ((Const *) arg1)->constisnull) ||
    1618         [ +  + ]:        2552 :                                 (IsA(arg2, Const) &&
    1619                 :        1007 :                                  ((Const *) arg2)->constisnull) ||
    1620   [ +  +  +  - ]:        1600 :                                 (arg3 != NULL && IsA(arg3, Const) &&
    1621                 :          55 :                                  ((Const *) arg3)->constisnull))
    1622                 :             :                         {
    1623                 :        2014 :                                 req->rows = 0;
    1624                 :        2014 :                                 ret = (Node *) req;
    1625                 :        2014 :                         }
    1626         [ +  + ]:        1545 :                         else if (IsA(arg1, Const) &&
    1627   [ +  +  +  - ]:        1587 :                                          IsA(arg2, Const) &&
    1628         [ +  + ]:         945 :                                          (arg3 == NULL || IsA(arg3, Const)))
    1629                 :             :                         {
    1630                 :         945 :                                 double          start,
    1631                 :             :                                                         finish,
    1632                 :             :                                                         step;
    1633                 :             : 
    1634                 :         945 :                                 start = DatumGetInt32(((Const *) arg1)->constvalue);
    1635                 :         945 :                                 finish = DatumGetInt32(((Const *) arg2)->constvalue);
    1636         [ +  + ]:         945 :                                 step = arg3 ? DatumGetInt32(((Const *) arg3)->constvalue) : 1;
    1637                 :             : 
    1638                 :             :                                 /* This equation works for either sign of step */
    1639         [ -  + ]:         945 :                                 if (step != 0)
    1640                 :             :                                 {
    1641                 :         945 :                                         req->rows = floor((finish - start + step) / step);
    1642                 :         945 :                                         ret = (Node *) req;
    1643                 :         945 :                                 }
    1644                 :         945 :                         }
    1645                 :        3559 :                 }
    1646                 :        5573 :         }
    1647                 :             : 
    1648                 :        7994 :         PG_RETURN_POINTER(ret);
    1649                 :        3997 : }
        

Generated by: LCOV version 2.3.2-1