LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - int.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 85.7 % 588 504 1 11 49 23 325 5 174 61 315 4
Current Date: 2023-04-08 15:15:32 Functions: 86.2 % 94 81 12 1 76 2 3 12 76
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  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-2023, 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 CBC     2839236 : int2in(PG_FUNCTION_ARGS)
      64                 : {
      65         2839236 :     char       *num = PG_GETARG_CSTRING(0);
      66                 : 
      67 GNC     2839236 :     PG_RETURN_INT16(pg_strtoint16_safe(num, fcinfo->context));
      68                 : }
      69                 : 
      70                 : /*
      71                 :  *      int2out         - converts short to "num"
      72                 :  */
      73                 : Datum
      74 CBC      113118 : int2out(PG_FUNCTION_ARGS)
      75                 : {
      76          113118 :     int16       arg1 = PG_GETARG_INT16(0);
      77          113118 :     char       *result = (char *) palloc(7);    /* sign, 5 digits, '\0' */
      78                 : 
      79          113118 :     pg_itoa(arg1, result);
      80          113118 :     PG_RETURN_CSTRING(result);
      81                 : }
      82                 : 
      83                 : /*
      84                 :  *      int2recv            - converts external binary format to int2
      85                 :  */
      86                 : Datum
      87 UBC           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                 : }
      93                 : 
      94                 : /*
      95                 :  *      int2send            - converts int2 to binary format
      96                 :  */
      97                 : Datum
      98 CBC           2 : int2send(PG_FUNCTION_ARGS)
      99                 : {
     100               2 :     int16       arg1 = PG_GETARG_INT16(0);
     101                 :     StringInfoData buf;
     102                 : 
     103               2 :     pq_begintypsend(&buf);
     104               2 :     pq_sendint16(&buf, arg1);
     105               2 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     106                 : }
     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          137840 : buildint2vector(const int16 *int2s, int n)
     115                 : {
     116                 :     int2vector *result;
     117                 : 
     118          137840 :     result = (int2vector *) palloc0(Int2VectorSize(n));
     119                 : 
     120          137840 :     if (n > 0 && int2s)
     121           67627 :         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          137840 :     SET_VARSIZE(result, Int2VectorSize(n));
     128          137840 :     result->ndim = 1;
     129          137840 :     result->dataoffset = 0;      /* never any nulls */
     130          137840 :     result->elemtype = INT2OID;
     131          137840 :     result->dim1 = n;
     132          137840 :     result->lbound1 = 0;
     133                 : 
     134          137840 :     return result;
     135                 : }
     136                 : 
     137                 : /*
     138                 :  *      int2vectorin            - converts "num num ..." to internal form
     139                 :  */
     140                 : Datum
     141             271 : int2vectorin(PG_FUNCTION_ARGS)
     142                 : {
     143             271 :     char       *intString = PG_GETARG_CSTRING(0);
     144 GNC         271 :     Node       *escontext = fcinfo->context;
     145 ECB             :     int2vector *result;
     146                 :     int         nalloc;
     147                 :     int         n;
     148                 : 
     149 GIC         271 :     nalloc = 32;                /* arbitrary initial size guess */
     150 CBC         271 :     result = (int2vector *) palloc0(Int2VectorSize(nalloc));
     151 ECB             : 
     152 GIC         271 :     for (n = 0;; n++)
     153 CBC         469 :     {
     154 ECB             :         long        l;
     155                 :         char       *endp;
     156                 : 
     157 GIC         953 :         while (*intString && isspace((unsigned char) *intString))
     158 CBC         213 :             intString++;
     159             740 :         if (*intString == '\0')
     160             265 :             break;
     161 ECB             : 
     162 GIC         475 :         if (n >= nalloc)
     163 ECB             :         {
     164 UIC           0 :             nalloc *= 2;
     165 UBC           0 :             result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
     166 EUB             :         }
     167                 : 
     168 GIC         475 :         errno = 0;
     169 CBC         475 :         l = strtol(intString, &endp, 10);
     170 ECB             : 
     171 GIC         475 :         if (intString == endp)
     172 GNC           6 :             ereturn(escontext, (Datum) 0,
     173 ECB             :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     174                 :                      errmsg("invalid input syntax for type %s: \"%s\"",
     175                 :                             "smallint", intString)));
     176                 : 
     177 GIC         472 :         if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX)
     178 GNC           3 :             ereturn(escontext, (Datum) 0,
     179 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     180                 :                      errmsg("value \"%s\" is out of range for type %s", intString,
     181                 :                             "smallint")));
     182                 : 
     183 GIC         469 :         if (*endp && *endp != ' ')
     184 UNC           0 :             ereturn(escontext, (Datum) 0,
     185 EUB             :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     186                 :                      errmsg("invalid input syntax for type %s: \"%s\"",
     187                 :                             "smallint", intString)));
     188                 : 
     189 GIC         469 :         result->values[n] = l;
     190 CBC         469 :         intString = endp;
     191 ECB             :     }
     192                 : 
     193 GIC         265 :     SET_VARSIZE(result, Int2VectorSize(n));
     194 CBC         265 :     result->ndim = 1;
     195             265 :     result->dataoffset = 0;      /* never any nulls */
     196             265 :     result->elemtype = INT2OID;
     197             265 :     result->dim1 = n;
     198             265 :     result->lbound1 = 0;
     199 ECB             : 
     200 GIC         265 :     PG_RETURN_POINTER(result);
     201 ECB             : }
     202                 : 
     203                 : /*
     204                 :  *      int2vectorout       - converts internal form to "num num ..."
     205                 :  */
     206                 : Datum
     207 GIC        2112 : int2vectorout(PG_FUNCTION_ARGS)
     208 ECB             : {
     209 GIC        2112 :     int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
     210 ECB             :     int         num,
     211 GIC        2112 :                 nnums = int2Array->dim1;
     212 ECB             :     char       *rp;
     213                 :     char       *result;
     214                 : 
     215                 :     /* assumes sign, 5 digits, ' ' */
     216 GIC        2112 :     rp = result = (char *) palloc(nnums * 7 + 1);
     217 CBC        5592 :     for (num = 0; num < nnums; num++)
     218 ECB             :     {
     219 GIC        3480 :         if (num != 0)
     220 CBC        1368 :             *rp++ = ' ';
     221            3480 :         rp += pg_itoa(int2Array->values[num], rp);
     222 ECB             :     }
     223 GIC        2112 :     *rp = '\0';
     224 CBC        2112 :     PG_RETURN_CSTRING(result);
     225 ECB             : }
     226                 : 
     227                 : /*
     228                 :  *      int2vectorrecv          - converts external binary format to int2vector
     229                 :  */
     230                 : Datum
     231 UIC           0 : int2vectorrecv(PG_FUNCTION_ARGS)
     232 EUB             : {
     233 UIC           0 :     LOCAL_FCINFO(locfcinfo, 3);
     234 UBC           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     235 EUB             :     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 UIC           0 :     InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3,
     244 EUB             :                              InvalidOid, NULL, NULL);
     245                 : 
     246 UIC           0 :     locfcinfo->args[0].value = PointerGetDatum(buf);
     247 UBC           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 EUB             : 
     253 UIC           0 :     result = (int2vector *) DatumGetPointer(array_recv(locfcinfo));
     254 EUB             : 
     255 UIC           0 :     Assert(!locfcinfo->isnull);
     256 EUB             : 
     257                 :     /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
     258 UIC           0 :     if (ARR_NDIM(result) != 1 ||
     259 UBC           0 :         ARR_HASNULL(result) ||
     260               0 :         ARR_ELEMTYPE(result) != INT2OID ||
     261               0 :         ARR_LBOUND(result)[0] != 0)
     262               0 :         ereport(ERROR,
     263 EUB             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
     264                 :                  errmsg("invalid int2vector data")));
     265                 : 
     266 UIC           0 :     PG_RETURN_POINTER(result);
     267 EUB             : }
     268                 : 
     269                 : /*
     270                 :  *      int2vectorsend          - converts int2vector to binary format
     271                 :  */
     272                 : Datum
     273 UIC           0 : int2vectorsend(PG_FUNCTION_ARGS)
     274 EUB             : {
     275 UIC           0 :     return array_send(fcinfo);
     276 EUB             : }
     277                 : 
     278                 : 
     279                 : /*****************************************************************************
     280                 :  *   PUBLIC ROUTINES                                                         *
     281                 :  *****************************************************************************/
     282                 : 
     283                 : /*
     284                 :  *      int4in          - converts "num" to int4
     285                 :  */
     286                 : Datum
     287 GIC     3478435 : int4in(PG_FUNCTION_ARGS)
     288 ECB             : {
     289 GIC     3478435 :     char       *num = PG_GETARG_CSTRING(0);
     290 ECB             : 
     291 GNC     3478435 :     PG_RETURN_INT32(pg_strtoint32_safe(num, fcinfo->context));
     292 ECB             : }
     293                 : 
     294                 : /*
     295                 :  *      int4out         - converts int4 to "num"
     296                 :  */
     297                 : Datum
     298 GIC     8918775 : int4out(PG_FUNCTION_ARGS)
     299 ECB             : {
     300 GIC     8918775 :     int32       arg1 = PG_GETARG_INT32(0);
     301 CBC     8918775 :     char       *result = (char *) palloc(12);   /* sign, 10 digits, '\0' */
     302 ECB             : 
     303 GIC     8918775 :     pg_ltoa(arg1, result);
     304 CBC     8918775 :     PG_RETURN_CSTRING(result);
     305 ECB             : }
     306                 : 
     307                 : /*
     308                 :  *      int4recv            - converts external binary format to int4
     309                 :  */
     310                 : Datum
     311 GIC      101435 : int4recv(PG_FUNCTION_ARGS)
     312 ECB             : {
     313 GIC      101435 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     314 ECB             : 
     315 GIC      101435 :     PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
     316 ECB             : }
     317                 : 
     318                 : /*
     319                 :  *      int4send            - converts int4 to binary format
     320                 :  */
     321                 : Datum
     322 GIC       84072 : int4send(PG_FUNCTION_ARGS)
     323 ECB             : {
     324 GIC       84072 :     int32       arg1 = PG_GETARG_INT32(0);
     325 ECB             :     StringInfoData buf;
     326                 : 
     327 GIC       84072 :     pq_begintypsend(&buf);
     328 CBC       84072 :     pq_sendint32(&buf, arg1);
     329           84072 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     330 ECB             : }
     331                 : 
     332                 : 
     333                 : /*
     334                 :  *      ===================
     335                 :  *      CONVERSION ROUTINES
     336                 :  *      ===================
     337                 :  */
     338                 : 
     339                 : Datum
     340 GIC       20649 : i2toi4(PG_FUNCTION_ARGS)
     341 ECB             : {
     342 GIC       20649 :     int16       arg1 = PG_GETARG_INT16(0);
     343 ECB             : 
     344 GIC       20649 :     PG_RETURN_INT32((int32) arg1);
     345 ECB             : }
     346                 : 
     347                 : Datum
     348 GIC        1951 : i4toi2(PG_FUNCTION_ARGS)
     349 ECB             : {
     350 GIC        1951 :     int32       arg1 = PG_GETARG_INT32(0);
     351 ECB             : 
     352 GIC        1951 :     if (unlikely(arg1 < SHRT_MIN) || unlikely(arg1 > SHRT_MAX))
     353 CBC          14 :         ereport(ERROR,
     354 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     355                 :                  errmsg("smallint out of range")));
     356                 : 
     357 GIC        1937 :     PG_RETURN_INT16((int16) arg1);
     358 ECB             : }
     359                 : 
     360                 : /* Cast int4 -> bool */
     361                 : Datum
     362 UIC           0 : int4_bool(PG_FUNCTION_ARGS)
     363 EUB             : {
     364 UIC           0 :     if (PG_GETARG_INT32(0) == 0)
     365 UBC           0 :         PG_RETURN_BOOL(false);
     366 EUB             :     else
     367 UIC           0 :         PG_RETURN_BOOL(true);
     368 EUB             : }
     369                 : 
     370                 : /* Cast bool -> int4 */
     371                 : Datum
     372 GIC         737 : bool_int4(PG_FUNCTION_ARGS)
     373 ECB             : {
     374 GIC         737 :     if (PG_GETARG_BOOL(0) == false)
     375 CBC         373 :         PG_RETURN_INT32(0);
     376 ECB             :     else
     377 GIC         364 :         PG_RETURN_INT32(1);
     378 ECB             : }
     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 GIC    18273345 : int4eq(PG_FUNCTION_ARGS)
     397 ECB             : {
     398 GIC    18273345 :     int32       arg1 = PG_GETARG_INT32(0);
     399 CBC    18273345 :     int32       arg2 = PG_GETARG_INT32(1);
     400 ECB             : 
     401 GIC    18273345 :     PG_RETURN_BOOL(arg1 == arg2);
     402 ECB             : }
     403                 : 
     404                 : Datum
     405 GIC      214016 : int4ne(PG_FUNCTION_ARGS)
     406 ECB             : {
     407 GIC      214016 :     int32       arg1 = PG_GETARG_INT32(0);
     408 CBC      214016 :     int32       arg2 = PG_GETARG_INT32(1);
     409 ECB             : 
     410 GIC      214016 :     PG_RETURN_BOOL(arg1 != arg2);
     411 ECB             : }
     412                 : 
     413                 : Datum
     414 GIC   110223409 : int4lt(PG_FUNCTION_ARGS)
     415 ECB             : {
     416 GIC   110223409 :     int32       arg1 = PG_GETARG_INT32(0);
     417 CBC   110223409 :     int32       arg2 = PG_GETARG_INT32(1);
     418 ECB             : 
     419 GIC   110223409 :     PG_RETURN_BOOL(arg1 < arg2);
     420 ECB             : }
     421                 : 
     422                 : Datum
     423 GIC      551927 : int4le(PG_FUNCTION_ARGS)
     424 ECB             : {
     425 GIC      551927 :     int32       arg1 = PG_GETARG_INT32(0);
     426 CBC      551927 :     int32       arg2 = PG_GETARG_INT32(1);
     427 ECB             : 
     428 GIC      551927 :     PG_RETURN_BOOL(arg1 <= arg2);
     429 ECB             : }
     430                 : 
     431                 : Datum
     432 GIC     1573183 : int4gt(PG_FUNCTION_ARGS)
     433 ECB             : {
     434 GIC     1573183 :     int32       arg1 = PG_GETARG_INT32(0);
     435 CBC     1573183 :     int32       arg2 = PG_GETARG_INT32(1);
     436 ECB             : 
     437 GIC     1573183 :     PG_RETURN_BOOL(arg1 > arg2);
     438 ECB             : }
     439                 : 
     440                 : Datum
     441 GIC      265957 : int4ge(PG_FUNCTION_ARGS)
     442 ECB             : {
     443 GIC      265957 :     int32       arg1 = PG_GETARG_INT32(0);
     444 CBC      265957 :     int32       arg2 = PG_GETARG_INT32(1);
     445 ECB             : 
     446 GIC      265957 :     PG_RETURN_BOOL(arg1 >= arg2);
     447 ECB             : }
     448                 : 
     449                 : Datum
     450 GIC     1288410 : int2eq(PG_FUNCTION_ARGS)
     451 ECB             : {
     452 GIC     1288410 :     int16       arg1 = PG_GETARG_INT16(0);
     453 CBC     1288410 :     int16       arg2 = PG_GETARG_INT16(1);
     454 ECB             : 
     455 GIC     1288410 :     PG_RETURN_BOOL(arg1 == arg2);
     456 ECB             : }
     457                 : 
     458                 : Datum
     459 GIC       14939 : int2ne(PG_FUNCTION_ARGS)
     460 ECB             : {
     461 GIC       14939 :     int16       arg1 = PG_GETARG_INT16(0);
     462 CBC       14939 :     int16       arg2 = PG_GETARG_INT16(1);
     463 ECB             : 
     464 GIC       14939 :     PG_RETURN_BOOL(arg1 != arg2);
     465 ECB             : }
     466                 : 
     467                 : Datum
     468 GIC      267202 : int2lt(PG_FUNCTION_ARGS)
     469 ECB             : {
     470 GIC      267202 :     int16       arg1 = PG_GETARG_INT16(0);
     471 CBC      267202 :     int16       arg2 = PG_GETARG_INT16(1);
     472 ECB             : 
     473 GIC      267202 :     PG_RETURN_BOOL(arg1 < arg2);
     474 ECB             : }
     475                 : 
     476                 : Datum
     477 GIC        2393 : int2le(PG_FUNCTION_ARGS)
     478 ECB             : {
     479 GIC        2393 :     int16       arg1 = PG_GETARG_INT16(0);
     480 CBC        2393 :     int16       arg2 = PG_GETARG_INT16(1);
     481 ECB             : 
     482 GIC        2393 :     PG_RETURN_BOOL(arg1 <= arg2);
     483 ECB             : }
     484                 : 
     485                 : Datum
     486 GIC     3856887 : int2gt(PG_FUNCTION_ARGS)
     487 ECB             : {
     488 GIC     3856887 :     int16       arg1 = PG_GETARG_INT16(0);
     489 CBC     3856887 :     int16       arg2 = PG_GETARG_INT16(1);
     490 ECB             : 
     491 GIC     3856887 :     PG_RETURN_BOOL(arg1 > arg2);
     492 ECB             : }
     493                 : 
     494                 : Datum
     495 GIC        1857 : int2ge(PG_FUNCTION_ARGS)
     496 ECB             : {
     497 GIC        1857 :     int16       arg1 = PG_GETARG_INT16(0);
     498 CBC        1857 :     int16       arg2 = PG_GETARG_INT16(1);
     499 ECB             : 
     500 GIC        1857 :     PG_RETURN_BOOL(arg1 >= arg2);
     501 ECB             : }
     502                 : 
     503                 : Datum
     504 GIC       60330 : int24eq(PG_FUNCTION_ARGS)
     505 ECB             : {
     506 GIC       60330 :     int16       arg1 = PG_GETARG_INT16(0);
     507 CBC       60330 :     int32       arg2 = PG_GETARG_INT32(1);
     508 ECB             : 
     509 GIC       60330 :     PG_RETURN_BOOL(arg1 == arg2);
     510 ECB             : }
     511                 : 
     512                 : Datum
     513 GIC       37200 : int24ne(PG_FUNCTION_ARGS)
     514 ECB             : {
     515 GIC       37200 :     int16       arg1 = PG_GETARG_INT16(0);
     516 CBC       37200 :     int32       arg2 = PG_GETARG_INT32(1);
     517 ECB             : 
     518 GIC       37200 :     PG_RETURN_BOOL(arg1 != arg2);
     519 ECB             : }
     520                 : 
     521                 : Datum
     522 GIC       63441 : int24lt(PG_FUNCTION_ARGS)
     523 ECB             : {
     524 GIC       63441 :     int16       arg1 = PG_GETARG_INT16(0);
     525 CBC       63441 :     int32       arg2 = PG_GETARG_INT32(1);
     526 ECB             : 
     527 GIC       63441 :     PG_RETURN_BOOL(arg1 < arg2);
     528 ECB             : }
     529                 : 
     530                 : Datum
     531 GIC       26492 : int24le(PG_FUNCTION_ARGS)
     532 ECB             : {
     533 GIC       26492 :     int16       arg1 = PG_GETARG_INT16(0);
     534 CBC       26492 :     int32       arg2 = PG_GETARG_INT32(1);
     535 ECB             : 
     536 GIC       26492 :     PG_RETURN_BOOL(arg1 <= arg2);
     537 ECB             : }
     538                 : 
     539                 : Datum
     540 GIC      232933 : int24gt(PG_FUNCTION_ARGS)
     541 ECB             : {
     542 GIC      232933 :     int16       arg1 = PG_GETARG_INT16(0);
     543 CBC      232933 :     int32       arg2 = PG_GETARG_INT32(1);
     544 ECB             : 
     545 GIC      232933 :     PG_RETURN_BOOL(arg1 > arg2);
     546 ECB             : }
     547                 : 
     548                 : Datum
     549 GIC       11285 : int24ge(PG_FUNCTION_ARGS)
     550 ECB             : {
     551 GIC       11285 :     int16       arg1 = PG_GETARG_INT16(0);
     552 CBC       11285 :     int32       arg2 = PG_GETARG_INT32(1);
     553 ECB             : 
     554 GIC       11285 :     PG_RETURN_BOOL(arg1 >= arg2);
     555 ECB             : }
     556                 : 
     557                 : Datum
     558 GIC       62694 : int42eq(PG_FUNCTION_ARGS)
     559 ECB             : {
     560 GIC       62694 :     int32       arg1 = PG_GETARG_INT32(0);
     561 CBC       62694 :     int16       arg2 = PG_GETARG_INT16(1);
     562 ECB             : 
     563 GIC       62694 :     PG_RETURN_BOOL(arg1 == arg2);
     564 ECB             : }
     565                 : 
     566                 : Datum
     567 GIC          15 : int42ne(PG_FUNCTION_ARGS)
     568 ECB             : {
     569 GIC          15 :     int32       arg1 = PG_GETARG_INT32(0);
     570 CBC          15 :     int16       arg2 = PG_GETARG_INT16(1);
     571 ECB             : 
     572 GIC          15 :     PG_RETURN_BOOL(arg1 != arg2);
     573 ECB             : }
     574                 : 
     575                 : Datum
     576 GIC        7202 : int42lt(PG_FUNCTION_ARGS)
     577 ECB             : {
     578 GIC        7202 :     int32       arg1 = PG_GETARG_INT32(0);
     579 CBC        7202 :     int16       arg2 = PG_GETARG_INT16(1);
     580 ECB             : 
     581 GIC        7202 :     PG_RETURN_BOOL(arg1 < arg2);
     582 ECB             : }
     583                 : 
     584                 : Datum
     585 GIC        7162 : int42le(PG_FUNCTION_ARGS)
     586 ECB             : {
     587 GIC        7162 :     int32       arg1 = PG_GETARG_INT32(0);
     588 CBC        7162 :     int16       arg2 = PG_GETARG_INT16(1);
     589 ECB             : 
     590 GIC        7162 :     PG_RETURN_BOOL(arg1 <= arg2);
     591 ECB             : }
     592                 : 
     593                 : Datum
     594 GIC        1614 : int42gt(PG_FUNCTION_ARGS)
     595 ECB             : {
     596 GIC        1614 :     int32       arg1 = PG_GETARG_INT32(0);
     597 CBC        1614 :     int16       arg2 = PG_GETARG_INT16(1);
     598 ECB             : 
     599 GIC        1614 :     PG_RETURN_BOOL(arg1 > arg2);
     600 ECB             : }
     601                 : 
     602                 : Datum
     603 GIC        1728 : int42ge(PG_FUNCTION_ARGS)
     604 ECB             : {
     605 GIC        1728 :     int32       arg1 = PG_GETARG_INT32(0);
     606 CBC        1728 :     int16       arg2 = PG_GETARG_INT16(1);
     607 ECB             : 
     608 GIC        1728 :     PG_RETURN_BOOL(arg1 >= arg2);
     609 ECB             : }
     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 GIC        1599 : in_range_int4_int4(PG_FUNCTION_ARGS)
     624 ECB             : {
     625 GIC        1599 :     int32       val = PG_GETARG_INT32(0);
     626 CBC        1599 :     int32       base = PG_GETARG_INT32(1);
     627            1599 :     int32       offset = PG_GETARG_INT32(2);
     628            1599 :     bool        sub = PG_GETARG_BOOL(3);
     629            1599 :     bool        less = PG_GETARG_BOOL(4);
     630 ECB             :     int32       sum;
     631                 : 
     632 GIC        1599 :     if (offset < 0)
     633 CBC           6 :         ereport(ERROR,
     634 ECB             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     635                 :                  errmsg("invalid preceding or following size in window function")));
     636                 : 
     637 GIC        1593 :     if (sub)
     638 CBC         720 :         offset = -offset;       /* cannot overflow */
     639 ECB             : 
     640 GIC        1593 :     if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
     641 ECB             :     {
     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 GIC          18 :         PG_RETURN_BOOL(sub ? !less : less);
     648 ECB             :     }
     649                 : 
     650 GIC        1575 :     if (less)
     651 CBC         930 :         PG_RETURN_BOOL(val <= sum);
     652 ECB             :     else
     653 GIC         645 :         PG_RETURN_BOOL(val >= sum);
     654 ECB             : }
     655                 : 
     656                 : Datum
     657 GIC         453 : in_range_int4_int2(PG_FUNCTION_ARGS)
     658 ECB             : {
     659                 :     /* Doesn't seem worth duplicating code for, so just invoke int4_int4 */
     660 GIC         453 :     return DirectFunctionCall5(in_range_int4_int4,
     661 ECB             :                                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 GIC         381 : in_range_int4_int8(PG_FUNCTION_ARGS)
     670 ECB             : {
     671                 :     /* We must do all the math in int64 */
     672 GIC         381 :     int64       val = (int64) PG_GETARG_INT32(0);
     673 CBC         381 :     int64       base = (int64) PG_GETARG_INT32(1);
     674             381 :     int64       offset = PG_GETARG_INT64(2);
     675             381 :     bool        sub = PG_GETARG_BOOL(3);
     676             381 :     bool        less = PG_GETARG_BOOL(4);
     677 ECB             :     int64       sum;
     678                 : 
     679 GIC         381 :     if (offset < 0)
     680 LBC           0 :         ereport(ERROR,
     681 EUB             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     682                 :                  errmsg("invalid preceding or following size in window function")));
     683                 : 
     684 GIC         381 :     if (sub)
     685 CBC         345 :         offset = -offset;       /* cannot overflow */
     686 ECB             : 
     687 GIC         381 :     if (unlikely(pg_add_s64_overflow(base, offset, &sum)))
     688 ECB             :     {
     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 UIC           0 :         PG_RETURN_BOOL(sub ? !less : less);
     695 EUB             :     }
     696                 : 
     697 GIC         381 :     if (less)
     698 CBC          36 :         PG_RETURN_BOOL(val <= sum);
     699 ECB             :     else
     700 GIC         345 :         PG_RETURN_BOOL(val >= sum);
     701 ECB             : }
     702                 : 
     703                 : Datum
     704 GIC          18 : in_range_int2_int4(PG_FUNCTION_ARGS)
     705 ECB             : {
     706                 :     /* We must do all the math in int32 */
     707 GIC          18 :     int32       val = (int32) PG_GETARG_INT16(0);
     708 CBC          18 :     int32       base = (int32) PG_GETARG_INT16(1);
     709              18 :     int32       offset = PG_GETARG_INT32(2);
     710              18 :     bool        sub = PG_GETARG_BOOL(3);
     711              18 :     bool        less = PG_GETARG_BOOL(4);
     712 ECB             :     int32       sum;
     713                 : 
     714 GIC          18 :     if (offset < 0)
     715 LBC           0 :         ereport(ERROR,
     716 EUB             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     717                 :                  errmsg("invalid preceding or following size in window function")));
     718                 : 
     719 GIC          18 :     if (sub)
     720 CBC           9 :         offset = -offset;       /* cannot overflow */
     721 ECB             : 
     722 GIC          18 :     if (unlikely(pg_add_s32_overflow(base, offset, &sum)))
     723 ECB             :     {
     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 GIC          18 :         PG_RETURN_BOOL(sub ? !less : less);
     730 ECB             :     }
     731                 : 
     732 UIC           0 :     if (less)
     733 UBC           0 :         PG_RETURN_BOOL(val <= sum);
     734 EUB             :     else
     735 UIC           0 :         PG_RETURN_BOOL(val >= sum);
     736 EUB             : }
     737                 : 
     738                 : Datum
     739 UIC           0 : in_range_int2_int2(PG_FUNCTION_ARGS)
     740 EUB             : {
     741                 :     /* Doesn't seem worth duplicating code for, so just invoke int2_int4 */
     742 UIC           0 :     return DirectFunctionCall5(in_range_int2_int4,
     743 EUB             :                                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 UIC           0 : in_range_int2_int8(PG_FUNCTION_ARGS)
     752 EUB             : {
     753                 :     /* Doesn't seem worth duplicating code for, so just invoke int4_int8 */
     754 UIC           0 :     return DirectFunctionCall5(in_range_int4_int8,
     755 EUB             :                                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 GIC       25866 : int4um(PG_FUNCTION_ARGS)
     772 ECB             : {
     773 GIC       25866 :     int32       arg = PG_GETARG_INT32(0);
     774 ECB             : 
     775 GIC       25866 :     if (unlikely(arg == PG_INT32_MIN))
     776 LBC           0 :         ereport(ERROR,
     777 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     778                 :                  errmsg("integer out of range")));
     779 GIC       25866 :     PG_RETURN_INT32(-arg);
     780 ECB             : }
     781                 : 
     782                 : Datum
     783 GIC           3 : int4up(PG_FUNCTION_ARGS)
     784 ECB             : {
     785 GIC           3 :     int32       arg = PG_GETARG_INT32(0);
     786 ECB             : 
     787 GIC           3 :     PG_RETURN_INT32(arg);
     788 ECB             : }
     789                 : 
     790                 : Datum
     791 GIC     1636336 : int4pl(PG_FUNCTION_ARGS)
     792 ECB             : {
     793 GIC     1636336 :     int32       arg1 = PG_GETARG_INT32(0);
     794 CBC     1636336 :     int32       arg2 = PG_GETARG_INT32(1);
     795 ECB             :     int32       result;
     796                 : 
     797 GIC     1636336 :     if (unlikely(pg_add_s32_overflow(arg1, arg2, &result)))
     798 CBC           3 :         ereport(ERROR,
     799 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     800                 :                  errmsg("integer out of range")));
     801 GIC     1636333 :     PG_RETURN_INT32(result);
     802 ECB             : }
     803                 : 
     804                 : Datum
     805 GIC      699968 : int4mi(PG_FUNCTION_ARGS)
     806 ECB             : {
     807 GIC      699968 :     int32       arg1 = PG_GETARG_INT32(0);
     808 CBC      699968 :     int32       arg2 = PG_GETARG_INT32(1);
     809 ECB             :     int32       result;
     810                 : 
     811 GIC      699968 :     if (unlikely(pg_sub_s32_overflow(arg1, arg2, &result)))
     812 CBC           3 :         ereport(ERROR,
     813 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     814                 :                  errmsg("integer out of range")));
     815 GIC      699965 :     PG_RETURN_INT32(result);
     816 ECB             : }
     817                 : 
     818                 : Datum
     819 GIC     1411530 : int4mul(PG_FUNCTION_ARGS)
     820 ECB             : {
     821 GIC     1411530 :     int32       arg1 = PG_GETARG_INT32(0);
     822 CBC     1411530 :     int32       arg2 = PG_GETARG_INT32(1);
     823 ECB             :     int32       result;
     824                 : 
     825 GIC     1411530 :     if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
     826 CBC           9 :         ereport(ERROR,
     827 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     828                 :                  errmsg("integer out of range")));
     829 GIC     1411521 :     PG_RETURN_INT32(result);
     830 ECB             : }
     831                 : 
     832                 : Datum
     833 GIC      730087 : int4div(PG_FUNCTION_ARGS)
     834 ECB             : {
     835 GIC      730087 :     int32       arg1 = PG_GETARG_INT32(0);
     836 CBC      730087 :     int32       arg2 = PG_GETARG_INT32(1);
     837 ECB             :     int32       result;
     838                 : 
     839 GIC      730087 :     if (arg2 == 0)
     840 ECB             :     {
     841 GIC         130 :         ereport(ERROR,
     842 ECB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     843                 :                  errmsg("division by zero")));
     844                 :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     845                 :         PG_RETURN_NULL();
     846                 :     }
     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 GIC      729957 :     if (arg2 == -1)
     855 ECB             :     {
     856 GIC           8 :         if (unlikely(arg1 == PG_INT32_MIN))
     857 CBC           3 :             ereport(ERROR,
     858 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     859                 :                      errmsg("integer out of range")));
     860 GIC           5 :         result = -arg1;
     861 CBC           5 :         PG_RETURN_INT32(result);
     862 ECB             :     }
     863                 : 
     864                 :     /* No overflow is possible */
     865                 : 
     866 GIC      729949 :     result = arg1 / arg2;
     867 ECB             : 
     868 GIC      729949 :     PG_RETURN_INT32(result);
     869 ECB             : }
     870                 : 
     871                 : Datum
     872 UIC           0 : int4inc(PG_FUNCTION_ARGS)
     873 EUB             : {
     874 UIC           0 :     int32       arg = PG_GETARG_INT32(0);
     875 EUB             :     int32       result;
     876                 : 
     877 UIC           0 :     if (unlikely(pg_add_s32_overflow(arg, 1, &result)))
     878 UBC           0 :         ereport(ERROR,
     879 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     880                 :                  errmsg("integer out of range")));
     881                 : 
     882 UIC           0 :     PG_RETURN_INT32(result);
     883 EUB             : }
     884                 : 
     885                 : Datum
     886 GIC           9 : int2um(PG_FUNCTION_ARGS)
     887 ECB             : {
     888 GIC           9 :     int16       arg = PG_GETARG_INT16(0);
     889 ECB             : 
     890 GIC           9 :     if (unlikely(arg == PG_INT16_MIN))
     891 LBC           0 :         ereport(ERROR,
     892 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     893                 :                  errmsg("smallint out of range")));
     894 GIC           9 :     PG_RETURN_INT16(-arg);
     895 ECB             : }
     896                 : 
     897                 : Datum
     898 UIC           0 : int2up(PG_FUNCTION_ARGS)
     899 EUB             : {
     900 UIC           0 :     int16       arg = PG_GETARG_INT16(0);
     901 EUB             : 
     902 UIC           0 :     PG_RETURN_INT16(arg);
     903 EUB             : }
     904                 : 
     905                 : Datum
     906 GIC          27 : int2pl(PG_FUNCTION_ARGS)
     907 ECB             : {
     908 GIC          27 :     int16       arg1 = PG_GETARG_INT16(0);
     909 CBC          27 :     int16       arg2 = PG_GETARG_INT16(1);
     910 ECB             :     int16       result;
     911                 : 
     912 GIC          27 :     if (unlikely(pg_add_s16_overflow(arg1, arg2, &result)))
     913 CBC           3 :         ereport(ERROR,
     914 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     915                 :                  errmsg("smallint out of range")));
     916 GIC          24 :     PG_RETURN_INT16(result);
     917 ECB             : }
     918                 : 
     919                 : Datum
     920 GIC          60 : int2mi(PG_FUNCTION_ARGS)
     921 ECB             : {
     922 GIC          60 :     int16       arg1 = PG_GETARG_INT16(0);
     923 CBC          60 :     int16       arg2 = PG_GETARG_INT16(1);
     924 ECB             :     int16       result;
     925                 : 
     926 GIC          60 :     if (unlikely(pg_sub_s16_overflow(arg1, arg2, &result)))
     927 CBC           3 :         ereport(ERROR,
     928 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     929                 :                  errmsg("smallint out of range")));
     930 GIC          57 :     PG_RETURN_INT16(result);
     931 ECB             : }
     932                 : 
     933                 : Datum
     934 GIC          27 : int2mul(PG_FUNCTION_ARGS)
     935 ECB             : {
     936 GIC          27 :     int16       arg1 = PG_GETARG_INT16(0);
     937 CBC          27 :     int16       arg2 = PG_GETARG_INT16(1);
     938 ECB             :     int16       result;
     939                 : 
     940 GIC          27 :     if (unlikely(pg_mul_s16_overflow(arg1, arg2, &result)))
     941 CBC           6 :         ereport(ERROR,
     942 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     943                 :                  errmsg("smallint out of range")));
     944                 : 
     945 GIC          21 :     PG_RETURN_INT16(result);
     946 ECB             : }
     947                 : 
     948                 : Datum
     949 GIC          21 : int2div(PG_FUNCTION_ARGS)
     950 ECB             : {
     951 GIC          21 :     int16       arg1 = PG_GETARG_INT16(0);
     952 CBC          21 :     int16       arg2 = PG_GETARG_INT16(1);
     953 ECB             :     int16       result;
     954                 : 
     955 GIC          21 :     if (arg2 == 0)
     956 ECB             :     {
     957 UIC           0 :         ereport(ERROR,
     958 EUB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     959                 :                  errmsg("division by zero")));
     960                 :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     961                 :         PG_RETURN_NULL();
     962                 :     }
     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 GIC          21 :     if (arg2 == -1)
     971 ECB             :     {
     972 GIC           3 :         if (unlikely(arg1 == PG_INT16_MIN))
     973 CBC           3 :             ereport(ERROR,
     974 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     975                 :                      errmsg("smallint out of range")));
     976 UIC           0 :         result = -arg1;
     977 UBC           0 :         PG_RETURN_INT16(result);
     978 EUB             :     }
     979                 : 
     980                 :     /* No overflow is possible */
     981                 : 
     982 GIC          18 :     result = arg1 / arg2;
     983 ECB             : 
     984 GIC          18 :     PG_RETURN_INT16(result);
     985 ECB             : }
     986                 : 
     987                 : Datum
     988 GIC        1104 : int24pl(PG_FUNCTION_ARGS)
     989 ECB             : {
     990 GIC        1104 :     int16       arg1 = PG_GETARG_INT16(0);
     991 CBC        1104 :     int32       arg2 = PG_GETARG_INT32(1);
     992 ECB             :     int32       result;
     993                 : 
     994 GIC        1104 :     if (unlikely(pg_add_s32_overflow((int32) arg1, arg2, &result)))
     995 LBC           0 :         ereport(ERROR,
     996 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     997                 :                  errmsg("integer out of range")));
     998 GIC        1104 :     PG_RETURN_INT32(result);
     999 ECB             : }
    1000                 : 
    1001                 : Datum
    1002 GIC       12810 : int24mi(PG_FUNCTION_ARGS)
    1003 ECB             : {
    1004 GIC       12810 :     int16       arg1 = PG_GETARG_INT16(0);
    1005 CBC       12810 :     int32       arg2 = PG_GETARG_INT32(1);
    1006 ECB             :     int32       result;
    1007                 : 
    1008 GIC       12810 :     if (unlikely(pg_sub_s32_overflow((int32) arg1, arg2, &result)))
    1009 LBC           0 :         ereport(ERROR,
    1010 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1011                 :                  errmsg("integer out of range")));
    1012 GIC       12810 :     PG_RETURN_INT32(result);
    1013 ECB             : }
    1014                 : 
    1015                 : Datum
    1016 GIC          18 : int24mul(PG_FUNCTION_ARGS)
    1017 ECB             : {
    1018 GIC          18 :     int16       arg1 = PG_GETARG_INT16(0);
    1019 CBC          18 :     int32       arg2 = PG_GETARG_INT32(1);
    1020 ECB             :     int32       result;
    1021                 : 
    1022 GIC          18 :     if (unlikely(pg_mul_s32_overflow((int32) arg1, arg2, &result)))
    1023 LBC           0 :         ereport(ERROR,
    1024 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1025                 :                  errmsg("integer out of range")));
    1026 GIC          18 :     PG_RETURN_INT32(result);
    1027 ECB             : }
    1028                 : 
    1029                 : Datum
    1030 GIC          21 : int24div(PG_FUNCTION_ARGS)
    1031 ECB             : {
    1032 GIC          21 :     int16       arg1 = PG_GETARG_INT16(0);
    1033 CBC          21 :     int32       arg2 = PG_GETARG_INT32(1);
    1034 ECB             : 
    1035 GIC          21 :     if (unlikely(arg2 == 0))
    1036 ECB             :     {
    1037 GIC           3 :         ereport(ERROR,
    1038 ECB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1039                 :                  errmsg("division by zero")));
    1040                 :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1041                 :         PG_RETURN_NULL();
    1042                 :     }
    1043                 : 
    1044                 :     /* No overflow is possible */
    1045 GIC          18 :     PG_RETURN_INT32((int32) arg1 / arg2);
    1046 ECB             : }
    1047                 : 
    1048                 : Datum
    1049 GIC          24 : int42pl(PG_FUNCTION_ARGS)
    1050 ECB             : {
    1051 GIC          24 :     int32       arg1 = PG_GETARG_INT32(0);
    1052 CBC          24 :     int16       arg2 = PG_GETARG_INT16(1);
    1053 ECB             :     int32       result;
    1054                 : 
    1055 GIC          24 :     if (unlikely(pg_add_s32_overflow(arg1, (int32) arg2, &result)))
    1056 CBC           3 :         ereport(ERROR,
    1057 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1058                 :                  errmsg("integer out of range")));
    1059 GIC          21 :     PG_RETURN_INT32(result);
    1060 ECB             : }
    1061                 : 
    1062                 : Datum
    1063 GIC          27 : int42mi(PG_FUNCTION_ARGS)
    1064 ECB             : {
    1065 GIC          27 :     int32       arg1 = PG_GETARG_INT32(0);
    1066 CBC          27 :     int16       arg2 = PG_GETARG_INT16(1);
    1067 ECB             :     int32       result;
    1068                 : 
    1069 GIC          27 :     if (unlikely(pg_sub_s32_overflow(arg1, (int32) arg2, &result)))
    1070 CBC           3 :         ereport(ERROR,
    1071 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1072                 :                  errmsg("integer out of range")));
    1073 GIC          24 :     PG_RETURN_INT32(result);
    1074 ECB             : }
    1075                 : 
    1076                 : Datum
    1077 GIC          27 : int42mul(PG_FUNCTION_ARGS)
    1078 ECB             : {
    1079 GIC          27 :     int32       arg1 = PG_GETARG_INT32(0);
    1080 CBC          27 :     int16       arg2 = PG_GETARG_INT16(1);
    1081 ECB             :     int32       result;
    1082                 : 
    1083 GIC          27 :     if (unlikely(pg_mul_s32_overflow(arg1, (int32) arg2, &result)))
    1084 CBC           6 :         ereport(ERROR,
    1085 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1086                 :                  errmsg("integer out of range")));
    1087 GIC          21 :     PG_RETURN_INT32(result);
    1088 ECB             : }
    1089                 : 
    1090                 : Datum
    1091 GIC          24 : int42div(PG_FUNCTION_ARGS)
    1092 ECB             : {
    1093 GIC          24 :     int32       arg1 = PG_GETARG_INT32(0);
    1094 CBC          24 :     int16       arg2 = PG_GETARG_INT16(1);
    1095 ECB             :     int32       result;
    1096                 : 
    1097 GIC          24 :     if (unlikely(arg2 == 0))
    1098 ECB             :     {
    1099 GIC           3 :         ereport(ERROR,
    1100 ECB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1101                 :                  errmsg("division by zero")));
    1102                 :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1103                 :         PG_RETURN_NULL();
    1104                 :     }
    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 GIC          21 :     if (arg2 == -1)
    1113 ECB             :     {
    1114 GIC           3 :         if (unlikely(arg1 == PG_INT32_MIN))
    1115 CBC           3 :             ereport(ERROR,
    1116 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1117                 :                      errmsg("integer out of range")));
    1118 UIC           0 :         result = -arg1;
    1119 UBC           0 :         PG_RETURN_INT32(result);
    1120 EUB             :     }
    1121                 : 
    1122                 :     /* No overflow is possible */
    1123                 : 
    1124 GIC          18 :     result = arg1 / arg2;
    1125 ECB             : 
    1126 GIC          18 :     PG_RETURN_INT32(result);
    1127 ECB             : }
    1128                 : 
    1129                 : Datum
    1130 GIC     3552563 : int4mod(PG_FUNCTION_ARGS)
    1131 ECB             : {
    1132 GIC     3552563 :     int32       arg1 = PG_GETARG_INT32(0);
    1133 CBC     3552563 :     int32       arg2 = PG_GETARG_INT32(1);
    1134 ECB             : 
    1135 GIC     3552563 :     if (unlikely(arg2 == 0))
    1136 ECB             :     {
    1137 UIC           0 :         ereport(ERROR,
    1138 EUB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1139                 :                  errmsg("division by zero")));
    1140                 :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1141                 :         PG_RETURN_NULL();
    1142                 :     }
    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 GIC     3552563 :     if (arg2 == -1)
    1150 CBC           6 :         PG_RETURN_INT32(0);
    1151 ECB             : 
    1152                 :     /* No overflow is possible */
    1153                 : 
    1154 GIC     3552557 :     PG_RETURN_INT32(arg1 % arg2);
    1155 ECB             : }
    1156                 : 
    1157                 : Datum
    1158 GIC          18 : int2mod(PG_FUNCTION_ARGS)
    1159 ECB             : {
    1160 GIC          18 :     int16       arg1 = PG_GETARG_INT16(0);
    1161 CBC          18 :     int16       arg2 = PG_GETARG_INT16(1);
    1162 ECB             : 
    1163 GIC          18 :     if (unlikely(arg2 == 0))
    1164 ECB             :     {
    1165 UIC           0 :         ereport(ERROR,
    1166 EUB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1167                 :                  errmsg("division by zero")));
    1168                 :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1169                 :         PG_RETURN_NULL();
    1170                 :     }
    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 GIC          18 :     if (arg2 == -1)
    1179 CBC           3 :         PG_RETURN_INT16(0);
    1180 ECB             : 
    1181                 :     /* No overflow is possible */
    1182                 : 
    1183 GIC          15 :     PG_RETURN_INT16(arg1 % arg2);
    1184 ECB             : }
    1185                 : 
    1186                 : 
    1187                 : /* int[24]abs()
    1188                 :  * Absolute value
    1189                 :  */
    1190                 : Datum
    1191 GIC       64405 : int4abs(PG_FUNCTION_ARGS)
    1192 ECB             : {
    1193 GIC       64405 :     int32       arg1 = PG_GETARG_INT32(0);
    1194 ECB             :     int32       result;
    1195                 : 
    1196 GIC       64405 :     if (unlikely(arg1 == PG_INT32_MIN))
    1197 LBC           0 :         ereport(ERROR,
    1198 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1199                 :                  errmsg("integer out of range")));
    1200 GIC       64405 :     result = (arg1 < 0) ? -arg1 : arg1;
    1201 CBC       64405 :     PG_RETURN_INT32(result);
    1202 ECB             : }
    1203                 : 
    1204                 : Datum
    1205 GIC          15 : int2abs(PG_FUNCTION_ARGS)
    1206 ECB             : {
    1207 GIC          15 :     int16       arg1 = PG_GETARG_INT16(0);
    1208 ECB             :     int16       result;
    1209                 : 
    1210 GIC          15 :     if (unlikely(arg1 == PG_INT16_MIN))
    1211 LBC           0 :         ereport(ERROR,
    1212 EUB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1213                 :                  errmsg("smallint out of range")));
    1214 GIC          15 :     result = (arg1 < 0) ? -arg1 : arg1;
    1215 CBC          15 :     PG_RETURN_INT16(result);
    1216 ECB             : }
    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 GIC         132 : int4gcd_internal(int32 arg1, int32 arg2)
    1234 ECB             : {
    1235                 :     int32       swap;
    1236                 :     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 GIC         132 :     a1 = (arg1 < 0) ? arg1 : -arg1;
    1249 CBC         132 :     a2 = (arg2 < 0) ? arg2 : -arg2;
    1250             132 :     if (a1 > a2)
    1251 ECB             :     {
    1252 GIC          48 :         swap = arg1;
    1253 CBC          48 :         arg1 = arg2;
    1254              48 :         arg2 = swap;
    1255 ECB             :     }
    1256                 : 
    1257                 :     /* Special care needs to be taken with INT_MIN.  See comments above. */
    1258 GIC         132 :     if (arg1 == PG_INT32_MIN)
    1259 ECB             :     {
    1260 GIC          45 :         if (arg2 == 0 || arg2 == PG_INT32_MIN)
    1261 CBC           6 :             ereport(ERROR,
    1262 ECB             :                     (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 GIC          39 :         if (arg2 == -1)
    1272 CBC           6 :             return 1;
    1273 ECB             :     }
    1274                 : 
    1275                 :     /* Use the Euclidean algorithm to find the GCD */
    1276 GIC         471 :     while (arg2 != 0)
    1277 ECB             :     {
    1278 GIC         351 :         swap = arg2;
    1279 CBC         351 :         arg2 = arg1 % arg2;
    1280             351 :         arg1 = swap;
    1281 ECB             :     }
    1282                 : 
    1283                 :     /*
    1284                 :      * Make sure the result is positive. (We know we don't have INT_MIN
    1285                 :      * anymore).
    1286                 :      */
    1287 GIC         120 :     if (arg1 < 0)
    1288 CBC          51 :         arg1 = -arg1;
    1289 ECB             : 
    1290 GIC         120 :     return arg1;
    1291 ECB             : }
    1292                 : 
    1293                 : Datum
    1294 GIC          90 : int4gcd(PG_FUNCTION_ARGS)
    1295 ECB             : {
    1296 GIC          90 :     int32       arg1 = PG_GETARG_INT32(0);
    1297 CBC          90 :     int32       arg2 = PG_GETARG_INT32(1);
    1298 ECB             :     int32       result;
    1299                 : 
    1300 GIC          90 :     result = int4gcd_internal(arg1, arg2);
    1301 ECB             : 
    1302 GIC          84 :     PG_RETURN_INT32(result);
    1303 ECB             : }
    1304                 : 
    1305                 : /*
    1306                 :  * Least Common Multiple
    1307                 :  */
    1308                 : Datum
    1309 GIC          78 : int4lcm(PG_FUNCTION_ARGS)
    1310 ECB             : {
    1311 GIC          78 :     int32       arg1 = PG_GETARG_INT32(0);
    1312 CBC          78 :     int32       arg2 = PG_GETARG_INT32(1);
    1313 ECB             :     int32       gcd;
    1314                 :     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 GIC          78 :     if (arg1 == 0 || arg2 == 0)
    1322 CBC          36 :         PG_RETURN_INT32(0);
    1323 ECB             : 
    1324                 :     /* lcm(x, y) = abs(x / gcd(x, y) * y) */
    1325 GIC          42 :     gcd = int4gcd_internal(arg1, arg2);
    1326 CBC          42 :     arg1 = arg1 / gcd;
    1327 ECB             : 
    1328 GIC          42 :     if (unlikely(pg_mul_s32_overflow(arg1, arg2, &result)))
    1329 CBC           3 :         ereport(ERROR,
    1330 ECB             :                 (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 GIC          39 :     if (unlikely(result == PG_INT32_MIN))
    1335 CBC           3 :         ereport(ERROR,
    1336 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1337                 :                  errmsg("integer out of range")));
    1338                 : 
    1339 GIC          36 :     if (result < 0)
    1340 CBC          18 :         result = -result;
    1341 ECB             : 
    1342 GIC          36 :     PG_RETURN_INT32(result);
    1343 ECB             : }
    1344                 : 
    1345                 : Datum
    1346 GIC         201 : int2larger(PG_FUNCTION_ARGS)
    1347 ECB             : {
    1348 GIC         201 :     int16       arg1 = PG_GETARG_INT16(0);
    1349 CBC         201 :     int16       arg2 = PG_GETARG_INT16(1);
    1350 ECB             : 
    1351 GIC         201 :     PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
    1352 ECB             : }
    1353                 : 
    1354                 : Datum
    1355 UIC           0 : int2smaller(PG_FUNCTION_ARGS)
    1356 EUB             : {
    1357 UIC           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1358 UBC           0 :     int16       arg2 = PG_GETARG_INT16(1);
    1359 EUB             : 
    1360 UIC           0 :     PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
    1361 EUB             : }
    1362                 : 
    1363                 : Datum
    1364 GIC      160196 : int4larger(PG_FUNCTION_ARGS)
    1365 ECB             : {
    1366 GIC      160196 :     int32       arg1 = PG_GETARG_INT32(0);
    1367 CBC      160196 :     int32       arg2 = PG_GETARG_INT32(1);
    1368 ECB             : 
    1369 GIC      160196 :     PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
    1370 ECB             : }
    1371                 : 
    1372                 : Datum
    1373 GIC      125166 : int4smaller(PG_FUNCTION_ARGS)
    1374 ECB             : {
    1375 GIC      125166 :     int32       arg1 = PG_GETARG_INT32(0);
    1376 CBC      125166 :     int32       arg2 = PG_GETARG_INT32(1);
    1377 ECB             : 
    1378 GIC      125166 :     PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
    1379 ECB             : }
    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 GIC        1770 : int4and(PG_FUNCTION_ARGS)
    1394 ECB             : {
    1395 GIC        1770 :     int32       arg1 = PG_GETARG_INT32(0);
    1396 CBC        1770 :     int32       arg2 = PG_GETARG_INT32(1);
    1397 ECB             : 
    1398 GIC        1770 :     PG_RETURN_INT32(arg1 & arg2);
    1399 ECB             : }
    1400                 : 
    1401                 : Datum
    1402 GIC           9 : int4or(PG_FUNCTION_ARGS)
    1403 ECB             : {
    1404 GIC           9 :     int32       arg1 = PG_GETARG_INT32(0);
    1405 CBC           9 :     int32       arg2 = PG_GETARG_INT32(1);
    1406 ECB             : 
    1407 GIC           9 :     PG_RETURN_INT32(arg1 | arg2);
    1408 ECB             : }
    1409                 : 
    1410                 : Datum
    1411 GIC           9 : int4xor(PG_FUNCTION_ARGS)
    1412 ECB             : {
    1413 GIC           9 :     int32       arg1 = PG_GETARG_INT32(0);
    1414 CBC           9 :     int32       arg2 = PG_GETARG_INT32(1);
    1415 ECB             : 
    1416 GIC           9 :     PG_RETURN_INT32(arg1 ^ arg2);
    1417 ECB             : }
    1418                 : 
    1419                 : Datum
    1420 GIC           6 : int4shl(PG_FUNCTION_ARGS)
    1421 ECB             : {
    1422 GIC           6 :     int32       arg1 = PG_GETARG_INT32(0);
    1423 CBC           6 :     int32       arg2 = PG_GETARG_INT32(1);
    1424 ECB             : 
    1425 GIC           6 :     PG_RETURN_INT32(arg1 << arg2);
    1426 ECB             : }
    1427                 : 
    1428                 : Datum
    1429 UIC           0 : int4shr(PG_FUNCTION_ARGS)
    1430 EUB             : {
    1431 UIC           0 :     int32       arg1 = PG_GETARG_INT32(0);
    1432 UBC           0 :     int32       arg2 = PG_GETARG_INT32(1);
    1433 EUB             : 
    1434 UIC           0 :     PG_RETURN_INT32(arg1 >> arg2);
    1435 EUB             : }
    1436                 : 
    1437                 : Datum
    1438 UIC           0 : int4not(PG_FUNCTION_ARGS)
    1439 EUB             : {
    1440 UIC           0 :     int32       arg1 = PG_GETARG_INT32(0);
    1441 EUB             : 
    1442 UIC           0 :     PG_RETURN_INT32(~arg1);
    1443 EUB             : }
    1444                 : 
    1445                 : Datum
    1446 GIC          12 : int2and(PG_FUNCTION_ARGS)
    1447 ECB             : {
    1448 GIC          12 :     int16       arg1 = PG_GETARG_INT16(0);
    1449 CBC          12 :     int16       arg2 = PG_GETARG_INT16(1);
    1450 ECB             : 
    1451 GIC          12 :     PG_RETURN_INT16(arg1 & arg2);
    1452 ECB             : }
    1453                 : 
    1454                 : Datum
    1455 GIC          12 : int2or(PG_FUNCTION_ARGS)
    1456 ECB             : {
    1457 GIC          12 :     int16       arg1 = PG_GETARG_INT16(0);
    1458 CBC          12 :     int16       arg2 = PG_GETARG_INT16(1);
    1459 ECB             : 
    1460 GIC          12 :     PG_RETURN_INT16(arg1 | arg2);
    1461 ECB             : }
    1462                 : 
    1463                 : Datum
    1464 GIC          12 : int2xor(PG_FUNCTION_ARGS)
    1465 ECB             : {
    1466 GIC          12 :     int16       arg1 = PG_GETARG_INT16(0);
    1467 CBC          12 :     int16       arg2 = PG_GETARG_INT16(1);
    1468 ECB             : 
    1469 GIC          12 :     PG_RETURN_INT16(arg1 ^ arg2);
    1470 ECB             : }
    1471                 : 
    1472                 : Datum
    1473 UIC           0 : int2not(PG_FUNCTION_ARGS)
    1474 EUB             : {
    1475 UIC           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1476 EUB             : 
    1477 UIC           0 :     PG_RETURN_INT16(~arg1);
    1478 EUB             : }
    1479                 : 
    1480                 : 
    1481                 : Datum
    1482 GIC           6 : int2shl(PG_FUNCTION_ARGS)
    1483 ECB             : {
    1484 GIC           6 :     int16       arg1 = PG_GETARG_INT16(0);
    1485 CBC           6 :     int32       arg2 = PG_GETARG_INT32(1);
    1486 ECB             : 
    1487 GIC           6 :     PG_RETURN_INT16(arg1 << arg2);
    1488 ECB             : }
    1489                 : 
    1490                 : Datum
    1491 UIC           0 : int2shr(PG_FUNCTION_ARGS)
    1492 EUB             : {
    1493 UIC           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1494 UBC           0 :     int32       arg2 = PG_GETARG_INT32(1);
    1495 EUB             : 
    1496 UIC           0 :     PG_RETURN_INT16(arg1 >> arg2);
    1497 EUB             : }
    1498                 : 
    1499                 : /*
    1500                 :  * non-persistent numeric series generator
    1501                 :  */
    1502                 : Datum
    1503 GIC     7141854 : generate_series_int4(PG_FUNCTION_ARGS)
    1504 ECB             : {
    1505 GIC     7141854 :     return generate_series_step_int4(fcinfo);
    1506 ECB             : }
    1507                 : 
    1508                 : Datum
    1509 GIC     7323514 : generate_series_step_int4(PG_FUNCTION_ARGS)
    1510 ECB             : {
    1511                 :     FuncCallContext *funcctx;
    1512                 :     generate_series_fctx *fctx;
    1513                 :     int32       result;
    1514                 :     MemoryContext oldcontext;
    1515                 : 
    1516                 :     /* stuff done only on the first call of the function */
    1517 GIC     7323514 :     if (SRF_IS_FIRSTCALL())
    1518 ECB             :     {
    1519 GIC        6142 :         int32       start = PG_GETARG_INT32(0);
    1520 CBC        6142 :         int32       finish = PG_GETARG_INT32(1);
    1521            6142 :         int32       step = 1;
    1522 ECB             : 
    1523                 :         /* see if we were given an explicit step size */
    1524 GIC        6142 :         if (PG_NARGS() == 3)
    1525 CBC         269 :             step = PG_GETARG_INT32(2);
    1526            6142 :         if (step == 0)
    1527 LBC           0 :             ereport(ERROR,
    1528 EUB             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1529                 :                      errmsg("step size cannot equal zero")));
    1530                 : 
    1531                 :         /* create a function context for cross-call persistence */
    1532 GIC        6142 :         funcctx = SRF_FIRSTCALL_INIT();
    1533 ECB             : 
    1534                 :         /*
    1535                 :          * switch to memory context appropriate for multiple function calls
    1536                 :          */
    1537 GIC        6142 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1538 ECB             : 
    1539                 :         /* allocate memory for user context */
    1540 GIC        6142 :         fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
    1541 ECB             : 
    1542                 :         /*
    1543                 :          * Use fctx to keep state from call to call. Seed current with the
    1544                 :          * original start value
    1545                 :          */
    1546 GIC        6142 :         fctx->current = start;
    1547 CBC        6142 :         fctx->finish = finish;
    1548            6142 :         fctx->step = step;
    1549 ECB             : 
    1550 GIC        6142 :         funcctx->user_fctx = fctx;
    1551 CBC        6142 :         MemoryContextSwitchTo(oldcontext);
    1552 ECB             :     }
    1553                 : 
    1554                 :     /* stuff done on every call of the function */
    1555 GIC     7323514 :     funcctx = SRF_PERCALL_SETUP();
    1556 ECB             : 
    1557                 :     /*
    1558                 :      * get the saved state and use current as the result for this iteration
    1559                 :      */
    1560 GIC     7323514 :     fctx = funcctx->user_fctx;
    1561 CBC     7323514 :     result = fctx->current;
    1562 ECB             : 
    1563 GIC     7323514 :     if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
    1564 CBC      106123 :         (fctx->step < 0 && fctx->current >= fctx->finish))
    1565 ECB             :     {
    1566                 :         /*
    1567                 :          * Increment current in preparation for next iteration. If next-value
    1568                 :          * computation overflows, this is the final result.
    1569                 :          */
    1570 GIC     7317396 :         if (pg_add_s32_overflow(fctx->current, fctx->step, &fctx->current))
    1571 LBC           0 :             fctx->step = 0;
    1572 EUB             : 
    1573                 :         /* do when there is more left to send */
    1574 GIC     7317396 :         SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
    1575 ECB             :     }
    1576                 :     else
    1577                 :         /* do when there is no more left */
    1578 GIC        6118 :         SRF_RETURN_DONE(funcctx);
    1579 ECB             : }
    1580                 : 
    1581                 : /*
    1582                 :  * Planner support function for generate_series(int4, int4 [, int4])
    1583                 :  */
    1584                 : Datum
    1585 GIC       15306 : generate_series_int4_support(PG_FUNCTION_ARGS)
    1586 ECB             : {
    1587 GIC       15306 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1588 CBC       15306 :     Node       *ret = NULL;
    1589 ECB             : 
    1590 GIC       15306 :     if (IsA(rawreq, SupportRequestRows))
    1591 ECB             :     {
    1592                 :         /* Try to estimate the number of rows returned */
    1593 GIC        5025 :         SupportRequestRows *req = (SupportRequestRows *) rawreq;
    1594 ECB             : 
    1595 GIC        5025 :         if (is_funcclause(req->node))    /* be paranoid */
    1596 ECB             :         {
    1597 GIC        5025 :             List       *args = ((FuncExpr *) req->node)->args;
    1598 ECB             :             Node       *arg1,
    1599                 :                        *arg2,
    1600                 :                        *arg3;
    1601                 : 
    1602                 :             /* We can use estimated argument values here */
    1603 GIC        5025 :             arg1 = estimate_expression_value(req->root, linitial(args));
    1604 CBC        5025 :             arg2 = estimate_expression_value(req->root, lsecond(args));
    1605            5025 :             if (list_length(args) >= 3)
    1606             203 :                 arg3 = estimate_expression_value(req->root, lthird(args));
    1607 ECB             :             else
    1608 GIC        4822 :                 arg3 = NULL;
    1609 ECB             : 
    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 GIC        5025 :             if ((IsA(arg1, Const) &&
    1617 CBC        4947 :                  ((Const *) arg1)->constisnull) ||
    1618            5025 :                 (IsA(arg2, Const) &&
    1619            5025 :                  ((Const *) arg2)->constisnull) ||
    1620             203 :                 (arg3 != NULL && IsA(arg3, Const) &&
    1621             203 :                  ((Const *) arg3)->constisnull))
    1622 ECB             :             {
    1623 UIC           0 :                 req->rows = 0;
    1624 UBC           0 :                 ret = (Node *) req;
    1625 EUB             :             }
    1626 GIC        5025 :             else if (IsA(arg1, Const) &&
    1627 CBC        4947 :                      IsA(arg2, Const) &&
    1628             200 :                      (arg3 == NULL || IsA(arg3, Const)))
    1629 ECB             :             {
    1630                 :                 double      start,
    1631                 :                             finish,
    1632                 :                             step;
    1633                 : 
    1634 GIC        3497 :                 start = DatumGetInt32(((Const *) arg1)->constvalue);
    1635 CBC        3497 :                 finish = DatumGetInt32(((Const *) arg2)->constvalue);
    1636            3497 :                 step = arg3 ? DatumGetInt32(((Const *) arg3)->constvalue) : 1;
    1637 ECB             : 
    1638                 :                 /* This equation works for either sign of step */
    1639 GIC        3497 :                 if (step != 0)
    1640 ECB             :                 {
    1641 GIC        3497 :                     req->rows = floor((finish - start + step) / step);
    1642 CBC        3497 :                     ret = (Node *) req;
    1643 ECB             :                 }
    1644                 :             }
    1645                 :         }
    1646                 :     }
    1647                 : 
    1648 GIC       15306 :     PG_RETURN_POINTER(ret);
    1649 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a