LCOV - code coverage report
Current view: top level - src/backend/utils/adt - int.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 364 484 75.2 %
Date: 2017-09-29 13:40:31 Functions: 67 84 79.8 %
Legend: Lines: hit not hit

          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-2017, 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             : 
      34             : #include "catalog/pg_type.h"
      35             : #include "funcapi.h"
      36             : #include "libpq/pqformat.h"
      37             : #include "utils/array.h"
      38             : #include "utils/builtins.h"
      39             : 
      40             : 
      41             : #define SAMESIGN(a,b)   (((a) < 0) == ((b) < 0))
      42             : 
      43             : #define Int2VectorSize(n)   (offsetof(int2vector, values) + (n) * sizeof(int16))
      44             : 
      45             : typedef struct
      46             : {
      47             :     int32       current;
      48             :     int32       finish;
      49             :     int32       step;
      50             : } generate_series_fctx;
      51             : 
      52             : 
      53             : /*****************************************************************************
      54             :  *   USER I/O ROUTINES                                                       *
      55             :  *****************************************************************************/
      56             : 
      57             : /*
      58             :  *      int2in          - converts "num" to short
      59             :  */
      60             : Datum
      61        7600 : int2in(PG_FUNCTION_ARGS)
      62             : {
      63        7600 :     char       *num = PG_GETARG_CSTRING(0);
      64             : 
      65        7600 :     PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0'));
      66             : }
      67             : 
      68             : /*
      69             :  *      int2out         - converts short to "num"
      70             :  */
      71             : Datum
      72        1543 : int2out(PG_FUNCTION_ARGS)
      73             : {
      74        1543 :     int16       arg1 = PG_GETARG_INT16(0);
      75        1543 :     char       *result = (char *) palloc(7);    /* sign, 5 digits, '\0' */
      76             : 
      77        1543 :     pg_itoa(arg1, result);
      78        1543 :     PG_RETURN_CSTRING(result);
      79             : }
      80             : 
      81             : /*
      82             :  *      int2recv            - converts external binary format to int2
      83             :  */
      84             : Datum
      85           0 : int2recv(PG_FUNCTION_ARGS)
      86             : {
      87           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
      88             : 
      89           0 :     PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
      90             : }
      91             : 
      92             : /*
      93             :  *      int2send            - converts int2 to binary format
      94             :  */
      95             : Datum
      96           0 : int2send(PG_FUNCTION_ARGS)
      97             : {
      98           0 :     int16       arg1 = PG_GETARG_INT16(0);
      99             :     StringInfoData buf;
     100             : 
     101           0 :     pq_begintypsend(&buf);
     102           0 :     pq_sendint(&buf, arg1, sizeof(int16));
     103           0 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     104             : }
     105             : 
     106             : /*
     107             :  * construct int2vector given a raw array of int2s
     108             :  *
     109             :  * If int2s is NULL then caller must fill values[] afterward
     110             :  */
     111             : int2vector *
     112        3383 : buildint2vector(const int16 *int2s, int n)
     113             : {
     114             :     int2vector *result;
     115             : 
     116        3383 :     result = (int2vector *) palloc0(Int2VectorSize(n));
     117             : 
     118        3383 :     if (n > 0 && int2s)
     119        1467 :         memcpy(result->values, int2s, n * sizeof(int16));
     120             : 
     121             :     /*
     122             :      * Attach standard array header.  For historical reasons, we set the index
     123             :      * lower bound to 0 not 1.
     124             :      */
     125        3383 :     SET_VARSIZE(result, Int2VectorSize(n));
     126        3383 :     result->ndim = 1;
     127        3383 :     result->dataoffset = 0;      /* never any nulls */
     128        3383 :     result->elemtype = INT2OID;
     129        3383 :     result->dim1 = n;
     130        3383 :     result->lbound1 = 0;
     131             : 
     132        3383 :     return result;
     133             : }
     134             : 
     135             : /*
     136             :  *      int2vectorin            - converts "num num ..." to internal form
     137             :  */
     138             : Datum
     139           0 : int2vectorin(PG_FUNCTION_ARGS)
     140             : {
     141           0 :     char       *intString = PG_GETARG_CSTRING(0);
     142             :     int2vector *result;
     143             :     int         n;
     144             : 
     145           0 :     result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
     146             : 
     147           0 :     for (n = 0; *intString && n < FUNC_MAX_ARGS; n++)
     148             :     {
     149           0 :         while (*intString && isspace((unsigned char) *intString))
     150           0 :             intString++;
     151           0 :         if (*intString == '\0')
     152           0 :             break;
     153           0 :         result->values[n] = pg_atoi(intString, sizeof(int16), ' ');
     154           0 :         while (*intString && !isspace((unsigned char) *intString))
     155           0 :             intString++;
     156             :     }
     157           0 :     while (*intString && isspace((unsigned char) *intString))
     158           0 :         intString++;
     159           0 :     if (*intString)
     160           0 :         ereport(ERROR,
     161             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     162             :                  errmsg("int2vector has too many elements")));
     163             : 
     164           0 :     SET_VARSIZE(result, Int2VectorSize(n));
     165           0 :     result->ndim = 1;
     166           0 :     result->dataoffset = 0;      /* never any nulls */
     167           0 :     result->elemtype = INT2OID;
     168           0 :     result->dim1 = n;
     169           0 :     result->lbound1 = 0;
     170             : 
     171           0 :     PG_RETURN_POINTER(result);
     172             : }
     173             : 
     174             : /*
     175             :  *      int2vectorout       - converts internal form to "num num ..."
     176             :  */
     177             : Datum
     178           0 : int2vectorout(PG_FUNCTION_ARGS)
     179             : {
     180           0 :     int2vector *int2Array = (int2vector *) PG_GETARG_POINTER(0);
     181             :     int         num,
     182           0 :                 nnums = int2Array->dim1;
     183             :     char       *rp;
     184             :     char       *result;
     185             : 
     186             :     /* assumes sign, 5 digits, ' ' */
     187           0 :     rp = result = (char *) palloc(nnums * 7 + 1);
     188           0 :     for (num = 0; num < nnums; num++)
     189             :     {
     190           0 :         if (num != 0)
     191           0 :             *rp++ = ' ';
     192           0 :         pg_itoa(int2Array->values[num], rp);
     193           0 :         while (*++rp != '\0')
     194             :             ;
     195             :     }
     196           0 :     *rp = '\0';
     197           0 :     PG_RETURN_CSTRING(result);
     198             : }
     199             : 
     200             : /*
     201             :  *      int2vectorrecv          - converts external binary format to int2vector
     202             :  */
     203             : Datum
     204           0 : int2vectorrecv(PG_FUNCTION_ARGS)
     205             : {
     206           0 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     207             :     FunctionCallInfoData locfcinfo;
     208             :     int2vector *result;
     209             : 
     210             :     /*
     211             :      * Normally one would call array_recv() using DirectFunctionCall3, but
     212             :      * that does not work since array_recv wants to cache some data using
     213             :      * fcinfo->flinfo->fn_extra.  So we need to pass it our own flinfo
     214             :      * parameter.
     215             :      */
     216           0 :     InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3,
     217             :                              InvalidOid, NULL, NULL);
     218             : 
     219           0 :     locfcinfo.arg[0] = PointerGetDatum(buf);
     220           0 :     locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
     221           0 :     locfcinfo.arg[2] = Int32GetDatum(-1);
     222           0 :     locfcinfo.argnull[0] = false;
     223           0 :     locfcinfo.argnull[1] = false;
     224           0 :     locfcinfo.argnull[2] = false;
     225             : 
     226           0 :     result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));
     227             : 
     228           0 :     Assert(!locfcinfo.isnull);
     229             : 
     230             :     /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
     231           0 :     if (ARR_NDIM(result) != 1 ||
     232           0 :         ARR_HASNULL(result) ||
     233           0 :         ARR_ELEMTYPE(result) != INT2OID ||
     234           0 :         ARR_LBOUND(result)[0] != 0)
     235           0 :         ereport(ERROR,
     236             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
     237             :                  errmsg("invalid int2vector data")));
     238             : 
     239             :     /* check length for consistency with int2vectorin() */
     240           0 :     if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
     241           0 :         ereport(ERROR,
     242             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     243             :                  errmsg("oidvector has too many elements")));
     244             : 
     245           0 :     PG_RETURN_POINTER(result);
     246             : }
     247             : 
     248             : /*
     249             :  *      int2vectorsend          - converts int2vector to binary format
     250             :  */
     251             : Datum
     252           0 : int2vectorsend(PG_FUNCTION_ARGS)
     253             : {
     254           0 :     return array_send(fcinfo);
     255             : }
     256             : 
     257             : 
     258             : /*****************************************************************************
     259             :  *   PUBLIC ROUTINES                                                         *
     260             :  *****************************************************************************/
     261             : 
     262             : /*
     263             :  *      int4in          - converts "num" to int4
     264             :  */
     265             : Datum
     266      292038 : int4in(PG_FUNCTION_ARGS)
     267             : {
     268      292038 :     char       *num = PG_GETARG_CSTRING(0);
     269             : 
     270      292038 :     PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0'));
     271             : }
     272             : 
     273             : /*
     274             :  *      int4out         - converts int4 to "num"
     275             :  */
     276             : Datum
     277      149692 : int4out(PG_FUNCTION_ARGS)
     278             : {
     279      149692 :     int32       arg1 = PG_GETARG_INT32(0);
     280      149692 :     char       *result = (char *) palloc(12);   /* sign, 10 digits, '\0' */
     281             : 
     282      149692 :     pg_ltoa(arg1, result);
     283      149692 :     PG_RETURN_CSTRING(result);
     284             : }
     285             : 
     286             : /*
     287             :  *      int4recv            - converts external binary format to int4
     288             :  */
     289             : Datum
     290         344 : int4recv(PG_FUNCTION_ARGS)
     291             : {
     292         344 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
     293             : 
     294         344 :     PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
     295             : }
     296             : 
     297             : /*
     298             :  *      int4send            - converts int4 to binary format
     299             :  */
     300             : Datum
     301         179 : int4send(PG_FUNCTION_ARGS)
     302             : {
     303         179 :     int32       arg1 = PG_GETARG_INT32(0);
     304             :     StringInfoData buf;
     305             : 
     306         179 :     pq_begintypsend(&buf);
     307         179 :     pq_sendint(&buf, arg1, sizeof(int32));
     308         179 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
     309             : }
     310             : 
     311             : 
     312             : /*
     313             :  *      ===================
     314             :  *      CONVERSION ROUTINES
     315             :  *      ===================
     316             :  */
     317             : 
     318             : Datum
     319         562 : i2toi4(PG_FUNCTION_ARGS)
     320             : {
     321         562 :     int16       arg1 = PG_GETARG_INT16(0);
     322             : 
     323         562 :     PG_RETURN_INT32((int32) arg1);
     324             : }
     325             : 
     326             : Datum
     327         244 : i4toi2(PG_FUNCTION_ARGS)
     328             : {
     329         244 :     int32       arg1 = PG_GETARG_INT32(0);
     330             : 
     331         244 :     if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
     332           6 :         ereport(ERROR,
     333             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     334             :                  errmsg("smallint out of range")));
     335             : 
     336         238 :     PG_RETURN_INT16((int16) arg1);
     337             : }
     338             : 
     339             : /* Cast int4 -> bool */
     340             : Datum
     341           0 : int4_bool(PG_FUNCTION_ARGS)
     342             : {
     343           0 :     if (PG_GETARG_INT32(0) == 0)
     344           0 :         PG_RETURN_BOOL(false);
     345             :     else
     346           0 :         PG_RETURN_BOOL(true);
     347             : }
     348             : 
     349             : /* Cast bool -> int4 */
     350             : Datum
     351           3 : bool_int4(PG_FUNCTION_ARGS)
     352             : {
     353           3 :     if (PG_GETARG_BOOL(0) == false)
     354           1 :         PG_RETURN_INT32(0);
     355             :     else
     356           2 :         PG_RETURN_INT32(1);
     357             : }
     358             : 
     359             : /*
     360             :  *      ============================
     361             :  *      COMPARISON OPERATOR ROUTINES
     362             :  *      ============================
     363             :  */
     364             : 
     365             : /*
     366             :  *      inteq           - returns 1 iff arg1 == arg2
     367             :  *      intne           - returns 1 iff arg1 != arg2
     368             :  *      intlt           - returns 1 iff arg1 < arg2
     369             :  *      intle           - returns 1 iff arg1 <= arg2
     370             :  *      intgt           - returns 1 iff arg1 > arg2
     371             :  *      intge           - returns 1 iff arg1 >= arg2
     372             :  */
     373             : 
     374             : Datum
     375     1103065 : int4eq(PG_FUNCTION_ARGS)
     376             : {
     377     1103065 :     int32       arg1 = PG_GETARG_INT32(0);
     378     1103065 :     int32       arg2 = PG_GETARG_INT32(1);
     379             : 
     380     1103065 :     PG_RETURN_BOOL(arg1 == arg2);
     381             : }
     382             : 
     383             : Datum
     384       42082 : int4ne(PG_FUNCTION_ARGS)
     385             : {
     386       42082 :     int32       arg1 = PG_GETARG_INT32(0);
     387       42082 :     int32       arg2 = PG_GETARG_INT32(1);
     388             : 
     389       42082 :     PG_RETURN_BOOL(arg1 != arg2);
     390             : }
     391             : 
     392             : Datum
     393       90653 : int4lt(PG_FUNCTION_ARGS)
     394             : {
     395       90653 :     int32       arg1 = PG_GETARG_INT32(0);
     396       90653 :     int32       arg2 = PG_GETARG_INT32(1);
     397             : 
     398       90653 :     PG_RETURN_BOOL(arg1 < arg2);
     399             : }
     400             : 
     401             : Datum
     402       13741 : int4le(PG_FUNCTION_ARGS)
     403             : {
     404       13741 :     int32       arg1 = PG_GETARG_INT32(0);
     405       13741 :     int32       arg2 = PG_GETARG_INT32(1);
     406             : 
     407       13741 :     PG_RETURN_BOOL(arg1 <= arg2);
     408             : }
     409             : 
     410             : Datum
     411      382791 : int4gt(PG_FUNCTION_ARGS)
     412             : {
     413      382791 :     int32       arg1 = PG_GETARG_INT32(0);
     414      382791 :     int32       arg2 = PG_GETARG_INT32(1);
     415             : 
     416      382791 :     PG_RETURN_BOOL(arg1 > arg2);
     417             : }
     418             : 
     419             : Datum
     420       32096 : int4ge(PG_FUNCTION_ARGS)
     421             : {
     422       32096 :     int32       arg1 = PG_GETARG_INT32(0);
     423       32096 :     int32       arg2 = PG_GETARG_INT32(1);
     424             : 
     425       32096 :     PG_RETURN_BOOL(arg1 >= arg2);
     426             : }
     427             : 
     428             : Datum
     429      284199 : int2eq(PG_FUNCTION_ARGS)
     430             : {
     431      284199 :     int16       arg1 = PG_GETARG_INT16(0);
     432      284199 :     int16       arg2 = PG_GETARG_INT16(1);
     433             : 
     434      284199 :     PG_RETURN_BOOL(arg1 == arg2);
     435             : }
     436             : 
     437             : Datum
     438        3643 : int2ne(PG_FUNCTION_ARGS)
     439             : {
     440        3643 :     int16       arg1 = PG_GETARG_INT16(0);
     441        3643 :     int16       arg2 = PG_GETARG_INT16(1);
     442             : 
     443        3643 :     PG_RETURN_BOOL(arg1 != arg2);
     444             : }
     445             : 
     446             : Datum
     447        1787 : int2lt(PG_FUNCTION_ARGS)
     448             : {
     449        1787 :     int16       arg1 = PG_GETARG_INT16(0);
     450        1787 :     int16       arg2 = PG_GETARG_INT16(1);
     451             : 
     452        1787 :     PG_RETURN_BOOL(arg1 < arg2);
     453             : }
     454             : 
     455             : Datum
     456         463 : int2le(PG_FUNCTION_ARGS)
     457             : {
     458         463 :     int16       arg1 = PG_GETARG_INT16(0);
     459         463 :     int16       arg2 = PG_GETARG_INT16(1);
     460             : 
     461         463 :     PG_RETURN_BOOL(arg1 <= arg2);
     462             : }
     463             : 
     464             : Datum
     465       88085 : int2gt(PG_FUNCTION_ARGS)
     466             : {
     467       88085 :     int16       arg1 = PG_GETARG_INT16(0);
     468       88085 :     int16       arg2 = PG_GETARG_INT16(1);
     469             : 
     470       88085 :     PG_RETURN_BOOL(arg1 > arg2);
     471             : }
     472             : 
     473             : Datum
     474         386 : int2ge(PG_FUNCTION_ARGS)
     475             : {
     476         386 :     int16       arg1 = PG_GETARG_INT16(0);
     477         386 :     int16       arg2 = PG_GETARG_INT16(1);
     478             : 
     479         386 :     PG_RETURN_BOOL(arg1 >= arg2);
     480             : }
     481             : 
     482             : Datum
     483        6773 : int24eq(PG_FUNCTION_ARGS)
     484             : {
     485        6773 :     int16       arg1 = PG_GETARG_INT16(0);
     486        6773 :     int32       arg2 = PG_GETARG_INT32(1);
     487             : 
     488        6773 :     PG_RETURN_BOOL(arg1 == arg2);
     489             : }
     490             : 
     491             : Datum
     492       33242 : int24ne(PG_FUNCTION_ARGS)
     493             : {
     494       33242 :     int16       arg1 = PG_GETARG_INT16(0);
     495       33242 :     int32       arg2 = PG_GETARG_INT32(1);
     496             : 
     497       33242 :     PG_RETURN_BOOL(arg1 != arg2);
     498             : }
     499             : 
     500             : Datum
     501        8588 : int24lt(PG_FUNCTION_ARGS)
     502             : {
     503        8588 :     int16       arg1 = PG_GETARG_INT16(0);
     504        8588 :     int32       arg2 = PG_GETARG_INT32(1);
     505             : 
     506        8588 :     PG_RETURN_BOOL(arg1 < arg2);
     507             : }
     508             : 
     509             : Datum
     510        1525 : int24le(PG_FUNCTION_ARGS)
     511             : {
     512        1525 :     int16       arg1 = PG_GETARG_INT16(0);
     513        1525 :     int32       arg2 = PG_GETARG_INT32(1);
     514             : 
     515        1525 :     PG_RETURN_BOOL(arg1 <= arg2);
     516             : }
     517             : 
     518             : Datum
     519       16316 : int24gt(PG_FUNCTION_ARGS)
     520             : {
     521       16316 :     int16       arg1 = PG_GETARG_INT16(0);
     522       16316 :     int32       arg2 = PG_GETARG_INT32(1);
     523             : 
     524       16316 :     PG_RETURN_BOOL(arg1 > arg2);
     525             : }
     526             : 
     527             : Datum
     528         648 : int24ge(PG_FUNCTION_ARGS)
     529             : {
     530         648 :     int16       arg1 = PG_GETARG_INT16(0);
     531         648 :     int32       arg2 = PG_GETARG_INT32(1);
     532             : 
     533         648 :     PG_RETURN_BOOL(arg1 >= arg2);
     534             : }
     535             : 
     536             : Datum
     537         902 : int42eq(PG_FUNCTION_ARGS)
     538             : {
     539         902 :     int32       arg1 = PG_GETARG_INT32(0);
     540         902 :     int16       arg2 = PG_GETARG_INT16(1);
     541             : 
     542         902 :     PG_RETURN_BOOL(arg1 == arg2);
     543             : }
     544             : 
     545             : Datum
     546           5 : int42ne(PG_FUNCTION_ARGS)
     547             : {
     548           5 :     int32       arg1 = PG_GETARG_INT32(0);
     549           5 :     int16       arg2 = PG_GETARG_INT16(1);
     550             : 
     551           5 :     PG_RETURN_BOOL(arg1 != arg2);
     552             : }
     553             : 
     554             : Datum
     555         419 : int42lt(PG_FUNCTION_ARGS)
     556             : {
     557         419 :     int32       arg1 = PG_GETARG_INT32(0);
     558         419 :     int16       arg2 = PG_GETARG_INT16(1);
     559             : 
     560         419 :     PG_RETURN_BOOL(arg1 < arg2);
     561             : }
     562             : 
     563             : Datum
     564         501 : int42le(PG_FUNCTION_ARGS)
     565             : {
     566         501 :     int32       arg1 = PG_GETARG_INT32(0);
     567         501 :     int16       arg2 = PG_GETARG_INT16(1);
     568             : 
     569         501 :     PG_RETURN_BOOL(arg1 <= arg2);
     570             : }
     571             : 
     572             : Datum
     573         305 : int42gt(PG_FUNCTION_ARGS)
     574             : {
     575         305 :     int32       arg1 = PG_GETARG_INT32(0);
     576         305 :     int16       arg2 = PG_GETARG_INT16(1);
     577             : 
     578         305 :     PG_RETURN_BOOL(arg1 > arg2);
     579             : }
     580             : 
     581             : Datum
     582         343 : int42ge(PG_FUNCTION_ARGS)
     583             : {
     584         343 :     int32       arg1 = PG_GETARG_INT32(0);
     585         343 :     int16       arg2 = PG_GETARG_INT16(1);
     586             : 
     587         343 :     PG_RETURN_BOOL(arg1 >= arg2);
     588             : }
     589             : 
     590             : /*
     591             :  *      int[24]pl       - returns arg1 + arg2
     592             :  *      int[24]mi       - returns arg1 - arg2
     593             :  *      int[24]mul      - returns arg1 * arg2
     594             :  *      int[24]div      - returns arg1 / arg2
     595             :  */
     596             : 
     597             : Datum
     598         993 : int4um(PG_FUNCTION_ARGS)
     599             : {
     600         993 :     int32       arg = PG_GETARG_INT32(0);
     601             :     int32       result;
     602             : 
     603         993 :     result = -arg;
     604             :     /* overflow check (needed for INT_MIN) */
     605         993 :     if (arg != 0 && SAMESIGN(result, arg))
     606           0 :         ereport(ERROR,
     607             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     608             :                  errmsg("integer out of range")));
     609         993 :     PG_RETURN_INT32(result);
     610             : }
     611             : 
     612             : Datum
     613           0 : int4up(PG_FUNCTION_ARGS)
     614             : {
     615           0 :     int32       arg = PG_GETARG_INT32(0);
     616             : 
     617           0 :     PG_RETURN_INT32(arg);
     618             : }
     619             : 
     620             : Datum
     621      135276 : int4pl(PG_FUNCTION_ARGS)
     622             : {
     623      135276 :     int32       arg1 = PG_GETARG_INT32(0);
     624      135276 :     int32       arg2 = PG_GETARG_INT32(1);
     625             :     int32       result;
     626             : 
     627      135276 :     result = arg1 + arg2;
     628             : 
     629             :     /*
     630             :      * Overflow check.  If the inputs are of different signs then their sum
     631             :      * cannot overflow.  If the inputs are of the same sign, their sum had
     632             :      * better be that sign too.
     633             :      */
     634      135276 :     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     635           1 :         ereport(ERROR,
     636             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     637             :                  errmsg("integer out of range")));
     638      135275 :     PG_RETURN_INT32(result);
     639             : }
     640             : 
     641             : Datum
     642       12361 : int4mi(PG_FUNCTION_ARGS)
     643             : {
     644       12361 :     int32       arg1 = PG_GETARG_INT32(0);
     645       12361 :     int32       arg2 = PG_GETARG_INT32(1);
     646             :     int32       result;
     647             : 
     648       12361 :     result = arg1 - arg2;
     649             : 
     650             :     /*
     651             :      * Overflow check.  If the inputs are of the same sign then their
     652             :      * difference cannot overflow.  If they are of different signs then the
     653             :      * result should be of the same sign as the first input.
     654             :      */
     655       12361 :     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     656           1 :         ereport(ERROR,
     657             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     658             :                  errmsg("integer out of range")));
     659       12360 :     PG_RETURN_INT32(result);
     660             : }
     661             : 
     662             : Datum
     663      122536 : int4mul(PG_FUNCTION_ARGS)
     664             : {
     665      122536 :     int32       arg1 = PG_GETARG_INT32(0);
     666      122536 :     int32       arg2 = PG_GETARG_INT32(1);
     667             :     int32       result;
     668             : 
     669      122536 :     result = arg1 * arg2;
     670             : 
     671             :     /*
     672             :      * Overflow check.  We basically check to see if result / arg2 gives arg1
     673             :      * again.  There are two cases where this fails: arg2 = 0 (which cannot
     674             :      * overflow) and arg1 = INT_MIN, arg2 = -1 (where the division itself will
     675             :      * overflow and thus incorrectly match).
     676             :      *
     677             :      * Since the division is likely much more expensive than the actual
     678             :      * multiplication, we'd like to skip it where possible.  The best bang for
     679             :      * the buck seems to be to check whether both inputs are in the int16
     680             :      * range; if so, no overflow is possible.
     681             :      */
     682      122536 :     if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
     683         117 :           arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
     684         117 :         arg2 != 0 &&
     685         117 :         ((arg2 == -1 && arg1 < 0 && result < 0) ||
     686         116 :          result / arg2 != arg1))
     687           2 :         ereport(ERROR,
     688             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     689             :                  errmsg("integer out of range")));
     690      122534 :     PG_RETURN_INT32(result);
     691             : }
     692             : 
     693             : Datum
     694      177258 : int4div(PG_FUNCTION_ARGS)
     695             : {
     696      177258 :     int32       arg1 = PG_GETARG_INT32(0);
     697      177258 :     int32       arg2 = PG_GETARG_INT32(1);
     698             :     int32       result;
     699             : 
     700      177258 :     if (arg2 == 0)
     701             :     {
     702          31 :         ereport(ERROR,
     703             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     704             :                  errmsg("division by zero")));
     705             :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     706             :         PG_RETURN_NULL();
     707             :     }
     708             : 
     709             :     /*
     710             :      * INT_MIN / -1 is problematic, since the result can't be represented on a
     711             :      * two's-complement machine.  Some machines produce INT_MIN, some produce
     712             :      * zero, some throw an exception.  We can dodge the problem by recognizing
     713             :      * that division by -1 is the same as negation.
     714             :      */
     715      177227 :     if (arg2 == -1)
     716             :     {
     717           1 :         result = -arg1;
     718             :         /* overflow check (needed for INT_MIN) */
     719           1 :         if (arg1 != 0 && SAMESIGN(result, arg1))
     720           1 :             ereport(ERROR,
     721             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     722             :                      errmsg("integer out of range")));
     723           0 :         PG_RETURN_INT32(result);
     724             :     }
     725             : 
     726             :     /* No overflow is possible */
     727             : 
     728      177226 :     result = arg1 / arg2;
     729             : 
     730      177226 :     PG_RETURN_INT32(result);
     731             : }
     732             : 
     733             : Datum
     734           0 : int4inc(PG_FUNCTION_ARGS)
     735             : {
     736           0 :     int32       arg = PG_GETARG_INT32(0);
     737             :     int32       result;
     738             : 
     739           0 :     result = arg + 1;
     740             :     /* Overflow check */
     741           0 :     if (arg > 0 && result < 0)
     742           0 :         ereport(ERROR,
     743             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     744             :                  errmsg("integer out of range")));
     745             : 
     746           0 :     PG_RETURN_INT32(result);
     747             : }
     748             : 
     749             : Datum
     750           2 : int2um(PG_FUNCTION_ARGS)
     751             : {
     752           2 :     int16       arg = PG_GETARG_INT16(0);
     753             :     int16       result;
     754             : 
     755           2 :     result = -arg;
     756             :     /* overflow check (needed for SHRT_MIN) */
     757           2 :     if (arg != 0 && SAMESIGN(result, arg))
     758           0 :         ereport(ERROR,
     759             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     760             :                  errmsg("smallint out of range")));
     761           2 :     PG_RETURN_INT16(result);
     762             : }
     763             : 
     764             : Datum
     765           0 : int2up(PG_FUNCTION_ARGS)
     766             : {
     767           0 :     int16       arg = PG_GETARG_INT16(0);
     768             : 
     769           0 :     PG_RETURN_INT16(arg);
     770             : }
     771             : 
     772             : Datum
     773           9 : int2pl(PG_FUNCTION_ARGS)
     774             : {
     775           9 :     int16       arg1 = PG_GETARG_INT16(0);
     776           9 :     int16       arg2 = PG_GETARG_INT16(1);
     777             :     int16       result;
     778             : 
     779           9 :     result = arg1 + arg2;
     780             : 
     781             :     /*
     782             :      * Overflow check.  If the inputs are of different signs then their sum
     783             :      * cannot overflow.  If the inputs are of the same sign, their sum had
     784             :      * better be that sign too.
     785             :      */
     786           9 :     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     787           1 :         ereport(ERROR,
     788             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     789             :                  errmsg("smallint out of range")));
     790           8 :     PG_RETURN_INT16(result);
     791             : }
     792             : 
     793             : Datum
     794          20 : int2mi(PG_FUNCTION_ARGS)
     795             : {
     796          20 :     int16       arg1 = PG_GETARG_INT16(0);
     797          20 :     int16       arg2 = PG_GETARG_INT16(1);
     798             :     int16       result;
     799             : 
     800          20 :     result = arg1 - arg2;
     801             : 
     802             :     /*
     803             :      * Overflow check.  If the inputs are of the same sign then their
     804             :      * difference cannot overflow.  If they are of different signs then the
     805             :      * result should be of the same sign as the first input.
     806             :      */
     807          20 :     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     808           1 :         ereport(ERROR,
     809             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     810             :                  errmsg("smallint out of range")));
     811          19 :     PG_RETURN_INT16(result);
     812             : }
     813             : 
     814             : Datum
     815           9 : int2mul(PG_FUNCTION_ARGS)
     816             : {
     817           9 :     int16       arg1 = PG_GETARG_INT16(0);
     818           9 :     int16       arg2 = PG_GETARG_INT16(1);
     819             :     int32       result32;
     820             : 
     821             :     /*
     822             :      * The most practical way to detect overflow is to do the arithmetic in
     823             :      * int32 (so that the result can't overflow) and then do a range check.
     824             :      */
     825           9 :     result32 = (int32) arg1 * (int32) arg2;
     826             : 
     827           9 :     if (result32 < SHRT_MIN || result32 > SHRT_MAX)
     828           2 :         ereport(ERROR,
     829             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     830             :                  errmsg("smallint out of range")));
     831             : 
     832           7 :     PG_RETURN_INT16((int16) result32);
     833             : }
     834             : 
     835             : Datum
     836           7 : int2div(PG_FUNCTION_ARGS)
     837             : {
     838           7 :     int16       arg1 = PG_GETARG_INT16(0);
     839           7 :     int16       arg2 = PG_GETARG_INT16(1);
     840             :     int16       result;
     841             : 
     842           7 :     if (arg2 == 0)
     843             :     {
     844           0 :         ereport(ERROR,
     845             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     846             :                  errmsg("division by zero")));
     847             :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     848             :         PG_RETURN_NULL();
     849             :     }
     850             : 
     851             :     /*
     852             :      * SHRT_MIN / -1 is problematic, since the result can't be represented on
     853             :      * a two's-complement machine.  Some machines produce SHRT_MIN, some
     854             :      * produce zero, some throw an exception.  We can dodge the problem by
     855             :      * recognizing that division by -1 is the same as negation.
     856             :      */
     857           7 :     if (arg2 == -1)
     858             :     {
     859           1 :         result = -arg1;
     860             :         /* overflow check (needed for SHRT_MIN) */
     861           1 :         if (arg1 != 0 && SAMESIGN(result, arg1))
     862           1 :             ereport(ERROR,
     863             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     864             :                      errmsg("smallint out of range")));
     865           0 :         PG_RETURN_INT16(result);
     866             :     }
     867             : 
     868             :     /* No overflow is possible */
     869             : 
     870           6 :     result = arg1 / arg2;
     871             : 
     872           6 :     PG_RETURN_INT16(result);
     873             : }
     874             : 
     875             : Datum
     876         468 : int24pl(PG_FUNCTION_ARGS)
     877             : {
     878         468 :     int16       arg1 = PG_GETARG_INT16(0);
     879         468 :     int32       arg2 = PG_GETARG_INT32(1);
     880             :     int32       result;
     881             : 
     882         468 :     result = arg1 + arg2;
     883             : 
     884             :     /*
     885             :      * Overflow check.  If the inputs are of different signs then their sum
     886             :      * cannot overflow.  If the inputs are of the same sign, their sum had
     887             :      * better be that sign too.
     888             :      */
     889         468 :     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     890           0 :         ereport(ERROR,
     891             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     892             :                  errmsg("integer out of range")));
     893         468 :     PG_RETURN_INT32(result);
     894             : }
     895             : 
     896             : Datum
     897        3560 : int24mi(PG_FUNCTION_ARGS)
     898             : {
     899        3560 :     int16       arg1 = PG_GETARG_INT16(0);
     900        3560 :     int32       arg2 = PG_GETARG_INT32(1);
     901             :     int32       result;
     902             : 
     903        3560 :     result = arg1 - arg2;
     904             : 
     905             :     /*
     906             :      * Overflow check.  If the inputs are of the same sign then their
     907             :      * difference cannot overflow.  If they are of different signs then the
     908             :      * result should be of the same sign as the first input.
     909             :      */
     910        3560 :     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     911           0 :         ereport(ERROR,
     912             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     913             :                  errmsg("integer out of range")));
     914        3560 :     PG_RETURN_INT32(result);
     915             : }
     916             : 
     917             : Datum
     918           6 : int24mul(PG_FUNCTION_ARGS)
     919             : {
     920           6 :     int16       arg1 = PG_GETARG_INT16(0);
     921           6 :     int32       arg2 = PG_GETARG_INT32(1);
     922             :     int32       result;
     923             : 
     924           6 :     result = arg1 * arg2;
     925             : 
     926             :     /*
     927             :      * Overflow check.  We basically check to see if result / arg2 gives arg1
     928             :      * again.  There is one case where this fails: arg2 = 0 (which cannot
     929             :      * overflow).
     930             :      *
     931             :      * Since the division is likely much more expensive than the actual
     932             :      * multiplication, we'd like to skip it where possible.  The best bang for
     933             :      * the buck seems to be to check whether both inputs are in the int16
     934             :      * range; if so, no overflow is possible.
     935             :      */
     936           6 :     if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
     937           0 :         result / arg2 != arg1)
     938           0 :         ereport(ERROR,
     939             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     940             :                  errmsg("integer out of range")));
     941           6 :     PG_RETURN_INT32(result);
     942             : }
     943             : 
     944             : Datum
     945           7 : int24div(PG_FUNCTION_ARGS)
     946             : {
     947           7 :     int16       arg1 = PG_GETARG_INT16(0);
     948           7 :     int32       arg2 = PG_GETARG_INT32(1);
     949             : 
     950           7 :     if (arg2 == 0)
     951             :     {
     952           1 :         ereport(ERROR,
     953             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
     954             :                  errmsg("division by zero")));
     955             :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
     956             :         PG_RETURN_NULL();
     957             :     }
     958             : 
     959             :     /* No overflow is possible */
     960           6 :     PG_RETURN_INT32((int32) arg1 / arg2);
     961             : }
     962             : 
     963             : Datum
     964           8 : int42pl(PG_FUNCTION_ARGS)
     965             : {
     966           8 :     int32       arg1 = PG_GETARG_INT32(0);
     967           8 :     int16       arg2 = PG_GETARG_INT16(1);
     968             :     int32       result;
     969             : 
     970           8 :     result = arg1 + arg2;
     971             : 
     972             :     /*
     973             :      * Overflow check.  If the inputs are of different signs then their sum
     974             :      * cannot overflow.  If the inputs are of the same sign, their sum had
     975             :      * better be that sign too.
     976             :      */
     977           8 :     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     978           1 :         ereport(ERROR,
     979             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     980             :                  errmsg("integer out of range")));
     981           7 :     PG_RETURN_INT32(result);
     982             : }
     983             : 
     984             : Datum
     985           9 : int42mi(PG_FUNCTION_ARGS)
     986             : {
     987           9 :     int32       arg1 = PG_GETARG_INT32(0);
     988           9 :     int16       arg2 = PG_GETARG_INT16(1);
     989             :     int32       result;
     990             : 
     991           9 :     result = arg1 - arg2;
     992             : 
     993             :     /*
     994             :      * Overflow check.  If the inputs are of the same sign then their
     995             :      * difference cannot overflow.  If they are of different signs then the
     996             :      * result should be of the same sign as the first input.
     997             :      */
     998           9 :     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
     999           1 :         ereport(ERROR,
    1000             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1001             :                  errmsg("integer out of range")));
    1002           8 :     PG_RETURN_INT32(result);
    1003             : }
    1004             : 
    1005             : Datum
    1006           9 : int42mul(PG_FUNCTION_ARGS)
    1007             : {
    1008           9 :     int32       arg1 = PG_GETARG_INT32(0);
    1009           9 :     int16       arg2 = PG_GETARG_INT16(1);
    1010             :     int32       result;
    1011             : 
    1012           9 :     result = arg1 * arg2;
    1013             : 
    1014             :     /*
    1015             :      * Overflow check.  We basically check to see if result / arg1 gives arg2
    1016             :      * again.  There is one case where this fails: arg1 = 0 (which cannot
    1017             :      * overflow).
    1018             :      *
    1019             :      * Since the division is likely much more expensive than the actual
    1020             :      * multiplication, we'd like to skip it where possible.  The best bang for
    1021             :      * the buck seems to be to check whether both inputs are in the int16
    1022             :      * range; if so, no overflow is possible.
    1023             :      */
    1024          15 :     if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
    1025           6 :         result / arg1 != arg2)
    1026           2 :         ereport(ERROR,
    1027             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1028             :                  errmsg("integer out of range")));
    1029           7 :     PG_RETURN_INT32(result);
    1030             : }
    1031             : 
    1032             : Datum
    1033           8 : int42div(PG_FUNCTION_ARGS)
    1034             : {
    1035           8 :     int32       arg1 = PG_GETARG_INT32(0);
    1036           8 :     int16       arg2 = PG_GETARG_INT16(1);
    1037             :     int32       result;
    1038             : 
    1039           8 :     if (arg2 == 0)
    1040             :     {
    1041           1 :         ereport(ERROR,
    1042             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1043             :                  errmsg("division by zero")));
    1044             :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1045             :         PG_RETURN_NULL();
    1046             :     }
    1047             : 
    1048             :     /*
    1049             :      * INT_MIN / -1 is problematic, since the result can't be represented on a
    1050             :      * two's-complement machine.  Some machines produce INT_MIN, some produce
    1051             :      * zero, some throw an exception.  We can dodge the problem by recognizing
    1052             :      * that division by -1 is the same as negation.
    1053             :      */
    1054           7 :     if (arg2 == -1)
    1055             :     {
    1056           1 :         result = -arg1;
    1057             :         /* overflow check (needed for INT_MIN) */
    1058           1 :         if (arg1 != 0 && SAMESIGN(result, arg1))
    1059           1 :             ereport(ERROR,
    1060             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1061             :                      errmsg("integer out of range")));
    1062           0 :         PG_RETURN_INT32(result);
    1063             :     }
    1064             : 
    1065             :     /* No overflow is possible */
    1066             : 
    1067           6 :     result = arg1 / arg2;
    1068             : 
    1069           6 :     PG_RETURN_INT32(result);
    1070             : }
    1071             : 
    1072             : Datum
    1073      283884 : int4mod(PG_FUNCTION_ARGS)
    1074             : {
    1075      283884 :     int32       arg1 = PG_GETARG_INT32(0);
    1076      283884 :     int32       arg2 = PG_GETARG_INT32(1);
    1077             : 
    1078      283884 :     if (arg2 == 0)
    1079             :     {
    1080           0 :         ereport(ERROR,
    1081             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1082             :                  errmsg("division by zero")));
    1083             :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1084             :         PG_RETURN_NULL();
    1085             :     }
    1086             : 
    1087             :     /*
    1088             :      * Some machines throw a floating-point exception for INT_MIN % -1, which
    1089             :      * is a bit silly since the correct answer is perfectly well-defined,
    1090             :      * namely zero.
    1091             :      */
    1092      283884 :     if (arg2 == -1)
    1093           2 :         PG_RETURN_INT32(0);
    1094             : 
    1095             :     /* No overflow is possible */
    1096             : 
    1097      283882 :     PG_RETURN_INT32(arg1 % arg2);
    1098             : }
    1099             : 
    1100             : Datum
    1101           6 : int2mod(PG_FUNCTION_ARGS)
    1102             : {
    1103           6 :     int16       arg1 = PG_GETARG_INT16(0);
    1104           6 :     int16       arg2 = PG_GETARG_INT16(1);
    1105             : 
    1106           6 :     if (arg2 == 0)
    1107             :     {
    1108           0 :         ereport(ERROR,
    1109             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    1110             :                  errmsg("division by zero")));
    1111             :         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
    1112             :         PG_RETURN_NULL();
    1113             :     }
    1114             : 
    1115             :     /*
    1116             :      * Some machines throw a floating-point exception for INT_MIN % -1, which
    1117             :      * is a bit silly since the correct answer is perfectly well-defined,
    1118             :      * namely zero.  (It's not clear this ever happens when dealing with
    1119             :      * int16, but we might as well have the test for safety.)
    1120             :      */
    1121           6 :     if (arg2 == -1)
    1122           1 :         PG_RETURN_INT16(0);
    1123             : 
    1124             :     /* No overflow is possible */
    1125             : 
    1126           5 :     PG_RETURN_INT16(arg1 % arg2);
    1127             : }
    1128             : 
    1129             : 
    1130             : /* int[24]abs()
    1131             :  * Absolute value
    1132             :  */
    1133             : Datum
    1134       20042 : int4abs(PG_FUNCTION_ARGS)
    1135             : {
    1136       20042 :     int32       arg1 = PG_GETARG_INT32(0);
    1137             :     int32       result;
    1138             : 
    1139       20042 :     result = (arg1 < 0) ? -arg1 : arg1;
    1140             :     /* overflow check (needed for INT_MIN) */
    1141       20042 :     if (result < 0)
    1142           0 :         ereport(ERROR,
    1143             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1144             :                  errmsg("integer out of range")));
    1145       20042 :     PG_RETURN_INT32(result);
    1146             : }
    1147             : 
    1148             : Datum
    1149           5 : int2abs(PG_FUNCTION_ARGS)
    1150             : {
    1151           5 :     int16       arg1 = PG_GETARG_INT16(0);
    1152             :     int16       result;
    1153             : 
    1154           5 :     result = (arg1 < 0) ? -arg1 : arg1;
    1155             :     /* overflow check (needed for SHRT_MIN) */
    1156           5 :     if (result < 0)
    1157           0 :         ereport(ERROR,
    1158             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1159             :                  errmsg("smallint out of range")));
    1160           5 :     PG_RETURN_INT16(result);
    1161             : }
    1162             : 
    1163             : Datum
    1164          67 : int2larger(PG_FUNCTION_ARGS)
    1165             : {
    1166          67 :     int16       arg1 = PG_GETARG_INT16(0);
    1167          67 :     int16       arg2 = PG_GETARG_INT16(1);
    1168             : 
    1169          67 :     PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2);
    1170             : }
    1171             : 
    1172             : Datum
    1173           0 : int2smaller(PG_FUNCTION_ARGS)
    1174             : {
    1175           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1176           0 :     int16       arg2 = PG_GETARG_INT16(1);
    1177             : 
    1178           0 :     PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2);
    1179             : }
    1180             : 
    1181             : Datum
    1182       12564 : int4larger(PG_FUNCTION_ARGS)
    1183             : {
    1184       12564 :     int32       arg1 = PG_GETARG_INT32(0);
    1185       12564 :     int32       arg2 = PG_GETARG_INT32(1);
    1186             : 
    1187       12564 :     PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2);
    1188             : }
    1189             : 
    1190             : Datum
    1191       10106 : int4smaller(PG_FUNCTION_ARGS)
    1192             : {
    1193       10106 :     int32       arg1 = PG_GETARG_INT32(0);
    1194       10106 :     int32       arg2 = PG_GETARG_INT32(1);
    1195             : 
    1196       10106 :     PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
    1197             : }
    1198             : 
    1199             : /*
    1200             :  * Bit-pushing operators
    1201             :  *
    1202             :  *      int[24]and      - returns arg1 & arg2
    1203             :  *      int[24]or       - returns arg1 | arg2
    1204             :  *      int[24]xor      - returns arg1 # arg2
    1205             :  *      int[24]not      - returns ~arg1
    1206             :  *      int[24]shl      - returns arg1 << arg2
    1207             :  *      int[24]shr      - returns arg1 >> arg2
    1208             :  */
    1209             : 
    1210             : Datum
    1211         168 : int4and(PG_FUNCTION_ARGS)
    1212             : {
    1213         168 :     int32       arg1 = PG_GETARG_INT32(0);
    1214         168 :     int32       arg2 = PG_GETARG_INT32(1);
    1215             : 
    1216         168 :     PG_RETURN_INT32(arg1 & arg2);
    1217             : }
    1218             : 
    1219             : Datum
    1220           3 : int4or(PG_FUNCTION_ARGS)
    1221             : {
    1222           3 :     int32       arg1 = PG_GETARG_INT32(0);
    1223           3 :     int32       arg2 = PG_GETARG_INT32(1);
    1224             : 
    1225           3 :     PG_RETURN_INT32(arg1 | arg2);
    1226             : }
    1227             : 
    1228             : Datum
    1229           0 : int4xor(PG_FUNCTION_ARGS)
    1230             : {
    1231           0 :     int32       arg1 = PG_GETARG_INT32(0);
    1232           0 :     int32       arg2 = PG_GETARG_INT32(1);
    1233             : 
    1234           0 :     PG_RETURN_INT32(arg1 ^ arg2);
    1235             : }
    1236             : 
    1237             : Datum
    1238           2 : int4shl(PG_FUNCTION_ARGS)
    1239             : {
    1240           2 :     int32       arg1 = PG_GETARG_INT32(0);
    1241           2 :     int32       arg2 = PG_GETARG_INT32(1);
    1242             : 
    1243           2 :     PG_RETURN_INT32(arg1 << arg2);
    1244             : }
    1245             : 
    1246             : Datum
    1247           0 : int4shr(PG_FUNCTION_ARGS)
    1248             : {
    1249           0 :     int32       arg1 = PG_GETARG_INT32(0);
    1250           0 :     int32       arg2 = PG_GETARG_INT32(1);
    1251             : 
    1252           0 :     PG_RETURN_INT32(arg1 >> arg2);
    1253             : }
    1254             : 
    1255             : Datum
    1256           0 : int4not(PG_FUNCTION_ARGS)
    1257             : {
    1258           0 :     int32       arg1 = PG_GETARG_INT32(0);
    1259             : 
    1260           0 :     PG_RETURN_INT32(~arg1);
    1261             : }
    1262             : 
    1263             : Datum
    1264           4 : int2and(PG_FUNCTION_ARGS)
    1265             : {
    1266           4 :     int16       arg1 = PG_GETARG_INT16(0);
    1267           4 :     int16       arg2 = PG_GETARG_INT16(1);
    1268             : 
    1269           4 :     PG_RETURN_INT16(arg1 & arg2);
    1270             : }
    1271             : 
    1272             : Datum
    1273           4 : int2or(PG_FUNCTION_ARGS)
    1274             : {
    1275           4 :     int16       arg1 = PG_GETARG_INT16(0);
    1276           4 :     int16       arg2 = PG_GETARG_INT16(1);
    1277             : 
    1278           4 :     PG_RETURN_INT16(arg1 | arg2);
    1279             : }
    1280             : 
    1281             : Datum
    1282           0 : int2xor(PG_FUNCTION_ARGS)
    1283             : {
    1284           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1285           0 :     int16       arg2 = PG_GETARG_INT16(1);
    1286             : 
    1287           0 :     PG_RETURN_INT16(arg1 ^ arg2);
    1288             : }
    1289             : 
    1290             : Datum
    1291           0 : int2not(PG_FUNCTION_ARGS)
    1292             : {
    1293           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1294             : 
    1295           0 :     PG_RETURN_INT16(~arg1);
    1296             : }
    1297             : 
    1298             : 
    1299             : Datum
    1300           2 : int2shl(PG_FUNCTION_ARGS)
    1301             : {
    1302           2 :     int16       arg1 = PG_GETARG_INT16(0);
    1303           2 :     int32       arg2 = PG_GETARG_INT32(1);
    1304             : 
    1305           2 :     PG_RETURN_INT16(arg1 << arg2);
    1306             : }
    1307             : 
    1308             : Datum
    1309           0 : int2shr(PG_FUNCTION_ARGS)
    1310             : {
    1311           0 :     int16       arg1 = PG_GETARG_INT16(0);
    1312           0 :     int32       arg2 = PG_GETARG_INT32(1);
    1313             : 
    1314           0 :     PG_RETURN_INT16(arg1 >> arg2);
    1315             : }
    1316             : 
    1317             : /*
    1318             :  * non-persistent numeric series generator
    1319             :  */
    1320             : Datum
    1321      667913 : generate_series_int4(PG_FUNCTION_ARGS)
    1322             : {
    1323      667913 :     return generate_series_step_int4(fcinfo);
    1324             : }
    1325             : 
    1326             : Datum
    1327      668034 : generate_series_step_int4(PG_FUNCTION_ARGS)
    1328             : {
    1329             :     FuncCallContext *funcctx;
    1330             :     generate_series_fctx *fctx;
    1331             :     int32       result;
    1332             :     MemoryContext oldcontext;
    1333             : 
    1334             :     /* stuff done only on the first call of the function */
    1335      668034 :     if (SRF_IS_FIRSTCALL())
    1336             :     {
    1337       10654 :         int32       start = PG_GETARG_INT32(0);
    1338       10654 :         int32       finish = PG_GETARG_INT32(1);
    1339       10654 :         int32       step = 1;
    1340             : 
    1341             :         /* see if we were given an explicit step size */
    1342       10654 :         if (PG_NARGS() == 3)
    1343          26 :             step = PG_GETARG_INT32(2);
    1344       10654 :         if (step == 0)
    1345           0 :             ereport(ERROR,
    1346             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1347             :                      errmsg("step size cannot equal zero")));
    1348             : 
    1349             :         /* create a function context for cross-call persistence */
    1350       10654 :         funcctx = SRF_FIRSTCALL_INIT();
    1351             : 
    1352             :         /*
    1353             :          * switch to memory context appropriate for multiple function calls
    1354             :          */
    1355       10654 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1356             : 
    1357             :         /* allocate memory for user context */
    1358       10654 :         fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
    1359             : 
    1360             :         /*
    1361             :          * Use fctx to keep state from call to call. Seed current with the
    1362             :          * original start value
    1363             :          */
    1364       10654 :         fctx->current = start;
    1365       10654 :         fctx->finish = finish;
    1366       10654 :         fctx->step = step;
    1367             : 
    1368       10654 :         funcctx->user_fctx = fctx;
    1369       10654 :         MemoryContextSwitchTo(oldcontext);
    1370             :     }
    1371             : 
    1372             :     /* stuff done on every call of the function */
    1373      668034 :     funcctx = SRF_PERCALL_SETUP();
    1374             : 
    1375             :     /*
    1376             :      * get the saved state and use current as the result for this iteration
    1377             :      */
    1378      668034 :     fctx = funcctx->user_fctx;
    1379      668034 :     result = fctx->current;
    1380             : 
    1381      678680 :     if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
    1382       10646 :         (fctx->step < 0 && fctx->current >= fctx->finish))
    1383             :     {
    1384             :         /* increment current in preparation for next iteration */
    1385      657388 :         fctx->current += fctx->step;
    1386             : 
    1387             :         /* if next-value computation overflows, this is the final result */
    1388      657388 :         if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
    1389           0 :             fctx->step = 0;
    1390             : 
    1391             :         /* do when there is more left to send */
    1392      657388 :         SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
    1393             :     }
    1394             :     else
    1395             :         /* do when there is no more left */
    1396       10646 :         SRF_RETURN_DONE(funcctx);
    1397             : }

Generated by: LCOV version 1.11