LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 94.0 % 3861 3628 20 65 142 6 74 2224 267 1063 150 2441 3 59
Current Date: 2023-04-08 15:15:32 Functions: 99.5 % 206 205 1 198 7 1 203 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * numeric.c
       4                 :  *    An exact numeric data type for the Postgres database system
       5                 :  *
       6                 :  * Original coding 1998, Jan Wieck.  Heavily revised 2003, Tom Lane.
       7                 :  *
       8                 :  * Many of the algorithmic ideas are borrowed from David M. Smith's "FM"
       9                 :  * multiple-precision math library, most recently published as Algorithm
      10                 :  * 786: Multiple-Precision Complex Arithmetic and Functions, ACM
      11                 :  * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998,
      12                 :  * pages 359-367.
      13                 :  *
      14                 :  * Copyright (c) 1998-2023, PostgreSQL Global Development Group
      15                 :  *
      16                 :  * IDENTIFICATION
      17                 :  *    src/backend/utils/adt/numeric.c
      18                 :  *
      19                 :  *-------------------------------------------------------------------------
      20                 :  */
      21                 : 
      22                 : #include "postgres.h"
      23                 : 
      24                 : #include <ctype.h>
      25                 : #include <float.h>
      26                 : #include <limits.h>
      27                 : #include <math.h>
      28                 : 
      29                 : #include "catalog/pg_type.h"
      30                 : #include "common/hashfn.h"
      31                 : #include "common/int.h"
      32                 : #include "funcapi.h"
      33                 : #include "lib/hyperloglog.h"
      34                 : #include "libpq/pqformat.h"
      35                 : #include "miscadmin.h"
      36                 : #include "nodes/nodeFuncs.h"
      37                 : #include "nodes/supportnodes.h"
      38                 : #include "utils/array.h"
      39                 : #include "utils/builtins.h"
      40                 : #include "utils/float.h"
      41                 : #include "utils/guc.h"
      42                 : #include "utils/numeric.h"
      43                 : #include "utils/pg_lsn.h"
      44                 : #include "utils/sortsupport.h"
      45                 : 
      46                 : /* ----------
      47                 :  * Uncomment the following to enable compilation of dump_numeric()
      48                 :  * and dump_var() and to get a dump of any result produced by make_result().
      49                 :  * ----------
      50                 : #define NUMERIC_DEBUG
      51                 :  */
      52                 : 
      53                 : 
      54                 : /* ----------
      55                 :  * Local data types
      56                 :  *
      57                 :  * Numeric values are represented in a base-NBASE floating point format.
      58                 :  * Each "digit" ranges from 0 to NBASE-1.  The type NumericDigit is signed
      59                 :  * and wide enough to store a digit.  We assume that NBASE*NBASE can fit in
      60                 :  * an int.  Although the purely calculational routines could handle any even
      61                 :  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
      62                 :  * in NBASE a power of ten, so that I/O conversions and decimal rounding
      63                 :  * are easy.  Also, it's actually more efficient if NBASE is rather less than
      64                 :  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var_fast to
      65                 :  * postpone processing carries.
      66                 :  *
      67                 :  * Values of NBASE other than 10000 are considered of historical interest only
      68                 :  * and are no longer supported in any sense; no mechanism exists for the client
      69                 :  * to discover the base, so every client supporting binary mode expects the
      70                 :  * base-10000 format.  If you plan to change this, also note the numeric
      71                 :  * abbreviation code, which assumes NBASE=10000.
      72                 :  * ----------
      73                 :  */
      74                 : 
      75                 : #if 0
      76                 : #define NBASE       10
      77                 : #define HALF_NBASE  5
      78                 : #define DEC_DIGITS  1           /* decimal digits per NBASE digit */
      79                 : #define MUL_GUARD_DIGITS    4   /* these are measured in NBASE digits */
      80                 : #define DIV_GUARD_DIGITS    8
      81                 : 
      82                 : typedef signed char NumericDigit;
      83                 : #endif
      84                 : 
      85                 : #if 0
      86                 : #define NBASE       100
      87                 : #define HALF_NBASE  50
      88                 : #define DEC_DIGITS  2           /* decimal digits per NBASE digit */
      89                 : #define MUL_GUARD_DIGITS    3   /* these are measured in NBASE digits */
      90                 : #define DIV_GUARD_DIGITS    6
      91                 : 
      92                 : typedef signed char NumericDigit;
      93                 : #endif
      94                 : 
      95                 : #if 1
      96                 : #define NBASE       10000
      97                 : #define HALF_NBASE  5000
      98                 : #define DEC_DIGITS  4           /* decimal digits per NBASE digit */
      99                 : #define MUL_GUARD_DIGITS    2   /* these are measured in NBASE digits */
     100                 : #define DIV_GUARD_DIGITS    4
     101                 : 
     102                 : typedef int16 NumericDigit;
     103                 : #endif
     104                 : 
     105                 : /*
     106                 :  * The Numeric type as stored on disk.
     107                 :  *
     108                 :  * If the high bits of the first word of a NumericChoice (n_header, or
     109                 :  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
     110                 :  * numeric follows the NumericShort format; if they are NUMERIC_POS or
     111                 :  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
     112                 :  * the value is a NaN or Infinity.  We currently always store SPECIAL values
     113                 :  * using just two bytes (i.e. only n_header), but previous releases used only
     114                 :  * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
     115                 :  * on disk if a database has been migrated using pg_upgrade.  In either case,
     116                 :  * the low-order bits of a special value's header are reserved and currently
     117                 :  * should always be set to zero.
     118                 :  *
     119                 :  * In the NumericShort format, the remaining 14 bits of the header word
     120                 :  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
     121                 :  * negative), 6 for dynamic scale, and 7 for weight.  In practice, most
     122                 :  * commonly-encountered values can be represented this way.
     123                 :  *
     124                 :  * In the NumericLong format, the remaining 14 bits of the header word
     125                 :  * (n_long.n_sign_dscale) represent the display scale; and the weight is
     126                 :  * stored separately in n_weight.
     127                 :  *
     128                 :  * NOTE: by convention, values in the packed form have been stripped of
     129                 :  * all leading and trailing zero digits (where a "digit" is of base NBASE).
     130                 :  * In particular, if the value is zero, there will be no digits at all!
     131                 :  * The weight is arbitrary in that case, but we normally set it to zero.
     132                 :  */
     133                 : 
     134                 : struct NumericShort
     135                 : {
     136                 :     uint16      n_header;       /* Sign + display scale + weight */
     137                 :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     138                 : };
     139                 : 
     140                 : struct NumericLong
     141                 : {
     142                 :     uint16      n_sign_dscale;  /* Sign + display scale */
     143                 :     int16       n_weight;       /* Weight of 1st digit  */
     144                 :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     145                 : };
     146                 : 
     147                 : union NumericChoice
     148                 : {
     149                 :     uint16      n_header;       /* Header word */
     150                 :     struct NumericLong n_long;  /* Long form (4-byte header) */
     151                 :     struct NumericShort n_short;    /* Short form (2-byte header) */
     152                 : };
     153                 : 
     154                 : struct NumericData
     155                 : {
     156                 :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     157                 :     union NumericChoice choice; /* choice of format */
     158                 : };
     159                 : 
     160                 : 
     161                 : /*
     162                 :  * Interpretation of high bits.
     163                 :  */
     164                 : 
     165                 : #define NUMERIC_SIGN_MASK   0xC000
     166                 : #define NUMERIC_POS         0x0000
     167                 : #define NUMERIC_NEG         0x4000
     168                 : #define NUMERIC_SHORT       0x8000
     169                 : #define NUMERIC_SPECIAL     0xC000
     170                 : 
     171                 : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
     172                 : #define NUMERIC_IS_SHORT(n)     (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
     173                 : #define NUMERIC_IS_SPECIAL(n)   (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
     174                 : 
     175                 : #define NUMERIC_HDRSZ   (VARHDRSZ + sizeof(uint16) + sizeof(int16))
     176                 : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
     177                 : 
     178                 : /*
     179                 :  * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
     180                 :  * header; otherwise, we want the long one.  Instead of testing against each
     181                 :  * value, we can just look at the high bit, for a slight efficiency gain.
     182                 :  */
     183                 : #define NUMERIC_HEADER_IS_SHORT(n)  (((n)->choice.n_header & 0x8000) != 0)
     184                 : #define NUMERIC_HEADER_SIZE(n) \
     185                 :     (VARHDRSZ + sizeof(uint16) + \
     186                 :      (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
     187                 : 
     188                 : /*
     189                 :  * Definitions for special values (NaN, positive infinity, negative infinity).
     190                 :  *
     191                 :  * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
     192                 :  * infinity, 11 for negative infinity.  (This makes the sign bit match where
     193                 :  * it is in a short-format value, though we make no use of that at present.)
     194                 :  * We could mask off the remaining bits before testing the active bits, but
     195                 :  * currently those bits must be zeroes, so masking would just add cycles.
     196                 :  */
     197                 : #define NUMERIC_EXT_SIGN_MASK   0xF000  /* high bits plus NaN/Inf flag bits */
     198                 : #define NUMERIC_NAN             0xC000
     199                 : #define NUMERIC_PINF            0xD000
     200                 : #define NUMERIC_NINF            0xF000
     201                 : #define NUMERIC_INF_SIGN_MASK   0x2000
     202                 : 
     203                 : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
     204                 : #define NUMERIC_IS_NAN(n)       ((n)->choice.n_header == NUMERIC_NAN)
     205                 : #define NUMERIC_IS_PINF(n)      ((n)->choice.n_header == NUMERIC_PINF)
     206                 : #define NUMERIC_IS_NINF(n)      ((n)->choice.n_header == NUMERIC_NINF)
     207                 : #define NUMERIC_IS_INF(n) \
     208                 :     (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
     209                 : 
     210                 : /*
     211                 :  * Short format definitions.
     212                 :  */
     213                 : 
     214                 : #define NUMERIC_SHORT_SIGN_MASK         0x2000
     215                 : #define NUMERIC_SHORT_DSCALE_MASK       0x1F80
     216                 : #define NUMERIC_SHORT_DSCALE_SHIFT      7
     217                 : #define NUMERIC_SHORT_DSCALE_MAX        \
     218                 :     (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
     219                 : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK  0x0040
     220                 : #define NUMERIC_SHORT_WEIGHT_MASK       0x003F
     221                 : #define NUMERIC_SHORT_WEIGHT_MAX        NUMERIC_SHORT_WEIGHT_MASK
     222                 : #define NUMERIC_SHORT_WEIGHT_MIN        (-(NUMERIC_SHORT_WEIGHT_MASK+1))
     223                 : 
     224                 : /*
     225                 :  * Extract sign, display scale, weight.  These macros extract field values
     226                 :  * suitable for the NumericVar format from the Numeric (on-disk) format.
     227                 :  *
     228                 :  * Note that we don't trouble to ensure that dscale and weight read as zero
     229                 :  * for an infinity; however, that doesn't matter since we never convert
     230                 :  * "special" numerics to NumericVar form.  Only the constants defined below
     231                 :  * (const_nan, etc) ever represent a non-finite value as a NumericVar.
     232                 :  */
     233                 : 
     234                 : #define NUMERIC_DSCALE_MASK         0x3FFF
     235                 : #define NUMERIC_DSCALE_MAX          NUMERIC_DSCALE_MASK
     236                 : 
     237                 : #define NUMERIC_SIGN(n) \
     238                 :     (NUMERIC_IS_SHORT(n) ? \
     239                 :         (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
     240                 :          NUMERIC_NEG : NUMERIC_POS) : \
     241                 :         (NUMERIC_IS_SPECIAL(n) ? \
     242                 :          NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
     243                 : #define NUMERIC_DSCALE(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     244                 :     ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
     245                 :         >> NUMERIC_SHORT_DSCALE_SHIFT \
     246                 :     : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
     247                 : #define NUMERIC_WEIGHT(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     248                 :     (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
     249                 :         ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
     250                 :      | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
     251                 :     : ((n)->choice.n_long.n_weight))
     252                 : 
     253                 : /* ----------
     254                 :  * NumericVar is the format we use for arithmetic.  The digit-array part
     255                 :  * is the same as the NumericData storage format, but the header is more
     256                 :  * complex.
     257                 :  *
     258                 :  * The value represented by a NumericVar is determined by the sign, weight,
     259                 :  * ndigits, and digits[] array.  If it is a "special" value (NaN or Inf)
     260                 :  * then only the sign field matters; ndigits should be zero, and the weight
     261                 :  * and dscale fields are ignored.
     262                 :  *
     263                 :  * Note: the first digit of a NumericVar's value is assumed to be multiplied
     264                 :  * by NBASE ** weight.  Another way to say it is that there are weight+1
     265                 :  * digits before the decimal point.  It is possible to have weight < 0.
     266                 :  *
     267                 :  * buf points at the physical start of the palloc'd digit buffer for the
     268                 :  * NumericVar.  digits points at the first digit in actual use (the one
     269                 :  * with the specified weight).  We normally leave an unused digit or two
     270                 :  * (preset to zeroes) between buf and digits, so that there is room to store
     271                 :  * a carry out of the top digit without reallocating space.  We just need to
     272                 :  * decrement digits (and increment weight) to make room for the carry digit.
     273                 :  * (There is no such extra space in a numeric value stored in the database,
     274                 :  * only in a NumericVar in memory.)
     275                 :  *
     276                 :  * If buf is NULL then the digit buffer isn't actually palloc'd and should
     277                 :  * not be freed --- see the constants below for an example.
     278                 :  *
     279                 :  * dscale, or display scale, is the nominal precision expressed as number
     280                 :  * of digits after the decimal point (it must always be >= 0 at present).
     281                 :  * dscale may be more than the number of physically stored fractional digits,
     282                 :  * implying that we have suppressed storage of significant trailing zeroes.
     283                 :  * It should never be less than the number of stored digits, since that would
     284                 :  * imply hiding digits that are present.  NOTE that dscale is always expressed
     285                 :  * in *decimal* digits, and so it may correspond to a fractional number of
     286                 :  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
     287                 :  *
     288                 :  * rscale, or result scale, is the target precision for a computation.
     289                 :  * Like dscale it is expressed as number of *decimal* digits after the decimal
     290                 :  * point, and is always >= 0 at present.
     291                 :  * Note that rscale is not stored in variables --- it's figured on-the-fly
     292                 :  * from the dscales of the inputs.
     293                 :  *
     294                 :  * While we consistently use "weight" to refer to the base-NBASE weight of
     295                 :  * a numeric value, it is convenient in some scale-related calculations to
     296                 :  * make use of the base-10 weight (ie, the approximate log10 of the value).
     297                 :  * To avoid confusion, such a decimal-units weight is called a "dweight".
     298                 :  *
     299                 :  * NB: All the variable-level functions are written in a style that makes it
     300                 :  * possible to give one and the same variable as argument and destination.
     301                 :  * This is feasible because the digit buffer is separate from the variable.
     302                 :  * ----------
     303                 :  */
     304                 : typedef struct NumericVar
     305                 : {
     306                 :     int         ndigits;        /* # of digits in digits[] - can be 0! */
     307                 :     int         weight;         /* weight of first digit */
     308                 :     int         sign;           /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
     309                 :     int         dscale;         /* display scale */
     310                 :     NumericDigit *buf;          /* start of palloc'd space for digits[] */
     311                 :     NumericDigit *digits;       /* base-NBASE digits */
     312                 : } NumericVar;
     313                 : 
     314                 : 
     315                 : /* ----------
     316                 :  * Data for generate_series
     317                 :  * ----------
     318                 :  */
     319                 : typedef struct
     320                 : {
     321                 :     NumericVar  current;
     322                 :     NumericVar  stop;
     323                 :     NumericVar  step;
     324                 : } generate_series_numeric_fctx;
     325                 : 
     326                 : 
     327                 : /* ----------
     328                 :  * Sort support.
     329                 :  * ----------
     330                 :  */
     331                 : typedef struct
     332                 : {
     333                 :     void       *buf;            /* buffer for short varlenas */
     334                 :     int64       input_count;    /* number of non-null values seen */
     335                 :     bool        estimating;     /* true if estimating cardinality */
     336                 : 
     337                 :     hyperLogLogState abbr_card; /* cardinality estimator */
     338                 : } NumericSortSupport;
     339                 : 
     340                 : 
     341                 : /* ----------
     342                 :  * Fast sum accumulator.
     343                 :  *
     344                 :  * NumericSumAccum is used to implement SUM(), and other standard aggregates
     345                 :  * that track the sum of input values.  It uses 32-bit integers to store the
     346                 :  * digits, instead of the normal 16-bit integers (with NBASE=10000).  This
     347                 :  * way, we can safely accumulate up to NBASE - 1 values without propagating
     348                 :  * carry, before risking overflow of any of the digits.  'num_uncarried'
     349                 :  * tracks how many values have been accumulated without propagating carry.
     350                 :  *
     351                 :  * Positive and negative values are accumulated separately, in 'pos_digits'
     352                 :  * and 'neg_digits'.  This is simpler and faster than deciding whether to add
     353                 :  * or subtract from the current value, for each new value (see sub_var() for
     354                 :  * the logic we avoid by doing this).  Both buffers are of same size, and
     355                 :  * have the same weight and scale.  In accum_sum_final(), the positive and
     356                 :  * negative sums are added together to produce the final result.
     357                 :  *
     358                 :  * When a new value has a larger ndigits or weight than the accumulator
     359                 :  * currently does, the accumulator is enlarged to accommodate the new value.
     360                 :  * We normally have one zero digit reserved for carry propagation, and that
     361                 :  * is indicated by the 'have_carry_space' flag.  When accum_sum_carry() uses
     362                 :  * up the reserved digit, it clears the 'have_carry_space' flag.  The next
     363                 :  * call to accum_sum_add() will enlarge the buffer, to make room for the
     364                 :  * extra digit, and set the flag again.
     365                 :  *
     366                 :  * To initialize a new accumulator, simply reset all fields to zeros.
     367                 :  *
     368                 :  * The accumulator does not handle NaNs.
     369                 :  * ----------
     370                 :  */
     371                 : typedef struct NumericSumAccum
     372                 : {
     373                 :     int         ndigits;
     374                 :     int         weight;
     375                 :     int         dscale;
     376                 :     int         num_uncarried;
     377                 :     bool        have_carry_space;
     378                 :     int32      *pos_digits;
     379                 :     int32      *neg_digits;
     380                 : } NumericSumAccum;
     381                 : 
     382                 : 
     383                 : /*
     384                 :  * We define our own macros for packing and unpacking abbreviated-key
     385                 :  * representations for numeric values in order to avoid depending on
     386                 :  * USE_FLOAT8_BYVAL.  The type of abbreviation we use is based only on
     387                 :  * the size of a datum, not the argument-passing convention for float8.
     388                 :  *
     389                 :  * The range of abbreviations for finite values is from +PG_INT64/32_MAX
     390                 :  * to -PG_INT64/32_MAX.  NaN has the abbreviation PG_INT64/32_MIN, and we
     391                 :  * define the sort ordering to make that work out properly (see further
     392                 :  * comments below).  PINF and NINF share the abbreviations of the largest
     393                 :  * and smallest finite abbreviation classes.
     394                 :  */
     395                 : #define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
     396                 : #if SIZEOF_DATUM == 8
     397                 : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     398                 : #define DatumGetNumericAbbrev(X) ((int64) (X))
     399                 : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT64_MIN)
     400                 : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT64_MAX)
     401                 : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT64_MAX)
     402                 : #else
     403                 : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     404                 : #define DatumGetNumericAbbrev(X) ((int32) (X))
     405                 : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT32_MIN)
     406                 : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT32_MAX)
     407                 : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT32_MAX)
     408                 : #endif
     409                 : 
     410                 : 
     411                 : /* ----------
     412                 :  * Some preinitialized constants
     413                 :  * ----------
     414                 :  */
     415                 : static const NumericDigit const_zero_data[1] = {0};
     416                 : static const NumericVar const_zero =
     417                 : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
     418                 : 
     419                 : static const NumericDigit const_one_data[1] = {1};
     420                 : static const NumericVar const_one =
     421                 : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
     422                 : 
     423                 : static const NumericVar const_minus_one =
     424                 : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
     425                 : 
     426                 : static const NumericDigit const_two_data[1] = {2};
     427                 : static const NumericVar const_two =
     428                 : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
     429                 : 
     430                 : #if DEC_DIGITS == 4
     431                 : static const NumericDigit const_zero_point_nine_data[1] = {9000};
     432                 : #elif DEC_DIGITS == 2
     433                 : static const NumericDigit const_zero_point_nine_data[1] = {90};
     434                 : #elif DEC_DIGITS == 1
     435                 : static const NumericDigit const_zero_point_nine_data[1] = {9};
     436                 : #endif
     437                 : static const NumericVar const_zero_point_nine =
     438                 : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
     439                 : 
     440                 : #if DEC_DIGITS == 4
     441                 : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
     442                 : #elif DEC_DIGITS == 2
     443                 : static const NumericDigit const_one_point_one_data[2] = {1, 10};
     444                 : #elif DEC_DIGITS == 1
     445                 : static const NumericDigit const_one_point_one_data[2] = {1, 1};
     446                 : #endif
     447                 : static const NumericVar const_one_point_one =
     448                 : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
     449                 : 
     450                 : static const NumericVar const_nan =
     451                 : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
     452                 : 
     453                 : static const NumericVar const_pinf =
     454                 : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
     455                 : 
     456                 : static const NumericVar const_ninf =
     457                 : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
     458                 : 
     459                 : #if DEC_DIGITS == 4
     460                 : static const int round_powers[4] = {0, 1000, 100, 10};
     461                 : #endif
     462                 : 
     463                 : 
     464                 : /* ----------
     465                 :  * Local functions
     466                 :  * ----------
     467                 :  */
     468                 : 
     469                 : #ifdef NUMERIC_DEBUG
     470                 : static void dump_numeric(const char *str, Numeric num);
     471                 : static void dump_var(const char *str, NumericVar *var);
     472                 : #else
     473                 : #define dump_numeric(s,n)
     474                 : #define dump_var(s,v)
     475                 : #endif
     476                 : 
     477                 : #define digitbuf_alloc(ndigits)  \
     478                 :     ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
     479                 : #define digitbuf_free(buf)  \
     480                 :     do { \
     481                 :          if ((buf) != NULL) \
     482                 :              pfree(buf); \
     483                 :     } while (0)
     484                 : 
     485                 : #define init_var(v)     memset(v, 0, sizeof(NumericVar))
     486                 : 
     487                 : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
     488                 :     (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
     489                 : #define NUMERIC_NDIGITS(num) \
     490                 :     ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
     491                 : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
     492                 :     ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
     493                 :     (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
     494                 :     (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
     495                 : 
     496                 : static void alloc_var(NumericVar *var, int ndigits);
     497                 : static void free_var(NumericVar *var);
     498                 : static void zero_var(NumericVar *var);
     499                 : 
     500                 : static bool set_var_from_str(const char *str, const char *cp,
     501                 :                              NumericVar *dest, const char **endptr,
     502                 :                              Node *escontext);
     503                 : static bool set_var_from_non_decimal_integer_str(const char *str,
     504                 :                                                  const char *cp, int sign,
     505                 :                                                  int base, NumericVar *dest,
     506                 :                                                  const char **endptr,
     507                 :                                                  Node *escontext);
     508                 : static void set_var_from_num(Numeric num, NumericVar *dest);
     509                 : static void init_var_from_num(Numeric num, NumericVar *dest);
     510                 : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
     511                 : static char *get_str_from_var(const NumericVar *var);
     512                 : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
     513                 : 
     514                 : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
     515                 : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
     516                 : 
     517                 : static Numeric duplicate_numeric(Numeric num);
     518                 : static Numeric make_result(const NumericVar *var);
     519                 : static Numeric make_result_opt_error(const NumericVar *var, bool *have_error);
     520                 : 
     521                 : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
     522                 : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
     523                 : 
     524                 : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
     525                 : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
     526                 : static void int64_to_numericvar(int64 val, NumericVar *var);
     527                 : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
     528                 : #ifdef HAVE_INT128
     529                 : static bool numericvar_to_int128(const NumericVar *var, int128 *result);
     530                 : static void int128_to_numericvar(int128 val, NumericVar *var);
     531                 : #endif
     532                 : static double numericvar_to_double_no_overflow(const NumericVar *var);
     533                 : 
     534                 : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
     535                 : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
     536                 : static int  numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
     537                 : static int  numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
     538                 : 
     539                 : static Datum numeric_abbrev_convert_var(const NumericVar *var,
     540                 :                                         NumericSortSupport *nss);
     541                 : 
     542                 : static int  cmp_numerics(Numeric num1, Numeric num2);
     543                 : static int  cmp_var(const NumericVar *var1, const NumericVar *var2);
     544                 : static int  cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
     545                 :                            int var1weight, int var1sign,
     546                 :                            const NumericDigit *var2digits, int var2ndigits,
     547                 :                            int var2weight, int var2sign);
     548                 : static void add_var(const NumericVar *var1, const NumericVar *var2,
     549                 :                     NumericVar *result);
     550                 : static void sub_var(const NumericVar *var1, const NumericVar *var2,
     551                 :                     NumericVar *result);
     552                 : static void mul_var(const NumericVar *var1, const NumericVar *var2,
     553                 :                     NumericVar *result,
     554                 :                     int rscale);
     555                 : static void div_var(const NumericVar *var1, const NumericVar *var2,
     556                 :                     NumericVar *result,
     557                 :                     int rscale, bool round);
     558                 : static void div_var_fast(const NumericVar *var1, const NumericVar *var2,
     559                 :                          NumericVar *result, int rscale, bool round);
     560                 : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
     561                 :                         NumericVar *result, int rscale, bool round);
     562                 : #ifdef HAVE_INT128
     563                 : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
     564                 :                           NumericVar *result, int rscale, bool round);
     565                 : #endif
     566                 : static int  select_div_scale(const NumericVar *var1, const NumericVar *var2);
     567                 : static void mod_var(const NumericVar *var1, const NumericVar *var2,
     568                 :                     NumericVar *result);
     569                 : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
     570                 :                         NumericVar *quot, NumericVar *rem);
     571                 : static void ceil_var(const NumericVar *var, NumericVar *result);
     572                 : static void floor_var(const NumericVar *var, NumericVar *result);
     573                 : 
     574                 : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
     575                 :                     NumericVar *result);
     576                 : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
     577                 : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
     578                 : static int  estimate_ln_dweight(const NumericVar *var);
     579                 : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
     580                 : static void log_var(const NumericVar *base, const NumericVar *num,
     581                 :                     NumericVar *result);
     582                 : static void power_var(const NumericVar *base, const NumericVar *exp,
     583                 :                       NumericVar *result);
     584                 : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
     585                 :                           NumericVar *result);
     586                 : static void power_ten_int(int exp, NumericVar *result);
     587                 : 
     588                 : static int  cmp_abs(const NumericVar *var1, const NumericVar *var2);
     589                 : static int  cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
     590                 :                            int var1weight,
     591                 :                            const NumericDigit *var2digits, int var2ndigits,
     592                 :                            int var2weight);
     593                 : static void add_abs(const NumericVar *var1, const NumericVar *var2,
     594                 :                     NumericVar *result);
     595                 : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
     596                 :                     NumericVar *result);
     597                 : static void round_var(NumericVar *var, int rscale);
     598                 : static void trunc_var(NumericVar *var, int rscale);
     599                 : static void strip_var(NumericVar *var);
     600                 : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
     601                 :                            const NumericVar *count_var, bool reversed_bounds,
     602                 :                            NumericVar *result_var);
     603                 : 
     604                 : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
     605                 : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
     606                 : static void accum_sum_carry(NumericSumAccum *accum);
     607                 : static void accum_sum_reset(NumericSumAccum *accum);
     608                 : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
     609                 : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
     610                 : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
     611                 : 
     612                 : 
     613                 : /* ----------------------------------------------------------------------
     614                 :  *
     615                 :  * Input-, output- and rounding-functions
     616                 :  *
     617                 :  * ----------------------------------------------------------------------
     618                 :  */
     619                 : 
     620                 : 
     621                 : /*
     622                 :  * numeric_in() -
     623                 :  *
     624                 :  *  Input function for numeric data type
     625                 :  */
     626                 : Datum
     627 GIC       47288 : numeric_in(PG_FUNCTION_ARGS)
     628                 : {
     629           47288 :     char       *str = PG_GETARG_CSTRING(0);
     630                 : #ifdef NOT_USED
     631                 :     Oid         typelem = PG_GETARG_OID(1);
     632                 : #endif
     633           47288 :     int32       typmod = PG_GETARG_INT32(2);
     634 GNC       47288 :     Node       *escontext = fcinfo->context;
     635                 :     Numeric     res;
     636                 :     const char *cp;
     637                 :     const char *numstart;
     638                 :     int         sign;
     639 ECB             : 
     640                 :     /* Skip leading spaces */
     641 CBC       47288 :     cp = str;
     642 GIC       47480 :     while (*cp)
     643                 :     {
     644           47474 :         if (!isspace((unsigned char) *cp))
     645 CBC       47282 :             break;
     646             192 :         cp++;
     647                 :     }
     648                 : 
     649                 :     /*
     650                 :      * Process the number's sign. This duplicates logic in set_var_from_str(),
     651                 :      * but it's worth doing here, since it simplifies the handling of
     652                 :      * infinities and non-decimal integers.
     653                 :      */
     654 GNC       47288 :     numstart = cp;
     655           47288 :     sign = NUMERIC_POS;
     656                 : 
     657           47288 :     if (*cp == '+')
     658              18 :         cp++;
     659           47270 :     else if (*cp == '-')
     660                 :     {
     661            1727 :         sign = NUMERIC_NEG;
     662            1727 :         cp++;
     663                 :     }
     664                 : 
     665                 :     /*
     666                 :      * Check for NaN and infinities.  We recognize the same strings allowed by
     667                 :      * float8in().
     668                 :      *
     669                 :      * Since all other legal inputs have a digit or a decimal point after the
     670                 :      * sign, we need only check for NaN/infinity if that's not the case.
     671                 :      */
     672           47288 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
     673                 :     {
     674 ECB             :         /*
     675                 :          * The number must be NaN or infinity; anything else can only be a
     676                 :          * syntax error. Note that NaN mustn't have a sign.
     677                 :          */
     678 GNC         722 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     679                 :         {
     680             271 :             res = make_result(&const_nan);
     681             271 :             cp = numstart + 3;
     682                 :         }
     683             451 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     684                 :         {
     685             156 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     686             156 :             cp += 8;
     687                 :         }
     688             295 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
     689                 :         {
     690             264 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     691             264 :             cp += 3;
     692                 :         }
     693                 :         else
     694              31 :             goto invalid_syntax;
     695 ECB             : 
     696                 :         /*
     697                 :          * Check for trailing junk; there should be nothing left but spaces.
     698                 :          *
     699                 :          * We intentionally do this check before applying the typmod because
     700                 :          * we would like to throw any trailing-junk syntax error before any
     701                 :          * semantic error resulting from apply_typmod_special().
     702                 :          */
     703 GIC         712 :         while (*cp)
     704 ECB             :         {
     705 GIC          21 :             if (!isspace((unsigned char) *cp))
     706 UNC           0 :                 goto invalid_syntax;
     707 GIC          21 :             cp++;
     708                 :         }
     709                 : 
     710 GNC         691 :         if (!apply_typmod_special(res, typmod, escontext))
     711 UNC           0 :             PG_RETURN_NULL();
     712                 :     }
     713                 :     else
     714                 :     {
     715                 :         /*
     716                 :          * We have a normal numeric value, which may be a non-decimal integer
     717                 :          * or a regular decimal number.
     718                 :          */
     719                 :         NumericVar  value;
     720                 :         int         base;
     721                 :         bool        have_error;
     722                 : 
     723 GNC       46566 :         init_var(&value);
     724                 : 
     725                 :         /*
     726                 :          * Determine the number's base by looking for a non-decimal prefix
     727                 :          * indicator ("0x", "0o", or "0b").
     728                 :          */
     729           46566 :         if (cp[0] == '0')
     730                 :         {
     731           12837 :             switch (cp[1])
     732                 :             {
     733              36 :                 case 'x':
     734                 :                 case 'X':
     735              36 :                     base = 16;
     736              36 :                     break;
     737              21 :                 case 'o':
     738                 :                 case 'O':
     739              21 :                     base = 8;
     740              21 :                     break;
     741              21 :                 case 'b':
     742                 :                 case 'B':
     743              21 :                     base = 2;
     744              21 :                     break;
     745           12759 :                 default:
     746           12759 :                     base = 10;
     747                 :             }
     748                 :         }
     749                 :         else
     750           33729 :             base = 10;
     751                 : 
     752                 :         /* Parse the rest of the number and apply the sign */
     753           46566 :         if (base == 10)
     754                 :         {
     755           46488 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     756              15 :                 PG_RETURN_NULL();
     757           46464 :             value.sign = sign;
     758                 :         }
     759                 :         else
     760                 :         {
     761              78 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
     762                 :                                                       &value, &cp, escontext))
     763 UNC           0 :                 PG_RETURN_NULL();
     764                 :         }
     765                 : 
     766                 :         /*
     767                 :          * Should be nothing left but spaces. As above, throw any typmod error
     768                 :          * after finishing syntax check.
     769                 :          */
     770 GNC       46572 :         while (*cp)
     771                 :         {
     772              69 :             if (!isspace((unsigned char) *cp))
     773              30 :                 goto invalid_syntax;
     774              39 :             cp++;
     775                 :         }
     776                 : 
     777           46503 :         if (!apply_typmod(&value, typmod, escontext))
     778               6 :             PG_RETURN_NULL();
     779                 : 
     780           46497 :         res = make_result_opt_error(&value, &have_error);
     781                 : 
     782           46497 :         if (have_error)
     783               9 :             ereturn(escontext, (Datum) 0,
     784                 :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     785                 :                      errmsg("value overflows numeric format")));
     786                 : 
     787           46488 :         free_var(&value);
     788                 :     }
     789                 : 
     790 GIC       47179 :     PG_RETURN_NUMERIC(res);
     791                 : 
     792 GNC          61 : invalid_syntax:
     793              61 :     ereturn(escontext, (Datum) 0,
     794                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     795                 :              errmsg("invalid input syntax for type %s: \"%s\"",
     796                 :                     "numeric", str)));
     797                 : }
     798                 : 
     799                 : 
     800 ECB             : /*
     801                 :  * numeric_out() -
     802                 :  *
     803                 :  *  Output function for numeric data type
     804                 :  */
     805                 : Datum
     806 CBC      389247 : numeric_out(PG_FUNCTION_ARGS)
     807 ECB             : {
     808 CBC      389247 :     Numeric     num = PG_GETARG_NUMERIC(0);
     809                 :     NumericVar  x;
     810 ECB             :     char       *str;
     811                 : 
     812                 :     /*
     813                 :      * Handle NaN and infinities
     814                 :      */
     815 CBC      389247 :     if (NUMERIC_IS_SPECIAL(num))
     816 ECB             :     {
     817 CBC        1698 :         if (NUMERIC_IS_PINF(num))
     818 GIC         478 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     819            1220 :         else if (NUMERIC_IS_NINF(num))
     820             287 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     821 ECB             :         else
     822 GIC         933 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     823                 :     }
     824 ECB             : 
     825                 :     /*
     826                 :      * Get the number in the variable format.
     827                 :      */
     828 CBC      387549 :     init_var_from_num(num, &x);
     829                 : 
     830 GIC      387549 :     str = get_str_from_var(&x);
     831                 : 
     832 CBC      387549 :     PG_RETURN_CSTRING(str);
     833                 : }
     834 EUB             : 
     835                 : /*
     836                 :  * numeric_is_nan() -
     837                 :  *
     838                 :  *  Is Numeric value a NaN?
     839                 :  */
     840                 : bool
     841 CBC        6547 : numeric_is_nan(Numeric num)
     842                 : {
     843            6547 :     return NUMERIC_IS_NAN(num);
     844 ECB             : }
     845                 : 
     846                 : /*
     847                 :  * numeric_is_inf() -
     848                 :  *
     849                 :  *  Is Numeric value an infinity?
     850                 :  */
     851                 : bool
     852 GIC          15 : numeric_is_inf(Numeric num)
     853 ECB             : {
     854 CBC          15 :     return NUMERIC_IS_INF(num);
     855                 : }
     856                 : 
     857                 : /*
     858 ECB             :  * numeric_is_integral() -
     859                 :  *
     860                 :  *  Is Numeric value integral?
     861                 :  */
     862                 : static bool
     863 CBC          33 : numeric_is_integral(Numeric num)
     864 ECB             : {
     865                 :     NumericVar  arg;
     866                 : 
     867                 :     /* Reject NaN, but infinities are considered integral */
     868 GIC          33 :     if (NUMERIC_IS_SPECIAL(num))
     869                 :     {
     870              15 :         if (NUMERIC_IS_NAN(num))
     871 UIC           0 :             return false;
     872 GIC          15 :         return true;
     873                 :     }
     874                 : 
     875                 :     /* Integral if there are no digits to the right of the decimal point */
     876              18 :     init_var_from_num(num, &arg);
     877 ECB             : 
     878 GIC          18 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
     879 ECB             : }
     880                 : 
     881                 : /*
     882                 :  * make_numeric_typmod() -
     883                 :  *
     884                 :  *  Pack numeric precision and scale values into a typmod.  The upper 16 bits
     885                 :  *  are used for the precision (though actually not all these bits are needed,
     886                 :  *  since the maximum allowed precision is 1000).  The lower 16 bits are for
     887                 :  *  the scale, but since the scale is constrained to the range [-1000, 1000],
     888                 :  *  we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
     889                 :  *  unset, for possible future use.
     890                 :  *
     891                 :  *  For purely historical reasons VARHDRSZ is then added to the result, thus
     892                 :  *  the unused space in the upper 16 bits is not all as freely available as it
     893                 :  *  might seem.  (We can't let the result overflow to a negative int32, as
     894                 :  *  other parts of the system would interpret that as not-a-valid-typmod.)
     895                 :  */
     896                 : static inline int32
     897 GIC         905 : make_numeric_typmod(int precision, int scale)
     898                 : {
     899 CBC         905 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
     900                 : }
     901 ECB             : 
     902                 : /*
     903                 :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
     904                 :  */
     905                 : static inline bool
     906 GIC       59150 : is_valid_numeric_typmod(int32 typmod)
     907                 : {
     908           59150 :     return typmod >= (int32) VARHDRSZ;
     909                 : }
     910                 : 
     911                 : /*
     912 ECB             :  * numeric_typmod_precision() -
     913                 :  *
     914                 :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
     915                 :  */
     916                 : static inline int
     917 GIC       12269 : numeric_typmod_precision(int32 typmod)
     918                 : {
     919           12269 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
     920                 : }
     921                 : 
     922                 : /*
     923 ECB             :  * numeric_typmod_scale() -
     924                 :  *
     925                 :  *  Extract the scale from a numeric typmod --- see make_numeric_typmod().
     926                 :  *
     927                 :  *  Note that the scale may be negative, so we must do sign extension when
     928                 :  *  unpacking it.  We do this using the bit hack (x^1024)-1024, which sign
     929                 :  *  extends an 11-bit two's complement number x.
     930                 :  */
     931                 : static inline int
     932 GIC        8503 : numeric_typmod_scale(int32 typmod)
     933                 : {
     934 CBC        8503 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
     935                 : }
     936                 : 
     937                 : /*
     938                 :  * numeric_maximum_size() -
     939 ECB             :  *
     940                 :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
     941                 :  */
     942 EUB             : int32
     943 CBC        3766 : numeric_maximum_size(int32 typmod)
     944                 : {
     945                 :     int         precision;
     946                 :     int         numeric_digits;
     947 ECB             : 
     948 GIC        3766 :     if (!is_valid_numeric_typmod(typmod))
     949 LBC           0 :         return -1;
     950                 : 
     951                 :     /* precision (ie, max # of digits) is in upper bits of typmod */
     952 GIC        3766 :     precision = numeric_typmod_precision(typmod);
     953                 : 
     954                 :     /*
     955                 :      * This formula computes the maximum number of NumericDigits we could need
     956                 :      * in order to store the specified number of decimal digits. Because the
     957                 :      * weight is stored as a number of NumericDigits rather than a number of
     958                 :      * decimal digits, it's possible that the first NumericDigit will contain
     959                 :      * only a single decimal digit.  Thus, the first two decimal digits can
     960                 :      * require two NumericDigits to store, but it isn't until we reach
     961                 :      * DEC_DIGITS + 2 decimal digits that we potentially need a third
     962                 :      * NumericDigit.
     963                 :      */
     964            3766 :     numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
     965                 : 
     966                 :     /*
     967                 :      * In most cases, the size of a numeric will be smaller than the value
     968 ECB             :      * computed below, because the varlena header will typically get toasted
     969                 :      * down to a single byte before being stored on disk, and it may also be
     970                 :      * possible to use a short numeric header.  But our job here is to compute
     971                 :      * the worst case.
     972                 :      */
     973 GIC        3766 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
     974                 : }
     975                 : 
     976                 : /*
     977 ECB             :  * numeric_out_sci() -
     978                 :  *
     979                 :  *  Output function for numeric data type in scientific notation.
     980                 :  */
     981                 : char *
     982 GIC         117 : numeric_out_sci(Numeric num, int scale)
     983                 : {
     984                 :     NumericVar  x;
     985                 :     char       *str;
     986                 : 
     987                 :     /*
     988 ECB             :      * Handle NaN and infinities
     989                 :      */
     990 CBC         117 :     if (NUMERIC_IS_SPECIAL(num))
     991                 :     {
     992 GIC           9 :         if (NUMERIC_IS_PINF(num))
     993               3 :             return pstrdup("Infinity");
     994               6 :         else if (NUMERIC_IS_NINF(num))
     995               3 :             return pstrdup("-Infinity");
     996                 :         else
     997               3 :             return pstrdup("NaN");
     998                 :     }
     999                 : 
    1000             108 :     init_var_from_num(num, &x);
    1001                 : 
    1002             108 :     str = get_str_from_var_sci(&x, scale);
    1003 ECB             : 
    1004 GIC         108 :     return str;
    1005 ECB             : }
    1006                 : 
    1007                 : /*
    1008                 :  * numeric_normalize() -
    1009                 :  *
    1010                 :  *  Output function for numeric data type, suppressing insignificant trailing
    1011                 :  *  zeroes and then any trailing decimal point.  The intent of this is to
    1012                 :  *  produce strings that are equal if and only if the input numeric values
    1013                 :  *  compare equal.
    1014                 :  */
    1015                 : char *
    1016 GIC        4983 : numeric_normalize(Numeric num)
    1017                 : {
    1018                 :     NumericVar  x;
    1019 ECB             :     char       *str;
    1020 EUB             :     int         last;
    1021                 : 
    1022                 :     /*
    1023 ECB             :      * Handle NaN and infinities
    1024                 :      */
    1025 GIC        4983 :     if (NUMERIC_IS_SPECIAL(num))
    1026                 :     {
    1027 UIC           0 :         if (NUMERIC_IS_PINF(num))
    1028               0 :             return pstrdup("Infinity");
    1029               0 :         else if (NUMERIC_IS_NINF(num))
    1030               0 :             return pstrdup("-Infinity");
    1031                 :         else
    1032               0 :             return pstrdup("NaN");
    1033                 :     }
    1034                 : 
    1035 CBC        4983 :     init_var_from_num(num, &x);
    1036                 : 
    1037 GIC        4983 :     str = get_str_from_var(&x);
    1038                 : 
    1039                 :     /* If there's no decimal point, there's certainly nothing to remove. */
    1040            4983 :     if (strchr(str, '.') != NULL)
    1041                 :     {
    1042                 :         /*
    1043                 :          * Back up over trailing fractional zeroes.  Since there is a decimal
    1044 ECB             :          * point, this loop will terminate safely.
    1045                 :          */
    1046 GIC          21 :         last = strlen(str) - 1;
    1047              42 :         while (str[last] == '0')
    1048              21 :             last--;
    1049                 : 
    1050                 :         /* We want to get rid of the decimal point too, if it's now last. */
    1051              21 :         if (str[last] == '.')
    1052              21 :             last--;
    1053 ECB             : 
    1054                 :         /* Delete whatever we backed up over. */
    1055 GIC          21 :         str[last + 1] = '\0';
    1056                 :     }
    1057                 : 
    1058            4983 :     return str;
    1059                 : }
    1060                 : 
    1061 ECB             : /*
    1062                 :  *      numeric_recv            - converts external binary format to numeric
    1063                 :  *
    1064                 :  * External format is a sequence of int16's:
    1065                 :  * ndigits, weight, sign, dscale, NumericDigits.
    1066                 :  */
    1067                 : Datum
    1068 CBC          51 : numeric_recv(PG_FUNCTION_ARGS)
    1069                 : {
    1070 GIC          51 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    1071 ECB             : 
    1072                 : #ifdef NOT_USED
    1073                 :     Oid         typelem = PG_GETARG_OID(1);
    1074                 : #endif
    1075 CBC          51 :     int32       typmod = PG_GETARG_INT32(2);
    1076                 :     NumericVar  value;
    1077                 :     Numeric     res;
    1078                 :     int         len,
    1079                 :                 i;
    1080                 : 
    1081 GIC          51 :     init_var(&value);
    1082                 : 
    1083              51 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1084                 : 
    1085              51 :     alloc_var(&value, len);
    1086                 : 
    1087 CBC          51 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
    1088                 :     /* we allow any int16 for weight --- OK? */
    1089                 : 
    1090 GIC          51 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1091              51 :     if (!(value.sign == NUMERIC_POS ||
    1092 UIC           0 :           value.sign == NUMERIC_NEG ||
    1093               0 :           value.sign == NUMERIC_NAN ||
    1094               0 :           value.sign == NUMERIC_PINF ||
    1095               0 :           value.sign == NUMERIC_NINF))
    1096 LBC           0 :         ereport(ERROR,
    1097                 :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1098 EUB             :                  errmsg("invalid sign in external \"numeric\" value")));
    1099                 : 
    1100 GBC          51 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1101              51 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
    1102 UIC           0 :         ereport(ERROR,
    1103 EUB             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1104                 :                  errmsg("invalid scale in external \"numeric\" value")));
    1105                 : 
    1106 CBC         137 :     for (i = 0; i < len; i++)
    1107                 :     {
    1108              86 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
    1109                 : 
    1110 GIC          86 :         if (d < 0 || d >= NBASE)
    1111 LBC           0 :             ereport(ERROR,
    1112                 :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1113                 :                      errmsg("invalid digit in external \"numeric\" value")));
    1114 GIC          86 :         value.digits[i] = d;
    1115                 :     }
    1116                 : 
    1117 ECB             :     /*
    1118                 :      * If the given dscale would hide any digits, truncate those digits away.
    1119                 :      * We could alternatively throw an error, but that would take a bunch of
    1120                 :      * extra code (about as much as trunc_var involves), and it might cause
    1121                 :      * client compatibility issues.  Be careful not to apply trunc_var to
    1122                 :      * special values, as it could do the wrong thing; we don't need it
    1123                 :      * anyway, since make_result will ignore all but the sign field.
    1124                 :      *
    1125                 :      * After doing that, be sure to check the typmod restriction.
    1126                 :      */
    1127 GIC          51 :     if (value.sign == NUMERIC_POS ||
    1128 UIC           0 :         value.sign == NUMERIC_NEG)
    1129 ECB             :     {
    1130 GIC          51 :         trunc_var(&value, value.dscale);
    1131                 : 
    1132 GNC          51 :         (void) apply_typmod(&value, typmod, NULL);
    1133                 : 
    1134 GIC          51 :         res = make_result(&value);
    1135                 :     }
    1136                 :     else
    1137                 :     {
    1138                 :         /* apply_typmod_special wants us to make the Numeric first */
    1139 LBC           0 :         res = make_result(&value);
    1140                 : 
    1141 UNC           0 :         (void) apply_typmod_special(res, typmod, NULL);
    1142                 :     }
    1143                 : 
    1144 GIC          51 :     free_var(&value);
    1145                 : 
    1146 CBC          51 :     PG_RETURN_NUMERIC(res);
    1147                 : }
    1148                 : 
    1149                 : /*
    1150                 :  *      numeric_send            - converts numeric to binary format
    1151                 :  */
    1152 ECB             : Datum
    1153 GIC          35 : numeric_send(PG_FUNCTION_ARGS)
    1154 ECB             : {
    1155 GIC          35 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1156 ECB             :     NumericVar  x;
    1157                 :     StringInfoData buf;
    1158                 :     int         i;
    1159                 : 
    1160 GIC          35 :     init_var_from_num(num, &x);
    1161 ECB             : 
    1162 CBC          35 :     pq_begintypsend(&buf);
    1163 EUB             : 
    1164 GBC          35 :     pq_sendint16(&buf, x.ndigits);
    1165              35 :     pq_sendint16(&buf, x.weight);
    1166              35 :     pq_sendint16(&buf, x.sign);
    1167              35 :     pq_sendint16(&buf, x.dscale);
    1168 GIC          97 :     for (i = 0; i < x.ndigits; i++)
    1169              62 :         pq_sendint16(&buf, x.digits[i]);
    1170                 : 
    1171 CBC          35 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    1172 ECB             : }
    1173 EUB             : 
    1174                 : 
    1175                 : /*
    1176                 :  * numeric_support()
    1177 ECB             :  *
    1178                 :  * Planner support function for the numeric() length coercion function.
    1179                 :  *
    1180                 :  * Flatten calls that solely represent increases in allowable precision.
    1181                 :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
    1182 EUB             :  * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
    1183                 :  * an unconstrained numeric to any constrained numeric is also unoptimizable.
    1184                 :  */
    1185 ECB             : Datum
    1186 GIC         258 : numeric_support(PG_FUNCTION_ARGS)
    1187                 : {
    1188             258 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1189             258 :     Node       *ret = NULL;
    1190                 : 
    1191             258 :     if (IsA(rawreq, SupportRequestSimplify))
    1192                 :     {
    1193             114 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
    1194             114 :         FuncExpr   *expr = req->fcall;
    1195                 :         Node       *typmod;
    1196                 : 
    1197             114 :         Assert(list_length(expr->args) >= 2);
    1198 ECB             : 
    1199 GBC         114 :         typmod = (Node *) lsecond(expr->args);
    1200                 : 
    1201 CBC         114 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
    1202                 :         {
    1203             114 :             Node       *source = (Node *) linitial(expr->args);
    1204 GIC         114 :             int32       old_typmod = exprTypmod(source);
    1205 CBC         114 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    1206 GIC         114 :             int32       old_scale = numeric_typmod_scale(old_typmod);
    1207             114 :             int32       new_scale = numeric_typmod_scale(new_typmod);
    1208             114 :             int32       old_precision = numeric_typmod_precision(old_typmod);
    1209             114 :             int32       new_precision = numeric_typmod_precision(new_typmod);
    1210 EUB             : 
    1211                 :             /*
    1212                 :              * If new_typmod is invalid, the destination is unconstrained;
    1213                 :              * that's always OK.  If old_typmod is valid, the source is
    1214                 :              * constrained, and we're OK if the scale is unchanged and the
    1215 ECB             :              * precision is not decreasing.  See further notes in function
    1216                 :              * header comment.
    1217                 :              */
    1218 GIC         228 :             if (!is_valid_numeric_typmod(new_typmod) ||
    1219             120 :                 (is_valid_numeric_typmod(old_typmod) &&
    1220               3 :                  new_scale == old_scale && new_precision >= old_precision))
    1221               3 :                 ret = relabel_to_typmod(source, new_typmod);
    1222                 :         }
    1223                 :     }
    1224 ECB             : 
    1225 GIC         258 :     PG_RETURN_POINTER(ret);
    1226 ECB             : }
    1227                 : 
    1228                 : /*
    1229                 :  * numeric() -
    1230                 :  *
    1231                 :  *  This is a special function called by the Postgres database system
    1232                 :  *  before a value is stored in a tuple's attribute. The precision and
    1233                 :  *  scale of the attribute have to be applied on the value.
    1234                 :  */
    1235                 : Datum
    1236 CBC        5880 : numeric     (PG_FUNCTION_ARGS)
    1237 ECB             : {
    1238 CBC        5880 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1239            5880 :     int32       typmod = PG_GETARG_INT32(1);
    1240 ECB             :     Numeric     new;
    1241                 :     int         precision;
    1242                 :     int         scale;
    1243                 :     int         ddigits;
    1244                 :     int         maxdigits;
    1245                 :     int         dscale;
    1246                 :     NumericVar  var;
    1247                 : 
    1248                 :     /*
    1249                 :      * Handle NaN and infinities: if apply_typmod_special doesn't complain,
    1250                 :      * just return a copy of the input.
    1251                 :      */
    1252 GIC        5880 :     if (NUMERIC_IS_SPECIAL(num))
    1253                 :     {
    1254 GNC         105 :         (void) apply_typmod_special(num, typmod, NULL);
    1255 GIC          96 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1256                 :     }
    1257 ECB             : 
    1258                 :     /*
    1259                 :      * If the value isn't a valid type modifier, simply return a copy of the
    1260                 :      * input value
    1261                 :      */
    1262 CBC        5775 :     if (!is_valid_numeric_typmod(typmod))
    1263 UIC           0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1264 ECB             : 
    1265                 :     /*
    1266                 :      * Get the precision and scale out of the typmod value
    1267                 :      */
    1268 CBC        5775 :     precision = numeric_typmod_precision(typmod);
    1269 GIC        5775 :     scale = numeric_typmod_scale(typmod);
    1270 CBC        5775 :     maxdigits = precision - scale;
    1271                 : 
    1272 ECB             :     /* The target display scale is non-negative */
    1273 GIC        5775 :     dscale = Max(scale, 0);
    1274 ECB             : 
    1275                 :     /*
    1276                 :      * If the number is certainly in bounds and due to the target scale no
    1277                 :      * rounding could be necessary, just make a copy of the input and modify
    1278                 :      * its scale fields, unless the larger scale forces us to abandon the
    1279                 :      * short representation.  (Note we assume the existing dscale is
    1280                 :      * honest...)
    1281                 :      */
    1282 GIC        5775 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1283            5775 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
    1284            3565 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
    1285 UIC           0 :             || !NUMERIC_IS_SHORT(num)))
    1286                 :     {
    1287 GIC        3565 :         new = duplicate_numeric(num);
    1288            3565 :         if (NUMERIC_IS_SHORT(num))
    1289 CBC        3565 :             new->choice.n_short.n_header =
    1290            3565 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
    1291            3565 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
    1292 ECB             :         else
    1293 UIC           0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
    1294               0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
    1295 GIC        3565 :         PG_RETURN_NUMERIC(new);
    1296 ECB             :     }
    1297                 : 
    1298                 :     /*
    1299                 :      * We really need to fiddle with things - unpack the number into a
    1300                 :      * variable and let apply_typmod() do it.
    1301                 :      */
    1302 GIC        2210 :     init_var(&var);
    1303                 : 
    1304            2210 :     set_var_from_num(num, &var);
    1305 GNC        2210 :     (void) apply_typmod(&var, typmod, NULL);
    1306 GIC        2180 :     new = make_result(&var);
    1307 ECB             : 
    1308 GIC        2180 :     free_var(&var);
    1309 ECB             : 
    1310 CBC        2180 :     PG_RETURN_NUMERIC(new);
    1311                 : }
    1312                 : 
    1313                 : Datum
    1314 GIC         911 : numerictypmodin(PG_FUNCTION_ARGS)
    1315                 : {
    1316             911 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1317                 :     int32      *tl;
    1318                 :     int         n;
    1319                 :     int32       typmod;
    1320                 : 
    1321             911 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1322                 : 
    1323 CBC         911 :     if (n == 2)
    1324                 :     {
    1325             903 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1326 LBC           0 :             ereport(ERROR,
    1327                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1328                 :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1329                 :                             tl[0], NUMERIC_MAX_PRECISION)));
    1330 GIC         903 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
    1331 UIC           0 :             ereport(ERROR,
    1332                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1333 ECB             :                      errmsg("NUMERIC scale %d must be between %d and %d",
    1334 EUB             :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
    1335 GIC         903 :         typmod = make_numeric_typmod(tl[0], tl[1]);
    1336                 :     }
    1337               8 :     else if (n == 1)
    1338                 :     {
    1339 CBC           2 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1340 LBC           0 :             ereport(ERROR,
    1341 ECB             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1342                 :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1343                 :                             tl[0], NUMERIC_MAX_PRECISION)));
    1344                 :         /* scale defaults to zero */
    1345 GIC           2 :         typmod = make_numeric_typmod(tl[0], 0);
    1346                 :     }
    1347                 :     else
    1348                 :     {
    1349               6 :         ereport(ERROR,
    1350                 :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1351                 :                  errmsg("invalid NUMERIC type modifier")));
    1352                 :         typmod = 0;             /* keep compiler quiet */
    1353 ECB             :     }
    1354                 : 
    1355 CBC         905 :     PG_RETURN_INT32(typmod);
    1356 EUB             : }
    1357                 : 
    1358 ECB             : Datum
    1359 CBC         188 : numerictypmodout(PG_FUNCTION_ARGS)
    1360 ECB             : {
    1361 CBC         188 :     int32       typmod = PG_GETARG_INT32(0);
    1362             188 :     char       *res = (char *) palloc(64);
    1363                 : 
    1364 GBC         188 :     if (is_valid_numeric_typmod(typmod))
    1365             188 :         snprintf(res, 64, "(%d,%d)",
    1366 ECB             :                  numeric_typmod_precision(typmod),
    1367                 :                  numeric_typmod_scale(typmod));
    1368                 :     else
    1369 UIC           0 :         *res = '\0';
    1370                 : 
    1371 GIC         188 :     PG_RETURN_CSTRING(res);
    1372                 : }
    1373 ECB             : 
    1374                 : 
    1375                 : /* ----------------------------------------------------------------------
    1376                 :  *
    1377                 :  * Sign manipulation, rounding and the like
    1378                 :  *
    1379                 :  * ----------------------------------------------------------------------
    1380                 :  */
    1381                 : 
    1382                 : Datum
    1383 GIC         630 : numeric_abs(PG_FUNCTION_ARGS)
    1384                 : {
    1385 CBC         630 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1386                 :     Numeric     res;
    1387 ECB             : 
    1388                 :     /*
    1389                 :      * Do it the easy way directly on the packed format
    1390                 :      */
    1391 GIC         630 :     res = duplicate_numeric(num);
    1392 ECB             : 
    1393 GIC         630 :     if (NUMERIC_IS_SHORT(num))
    1394 CBC         597 :         res->choice.n_short.n_header =
    1395 GIC         597 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
    1396 CBC          33 :     else if (NUMERIC_IS_SPECIAL(num))
    1397 EUB             :     {
    1398                 :         /* This changes -Inf to Inf, and doesn't affect NaN */
    1399 GIC           9 :         res->choice.n_short.n_header =
    1400               9 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
    1401 ECB             :     }
    1402 EUB             :     else
    1403 GIC          24 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
    1404                 : 
    1405             630 :     PG_RETURN_NUMERIC(res);
    1406 ECB             : }
    1407                 : 
    1408                 : 
    1409                 : Datum
    1410 CBC         427 : numeric_uminus(PG_FUNCTION_ARGS)
    1411 EUB             : {
    1412 GIC         427 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1413                 :     Numeric     res;
    1414                 : 
    1415                 :     /*
    1416 ECB             :      * Do it the easy way directly on the packed format
    1417                 :      */
    1418 GIC         427 :     res = duplicate_numeric(num);
    1419                 : 
    1420 CBC         427 :     if (NUMERIC_IS_SPECIAL(num))
    1421                 :     {
    1422                 :         /* Flip the sign, if it's Inf or -Inf */
    1423 GIC          63 :         if (!NUMERIC_IS_NAN(num))
    1424              42 :             res->choice.n_short.n_header =
    1425              42 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
    1426 ECB             :     }
    1427                 : 
    1428                 :     /*
    1429                 :      * The packed format is known to be totally zero digit trimmed always. So
    1430                 :      * once we've eliminated specials, we can identify a zero by the fact that
    1431                 :      * there are no digits at all. Do nothing to a zero.
    1432                 :      */
    1433 CBC         364 :     else if (NUMERIC_NDIGITS(num) != 0)
    1434                 :     {
    1435 ECB             :         /* Else, flip the sign */
    1436 CBC         307 :         if (NUMERIC_IS_SHORT(num))
    1437 GIC         307 :             res->choice.n_short.n_header =
    1438             307 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
    1439 UIC           0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
    1440 UBC           0 :             res->choice.n_long.n_sign_dscale =
    1441 UIC           0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
    1442 ECB             :         else
    1443 UIC           0 :             res->choice.n_long.n_sign_dscale =
    1444               0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
    1445                 :     }
    1446                 : 
    1447 GIC         427 :     PG_RETURN_NUMERIC(res);
    1448                 : }
    1449                 : 
    1450                 : 
    1451                 : Datum
    1452             243 : numeric_uplus(PG_FUNCTION_ARGS)
    1453                 : {
    1454 CBC         243 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1455                 : 
    1456             243 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
    1457                 : }
    1458                 : 
    1459                 : 
    1460                 : /*
    1461                 :  * numeric_sign_internal() -
    1462 ECB             :  *
    1463                 :  * Returns -1 if the argument is less than 0, 0 if the argument is equal
    1464                 :  * to 0, and 1 if the argument is greater than zero.  Caller must have
    1465                 :  * taken care of the NaN case, but we can handle infinities here.
    1466                 :  */
    1467                 : static int
    1468 GIC        1527 : numeric_sign_internal(Numeric num)
    1469                 : {
    1470 CBC        1527 :     if (NUMERIC_IS_SPECIAL(num))
    1471 ECB             :     {
    1472 GIC         156 :         Assert(!NUMERIC_IS_NAN(num));
    1473                 :         /* Must be Inf or -Inf */
    1474 CBC         156 :         if (NUMERIC_IS_PINF(num))
    1475 GIC          93 :             return 1;
    1476 ECB             :         else
    1477 GIC          63 :             return -1;
    1478                 :     }
    1479                 : 
    1480                 :     /*
    1481 ECB             :      * The packed format is known to be totally zero digit trimmed always. So
    1482                 :      * once we've eliminated specials, we can identify a zero by the fact that
    1483                 :      * there are no digits at all.
    1484                 :      */
    1485 GIC        1371 :     else if (NUMERIC_NDIGITS(num) == 0)
    1486             111 :         return 0;
    1487            1260 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
    1488             303 :         return -1;
    1489 ECB             :     else
    1490 GIC         957 :         return 1;
    1491 ECB             : }
    1492                 : 
    1493                 : /*
    1494                 :  * numeric_sign() -
    1495                 :  *
    1496                 :  * returns -1 if the argument is less than 0, 0 if the argument is equal
    1497                 :  * to 0, and 1 if the argument is greater than zero.
    1498                 :  */
    1499                 : Datum
    1500 GIC          24 : numeric_sign(PG_FUNCTION_ARGS)
    1501                 : {
    1502              24 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1503                 : 
    1504 ECB             :     /*
    1505                 :      * Handle NaN (infinities can be handled normally)
    1506                 :      */
    1507 CBC          24 :     if (NUMERIC_IS_NAN(num))
    1508               3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    1509 ECB             : 
    1510 GBC          21 :     switch (numeric_sign_internal(num))
    1511 EUB             :     {
    1512 GBC           3 :         case 0:
    1513 GIC           3 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    1514 GBC           9 :         case 1:
    1515               9 :             PG_RETURN_NUMERIC(make_result(&const_one));
    1516 GIC           9 :         case -1:
    1517               9 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
    1518 ECB             :     }
    1519                 : 
    1520 UIC           0 :     Assert(false);
    1521                 :     return (Datum) 0;
    1522                 : }
    1523 ECB             : 
    1524                 : 
    1525                 : /*
    1526                 :  * numeric_round() -
    1527                 :  *
    1528                 :  *  Round a value to have 'scale' digits after the decimal point.
    1529                 :  *  We allow negative 'scale', implying rounding before the decimal
    1530                 :  *  point --- Oracle interprets rounding that way.
    1531                 :  */
    1532                 : Datum
    1533 GIC        3751 : numeric_round(PG_FUNCTION_ARGS)
    1534                 : {
    1535            3751 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1536            3751 :     int32       scale = PG_GETARG_INT32(1);
    1537                 :     Numeric     res;
    1538                 :     NumericVar  arg;
    1539 ECB             : 
    1540                 :     /*
    1541                 :      * Handle NaN and infinities
    1542                 :      */
    1543 CBC        3751 :     if (NUMERIC_IS_SPECIAL(num))
    1544 GIC          48 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1545 ECB             : 
    1546                 :     /*
    1547                 :      * Limit the scale value to avoid possible overflow in calculations
    1548                 :      */
    1549 GIC        3703 :     scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
    1550            3703 :     scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
    1551                 : 
    1552                 :     /*
    1553                 :      * Unpack the argument and round it at the proper digit position
    1554                 :      */
    1555            3703 :     init_var(&arg);
    1556 CBC        3703 :     set_var_from_num(num, &arg);
    1557 ECB             : 
    1558 CBC        3703 :     round_var(&arg, scale);
    1559 ECB             : 
    1560                 :     /* We don't allow negative output dscale */
    1561 CBC        3703 :     if (scale < 0)
    1562 GIC          90 :         arg.dscale = 0;
    1563                 : 
    1564                 :     /*
    1565                 :      * Return the rounded result
    1566                 :      */
    1567            3703 :     res = make_result(&arg);
    1568                 : 
    1569            3703 :     free_var(&arg);
    1570            3703 :     PG_RETURN_NUMERIC(res);
    1571 ECB             : }
    1572                 : 
    1573                 : 
    1574                 : /*
    1575                 :  * numeric_trunc() -
    1576                 :  *
    1577                 :  *  Truncate a value to have 'scale' digits after the decimal point.
    1578                 :  *  We allow negative 'scale', implying a truncation before the decimal
    1579                 :  *  point --- Oracle interprets truncation that way.
    1580                 :  */
    1581                 : Datum
    1582 GIC         193 : numeric_trunc(PG_FUNCTION_ARGS)
    1583 ECB             : {
    1584 CBC         193 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1585             193 :     int32       scale = PG_GETARG_INT32(1);
    1586 ECB             :     Numeric     res;
    1587                 :     NumericVar  arg;
    1588                 : 
    1589                 :     /*
    1590                 :      * Handle NaN and infinities
    1591 EUB             :      */
    1592 GIC         193 :     if (NUMERIC_IS_SPECIAL(num))
    1593              18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1594                 : 
    1595                 :     /*
    1596                 :      * Limit the scale value to avoid possible overflow in calculations
    1597                 :      */
    1598             175 :     scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
    1599             175 :     scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
    1600                 : 
    1601                 :     /*
    1602                 :      * Unpack the argument and truncate it at the proper digit position
    1603                 :      */
    1604 CBC         175 :     init_var(&arg);
    1605 GIC         175 :     set_var_from_num(num, &arg);
    1606 ECB             : 
    1607 CBC         175 :     trunc_var(&arg, scale);
    1608                 : 
    1609                 :     /* We don't allow negative output dscale */
    1610 GIC         175 :     if (scale < 0)
    1611 UIC           0 :         arg.dscale = 0;
    1612                 : 
    1613                 :     /*
    1614 ECB             :      * Return the truncated result
    1615                 :      */
    1616 GIC         175 :     res = make_result(&arg);
    1617                 : 
    1618             175 :     free_var(&arg);
    1619             175 :     PG_RETURN_NUMERIC(res);
    1620 ECB             : }
    1621                 : 
    1622                 : 
    1623                 : /*
    1624                 :  * numeric_ceil() -
    1625                 :  *
    1626                 :  *  Return the smallest integer greater than or equal to the argument
    1627                 :  */
    1628                 : Datum
    1629 CBC         111 : numeric_ceil(PG_FUNCTION_ARGS)
    1630                 : {
    1631 GIC         111 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1632 ECB             :     Numeric     res;
    1633                 :     NumericVar  result;
    1634                 : 
    1635                 :     /*
    1636                 :      * Handle NaN and infinities
    1637                 :      */
    1638 CBC         111 :     if (NUMERIC_IS_SPECIAL(num))
    1639 GIC           9 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1640 ECB             : 
    1641 CBC         102 :     init_var_from_num(num, &result);
    1642 GIC         102 :     ceil_var(&result, &result);
    1643                 : 
    1644             102 :     res = make_result(&result);
    1645             102 :     free_var(&result);
    1646                 : 
    1647             102 :     PG_RETURN_NUMERIC(res);
    1648                 : }
    1649                 : 
    1650                 : 
    1651                 : /*
    1652                 :  * numeric_floor() -
    1653 ECB             :  *
    1654                 :  *  Return the largest integer equal to or less than the argument
    1655                 :  */
    1656                 : Datum
    1657 GIC          63 : numeric_floor(PG_FUNCTION_ARGS)
    1658                 : {
    1659              63 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1660                 :     Numeric     res;
    1661                 :     NumericVar  result;
    1662                 : 
    1663 ECB             :     /*
    1664                 :      * Handle NaN and infinities
    1665                 :      */
    1666 GIC          63 :     if (NUMERIC_IS_SPECIAL(num))
    1667               9 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1668                 : 
    1669 CBC          54 :     init_var_from_num(num, &result);
    1670              54 :     floor_var(&result, &result);
    1671                 : 
    1672 GIC          54 :     res = make_result(&result);
    1673              54 :     free_var(&result);
    1674                 : 
    1675 CBC          54 :     PG_RETURN_NUMERIC(res);
    1676 ECB             : }
    1677                 : 
    1678                 : 
    1679                 : /*
    1680                 :  * generate_series_numeric() -
    1681                 :  *
    1682 EUB             :  *  Generate series of numeric.
    1683                 :  */
    1684                 : Datum
    1685 GIC         108 : generate_series_numeric(PG_FUNCTION_ARGS)
    1686                 : {
    1687 CBC         108 :     return generate_series_step_numeric(fcinfo);
    1688                 : }
    1689 ECB             : 
    1690                 : Datum
    1691 GIC         210 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1692                 : {
    1693                 :     generate_series_numeric_fctx *fctx;
    1694                 :     FuncCallContext *funcctx;
    1695                 :     MemoryContext oldcontext;
    1696                 : 
    1697             210 :     if (SRF_IS_FIRSTCALL())
    1698                 :     {
    1699              69 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1700 CBC          69 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1701 GIC          69 :         NumericVar  steploc = const_one;
    1702 ECB             : 
    1703                 :         /* Reject NaN and infinities in start and stop values */
    1704 GIC          69 :         if (NUMERIC_IS_SPECIAL(start_num))
    1705                 :         {
    1706               6 :             if (NUMERIC_IS_NAN(start_num))
    1707               3 :                 ereport(ERROR,
    1708                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1709 ECB             :                          errmsg("start value cannot be NaN")));
    1710                 :             else
    1711 GIC           3 :                 ereport(ERROR,
    1712 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1713                 :                          errmsg("start value cannot be infinity")));
    1714                 :         }
    1715 CBC          63 :         if (NUMERIC_IS_SPECIAL(stop_num))
    1716 ECB             :         {
    1717 GIC           6 :             if (NUMERIC_IS_NAN(stop_num))
    1718 CBC           3 :                 ereport(ERROR,
    1719                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1720                 :                          errmsg("stop value cannot be NaN")));
    1721                 :             else
    1722 GIC           3 :                 ereport(ERROR,
    1723                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1724                 :                          errmsg("stop value cannot be infinity")));
    1725                 :         }
    1726                 : 
    1727                 :         /* see if we were given an explicit step size */
    1728 CBC          57 :         if (PG_NARGS() == 3)
    1729                 :         {
    1730              27 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
    1731                 : 
    1732 GIC          27 :             if (NUMERIC_IS_SPECIAL(step_num))
    1733                 :             {
    1734               6 :                 if (NUMERIC_IS_NAN(step_num))
    1735               3 :                     ereport(ERROR,
    1736                 :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1737 ECB             :                              errmsg("step size cannot be NaN")));
    1738                 :                 else
    1739 GIC           3 :                     ereport(ERROR,
    1740 ECB             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1741                 :                              errmsg("step size cannot be infinity")));
    1742                 :             }
    1743                 : 
    1744 CBC          21 :             init_var_from_num(step_num, &steploc);
    1745                 : 
    1746              21 :             if (cmp_var(&steploc, &const_zero) == 0)
    1747 GIC           3 :                 ereport(ERROR,
    1748                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1749                 :                          errmsg("step size cannot equal zero")));
    1750                 :         }
    1751                 : 
    1752                 :         /* create a function context for cross-call persistence */
    1753              48 :         funcctx = SRF_FIRSTCALL_INIT();
    1754                 : 
    1755                 :         /*
    1756 ECB             :          * Switch to memory context appropriate for multiple function calls.
    1757                 :          */
    1758 CBC          48 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1759                 : 
    1760                 :         /* allocate memory for user context */
    1761                 :         fctx = (generate_series_numeric_fctx *)
    1762              48 :             palloc(sizeof(generate_series_numeric_fctx));
    1763                 : 
    1764                 :         /*
    1765                 :          * Use fctx to keep state from call to call. Seed current with the
    1766                 :          * original start value. We must copy the start_num and stop_num
    1767                 :          * values rather than pointing to them, since we may have detoasted
    1768 ECB             :          * them in the per-call context.
    1769                 :          */
    1770 CBC          48 :         init_var(&fctx->current);
    1771              48 :         init_var(&fctx->stop);
    1772              48 :         init_var(&fctx->step);
    1773                 : 
    1774 GIC          48 :         set_var_from_num(start_num, &fctx->current);
    1775 CBC          48 :         set_var_from_num(stop_num, &fctx->stop);
    1776 GIC          48 :         set_var_from_var(&steploc, &fctx->step);
    1777 ECB             : 
    1778 CBC          48 :         funcctx->user_fctx = fctx;
    1779 GIC          48 :         MemoryContextSwitchTo(oldcontext);
    1780                 :     }
    1781                 : 
    1782 ECB             :     /* stuff done on every call of the function */
    1783 GIC         189 :     funcctx = SRF_PERCALL_SETUP();
    1784                 : 
    1785                 :     /*
    1786 ECB             :      * Get the saved state and use current state as the result of this
    1787                 :      * iteration.
    1788                 :      */
    1789 CBC         189 :     fctx = funcctx->user_fctx;
    1790                 : 
    1791 GIC         366 :     if ((fctx->step.sign == NUMERIC_POS &&
    1792             177 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1793 CBC          69 :         (fctx->step.sign == NUMERIC_NEG &&
    1794 GIC          12 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1795                 :     {
    1796             141 :         Numeric     result = make_result(&fctx->current);
    1797                 : 
    1798                 :         /* switch to memory context appropriate for iteration calculation */
    1799 CBC         141 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1800                 : 
    1801 ECB             :         /* increment current in preparation for next iteration */
    1802 GIC         141 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1803 CBC         141 :         MemoryContextSwitchTo(oldcontext);
    1804                 : 
    1805 ECB             :         /* do when there is more left to send */
    1806 CBC         141 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1807                 :     }
    1808                 :     else
    1809                 :         /* do when there is no more left */
    1810              48 :         SRF_RETURN_DONE(funcctx);
    1811                 : }
    1812                 : 
    1813                 : 
    1814                 : /*
    1815 ECB             :  * Implements the numeric version of the width_bucket() function
    1816                 :  * defined by SQL2003. See also width_bucket_float8().
    1817                 :  *
    1818                 :  * 'bound1' and 'bound2' are the lower and upper bounds of the
    1819                 :  * histogram's range, respectively. 'count' is the number of buckets
    1820                 :  * in the histogram. width_bucket() returns an integer indicating the
    1821                 :  * bucket number that 'operand' belongs to in an equiwidth histogram
    1822                 :  * with the specified characteristics. An operand smaller than the
    1823                 :  * lower bound is assigned to bucket 0. An operand greater than the
    1824                 :  * upper bound is assigned to an additional bucket (with number
    1825                 :  * count+1). We don't allow "NaN" for any of the numeric arguments.
    1826                 :  */
    1827                 : Datum
    1828 GIC         390 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1829 ECB             : {
    1830 GIC         390 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1831             390 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1832             390 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1833 CBC         390 :     int32       count = PG_GETARG_INT32(3);
    1834                 :     NumericVar  count_var;
    1835                 :     NumericVar  result_var;
    1836                 :     int32       result;
    1837                 : 
    1838 GIC         390 :     if (count <= 0)
    1839               6 :         ereport(ERROR,
    1840                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1841 ECB             :                  errmsg("count must be greater than zero")));
    1842                 : 
    1843 CBC         384 :     if (NUMERIC_IS_SPECIAL(operand) ||
    1844 GIC         375 :         NUMERIC_IS_SPECIAL(bound1) ||
    1845 CBC         372 :         NUMERIC_IS_SPECIAL(bound2))
    1846 ECB             :     {
    1847 CBC          18 :         if (NUMERIC_IS_NAN(operand) ||
    1848 GIC          15 :             NUMERIC_IS_NAN(bound1) ||
    1849 CBC          15 :             NUMERIC_IS_NAN(bound2))
    1850               3 :             ereport(ERROR,
    1851                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1852                 :                      errmsg("operand, lower bound, and upper bound cannot be NaN")));
    1853                 :         /* We allow "operand" to be infinite; cmp_numerics will cope */
    1854              15 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1855 GIC           9 :             ereport(ERROR,
    1856                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1857                 :                      errmsg("lower and upper bounds must be finite")));
    1858                 :     }
    1859                 : 
    1860 CBC         372 :     init_var(&result_var);
    1861 GIC         372 :     init_var(&count_var);
    1862 ECB             : 
    1863                 :     /* Convert 'count' to a numeric, for ease of use later */
    1864 CBC         372 :     int64_to_numericvar((int64) count, &count_var);
    1865 ECB             : 
    1866 GIC         372 :     switch (cmp_numerics(bound1, bound2))
    1867 ECB             :     {
    1868 GIC           3 :         case 0:
    1869               3 :             ereport(ERROR,
    1870 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1871                 :                      errmsg("lower bound cannot equal upper bound")));
    1872                 :             break;
    1873                 : 
    1874                 :             /* bound1 < bound2 */
    1875 GIC         273 :         case -1:
    1876             273 :             if (cmp_numerics(operand, bound1) < 0)
    1877 CBC          57 :                 set_var_from_var(&const_zero, &result_var);
    1878 GIC         216 :             else if (cmp_numerics(operand, bound2) >= 0)
    1879              54 :                 add_var(&count_var, &const_one, &result_var);
    1880                 :             else
    1881 CBC         162 :                 compute_bucket(operand, bound1, bound2, &count_var, false,
    1882                 :                                &result_var);
    1883 GIC         273 :             break;
    1884                 : 
    1885                 :             /* bound1 > bound2 */
    1886              96 :         case 1:
    1887              96 :             if (cmp_numerics(operand, bound1) > 0)
    1888               6 :                 set_var_from_var(&const_zero, &result_var);
    1889              90 :             else if (cmp_numerics(operand, bound2) <= 0)
    1890              12 :                 add_var(&count_var, &const_one, &result_var);
    1891                 :             else
    1892              78 :                 compute_bucket(operand, bound1, bound2, &count_var, true,
    1893                 :                                &result_var);
    1894              96 :             break;
    1895                 :     }
    1896                 : 
    1897                 :     /* if result exceeds the range of a legal int4, we ereport here */
    1898             369 :     if (!numericvar_to_int32(&result_var, &result))
    1899 LBC           0 :         ereport(ERROR,
    1900                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1901 ECB             :                  errmsg("integer out of range")));
    1902                 : 
    1903 CBC         369 :     free_var(&count_var);
    1904             369 :     free_var(&result_var);
    1905                 : 
    1906 GIC         369 :     PG_RETURN_INT32(result);
    1907                 : }
    1908                 : 
    1909 ECB             : /*
    1910                 :  * 'operand' is inside the bucket range, so determine the correct
    1911                 :  * bucket for it to go. The calculations performed by this function
    1912                 :  * are derived directly from the SQL2003 spec. Note however that we
    1913                 :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    1914                 :  */
    1915                 : static void
    1916 CBC         240 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    1917                 :                const NumericVar *count_var, bool reversed_bounds,
    1918 ECB             :                NumericVar *result_var)
    1919                 : {
    1920                 :     NumericVar  bound1_var;
    1921                 :     NumericVar  bound2_var;
    1922                 :     NumericVar  operand_var;
    1923                 : 
    1924 GIC         240 :     init_var_from_num(bound1, &bound1_var);
    1925 CBC         240 :     init_var_from_num(bound2, &bound2_var);
    1926             240 :     init_var_from_num(operand, &operand_var);
    1927                 : 
    1928 GIC         240 :     if (!reversed_bounds)
    1929                 :     {
    1930             162 :         sub_var(&operand_var, &bound1_var, &operand_var);
    1931 CBC         162 :         sub_var(&bound2_var, &bound1_var, &bound2_var);
    1932 ECB             :     }
    1933                 :     else
    1934                 :     {
    1935 CBC          78 :         sub_var(&bound1_var, &operand_var, &operand_var);
    1936 GIC          78 :         sub_var(&bound1_var, &bound2_var, &bound2_var);
    1937 ECB             :     }
    1938                 : 
    1939 CBC         240 :     mul_var(&operand_var, count_var, &operand_var,
    1940             240 :             operand_var.dscale + count_var->dscale);
    1941 GIC         240 :     div_var(&operand_var, &bound2_var, result_var,
    1942                 :             select_div_scale(&operand_var, &bound2_var), true);
    1943                 : 
    1944                 :     /*
    1945                 :      * Roundoff in the division could give us a quotient exactly equal to
    1946                 :      * "count", which is too large.  Clamp so that we do not emit a result
    1947                 :      * larger than "count".
    1948                 :      */
    1949 GNC         240 :     if (cmp_var(result_var, count_var) >= 0)
    1950               6 :         set_var_from_var(count_var, result_var);
    1951                 :     else
    1952                 :     {
    1953             234 :         add_var(result_var, &const_one, result_var);
    1954             234 :         floor_var(result_var, result_var);
    1955                 :     }
    1956                 : 
    1957 CBC         240 :     free_var(&bound1_var);
    1958             240 :     free_var(&bound2_var);
    1959             240 :     free_var(&operand_var);
    1960             240 : }
    1961 ECB             : 
    1962                 : /* ----------------------------------------------------------------------
    1963                 :  *
    1964                 :  * Comparison functions
    1965                 :  *
    1966                 :  * Note: btree indexes need these routines not to leak memory; therefore,
    1967                 :  * be careful to free working copies of toasted datums.  Most places don't
    1968                 :  * need to be so careful.
    1969                 :  *
    1970                 :  * Sort support:
    1971                 :  *
    1972                 :  * We implement the sortsupport strategy routine in order to get the benefit of
    1973                 :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    1974                 :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    1975                 :  * while this could be worked on itself, the abbreviation strategy gives more
    1976                 :  * speedup in many common cases.
    1977                 :  *
    1978                 :  * Two different representations are used for the abbreviated form, one in
    1979                 :  * int32 and one in int64, whichever fits into a by-value Datum.  In both cases
    1980                 :  * the representation is negated relative to the original value, because we use
    1981 EUB             :  * the largest negative value for NaN, which sorts higher than other values. We
    1982                 :  * convert the absolute value of the numeric to a 31-bit or 63-bit positive
    1983                 :  * value, and then negate it if the original number was positive.
    1984                 :  *
    1985 ECB             :  * We abort the abbreviation process if the abbreviation cardinality is below
    1986                 :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    1987                 :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    1988                 :  * very small penalty), but we don't want to build up too many abbreviated
    1989                 :  * values before first testing for abort, so we take the slightly pessimistic
    1990                 :  * number.  We make no attempt to estimate the cardinality of the real values,
    1991                 :  * since it plays no part in the cost model here (if the abbreviation is equal,
    1992                 :  * the cost of comparing equal and unequal underlying values is comparable).
    1993                 :  * We discontinue even checking for abort (saving us the hashing overhead) if
    1994                 :  * the estimated cardinality gets to 100k; that would be enough to support many
    1995                 :  * billions of rows while doing no worse than breaking even.
    1996                 :  *
    1997                 :  * ----------------------------------------------------------------------
    1998                 :  */
    1999                 : 
    2000                 : /*
    2001                 :  * Sort support strategy routine.
    2002                 :  */
    2003                 : Datum
    2004 GIC         463 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2005                 : {
    2006 CBC         463 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2007 ECB             : 
    2008 CBC         463 :     ssup->comparator = numeric_fast_cmp;
    2009                 : 
    2010             463 :     if (ssup->abbreviate)
    2011                 :     {
    2012 ECB             :         NumericSortSupport *nss;
    2013 CBC         111 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2014                 : 
    2015 GIC         111 :         nss = palloc(sizeof(NumericSortSupport));
    2016                 : 
    2017 ECB             :         /*
    2018                 :          * palloc a buffer for handling unaligned packed values in addition to
    2019                 :          * the support struct
    2020                 :          */
    2021 CBC         111 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2022 ECB             : 
    2023 CBC         111 :         nss->input_count = 0;
    2024 GIC         111 :         nss->estimating = true;
    2025             111 :         initHyperLogLog(&nss->abbr_card, 10);
    2026                 : 
    2027             111 :         ssup->ssup_extra = nss;
    2028                 : 
    2029             111 :         ssup->abbrev_full_comparator = ssup->comparator;
    2030             111 :         ssup->comparator = numeric_cmp_abbrev;
    2031 CBC         111 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2032             111 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2033                 : 
    2034 GIC         111 :         MemoryContextSwitchTo(oldcontext);
    2035 ECB             :     }
    2036                 : 
    2037 GIC         463 :     PG_RETURN_VOID();
    2038                 : }
    2039 ECB             : 
    2040                 : /*
    2041                 :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2042                 :  * (must not leak memory!)
    2043                 :  */
    2044                 : static Datum
    2045 GIC         443 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2046                 : {
    2047             443 :     NumericSortSupport *nss = ssup->ssup_extra;
    2048             443 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2049                 :     Numeric     value;
    2050                 :     Datum       result;
    2051                 : 
    2052             443 :     nss->input_count += 1;
    2053                 : 
    2054                 :     /*
    2055                 :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2056                 :      * we keep and reuse a buffer large enough to handle any short datum.
    2057                 :      */
    2058             443 :     if (VARATT_IS_SHORT(original_varatt))
    2059                 :     {
    2060             408 :         void       *buf = nss->buf;
    2061             408 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2062                 : 
    2063             408 :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2064                 : 
    2065             408 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2066             408 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2067                 : 
    2068             408 :         value = (Numeric) buf;
    2069                 :     }
    2070                 :     else
    2071              35 :         value = (Numeric) original_varatt;
    2072                 : 
    2073             443 :     if (NUMERIC_IS_SPECIAL(value))
    2074                 :     {
    2075              75 :         if (NUMERIC_IS_PINF(value))
    2076              24 :             result = NUMERIC_ABBREV_PINF;
    2077              51 :         else if (NUMERIC_IS_NINF(value))
    2078              24 :             result = NUMERIC_ABBREV_NINF;
    2079                 :         else
    2080              27 :             result = NUMERIC_ABBREV_NAN;
    2081                 :     }
    2082                 :     else
    2083                 :     {
    2084                 :         NumericVar  var;
    2085                 : 
    2086 CBC         368 :         init_var_from_num(value, &var);
    2087                 : 
    2088             368 :         result = numeric_abbrev_convert_var(&var, nss);
    2089                 :     }
    2090 ECB             : 
    2091                 :     /* should happen only for external/compressed toasts */
    2092 CBC         443 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
    2093 UIC           0 :         pfree(original_varatt);
    2094                 : 
    2095 CBC         443 :     return result;
    2096                 : }
    2097 ECB             : 
    2098                 : /*
    2099                 :  * Consider whether to abort abbreviation.
    2100                 :  *
    2101                 :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2102                 :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2103                 :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2104                 :  * whether the underlying values are also equal.
    2105                 :  */
    2106                 : static bool
    2107 CBC           3 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2108                 : {
    2109               3 :     NumericSortSupport *nss = ssup->ssup_extra;
    2110                 :     double      abbr_card;
    2111 ECB             : 
    2112 CBC           3 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2113               3 :         return false;
    2114 ECB             : 
    2115 UIC           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2116 ECB             : 
    2117                 :     /*
    2118                 :      * If we have >100k distinct values, then even if we were sorting many
    2119                 :      * billion rows we'd likely still break even, and the penalty of undoing
    2120                 :      * that many rows of abbrevs would probably not be worth it. Stop even
    2121                 :      * counting at that point.
    2122                 :      */
    2123 UIC           0 :     if (abbr_card > 100000.0)
    2124                 :     {
    2125                 : #ifdef TRACE_SORT
    2126               0 :         if (trace_sort)
    2127 LBC           0 :             elog(LOG,
    2128                 :                  "numeric_abbrev: estimation ends at cardinality %f"
    2129 ECB             :                  " after " INT64_FORMAT " values (%d rows)",
    2130                 :                  abbr_card, nss->input_count, memtupcount);
    2131                 : #endif
    2132 UIC           0 :         nss->estimating = false;
    2133               0 :         return false;
    2134 ECB             :     }
    2135                 : 
    2136                 :     /*
    2137                 :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2138                 :      * break even point is somewhere between one per 100k rows, where
    2139                 :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2140                 :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2141                 :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2142                 :      * abort earlier on genuinely pathological data where we've had exactly
    2143                 :      * one abbreviated value in the first 10k (non-null) rows.
    2144                 :      */
    2145 LBC           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2146                 :     {
    2147 ECB             : #ifdef TRACE_SORT
    2148 LBC           0 :         if (trace_sort)
    2149 UIC           0 :             elog(LOG,
    2150 ECB             :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2151                 :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2152                 :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2153                 :                  nss->input_count, memtupcount);
    2154                 : #endif
    2155 LBC           0 :         return true;
    2156                 :     }
    2157 ECB             : 
    2158                 : #ifdef TRACE_SORT
    2159 LBC           0 :     if (trace_sort)
    2160               0 :         elog(LOG,
    2161                 :              "numeric_abbrev: cardinality %f"
    2162 ECB             :              " after " INT64_FORMAT " values (%d rows)",
    2163                 :              abbr_card, nss->input_count, memtupcount);
    2164                 : #endif
    2165                 : 
    2166 UIC           0 :     return false;
    2167                 : }
    2168 ECB             : 
    2169                 : /*
    2170                 :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2171                 :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2172                 :  * are, but it is a required part of the sort support API when abbreviations
    2173                 :  * are performed.
    2174                 :  *
    2175 EUB             :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2176                 :  * aligning short-varlena inputs, but this has not so far been considered to
    2177 ECB             :  * be worth the effort.
    2178                 :  */
    2179                 : static int
    2180 GIC     2345834 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2181                 : {
    2182         2345834 :     Numeric     nx = DatumGetNumeric(x);
    2183         2345834 :     Numeric     ny = DatumGetNumeric(y);
    2184                 :     int         result;
    2185                 : 
    2186         2345834 :     result = cmp_numerics(nx, ny);
    2187                 : 
    2188         2345834 :     if ((Pointer) nx != DatumGetPointer(x))
    2189 CBC       86331 :         pfree(nx);
    2190 GIC     2345834 :     if ((Pointer) ny != DatumGetPointer(y))
    2191 CBC       86328 :         pfree(ny);
    2192                 : 
    2193 GIC     2345834 :     return result;
    2194 ECB             : }
    2195                 : 
    2196                 : /*
    2197 EUB             :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2198                 :  * values differ, but if the abbreviations differ, they must reflect the
    2199                 :  * ordering of the true values.)
    2200                 :  */
    2201                 : static int
    2202 GIC         463 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2203                 : {
    2204                 :     /*
    2205 EUB             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2206                 :      * negated relative to the original value, to handle NaN/infinity cases.
    2207                 :      */
    2208 GBC         463 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2209              60 :         return 1;
    2210 GIC         403 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2211             370 :         return -1;
    2212              33 :     return 0;
    2213                 : }
    2214 EUB             : 
    2215                 : /*
    2216                 :  * Abbreviate a NumericVar according to the available bit size.
    2217                 :  *
    2218                 :  * The 31-bit value is constructed as:
    2219                 :  *
    2220                 :  *  0 + 7bits digit weight + 24 bits digit value
    2221                 :  *
    2222                 :  * where the digit weight is in single decimal digits, not digit words, and
    2223                 :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2224                 :  * significant decimal digits of the value converted to binary. Values whose
    2225                 :  * weights would fall outside the representable range are rounded off to zero
    2226                 :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2227                 :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2228                 :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2229                 :  * to be a serious limitation, or when values are of the same magnitude and
    2230                 :  * equal in the first 7 decimal digits, which is considered to be an
    2231                 :  * unavoidable limitation given the available bits. (Stealing three more bits
    2232                 :  * to compare another digit would narrow the range of representable weights by
    2233                 :  * a factor of 8, which starts to look like a real limiting factor.)
    2234                 :  *
    2235                 :  * (The value 44 for the excess is essentially arbitrary)
    2236                 :  *
    2237                 :  * The 63-bit value is constructed as:
    2238                 :  *
    2239                 :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2240                 :  *
    2241                 :  * The weight in this case is again stored in excess-44, but this time it is
    2242                 :  * the original weight in digit words (i.e. powers of 10000). The first four
    2243                 :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2244                 :  * are packed into 14 bits each to form the rest of the value. Again,
    2245                 :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2246                 :  * representable range in this case is 10^-176 to 10^332, which is considered
    2247                 :  * to be good enough for all practical purposes, and comparison of 4 words
    2248                 :  * means that at least 13 decimal digits are compared, which is considered to
    2249                 :  * be a reasonable compromise between effectiveness and efficiency in computing
    2250                 :  * the abbreviation.
    2251                 :  *
    2252                 :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2253                 :  * to match the value used in the 31-bit case)
    2254                 :  *
    2255                 :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2256                 :  * and then treated as unsigned, so the smallest representable value is stored
    2257                 :  * with all bits zero. This allows simple comparisons to work on the composite
    2258                 :  * value.
    2259                 :  */
    2260                 : 
    2261                 : #if NUMERIC_ABBREV_BITS == 64
    2262 ECB             : 
    2263                 : static Datum
    2264 CBC         368 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2265 ECB             : {
    2266 GIC         368 :     int         ndigits = var->ndigits;
    2267             368 :     int         weight = var->weight;
    2268 ECB             :     int64       result;
    2269                 : 
    2270 CBC         368 :     if (ndigits == 0 || weight < -44)
    2271 ECB             :     {
    2272 CBC          26 :         result = 0;
    2273 ECB             :     }
    2274 GIC         342 :     else if (weight > 83)
    2275 ECB             :     {
    2276 GIC           6 :         result = PG_INT64_MAX;
    2277                 :     }
    2278                 :     else
    2279                 :     {
    2280             336 :         result = ((int64) (weight + 44) << 56);
    2281                 : 
    2282             336 :         switch (ndigits)
    2283                 :         {
    2284 LBC           0 :             default:
    2285 UIC           0 :                 result |= ((int64) var->digits[3]);
    2286                 :                 /* FALLTHROUGH */
    2287 GIC           2 :             case 3:
    2288               2 :                 result |= ((int64) var->digits[2]) << 14;
    2289                 :                 /* FALLTHROUGH */
    2290 CBC          80 :             case 2:
    2291              80 :                 result |= ((int64) var->digits[1]) << 28;
    2292 ECB             :                 /* FALLTHROUGH */
    2293 CBC         336 :             case 1:
    2294             336 :                 result |= ((int64) var->digits[0]) << 42;
    2295 GIC         336 :                 break;
    2296                 :         }
    2297                 :     }
    2298                 : 
    2299                 :     /* the abbrev is negated relative to the original */
    2300             368 :     if (var->sign == NUMERIC_POS)
    2301             319 :         result = -result;
    2302                 : 
    2303             368 :     if (nss->estimating)
    2304                 :     {
    2305             368 :         uint32      tmp = ((uint32) result
    2306             368 :                            ^ (uint32) ((uint64) result >> 32));
    2307                 : 
    2308             368 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2309                 :     }
    2310                 : 
    2311             368 :     return NumericAbbrevGetDatum(result);
    2312                 : }
    2313                 : 
    2314                 : #endif                          /* NUMERIC_ABBREV_BITS == 64 */
    2315                 : 
    2316                 : #if NUMERIC_ABBREV_BITS == 32
    2317                 : 
    2318                 : static Datum
    2319                 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2320                 : {
    2321                 :     int         ndigits = var->ndigits;
    2322                 :     int         weight = var->weight;
    2323                 :     int32       result;
    2324                 : 
    2325                 :     if (ndigits == 0 || weight < -11)
    2326                 :     {
    2327                 :         result = 0;
    2328                 :     }
    2329                 :     else if (weight > 20)
    2330                 :     {
    2331                 :         result = PG_INT32_MAX;
    2332                 :     }
    2333                 :     else
    2334                 :     {
    2335                 :         NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
    2336                 : 
    2337                 :         weight = (weight + 11) * 4;
    2338                 : 
    2339                 :         result = var->digits[0];
    2340                 : 
    2341                 :         /*
    2342                 :          * "result" now has 1 to 4 nonzero decimal digits. We pack in more
    2343                 :          * digits to make 7 in total (largest we can fit in 24 bits)
    2344                 :          */
    2345                 : 
    2346 ECB             :         if (result > 999)
    2347                 :         {
    2348                 :             /* already have 4 digits, add 3 more */
    2349                 :             result = (result * 1000) + (nxt1 / 10);
    2350                 :             weight += 3;
    2351                 :         }
    2352                 :         else if (result > 99)
    2353                 :         {
    2354                 :             /* already have 3 digits, add 4 more */
    2355                 :             result = (result * 10000) + nxt1;
    2356                 :             weight += 2;
    2357                 :         }
    2358                 :         else if (result > 9)
    2359                 :         {
    2360                 :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2361                 : 
    2362                 :             /* already have 2 digits, add 5 more */
    2363                 :             result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
    2364                 :             weight += 1;
    2365                 :         }
    2366 EUB             :         else
    2367                 :         {
    2368                 :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2369 ECB             : 
    2370                 :             /* already have 1 digit, add 6 more */
    2371                 :             result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
    2372                 :         }
    2373                 : 
    2374                 :         result = result | (weight << 24);
    2375                 :     }
    2376                 : 
    2377                 :     /* the abbrev is negated relative to the original */
    2378                 :     if (var->sign == NUMERIC_POS)
    2379                 :         result = -result;
    2380                 : 
    2381                 :     if (nss->estimating)
    2382                 :     {
    2383                 :         uint32      tmp = (uint32) result;
    2384                 : 
    2385                 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2386                 :     }
    2387                 : 
    2388                 :     return NumericAbbrevGetDatum(result);
    2389                 : }
    2390                 : 
    2391                 : #endif                          /* NUMERIC_ABBREV_BITS == 32 */
    2392                 : 
    2393                 : /*
    2394                 :  * Ordinary (non-sortsupport) comparisons follow.
    2395                 :  */
    2396                 : 
    2397                 : Datum
    2398 GIC      468176 : numeric_cmp(PG_FUNCTION_ARGS)
    2399                 : {
    2400          468176 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2401          468176 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2402                 :     int         result;
    2403                 : 
    2404          468176 :     result = cmp_numerics(num1, num2);
    2405                 : 
    2406          468176 :     PG_FREE_IF_COPY(num1, 0);
    2407          468176 :     PG_FREE_IF_COPY(num2, 1);
    2408                 : 
    2409          468176 :     PG_RETURN_INT32(result);
    2410                 : }
    2411                 : 
    2412                 : 
    2413                 : Datum
    2414          317512 : numeric_eq(PG_FUNCTION_ARGS)
    2415                 : {
    2416          317512 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2417          317512 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2418                 :     bool        result;
    2419                 : 
    2420          317512 :     result = cmp_numerics(num1, num2) == 0;
    2421                 : 
    2422          317512 :     PG_FREE_IF_COPY(num1, 0);
    2423          317512 :     PG_FREE_IF_COPY(num2, 1);
    2424                 : 
    2425          317512 :     PG_RETURN_BOOL(result);
    2426                 : }
    2427                 : 
    2428                 : Datum
    2429            2661 : numeric_ne(PG_FUNCTION_ARGS)
    2430                 : {
    2431            2661 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2432            2661 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2433                 :     bool        result;
    2434                 : 
    2435            2661 :     result = cmp_numerics(num1, num2) != 0;
    2436                 : 
    2437            2661 :     PG_FREE_IF_COPY(num1, 0);
    2438            2661 :     PG_FREE_IF_COPY(num2, 1);
    2439                 : 
    2440            2661 :     PG_RETURN_BOOL(result);
    2441                 : }
    2442                 : 
    2443                 : Datum
    2444           18620 : numeric_gt(PG_FUNCTION_ARGS)
    2445                 : {
    2446           18620 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2447           18620 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2448                 :     bool        result;
    2449                 : 
    2450           18620 :     result = cmp_numerics(num1, num2) > 0;
    2451                 : 
    2452           18620 :     PG_FREE_IF_COPY(num1, 0);
    2453           18620 :     PG_FREE_IF_COPY(num2, 1);
    2454                 : 
    2455           18620 :     PG_RETURN_BOOL(result);
    2456                 : }
    2457                 : 
    2458                 : Datum
    2459            8364 : numeric_ge(PG_FUNCTION_ARGS)
    2460                 : {
    2461            8364 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2462            8364 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2463                 :     bool        result;
    2464                 : 
    2465            8364 :     result = cmp_numerics(num1, num2) >= 0;
    2466                 : 
    2467            8364 :     PG_FREE_IF_COPY(num1, 0);
    2468            8364 :     PG_FREE_IF_COPY(num2, 1);
    2469                 : 
    2470            8364 :     PG_RETURN_BOOL(result);
    2471                 : }
    2472                 : 
    2473                 : Datum
    2474           53158 : numeric_lt(PG_FUNCTION_ARGS)
    2475                 : {
    2476           53158 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2477           53158 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2478                 :     bool        result;
    2479                 : 
    2480 CBC       53158 :     result = cmp_numerics(num1, num2) < 0;
    2481                 : 
    2482           53158 :     PG_FREE_IF_COPY(num1, 0);
    2483           53158 :     PG_FREE_IF_COPY(num2, 1);
    2484                 : 
    2485 GIC       53158 :     PG_RETURN_BOOL(result);
    2486 ECB             : }
    2487                 : 
    2488                 : Datum
    2489 CBC        8246 : numeric_le(PG_FUNCTION_ARGS)
    2490                 : {
    2491            8246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2492 GIC        8246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2493                 :     bool        result;
    2494                 : 
    2495            8246 :     result = cmp_numerics(num1, num2) <= 0;
    2496 ECB             : 
    2497 GIC        8246 :     PG_FREE_IF_COPY(num1, 0);
    2498 CBC        8246 :     PG_FREE_IF_COPY(num2, 1);
    2499 ECB             : 
    2500 GIC        8246 :     PG_RETURN_BOOL(result);
    2501                 : }
    2502 ECB             : 
    2503                 : static int
    2504 CBC     3223747 : cmp_numerics(Numeric num1, Numeric num2)
    2505 ECB             : {
    2506                 :     int         result;
    2507                 : 
    2508                 :     /*
    2509                 :      * We consider all NANs to be equal and larger than any non-NAN (including
    2510                 :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2511                 :      * a consistent sort order.
    2512                 :      */
    2513 CBC     3223747 :     if (NUMERIC_IS_SPECIAL(num1))
    2514 ECB             :     {
    2515 GIC        4450 :         if (NUMERIC_IS_NAN(num1))
    2516                 :         {
    2517 CBC        4405 :             if (NUMERIC_IS_NAN(num2))
    2518 GIC         574 :                 result = 0;     /* NAN = NAN */
    2519 ECB             :             else
    2520 CBC        3831 :                 result = 1;     /* NAN > non-NAN */
    2521                 :         }
    2522              45 :         else if (NUMERIC_IS_PINF(num1))
    2523                 :         {
    2524 GIC          36 :             if (NUMERIC_IS_NAN(num2))
    2525 UIC           0 :                 result = -1;    /* PINF < NAN */
    2526 CBC          36 :             else if (NUMERIC_IS_PINF(num2))
    2527 GIC           3 :                 result = 0;     /* PINF = PINF */
    2528 ECB             :             else
    2529 CBC          33 :                 result = 1;     /* PINF > anything else */
    2530                 :         }
    2531                 :         else                    /* num1 must be NINF */
    2532 ECB             :         {
    2533 GIC           9 :             if (NUMERIC_IS_NINF(num2))
    2534 CBC           3 :                 result = 0;     /* NINF = NINF */
    2535 ECB             :             else
    2536 GIC           6 :                 result = -1;    /* NINF < anything else */
    2537 ECB             :         }
    2538                 :     }
    2539 GIC     3219297 :     else if (NUMERIC_IS_SPECIAL(num2))
    2540                 :     {
    2541 CBC        5628 :         if (NUMERIC_IS_NINF(num2))
    2542 GIC           6 :             result = 1;         /* normal > NINF */
    2543 ECB             :         else
    2544 CBC        5622 :             result = -1;        /* normal < NAN or PINF */
    2545                 :     }
    2546                 :     else
    2547 ECB             :     {
    2548 GIC     6427872 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2549 CBC     3213821 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2550         3213669 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2551 GIC     3214051 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2552 ECB             :     }
    2553                 : 
    2554 GIC     3223747 :     return result;
    2555                 : }
    2556 ECB             : 
    2557                 : /*
    2558                 :  * in_range support function for numeric.
    2559                 :  */
    2560                 : Datum
    2561 GIC         576 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2562 ECB             : {
    2563 GIC         576 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2564 CBC         576 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2565             576 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2566 GIC         576 :     bool        sub = PG_GETARG_BOOL(3);
    2567 CBC         576 :     bool        less = PG_GETARG_BOOL(4);
    2568                 :     bool        result;
    2569                 : 
    2570                 :     /*
    2571 ECB             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2572                 :      * and NaN is because appropriate semantics for that seem non-obvious.
    2573                 :      */
    2574 CBC         576 :     if (NUMERIC_IS_NAN(offset) ||
    2575 GIC         573 :         NUMERIC_IS_NINF(offset) ||
    2576             573 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2577 CBC           3 :         ereport(ERROR,
    2578                 :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2579 ECB             :                  errmsg("invalid preceding or following size in window function")));
    2580                 : 
    2581                 :     /*
    2582                 :      * Deal with cases where val and/or base is NaN, following the rule that
    2583                 :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2584                 :      * the conclusion.
    2585                 :      */
    2586 CBC         573 :     if (NUMERIC_IS_NAN(val))
    2587                 :     {
    2588 GIC          93 :         if (NUMERIC_IS_NAN(base))
    2589              30 :             result = true;      /* NAN = NAN */
    2590                 :         else
    2591              63 :             result = !less;     /* NAN > non-NAN */
    2592                 :     }
    2593             480 :     else if (NUMERIC_IS_NAN(base))
    2594                 :     {
    2595 CBC          63 :         result = less;          /* non-NAN < NAN */
    2596                 :     }
    2597 ECB             : 
    2598                 :     /*
    2599                 :      * Deal with infinite offset (necessarily +Inf, at this point).
    2600                 :      */
    2601 GIC         417 :     else if (NUMERIC_IS_SPECIAL(offset))
    2602 ECB             :     {
    2603 GIC         210 :         Assert(NUMERIC_IS_PINF(offset));
    2604 CBC         210 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2605                 :         {
    2606 ECB             :             /*
    2607 EUB             :              * base +/- offset would produce NaN, so return true for any val
    2608 ECB             :              * (see in_range_float8_float8() for reasoning).
    2609                 :              */
    2610 GIC          87 :             result = true;
    2611 ECB             :         }
    2612 GIC         123 :         else if (sub)
    2613                 :         {
    2614                 :             /* base - offset must be -inf */
    2615 CBC          75 :             if (less)
    2616              27 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2617                 :             else
    2618              48 :                 result = true;  /* any val is >= sum */
    2619                 :         }
    2620                 :         else
    2621 ECB             :         {
    2622                 :             /* base + offset must be +inf */
    2623 CBC          48 :             if (less)
    2624 LBC           0 :                 result = true;  /* any val is <= sum */
    2625                 :             else
    2626 CBC          48 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2627                 :         }
    2628                 :     }
    2629                 : 
    2630 ECB             :     /*
    2631                 :      * Deal with cases where val and/or base is infinite.  The offset, being
    2632                 :      * now known finite, cannot affect the conclusion.
    2633                 :      */
    2634 GIC         207 :     else if (NUMERIC_IS_SPECIAL(val))
    2635                 :     {
    2636 CBC          39 :         if (NUMERIC_IS_PINF(val))
    2637                 :         {
    2638 GIC          18 :             if (NUMERIC_IS_PINF(base))
    2639              12 :                 result = true;  /* PINF = PINF */
    2640                 :             else
    2641               6 :                 result = !less; /* PINF > any other non-NAN */
    2642                 :         }
    2643 ECB             :         else                    /* val must be NINF */
    2644                 :         {
    2645 CBC          21 :             if (NUMERIC_IS_NINF(base))
    2646              15 :                 result = true;  /* NINF = NINF */
    2647 ECB             :             else
    2648 CBC           6 :                 result = less;  /* NINF < anything else */
    2649 ECB             :         }
    2650                 :     }
    2651 GIC         168 :     else if (NUMERIC_IS_SPECIAL(base))
    2652                 :     {
    2653              12 :         if (NUMERIC_IS_NINF(base))
    2654               6 :             result = !less;     /* normal > NINF */
    2655                 :         else
    2656 CBC           6 :             result = less;      /* normal < PINF */
    2657 ECB             :     }
    2658                 :     else
    2659                 :     {
    2660                 :         /*
    2661                 :          * Otherwise go ahead and compute base +/- offset.  While it's
    2662                 :          * possible for this to overflow the numeric format, it's unlikely
    2663                 :          * enough that we don't take measures to prevent it.
    2664                 :          */
    2665                 :         NumericVar  valv;
    2666                 :         NumericVar  basev;
    2667                 :         NumericVar  offsetv;
    2668                 :         NumericVar  sum;
    2669                 : 
    2670 CBC         156 :         init_var_from_num(val, &valv);
    2671             156 :         init_var_from_num(base, &basev);
    2672 GIC         156 :         init_var_from_num(offset, &offsetv);
    2673 CBC         156 :         init_var(&sum);
    2674                 : 
    2675             156 :         if (sub)
    2676 GIC          78 :             sub_var(&basev, &offsetv, &sum);
    2677 ECB             :         else
    2678 GIC          78 :             add_var(&basev, &offsetv, &sum);
    2679                 : 
    2680             156 :         if (less)
    2681              78 :             result = (cmp_var(&valv, &sum) <= 0);
    2682                 :         else
    2683 CBC          78 :             result = (cmp_var(&valv, &sum) >= 0);
    2684                 : 
    2685             156 :         free_var(&sum);
    2686 ECB             :     }
    2687                 : 
    2688 GIC         573 :     PG_FREE_IF_COPY(val, 0);
    2689             573 :     PG_FREE_IF_COPY(base, 1);
    2690             573 :     PG_FREE_IF_COPY(offset, 2);
    2691                 : 
    2692 CBC         573 :     PG_RETURN_BOOL(result);
    2693                 : }
    2694 ECB             : 
    2695                 : Datum
    2696 GIC      296013 : hash_numeric(PG_FUNCTION_ARGS)
    2697 ECB             : {
    2698 CBC      296013 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2699                 :     Datum       digit_hash;
    2700 ECB             :     Datum       result;
    2701                 :     int         weight;
    2702                 :     int         start_offset;
    2703                 :     int         end_offset;
    2704                 :     int         i;
    2705                 :     int         hash_len;
    2706 EUB             :     NumericDigit *digits;
    2707                 : 
    2708 ECB             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2709 GIC      296013 :     if (NUMERIC_IS_SPECIAL(key))
    2710 UIC           0 :         PG_RETURN_UINT32(0);
    2711                 : 
    2712 GIC      296013 :     weight = NUMERIC_WEIGHT(key);
    2713          296013 :     start_offset = 0;
    2714          296013 :     end_offset = 0;
    2715                 : 
    2716 ECB             :     /*
    2717                 :      * Omit any leading or trailing zeros from the input to the hash. The
    2718                 :      * numeric implementation *should* guarantee that leading and trailing
    2719                 :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2720                 :      * starting and ending offsets in units of NumericDigits, not bytes.
    2721                 :      */
    2722 GIC      296013 :     digits = NUMERIC_DIGITS(key);
    2723 CBC      296013 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2724                 :     {
    2725 GIC      295266 :         if (digits[i] != (NumericDigit) 0)
    2726          295266 :             break;
    2727 ECB             : 
    2728 LBC           0 :         start_offset++;
    2729                 : 
    2730 ECB             :         /*
    2731                 :          * The weight is effectively the # of digits before the decimal point,
    2732                 :          * so decrement it for each leading zero we skip.
    2733                 :          */
    2734 UIC           0 :         weight--;
    2735 ECB             :     }
    2736                 : 
    2737                 :     /*
    2738                 :      * If there are no non-zero digits, then the value of the number is zero,
    2739                 :      * regardless of any other fields.
    2740                 :      */
    2741 GIC      296013 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2742             747 :         PG_RETURN_UINT32(-1);
    2743                 : 
    2744          295266 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2745                 :     {
    2746          295266 :         if (digits[i] != (NumericDigit) 0)
    2747          295266 :             break;
    2748                 : 
    2749 UIC           0 :         end_offset++;
    2750                 :     }
    2751                 : 
    2752 ECB             :     /* If we get here, there should be at least one non-zero digit */
    2753 CBC      295266 :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2754 ECB             : 
    2755                 :     /*
    2756                 :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2757                 :      * compare equal but have different scales. We also don't hash on the
    2758                 :      * sign, although we could: since a sign difference implies inequality,
    2759                 :      * this shouldn't affect correctness.
    2760                 :      */
    2761 GIC      295266 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2762 CBC      295266 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2763 ECB             :                           hash_len * sizeof(NumericDigit));
    2764                 : 
    2765                 :     /* Mix in the weight, via XOR */
    2766 GIC      295266 :     result = digit_hash ^ weight;
    2767 ECB             : 
    2768 GIC      295266 :     PG_RETURN_DATUM(result);
    2769                 : }
    2770 ECB             : 
    2771                 : /*
    2772                 :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2773                 :  * Otherwise, similar to hash_numeric.
    2774                 :  */
    2775                 : Datum
    2776 GIC          42 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2777                 : {
    2778 CBC          42 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2779 GIC          42 :     uint64      seed = PG_GETARG_INT64(1);
    2780 ECB             :     Datum       digit_hash;
    2781                 :     Datum       result;
    2782                 :     int         weight;
    2783                 :     int         start_offset;
    2784                 :     int         end_offset;
    2785                 :     int         i;
    2786                 :     int         hash_len;
    2787                 :     NumericDigit *digits;
    2788                 : 
    2789                 :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2790 GIC          42 :     if (NUMERIC_IS_SPECIAL(key))
    2791 LBC           0 :         PG_RETURN_UINT64(seed);
    2792 EUB             : 
    2793 GIC          42 :     weight = NUMERIC_WEIGHT(key);
    2794 CBC          42 :     start_offset = 0;
    2795              42 :     end_offset = 0;
    2796 ECB             : 
    2797 GIC          42 :     digits = NUMERIC_DIGITS(key);
    2798              42 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2799                 :     {
    2800              36 :         if (digits[i] != (NumericDigit) 0)
    2801              36 :             break;
    2802                 : 
    2803 UIC           0 :         start_offset++;
    2804 ECB             : 
    2805 LBC           0 :         weight--;
    2806                 :     }
    2807 ECB             : 
    2808 CBC          42 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2809 GIC           6 :         PG_RETURN_UINT64(seed - 1);
    2810 EUB             : 
    2811 GIC          36 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2812                 :     {
    2813              36 :         if (digits[i] != (NumericDigit) 0)
    2814              36 :             break;
    2815                 : 
    2816 UBC           0 :         end_offset++;
    2817                 :     }
    2818                 : 
    2819 GIC          36 :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2820                 : 
    2821              36 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2822              36 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2823 CBC          36 :                                                       + start_offset),
    2824 ECB             :                                    hash_len * sizeof(NumericDigit),
    2825                 :                                    seed);
    2826                 : 
    2827 GIC          36 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2828 ECB             : 
    2829 CBC          36 :     PG_RETURN_DATUM(result);
    2830                 : }
    2831 EUB             : 
    2832                 : 
    2833                 : /* ----------------------------------------------------------------------
    2834                 :  *
    2835 ECB             :  * Basic arithmetic functions
    2836                 :  *
    2837                 :  * ----------------------------------------------------------------------
    2838                 :  */
    2839                 : 
    2840                 : 
    2841                 : /*
    2842                 :  * numeric_add() -
    2843                 :  *
    2844                 :  *  Add two numerics
    2845                 :  */
    2846                 : Datum
    2847 GIC      125968 : numeric_add(PG_FUNCTION_ARGS)
    2848 ECB             : {
    2849 GIC      125968 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2850 CBC      125968 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2851                 :     Numeric     res;
    2852                 : 
    2853 GIC      125968 :     res = numeric_add_opt_error(num1, num2, NULL);
    2854                 : 
    2855          125968 :     PG_RETURN_NUMERIC(res);
    2856                 : }
    2857                 : 
    2858 ECB             : /*
    2859                 :  * numeric_add_opt_error() -
    2860                 :  *
    2861                 :  *  Internal version of numeric_add().  If "*have_error" flag is provided,
    2862                 :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2863                 :  *  need to handle errors by itself.
    2864                 :  */
    2865                 : Numeric
    2866 GIC      126391 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2867                 : {
    2868                 :     NumericVar  arg1;
    2869                 :     NumericVar  arg2;
    2870                 :     NumericVar  result;
    2871                 :     Numeric     res;
    2872 ECB             : 
    2873 EUB             :     /*
    2874                 :      * Handle NaN and infinities
    2875 ECB             :      */
    2876 CBC      126391 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2877 ECB             :     {
    2878 GIC          99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2879 CBC          39 :             return make_result(&const_nan);
    2880              60 :         if (NUMERIC_IS_PINF(num1))
    2881                 :         {
    2882              18 :             if (NUMERIC_IS_NINF(num2))
    2883               3 :                 return make_result(&const_nan); /* Inf + -Inf */
    2884                 :             else
    2885 GBC          15 :                 return make_result(&const_pinf);
    2886                 :         }
    2887              42 :         if (NUMERIC_IS_NINF(num1))
    2888                 :         {
    2889 GIC          18 :             if (NUMERIC_IS_PINF(num2))
    2890 CBC           3 :                 return make_result(&const_nan); /* -Inf + Inf */
    2891 ECB             :             else
    2892 GIC          15 :                 return make_result(&const_ninf);
    2893 ECB             :         }
    2894                 :         /* by here, num1 must be finite, so num2 is not */
    2895 CBC          24 :         if (NUMERIC_IS_PINF(num2))
    2896              12 :             return make_result(&const_pinf);
    2897 GIC          12 :         Assert(NUMERIC_IS_NINF(num2));
    2898 GBC          12 :         return make_result(&const_ninf);
    2899                 :     }
    2900                 : 
    2901 ECB             :     /*
    2902                 :      * Unpack the values, let add_var() compute the result and return it.
    2903                 :      */
    2904 CBC      126292 :     init_var_from_num(num1, &arg1);
    2905          126292 :     init_var_from_num(num2, &arg2);
    2906                 : 
    2907 GIC      126292 :     init_var(&result);
    2908          126292 :     add_var(&arg1, &arg2, &result);
    2909 ECB             : 
    2910 GIC      126292 :     res = make_result_opt_error(&result, have_error);
    2911 ECB             : 
    2912 GIC      126292 :     free_var(&result);
    2913                 : 
    2914          126292 :     return res;
    2915                 : }
    2916                 : 
    2917                 : 
    2918                 : /*
    2919                 :  * numeric_sub() -
    2920                 :  *
    2921                 :  *  Subtract one numeric from another
    2922                 :  */
    2923                 : Datum
    2924           27016 : numeric_sub(PG_FUNCTION_ARGS)
    2925                 : {
    2926           27016 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2927           27016 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2928                 :     Numeric     res;
    2929 ECB             : 
    2930 GIC       27016 :     res = numeric_sub_opt_error(num1, num2, NULL);
    2931 ECB             : 
    2932 CBC       27016 :     PG_RETURN_NUMERIC(res);
    2933                 : }
    2934                 : 
    2935 ECB             : 
    2936                 : /*
    2937                 :  * numeric_sub_opt_error() -
    2938                 :  *
    2939                 :  *  Internal version of numeric_sub().  If "*have_error" flag is provided,
    2940                 :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2941                 :  *  need to handle errors by itself.
    2942                 :  */
    2943                 : Numeric
    2944 GIC       27043 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2945                 : {
    2946                 :     NumericVar  arg1;
    2947                 :     NumericVar  arg2;
    2948 ECB             :     NumericVar  result;
    2949                 :     Numeric     res;
    2950                 : 
    2951                 :     /*
    2952                 :      * Handle NaN and infinities
    2953                 :      */
    2954 GIC       27043 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2955                 :     {
    2956            1205 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2957            1145 :             return make_result(&const_nan);
    2958 CBC          60 :         if (NUMERIC_IS_PINF(num1))
    2959                 :         {
    2960              18 :             if (NUMERIC_IS_PINF(num2))
    2961               3 :                 return make_result(&const_nan); /* Inf - Inf */
    2962 ECB             :             else
    2963 GIC          15 :                 return make_result(&const_pinf);
    2964 ECB             :         }
    2965 CBC          42 :         if (NUMERIC_IS_NINF(num1))
    2966                 :         {
    2967              18 :             if (NUMERIC_IS_NINF(num2))
    2968 GIC           3 :                 return make_result(&const_nan); /* -Inf - -Inf */
    2969 ECB             :             else
    2970 GIC          15 :                 return make_result(&const_ninf);
    2971 ECB             :         }
    2972                 :         /* by here, num1 must be finite, so num2 is not */
    2973 GIC          24 :         if (NUMERIC_IS_PINF(num2))
    2974 CBC          12 :             return make_result(&const_ninf);
    2975 GIC          12 :         Assert(NUMERIC_IS_NINF(num2));
    2976              12 :         return make_result(&const_pinf);
    2977 ECB             :     }
    2978                 : 
    2979                 :     /*
    2980                 :      * Unpack the values, let sub_var() compute the result and return it.
    2981                 :      */
    2982 GIC       25838 :     init_var_from_num(num1, &arg1);
    2983           25838 :     init_var_from_num(num2, &arg2);
    2984                 : 
    2985           25838 :     init_var(&result);
    2986 CBC       25838 :     sub_var(&arg1, &arg2, &result);
    2987 ECB             : 
    2988 GIC       25838 :     res = make_result_opt_error(&result, have_error);
    2989 ECB             : 
    2990 CBC       25838 :     free_var(&result);
    2991                 : 
    2992           25838 :     return res;
    2993                 : }
    2994 ECB             : 
    2995                 : 
    2996                 : /*
    2997                 :  * numeric_mul() -
    2998                 :  *
    2999                 :  *  Calculate the product of two numerics
    3000                 :  */
    3001                 : Datum
    3002 GIC      244830 : numeric_mul(PG_FUNCTION_ARGS)
    3003                 : {
    3004          244830 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3005          244830 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3006 ECB             :     Numeric     res;
    3007                 : 
    3008 CBC      244830 :     res = numeric_mul_opt_error(num1, num2, NULL);
    3009 ECB             : 
    3010 GIC      244830 :     PG_RETURN_NUMERIC(res);
    3011                 : }
    3012 ECB             : 
    3013                 : 
    3014                 : /*
    3015                 :  * numeric_mul_opt_error() -
    3016                 :  *
    3017                 :  *  Internal version of numeric_mul().  If "*have_error" flag is provided,
    3018                 :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3019                 :  *  need to handle errors by itself.
    3020                 :  */
    3021                 : Numeric
    3022 GIC      244836 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3023                 : {
    3024                 :     NumericVar  arg1;
    3025                 :     NumericVar  arg2;
    3026 ECB             :     NumericVar  result;
    3027                 :     Numeric     res;
    3028                 : 
    3029                 :     /*
    3030                 :      * Handle NaN and infinities
    3031                 :      */
    3032 GIC      244836 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3033                 :     {
    3034              99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3035              39 :             return make_result(&const_nan);
    3036 CBC          60 :         if (NUMERIC_IS_PINF(num1))
    3037                 :         {
    3038              18 :             switch (numeric_sign_internal(num2))
    3039 ECB             :             {
    3040 CBC           3 :                 case 0:
    3041 GIC           3 :                     return make_result(&const_nan); /* Inf * 0 */
    3042 CBC           9 :                 case 1:
    3043               9 :                     return make_result(&const_pinf);
    3044 GIC           6 :                 case -1:
    3045 CBC           6 :                     return make_result(&const_ninf);
    3046                 :             }
    3047 LBC           0 :             Assert(false);
    3048                 :         }
    3049 CBC          42 :         if (NUMERIC_IS_NINF(num1))
    3050 ECB             :         {
    3051 GIC          18 :             switch (numeric_sign_internal(num2))
    3052 ECB             :             {
    3053 GIC           3 :                 case 0:
    3054               3 :                     return make_result(&const_nan); /* -Inf * 0 */
    3055 CBC           9 :                 case 1:
    3056               9 :                     return make_result(&const_ninf);
    3057               6 :                 case -1:
    3058               6 :                     return make_result(&const_pinf);
    3059                 :             }
    3060 UIC           0 :             Assert(false);
    3061                 :         }
    3062                 :         /* by here, num1 must be finite, so num2 is not */
    3063 GIC          24 :         if (NUMERIC_IS_PINF(num2))
    3064 ECB             :         {
    3065 CBC          12 :             switch (numeric_sign_internal(num1))
    3066                 :             {
    3067               3 :                 case 0:
    3068               3 :                     return make_result(&const_nan); /* 0 * Inf */
    3069 GIC           6 :                 case 1:
    3070 CBC           6 :                     return make_result(&const_pinf);
    3071 GIC           3 :                 case -1:
    3072 CBC           3 :                     return make_result(&const_ninf);
    3073                 :             }
    3074 LBC           0 :             Assert(false);
    3075                 :         }
    3076 GIC          12 :         Assert(NUMERIC_IS_NINF(num2));
    3077              12 :         switch (numeric_sign_internal(num1))
    3078                 :         {
    3079               3 :             case 0:
    3080               3 :                 return make_result(&const_nan); /* 0 * -Inf */
    3081               6 :             case 1:
    3082               6 :                 return make_result(&const_ninf);
    3083               3 :             case -1:
    3084 CBC           3 :                 return make_result(&const_pinf);
    3085                 :         }
    3086 LBC           0 :         Assert(false);
    3087 ECB             :     }
    3088                 : 
    3089                 :     /*
    3090                 :      * Unpack the values, let mul_var() compute the result and return it.
    3091                 :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3092                 :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3093                 :      * we request exact representation for the product (rscale = sum(dscale of
    3094                 :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3095                 :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3096                 :      * after computing the exact result ensures that the final result is
    3097                 :      * correctly rounded (rounding in mul_var() using a truncated product
    3098                 :      * would not guarantee this).
    3099                 :      */
    3100 GIC      244737 :     init_var_from_num(num1, &arg1);
    3101          244737 :     init_var_from_num(num2, &arg2);
    3102                 : 
    3103          244737 :     init_var(&result);
    3104 CBC      244737 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3105                 : 
    3106 GIC      244737 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3107               3 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3108                 : 
    3109          244737 :     res = make_result_opt_error(&result, have_error);
    3110                 : 
    3111          244737 :     free_var(&result);
    3112                 : 
    3113          244737 :     return res;
    3114 ECB             : }
    3115                 : 
    3116                 : 
    3117                 : /*
    3118                 :  * numeric_div() -
    3119                 :  *
    3120                 :  *  Divide one numeric into another
    3121                 :  */
    3122                 : Datum
    3123 CBC       60494 : numeric_div(PG_FUNCTION_ARGS)
    3124 ECB             : {
    3125 CBC       60494 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3126           60494 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3127 ECB             :     Numeric     res;
    3128                 : 
    3129 GBC       60494 :     res = numeric_div_opt_error(num1, num2, NULL);
    3130                 : 
    3131 CBC       60478 :     PG_RETURN_NUMERIC(res);
    3132                 : }
    3133 ECB             : 
    3134                 : 
    3135                 : /*
    3136                 :  * numeric_div_opt_error() -
    3137                 :  *
    3138                 :  *  Internal version of numeric_div().  If "*have_error" flag is provided,
    3139                 :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3140                 :  *  need to handle errors by itself.
    3141                 :  */
    3142 EUB             : Numeric
    3143 GIC       60914 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3144                 : {
    3145 ECB             :     NumericVar  arg1;
    3146                 :     NumericVar  arg2;
    3147                 :     NumericVar  result;
    3148                 :     Numeric     res;
    3149                 :     int         rscale;
    3150                 : 
    3151 CBC       60914 :     if (have_error)
    3152              24 :         *have_error = false;
    3153 ECB             : 
    3154                 :     /*
    3155                 :      * Handle NaN and infinities
    3156 EUB             :      */
    3157 GIC       60914 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3158 ECB             :     {
    3159 CBC          99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3160 GIC          39 :             return make_result(&const_nan);
    3161 CBC          60 :         if (NUMERIC_IS_PINF(num1))
    3162 ECB             :         {
    3163 CBC          18 :             if (NUMERIC_IS_SPECIAL(num2))
    3164               6 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3165              12 :             switch (numeric_sign_internal(num2))
    3166 ECB             :             {
    3167 GIC           3 :                 case 0:
    3168 GBC           3 :                     if (have_error)
    3169                 :                     {
    3170 UIC           0 :                         *have_error = true;
    3171               0 :                         return NULL;
    3172                 :                     }
    3173 GIC           3 :                     ereport(ERROR,
    3174                 :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3175                 :                              errmsg("division by zero")));
    3176                 :                     break;
    3177               6 :                 case 1:
    3178               6 :                     return make_result(&const_pinf);
    3179               3 :                 case -1:
    3180               3 :                     return make_result(&const_ninf);
    3181                 :             }
    3182 LBC           0 :             Assert(false);
    3183 ECB             :         }
    3184 GIC          42 :         if (NUMERIC_IS_NINF(num1))
    3185 ECB             :         {
    3186 CBC          18 :             if (NUMERIC_IS_SPECIAL(num2))
    3187 GIC           6 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
    3188 CBC          12 :             switch (numeric_sign_internal(num2))
    3189 ECB             :             {
    3190 GIC           3 :                 case 0:
    3191 CBC           3 :                     if (have_error)
    3192                 :                     {
    3193 LBC           0 :                         *have_error = true;
    3194 UIC           0 :                         return NULL;
    3195 ECB             :                     }
    3196 GIC           3 :                     ereport(ERROR,
    3197                 :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3198                 :                              errmsg("division by zero")));
    3199                 :                     break;
    3200               6 :                 case 1:
    3201               6 :                     return make_result(&const_ninf);
    3202               3 :                 case -1:
    3203               3 :                     return make_result(&const_pinf);
    3204                 :             }
    3205 LBC           0 :             Assert(false);
    3206                 :         }
    3207 ECB             :         /* by here, num1 must be finite, so num2 is not */
    3208                 : 
    3209                 :         /*
    3210                 :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3211                 :          * otherwise throw an underflow error.  But the numeric type doesn't
    3212                 :          * really do underflow, so let's just return zero.
    3213                 :          */
    3214 GIC          24 :         return make_result(&const_zero);
    3215                 :     }
    3216                 : 
    3217                 :     /*
    3218                 :      * Unpack the arguments
    3219                 :      */
    3220           60815 :     init_var_from_num(num1, &arg1);
    3221           60815 :     init_var_from_num(num2, &arg2);
    3222                 : 
    3223           60815 :     init_var(&result);
    3224                 : 
    3225 ECB             :     /*
    3226                 :      * Select scale for division result
    3227                 :      */
    3228 GIC       60815 :     rscale = select_div_scale(&arg1, &arg2);
    3229                 : 
    3230                 :     /*
    3231                 :      * If "have_error" is provided, check for division by zero here
    3232                 :      */
    3233 CBC       60815 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3234 ECB             :     {
    3235 GIC           6 :         *have_error = true;
    3236               6 :         return NULL;
    3237                 :     }
    3238                 : 
    3239 ECB             :     /*
    3240                 :      * Do the divide and return the result
    3241                 :      */
    3242 CBC       60809 :     div_var(&arg1, &arg2, &result, rscale, true);
    3243 ECB             : 
    3244 GIC       60790 :     res = make_result_opt_error(&result, have_error);
    3245 ECB             : 
    3246 CBC       60790 :     free_var(&result);
    3247 ECB             : 
    3248 GIC       60790 :     return res;
    3249 ECB             : }
    3250                 : 
    3251                 : 
    3252 EUB             : /*
    3253                 :  * numeric_div_trunc() -
    3254                 :  *
    3255 ECB             :  *  Divide one numeric into another, truncating the result to an integer
    3256                 :  */
    3257                 : Datum
    3258 GIC         600 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3259 ECB             : {
    3260 CBC         600 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3261             600 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3262 ECB             :     NumericVar  arg1;
    3263                 :     NumericVar  arg2;
    3264 EUB             :     NumericVar  result;
    3265                 :     Numeric     res;
    3266 ECB             : 
    3267                 :     /*
    3268                 :      * Handle NaN and infinities
    3269                 :      */
    3270 CBC         600 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3271                 :     {
    3272              99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3273              39 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3274 GIC          60 :         if (NUMERIC_IS_PINF(num1))
    3275 EUB             :         {
    3276 GBC          18 :             if (NUMERIC_IS_SPECIAL(num2))
    3277 GIC           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3278 CBC          12 :             switch (numeric_sign_internal(num2))
    3279                 :             {
    3280 GIC           3 :                 case 0:
    3281               3 :                     ereport(ERROR,
    3282 ECB             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3283                 :                              errmsg("division by zero")));
    3284                 :                     break;
    3285 CBC           6 :                 case 1:
    3286 GIC           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3287 GBC           3 :                 case -1:
    3288 GIC           3 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3289                 :             }
    3290 UIC           0 :             Assert(false);
    3291                 :         }
    3292 GIC          42 :         if (NUMERIC_IS_NINF(num1))
    3293                 :         {
    3294              18 :             if (NUMERIC_IS_SPECIAL(num2))
    3295               6 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3296 CBC          12 :             switch (numeric_sign_internal(num2))
    3297                 :             {
    3298 GIC           3 :                 case 0:
    3299               3 :                     ereport(ERROR,
    3300                 :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3301                 :                              errmsg("division by zero")));
    3302 ECB             :                     break;
    3303 CBC           6 :                 case 1:
    3304 GIC           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3305 CBC           3 :                 case -1:
    3306 GIC           3 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3307                 :             }
    3308 UIC           0 :             Assert(false);
    3309                 :         }
    3310 ECB             :         /* by here, num1 must be finite, so num2 is not */
    3311                 : 
    3312                 :         /*
    3313                 :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3314                 :          * otherwise throw an underflow error.  But the numeric type doesn't
    3315                 :          * really do underflow, so let's just return zero.
    3316                 :          */
    3317 CBC          24 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3318 ECB             :     }
    3319                 : 
    3320                 :     /*
    3321                 :      * Unpack the arguments
    3322                 :      */
    3323 GIC         501 :     init_var_from_num(num1, &arg1);
    3324 CBC         501 :     init_var_from_num(num2, &arg2);
    3325                 : 
    3326             501 :     init_var(&result);
    3327                 : 
    3328 ECB             :     /*
    3329                 :      * Do the divide and return the result
    3330                 :      */
    3331 GIC         501 :     div_var(&arg1, &arg2, &result, 0, false);
    3332                 : 
    3333             498 :     res = make_result(&result);
    3334                 : 
    3335             498 :     free_var(&result);
    3336                 : 
    3337             498 :     PG_RETURN_NUMERIC(res);
    3338                 : }
    3339                 : 
    3340 ECB             : 
    3341                 : /*
    3342                 :  * numeric_mod() -
    3343                 :  *
    3344                 :  *  Calculate the modulo of two numerics
    3345                 :  */
    3346                 : Datum
    3347 GIC       26283 : numeric_mod(PG_FUNCTION_ARGS)
    3348                 : {
    3349           26283 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3350           26283 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3351                 :     Numeric     res;
    3352 ECB             : 
    3353 GIC       26283 :     res = numeric_mod_opt_error(num1, num2, NULL);
    3354 ECB             : 
    3355 CBC       26274 :     PG_RETURN_NUMERIC(res);
    3356 ECB             : }
    3357                 : 
    3358                 : 
    3359                 : /*
    3360                 :  * numeric_mod_opt_error() -
    3361                 :  *
    3362                 :  *  Internal version of numeric_mod().  If "*have_error" flag is provided,
    3363                 :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3364                 :  *  need to handle errors by itself.
    3365                 :  */
    3366                 : Numeric
    3367 CBC       26289 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3368 ECB             : {
    3369                 :     Numeric     res;
    3370                 :     NumericVar  arg1;
    3371                 :     NumericVar  arg2;
    3372 EUB             :     NumericVar  result;
    3373                 : 
    3374 CBC       26289 :     if (have_error)
    3375 UIC           0 :         *have_error = false;
    3376 ECB             : 
    3377                 :     /*
    3378                 :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3379                 :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3380                 :      * returning NaN.  We choose to throw error only for y-is-zero.
    3381                 :      */
    3382 GIC       26289 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3383                 :     {
    3384              99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3385 CBC          39 :             return make_result(&const_nan);
    3386              60 :         if (NUMERIC_IS_INF(num1))
    3387 ECB             :         {
    3388 CBC          36 :             if (numeric_sign_internal(num2) == 0)
    3389                 :             {
    3390 GBC           6 :                 if (have_error)
    3391                 :                 {
    3392 UIC           0 :                     *have_error = true;
    3393               0 :                     return NULL;
    3394                 :                 }
    3395 GIC           6 :                 ereport(ERROR,
    3396                 :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
    3397                 :                          errmsg("division by zero")));
    3398                 :             }
    3399 ECB             :             /* Inf % any nonzero = NaN */
    3400 GIC          30 :             return make_result(&const_nan);
    3401                 :         }
    3402                 :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3403              24 :         return duplicate_numeric(num1);
    3404                 :     }
    3405 ECB             : 
    3406 CBC       26190 :     init_var_from_num(num1, &arg1);
    3407 GIC       26190 :     init_var_from_num(num2, &arg2);
    3408 ECB             : 
    3409 GIC       26190 :     init_var(&result);
    3410                 : 
    3411                 :     /*
    3412                 :      * If "have_error" is provided, check for division by zero here
    3413 ECB             :      */
    3414 GIC       26190 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3415 ECB             :     {
    3416 UIC           0 :         *have_error = true;
    3417 LBC           0 :         return NULL;
    3418                 :     }
    3419 ECB             : 
    3420 GIC       26190 :     mod_var(&arg1, &arg2, &result);
    3421                 : 
    3422           26184 :     res = make_result_opt_error(&result, NULL);
    3423                 : 
    3424           26184 :     free_var(&result);
    3425                 : 
    3426           26184 :     return res;
    3427                 : }
    3428                 : 
    3429 ECB             : 
    3430                 : /*
    3431                 :  * numeric_inc() -
    3432                 :  *
    3433                 :  *  Increment a number by one
    3434                 :  */
    3435                 : Datum
    3436 GIC          24 : numeric_inc(PG_FUNCTION_ARGS)
    3437 ECB             : {
    3438 GIC          24 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3439                 :     NumericVar  arg;
    3440                 :     Numeric     res;
    3441                 : 
    3442                 :     /*
    3443                 :      * Handle NaN and infinities
    3444                 :      */
    3445              24 :     if (NUMERIC_IS_SPECIAL(num))
    3446               9 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3447                 : 
    3448                 :     /*
    3449 ECB             :      * Compute the result and return it
    3450                 :      */
    3451 GIC          15 :     init_var_from_num(num, &arg);
    3452                 : 
    3453              15 :     add_var(&arg, &const_one, &arg);
    3454                 : 
    3455              15 :     res = make_result(&arg);
    3456 ECB             : 
    3457 GBC          15 :     free_var(&arg);
    3458                 : 
    3459 GIC          15 :     PG_RETURN_NUMERIC(res);
    3460                 : }
    3461                 : 
    3462                 : 
    3463                 : /*
    3464 ECB             :  * numeric_smaller() -
    3465                 :  *
    3466                 :  *  Return the smaller of two numbers
    3467                 :  */
    3468                 : Datum
    3469 GIC         102 : numeric_smaller(PG_FUNCTION_ARGS)
    3470 ECB             : {
    3471 GIC         102 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3472 CBC         102 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3473                 : 
    3474 EUB             :     /*
    3475                 :      * Use cmp_numerics so that this will agree with the comparison operators,
    3476                 :      * particularly as regards comparisons involving NaN.
    3477 ECB             :      */
    3478 GIC         102 :     if (cmp_numerics(num1, num2) < 0)
    3479              42 :         PG_RETURN_NUMERIC(num1);
    3480                 :     else
    3481              60 :         PG_RETURN_NUMERIC(num2);
    3482 ECB             : }
    3483                 : 
    3484                 : 
    3485                 : /*
    3486                 :  * numeric_larger() -
    3487                 :  *
    3488                 :  *  Return the larger of two numbers
    3489                 :  */
    3490                 : Datum
    3491 CBC          27 : numeric_larger(PG_FUNCTION_ARGS)
    3492                 : {
    3493 GIC          27 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3494              27 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3495                 : 
    3496 ECB             :     /*
    3497                 :      * Use cmp_numerics so that this will agree with the comparison operators,
    3498 EUB             :      * particularly as regards comparisons involving NaN.
    3499                 :      */
    3500 GIC          27 :     if (cmp_numerics(num1, num2) > 0)
    3501              18 :         PG_RETURN_NUMERIC(num1);
    3502 ECB             :     else
    3503 GIC           9 :         PG_RETURN_NUMERIC(num2);
    3504 ECB             : }
    3505                 : 
    3506                 : 
    3507                 : /* ----------------------------------------------------------------------
    3508                 :  *
    3509                 :  * Advanced math functions
    3510                 :  *
    3511                 :  * ----------------------------------------------------------------------
    3512                 :  */
    3513                 : 
    3514                 : /*
    3515                 :  * numeric_gcd() -
    3516                 :  *
    3517                 :  *  Calculate the greatest common divisor of two numerics
    3518                 :  */
    3519                 : Datum
    3520 CBC         108 : numeric_gcd(PG_FUNCTION_ARGS)
    3521                 : {
    3522 GIC         108 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3523             108 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3524                 :     NumericVar  arg1;
    3525                 :     NumericVar  arg2;
    3526                 :     NumericVar  result;
    3527 ECB             :     Numeric     res;
    3528                 : 
    3529                 :     /*
    3530                 :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3531                 :      * cases.
    3532                 :      */
    3533 CBC         108 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3534 GIC          48 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3535 ECB             : 
    3536                 :     /*
    3537                 :      * Unpack the arguments
    3538                 :      */
    3539 CBC          60 :     init_var_from_num(num1, &arg1);
    3540 GIC          60 :     init_var_from_num(num2, &arg2);
    3541 ECB             : 
    3542 GIC          60 :     init_var(&result);
    3543                 : 
    3544                 :     /*
    3545                 :      * Find the GCD and return the result
    3546                 :      */
    3547              60 :     gcd_var(&arg1, &arg2, &result);
    3548                 : 
    3549              60 :     res = make_result(&result);
    3550                 : 
    3551 CBC          60 :     free_var(&result);
    3552                 : 
    3553              60 :     PG_RETURN_NUMERIC(res);
    3554 ECB             : }
    3555                 : 
    3556                 : 
    3557                 : /*
    3558                 :  * numeric_lcm() -
    3559                 :  *
    3560                 :  *  Calculate the least common multiple of two numerics
    3561                 :  */
    3562                 : Datum
    3563 CBC         123 : numeric_lcm(PG_FUNCTION_ARGS)
    3564                 : {
    3565 GIC         123 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3566             123 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3567                 :     NumericVar  arg1;
    3568                 :     NumericVar  arg2;
    3569                 :     NumericVar  result;
    3570                 :     Numeric     res;
    3571                 : 
    3572                 :     /*
    3573 ECB             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3574                 :      * cases.
    3575                 :      */
    3576 CBC         123 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3577 GIC          48 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3578                 : 
    3579                 :     /*
    3580                 :      * Unpack the arguments
    3581                 :      */
    3582 CBC          75 :     init_var_from_num(num1, &arg1);
    3583              75 :     init_var_from_num(num2, &arg2);
    3584                 : 
    3585              75 :     init_var(&result);
    3586                 : 
    3587                 :     /*
    3588                 :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3589                 :      * zero if either input is zero.
    3590                 :      *
    3591                 :      * Note that the division is guaranteed to be exact, returning an integer
    3592                 :      * result, so the LCM is an integral multiple of both x and y.  A display
    3593                 :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3594                 :      * but as with other numeric functions, we choose to return a result whose
    3595                 :      * display scale is no smaller than either input.
    3596                 :      */
    3597 GIC          75 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3598              24 :         set_var_from_var(&const_zero, &result);
    3599                 :     else
    3600                 :     {
    3601              51 :         gcd_var(&arg1, &arg2, &result);
    3602 CBC          51 :         div_var(&arg1, &result, &result, 0, false);
    3603 GIC          51 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3604 CBC          51 :         result.sign = NUMERIC_POS;
    3605 ECB             :     }
    3606                 : 
    3607 GIC          75 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3608                 : 
    3609              75 :     res = make_result(&result);
    3610                 : 
    3611              72 :     free_var(&result);
    3612                 : 
    3613              72 :     PG_RETURN_NUMERIC(res);
    3614                 : }
    3615 ECB             : 
    3616                 : 
    3617                 : /*
    3618                 :  * numeric_fac()
    3619                 :  *
    3620                 :  * Compute factorial
    3621                 :  */
    3622                 : Datum
    3623 GIC          21 : numeric_fac(PG_FUNCTION_ARGS)
    3624 ECB             : {
    3625 GIC          21 :     int64       num = PG_GETARG_INT64(0);
    3626                 :     Numeric     res;
    3627                 :     NumericVar  fact;
    3628                 :     NumericVar  result;
    3629 ECB             : 
    3630 GIC          21 :     if (num < 0)
    3631 CBC           3 :         ereport(ERROR,
    3632                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3633 ECB             :                  errmsg("factorial of a negative number is undefined")));
    3634 GIC          18 :     if (num <= 1)
    3635 ECB             :     {
    3636 GIC           3 :         res = make_result(&const_one);
    3637               3 :         PG_RETURN_NUMERIC(res);
    3638                 :     }
    3639                 :     /* Fail immediately if the result would overflow */
    3640              15 :     if (num > 32177)
    3641               3 :         ereport(ERROR,
    3642                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3643                 :                  errmsg("value overflows numeric format")));
    3644                 : 
    3645 CBC          12 :     init_var(&fact);
    3646 GIC          12 :     init_var(&result);
    3647 ECB             : 
    3648 CBC          12 :     int64_to_numericvar(num, &result);
    3649                 : 
    3650 GIC         147 :     for (num = num - 1; num > 1; num--)
    3651                 :     {
    3652                 :         /* this loop can take awhile, so allow it to be interrupted */
    3653             135 :         CHECK_FOR_INTERRUPTS();
    3654                 : 
    3655             135 :         int64_to_numericvar(num, &fact);
    3656                 : 
    3657             135 :         mul_var(&result, &fact, &result, 0);
    3658 ECB             :     }
    3659                 : 
    3660 GIC          12 :     res = make_result(&result);
    3661                 : 
    3662              12 :     free_var(&fact);
    3663              12 :     free_var(&result);
    3664 ECB             : 
    3665 CBC          12 :     PG_RETURN_NUMERIC(res);
    3666                 : }
    3667 ECB             : 
    3668                 : 
    3669                 : /*
    3670                 :  * numeric_sqrt() -
    3671                 :  *
    3672                 :  *  Compute the square root of a numeric.
    3673                 :  */
    3674                 : Datum
    3675 GIC          75 : numeric_sqrt(PG_FUNCTION_ARGS)
    3676                 : {
    3677              75 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3678                 :     Numeric     res;
    3679 ECB             :     NumericVar  arg;
    3680                 :     NumericVar  result;
    3681                 :     int         sweight;
    3682                 :     int         rscale;
    3683                 : 
    3684                 :     /*
    3685                 :      * Handle NaN and infinities
    3686                 :      */
    3687 GIC          75 :     if (NUMERIC_IS_SPECIAL(num))
    3688                 :     {
    3689 ECB             :         /* error should match that in sqrt_var() */
    3690 GIC           9 :         if (NUMERIC_IS_NINF(num))
    3691 CBC           3 :             ereport(ERROR,
    3692                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3693 ECB             :                      errmsg("cannot take square root of a negative number")));
    3694                 :         /* For NAN or PINF, just duplicate the input */
    3695 CBC           6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3696                 :     }
    3697                 : 
    3698                 :     /*
    3699                 :      * Unpack the argument and determine the result scale.  We choose a scale
    3700                 :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3701                 :      * case not less than the input's dscale.
    3702                 :      */
    3703 GIC          66 :     init_var_from_num(num, &arg);
    3704                 : 
    3705 CBC          66 :     init_var(&result);
    3706                 : 
    3707                 :     /*
    3708                 :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3709                 :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3710                 :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3711                 :      * a few cycles, since the division is exact and there is no need to round
    3712                 :      * towards negative infinity.
    3713                 :      */
    3714                 : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3715 GNC          66 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3716                 : #else
    3717                 :     if (arg.weight >= 0)
    3718                 :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3719                 :     else
    3720                 :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3721                 : #endif
    3722                 : 
    3723 GIC          66 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3724              66 :     rscale = Max(rscale, arg.dscale);
    3725 CBC          66 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3726              66 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3727                 : 
    3728                 :     /*
    3729 ECB             :      * Let sqrt_var() do the calculation and return the result.
    3730                 :      */
    3731 CBC          66 :     sqrt_var(&arg, &result, rscale);
    3732 ECB             : 
    3733 GIC          63 :     res = make_result(&result);
    3734                 : 
    3735 CBC          63 :     free_var(&result);
    3736 ECB             : 
    3737 GIC          63 :     PG_RETURN_NUMERIC(res);
    3738                 : }
    3739                 : 
    3740 ECB             : 
    3741                 : /*
    3742                 :  * numeric_exp() -
    3743                 :  *
    3744                 :  *  Raise e to the power of x
    3745                 :  */
    3746                 : Datum
    3747 GIC          39 : numeric_exp(PG_FUNCTION_ARGS)
    3748 ECB             : {
    3749 GIC          39 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3750 ECB             :     Numeric     res;
    3751                 :     NumericVar  arg;
    3752                 :     NumericVar  result;
    3753                 :     int         rscale;
    3754                 :     double      val;
    3755                 : 
    3756                 :     /*
    3757                 :      * Handle NaN and infinities
    3758                 :      */
    3759 GIC          39 :     if (NUMERIC_IS_SPECIAL(num))
    3760 ECB             :     {
    3761                 :         /* Per POSIX, exp(-Inf) is zero */
    3762 GIC           9 :         if (NUMERIC_IS_NINF(num))
    3763               3 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3764                 :         /* For NAN or PINF, just duplicate the input */
    3765               6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3766                 :     }
    3767                 : 
    3768                 :     /*
    3769                 :      * Unpack the argument and determine the result scale.  We choose a scale
    3770 ECB             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3771                 :      * case not less than the input's dscale.
    3772                 :      */
    3773 GIC          30 :     init_var_from_num(num, &arg);
    3774                 : 
    3775              30 :     init_var(&result);
    3776                 : 
    3777                 :     /* convert input to float8, ignoring overflow */
    3778              30 :     val = numericvar_to_double_no_overflow(&arg);
    3779                 : 
    3780                 :     /*
    3781                 :      * log10(result) = num * log10(e), so this is approximately the decimal
    3782 ECB             :      * weight of the result:
    3783                 :      */
    3784 GIC          30 :     val *= 0.434294481903252;
    3785 ECB             : 
    3786                 :     /* limit to something that won't cause integer overflow */
    3787 GIC          30 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3788              30 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3789                 : 
    3790 CBC          30 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3791 GIC          30 :     rscale = Max(rscale, arg.dscale);
    3792              30 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3793              30 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3794                 : 
    3795                 :     /*
    3796                 :      * Let exp_var() do the calculation and return the result.
    3797                 :      */
    3798 CBC          30 :     exp_var(&arg, &result, rscale);
    3799                 : 
    3800              30 :     res = make_result(&result);
    3801                 : 
    3802 GIC          30 :     free_var(&result);
    3803                 : 
    3804              30 :     PG_RETURN_NUMERIC(res);
    3805                 : }
    3806                 : 
    3807                 : 
    3808                 : /*
    3809                 :  * numeric_ln() -
    3810 ECB             :  *
    3811                 :  *  Compute the natural logarithm of x
    3812                 :  */
    3813                 : Datum
    3814 GIC          99 : numeric_ln(PG_FUNCTION_ARGS)
    3815                 : {
    3816              99 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3817                 :     Numeric     res;
    3818 ECB             :     NumericVar  arg;
    3819                 :     NumericVar  result;
    3820                 :     int         ln_dweight;
    3821                 :     int         rscale;
    3822                 : 
    3823                 :     /*
    3824                 :      * Handle NaN and infinities
    3825                 :      */
    3826 CBC          99 :     if (NUMERIC_IS_SPECIAL(num))
    3827                 :     {
    3828               9 :         if (NUMERIC_IS_NINF(num))
    3829 GIC           3 :             ereport(ERROR,
    3830 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3831                 :                      errmsg("cannot take logarithm of a negative number")));
    3832                 :         /* For NAN or PINF, just duplicate the input */
    3833 GIC           6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3834                 :     }
    3835                 : 
    3836              90 :     init_var_from_num(num, &arg);
    3837              90 :     init_var(&result);
    3838                 : 
    3839                 :     /* Estimated dweight of logarithm */
    3840              90 :     ln_dweight = estimate_ln_dweight(&arg);
    3841                 : 
    3842 CBC          90 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3843 GIC          90 :     rscale = Max(rscale, arg.dscale);
    3844 CBC          90 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3845 GIC          90 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3846                 : 
    3847              90 :     ln_var(&arg, &result, rscale);
    3848                 : 
    3849              78 :     res = make_result(&result);
    3850                 : 
    3851              78 :     free_var(&result);
    3852                 : 
    3853              78 :     PG_RETURN_NUMERIC(res);
    3854 ECB             : }
    3855                 : 
    3856                 : 
    3857                 : /*
    3858                 :  * numeric_log() -
    3859                 :  *
    3860                 :  *  Compute the logarithm of x in a given base
    3861                 :  */
    3862                 : Datum
    3863 GIC         171 : numeric_log(PG_FUNCTION_ARGS)
    3864                 : {
    3865             171 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3866             171 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3867                 :     Numeric     res;
    3868 ECB             :     NumericVar  arg1;
    3869                 :     NumericVar  arg2;
    3870                 :     NumericVar  result;
    3871                 : 
    3872                 :     /*
    3873                 :      * Handle NaN and infinities
    3874                 :      */
    3875 GIC         171 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3876                 :     {
    3877                 :         int         sign1,
    3878                 :                     sign2;
    3879 ECB             : 
    3880 GIC          63 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3881              27 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3882 ECB             :         /* fail on negative inputs including -Inf, as log_var would */
    3883 CBC          36 :         sign1 = numeric_sign_internal(num1);
    3884 GIC          36 :         sign2 = numeric_sign_internal(num2);
    3885 CBC          36 :         if (sign1 < 0 || sign2 < 0)
    3886              12 :             ereport(ERROR,
    3887 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3888                 :                      errmsg("cannot take logarithm of a negative number")));
    3889                 :         /* fail on zero inputs, as log_var would */
    3890 GIC          24 :         if (sign1 == 0 || sign2 == 0)
    3891               3 :             ereport(ERROR,
    3892                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3893 ECB             :                      errmsg("cannot take logarithm of zero")));
    3894 GIC          21 :         if (NUMERIC_IS_PINF(num1))
    3895 ECB             :         {
    3896                 :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    3897 CBC           9 :             if (NUMERIC_IS_PINF(num2))
    3898 GIC           3 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    3899 ECB             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    3900 GIC           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3901                 :         }
    3902              12 :         Assert(NUMERIC_IS_PINF(num2));
    3903                 :         /* log(finite-positive, Inf) is Inf */
    3904              12 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    3905                 :     }
    3906                 : 
    3907                 :     /*
    3908                 :      * Initialize things
    3909 ECB             :      */
    3910 GIC         108 :     init_var_from_num(num1, &arg1);
    3911 CBC         108 :     init_var_from_num(num2, &arg2);
    3912 GIC         108 :     init_var(&result);
    3913                 : 
    3914                 :     /*
    3915                 :      * Call log_var() to compute and return the result; note it handles scale
    3916                 :      * selection itself.
    3917                 :      */
    3918             108 :     log_var(&arg1, &arg2, &result);
    3919                 : 
    3920              78 :     res = make_result(&result);
    3921 ECB             : 
    3922 GIC          78 :     free_var(&result);
    3923 ECB             : 
    3924 CBC          78 :     PG_RETURN_NUMERIC(res);
    3925                 : }
    3926                 : 
    3927                 : 
    3928 ECB             : /*
    3929                 :  * numeric_power() -
    3930                 :  *
    3931                 :  *  Raise x to the power of y
    3932                 :  */
    3933                 : Datum
    3934 GIC         693 : numeric_power(PG_FUNCTION_ARGS)
    3935 ECB             : {
    3936 GIC         693 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3937 CBC         693 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3938 ECB             :     Numeric     res;
    3939                 :     NumericVar  arg1;
    3940                 :     NumericVar  arg2;
    3941                 :     NumericVar  result;
    3942                 :     int         sign1,
    3943                 :                 sign2;
    3944                 : 
    3945                 :     /*
    3946                 :      * Handle NaN and infinities
    3947                 :      */
    3948 CBC         693 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3949                 :     {
    3950                 :         /*
    3951                 :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    3952                 :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    3953                 :          * (with no error).
    3954                 :          */
    3955 GIC         117 :         if (NUMERIC_IS_NAN(num1))
    3956                 :         {
    3957              27 :             if (!NUMERIC_IS_SPECIAL(num2))
    3958 ECB             :             {
    3959 GIC          18 :                 init_var_from_num(num2, &arg2);
    3960 CBC          18 :                 if (cmp_var(&arg2, &const_zero) == 0)
    3961               6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3962                 :             }
    3963 GIC          21 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3964                 :         }
    3965              90 :         if (NUMERIC_IS_NAN(num2))
    3966                 :         {
    3967              21 :             if (!NUMERIC_IS_SPECIAL(num1))
    3968                 :             {
    3969              18 :                 init_var_from_num(num1, &arg1);
    3970 CBC          18 :                 if (cmp_var(&arg1, &const_one) == 0)
    3971 GIC           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3972                 :             }
    3973              15 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3974                 :         }
    3975 ECB             :         /* At least one input is infinite, but error rules still apply */
    3976 CBC          69 :         sign1 = numeric_sign_internal(num1);
    3977 GIC          69 :         sign2 = numeric_sign_internal(num2);
    3978 CBC          69 :         if (sign1 == 0 && sign2 < 0)
    3979               3 :             ereport(ERROR,
    3980 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3981                 :                      errmsg("zero raised to a negative power is undefined")));
    3982 GIC          66 :         if (sign1 < 0 && !numeric_is_integral(num2))
    3983               3 :             ereport(ERROR,
    3984                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3985 ECB             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    3986                 : 
    3987                 :         /*
    3988                 :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    3989                 :          *
    3990                 :          * For any value of y, if x is +1, 1.0 shall be returned.
    3991                 :          */
    3992 CBC          63 :         if (!NUMERIC_IS_SPECIAL(num1))
    3993 ECB             :         {
    3994 GIC          21 :             init_var_from_num(num1, &arg1);
    3995 CBC          21 :             if (cmp_var(&arg1, &const_one) == 0)
    3996 GIC           3 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    3997 ECB             :         }
    3998                 : 
    3999                 :         /*
    4000                 :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    4001                 :          */
    4002 GIC          60 :         if (sign2 == 0)
    4003               6 :             PG_RETURN_NUMERIC(make_result(&const_one));
    4004                 : 
    4005 ECB             :         /*
    4006                 :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    4007                 :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    4008                 :          * be returned.  (Since we don't deal in minus zero, we need not
    4009                 :          * distinguish these two cases.)
    4010                 :          */
    4011 GIC          54 :         if (sign1 == 0 && sign2 > 0)
    4012               3 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4013 ECB             : 
    4014                 :         /*
    4015                 :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    4016                 :          *
    4017                 :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4018                 :          *
    4019                 :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4020                 :          *
    4021                 :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4022                 :          *
    4023                 :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4024                 :          */
    4025 GIC          51 :         if (NUMERIC_IS_INF(num2))
    4026                 :         {
    4027                 :             bool        abs_x_gt_one;
    4028                 : 
    4029 CBC          27 :             if (NUMERIC_IS_SPECIAL(num1))
    4030 GIC          12 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4031 ECB             :             else
    4032                 :             {
    4033 GIC          15 :                 init_var_from_num(num1, &arg1);
    4034              15 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4035               3 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4036              12 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4037              12 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4038                 :             }
    4039              24 :             if (abs_x_gt_one == (sign2 > 0))
    4040              15 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4041                 :             else
    4042               9 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4043 ECB             :         }
    4044                 : 
    4045                 :         /*
    4046                 :          * For y < 0, if x is +Inf, +0 shall be returned.
    4047                 :          *
    4048                 :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4049                 :          */
    4050 CBC          24 :         if (NUMERIC_IS_PINF(num1))
    4051                 :         {
    4052              12 :             if (sign2 > 0)
    4053 GIC           9 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4054 ECB             :             else
    4055 CBC           3 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4056 ECB             :         }
    4057                 : 
    4058 CBC          12 :         Assert(NUMERIC_IS_NINF(num1));
    4059                 : 
    4060 ECB             :         /*
    4061                 :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4062                 :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4063                 :          * (Again, we need not distinguish these two cases.)
    4064                 :          */
    4065 CBC          12 :         if (sign2 < 0)
    4066               6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4067                 : 
    4068 ECB             :         /*
    4069                 :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4070                 :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4071                 :          */
    4072 CBC           6 :         init_var_from_num(num2, &arg2);
    4073               6 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4074               6 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4075 GIC           3 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4076                 :         else
    4077 CBC           3 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4078 ECB             :     }
    4079                 : 
    4080                 :     /*
    4081                 :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4082                 :      * certain error conditions.  Specifically, we don't return a
    4083                 :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4084                 :      * non-integer power must produce the same error code, but that case is
    4085                 :      * handled in power_var().
    4086                 :      */
    4087 CBC         576 :     sign1 = numeric_sign_internal(num1);
    4088 GIC         576 :     sign2 = numeric_sign_internal(num2);
    4089 ECB             : 
    4090 CBC         576 :     if (sign1 == 0 && sign2 < 0)
    4091               6 :         ereport(ERROR,
    4092                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4093                 :                  errmsg("zero raised to a negative power is undefined")));
    4094                 : 
    4095                 :     /*
    4096                 :      * Initialize things
    4097 ECB             :      */
    4098 CBC         570 :     init_var(&result);
    4099 GIC         570 :     init_var_from_num(num1, &arg1);
    4100             570 :     init_var_from_num(num2, &arg2);
    4101                 : 
    4102                 :     /*
    4103                 :      * Call power_var() to compute and return the result; note it handles
    4104                 :      * scale selection itself.
    4105                 :      */
    4106 CBC         570 :     power_var(&arg1, &arg2, &result);
    4107 ECB             : 
    4108 GIC         555 :     res = make_result(&result);
    4109                 : 
    4110             555 :     free_var(&result);
    4111                 : 
    4112             555 :     PG_RETURN_NUMERIC(res);
    4113                 : }
    4114                 : 
    4115                 : /*
    4116                 :  * numeric_scale() -
    4117                 :  *
    4118                 :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4119                 :  */
    4120 ECB             : Datum
    4121 GIC          54 : numeric_scale(PG_FUNCTION_ARGS)
    4122                 : {
    4123              54 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4124 ECB             : 
    4125 CBC          54 :     if (NUMERIC_IS_SPECIAL(num))
    4126 GIC           9 :         PG_RETURN_NULL();
    4127                 : 
    4128 CBC          45 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4129 ECB             : }
    4130                 : 
    4131                 : /*
    4132                 :  * Calculate minimum scale for value.
    4133                 :  */
    4134                 : static int
    4135 CBC          63 : get_min_scale(NumericVar *var)
    4136                 : {
    4137 ECB             :     int         min_scale;
    4138                 :     int         last_digit_pos;
    4139                 : 
    4140                 :     /*
    4141                 :      * Ordinarily, the input value will be "stripped" so that the last
    4142                 :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4143                 :      * loop if it isn't, so explicitly find the last nonzero digit.
    4144                 :      */
    4145 CBC          63 :     last_digit_pos = var->ndigits - 1;
    4146 GIC          63 :     while (last_digit_pos >= 0 &&
    4147 CBC          51 :            var->digits[last_digit_pos] == 0)
    4148 LBC           0 :         last_digit_pos--;
    4149                 : 
    4150 CBC          63 :     if (last_digit_pos >= 0)
    4151                 :     {
    4152                 :         /* compute min_scale assuming that last ndigit has no zeroes */
    4153              51 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4154                 : 
    4155                 :         /*
    4156                 :          * We could get a negative result if there are no digits after the
    4157                 :          * decimal point.  In this case the min_scale must be zero.
    4158                 :          */
    4159 GIC          51 :         if (min_scale > 0)
    4160 ECB             :         {
    4161                 :             /*
    4162                 :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4163                 :              * zero.
    4164                 :              */
    4165 GIC          33 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4166                 : 
    4167 CBC          99 :             while (last_digit % 10 == 0)
    4168 ECB             :             {
    4169 CBC          66 :                 min_scale--;
    4170              66 :                 last_digit /= 10;
    4171                 :             }
    4172 ECB             :         }
    4173                 :         else
    4174 GIC          18 :             min_scale = 0;
    4175                 :     }
    4176                 :     else
    4177              12 :         min_scale = 0;          /* result if input is zero */
    4178                 : 
    4179              63 :     return min_scale;
    4180                 : }
    4181                 : 
    4182 ECB             : /*
    4183                 :  * Returns minimum scale required to represent supplied value without loss.
    4184                 :  */
    4185                 : Datum
    4186 CBC          36 : numeric_min_scale(PG_FUNCTION_ARGS)
    4187                 : {
    4188 GIC          36 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4189                 :     NumericVar  arg;
    4190                 :     int         min_scale;
    4191                 : 
    4192              36 :     if (NUMERIC_IS_SPECIAL(num))
    4193 CBC           6 :         PG_RETURN_NULL();
    4194 ECB             : 
    4195 CBC          30 :     init_var_from_num(num, &arg);
    4196 GIC          30 :     min_scale = get_min_scale(&arg);
    4197              30 :     free_var(&arg);
    4198                 : 
    4199              30 :     PG_RETURN_INT32(min_scale);
    4200                 : }
    4201 ECB             : 
    4202                 : /*
    4203                 :  * Reduce scale of numeric value to represent supplied value without loss.
    4204                 :  */
    4205                 : Datum
    4206 GIC          39 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4207 ECB             : {
    4208 GIC          39 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4209                 :     Numeric     res;
    4210                 :     NumericVar  result;
    4211                 : 
    4212              39 :     if (NUMERIC_IS_SPECIAL(num))
    4213               6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4214                 : 
    4215              33 :     init_var_from_num(num, &result);
    4216 CBC          33 :     result.dscale = get_min_scale(&result);
    4217 GIC          33 :     res = make_result(&result);
    4218 CBC          33 :     free_var(&result);
    4219                 : 
    4220              33 :     PG_RETURN_NUMERIC(res);
    4221 ECB             : }
    4222                 : 
    4223                 : 
    4224                 : /* ----------------------------------------------------------------------
    4225                 :  *
    4226                 :  * Type conversion functions
    4227                 :  *
    4228                 :  * ----------------------------------------------------------------------
    4229                 :  */
    4230                 : 
    4231                 : Numeric
    4232 GIC      906490 : int64_to_numeric(int64 val)
    4233                 : {
    4234                 :     Numeric     res;
    4235                 :     NumericVar  result;
    4236                 : 
    4237          906490 :     init_var(&result);
    4238                 : 
    4239          906490 :     int64_to_numericvar(val, &result);
    4240 ECB             : 
    4241 CBC      906490 :     res = make_result(&result);
    4242 ECB             : 
    4243 GBC      906490 :     free_var(&result);
    4244                 : 
    4245 CBC      906490 :     return res;
    4246                 : }
    4247                 : 
    4248 ECB             : /*
    4249                 :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4250                 :  * numeric division.
    4251                 :  */
    4252                 : Numeric
    4253 GIC       14600 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4254 ECB             : {
    4255                 :     Numeric     res;
    4256                 :     NumericVar  result;
    4257                 :     int         rscale;
    4258                 :     int         w;
    4259                 :     int         m;
    4260                 : 
    4261 GIC       14600 :     init_var(&result);
    4262 ECB             : 
    4263                 :     /* result scale */
    4264 CBC       14600 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4265 ECB             : 
    4266                 :     /* how much to decrease the weight by */
    4267 GIC       14600 :     w = log10val2 / DEC_DIGITS;
    4268                 :     /* how much is left to divide by */
    4269 CBC       14600 :     m = log10val2 % DEC_DIGITS;
    4270 GIC       14600 :     if (m < 0)
    4271                 :     {
    4272 LBC           0 :         m += DEC_DIGITS;
    4273 UIC           0 :         w--;
    4274 ECB             :     }
    4275                 : 
    4276                 :     /*
    4277                 :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4278                 :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4279                 :      * one more.
    4280                 :      */
    4281 CBC       14600 :     if (m > 0)
    4282                 :     {
    4283 ECB             : #if DEC_DIGITS == 4
    4284                 :         static const int pow10[] = {1, 10, 100, 1000};
    4285                 : #elif DEC_DIGITS == 2
    4286                 :         static const int pow10[] = {1, 10};
    4287                 : #elif DEC_DIGITS == 1
    4288                 :         static const int pow10[] = {1};
    4289                 : #else
    4290                 : #error unsupported NBASE
    4291                 : #endif
    4292 CBC       14600 :         int64       factor = pow10[DEC_DIGITS - m];
    4293                 :         int64       new_val1;
    4294 ECB             : 
    4295                 :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4296                 : 
    4297 GIC       14600 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4298                 :         {
    4299                 : #ifdef HAVE_INT128
    4300                 :             /* do the multiplication using 128-bit integers */
    4301 ECB             :             int128      tmp;
    4302                 : 
    4303 CBC           6 :             tmp = (int128) val1 * (int128) factor;
    4304                 : 
    4305 GIC           6 :             int128_to_numericvar(tmp, &result);
    4306                 : #else
    4307 ECB             :             /* do the multiplication using numerics */
    4308                 :             NumericVar  tmp;
    4309                 : 
    4310                 :             init_var(&tmp);
    4311                 : 
    4312                 :             int64_to_numericvar(val1, &result);
    4313                 :             int64_to_numericvar(factor, &tmp);
    4314                 :             mul_var(&result, &tmp, &result, 0);
    4315                 : 
    4316                 :             free_var(&tmp);
    4317                 : #endif
    4318                 :         }
    4319                 :         else
    4320 GIC       14594 :             int64_to_numericvar(new_val1, &result);
    4321                 : 
    4322           14600 :         w++;
    4323                 :     }
    4324                 :     else
    4325 UIC           0 :         int64_to_numericvar(val1, &result);
    4326                 : 
    4327 CBC       14600 :     result.weight -= w;
    4328 GIC       14600 :     result.dscale = rscale;
    4329                 : 
    4330           14600 :     res = make_result(&result);
    4331                 : 
    4332 CBC       14600 :     free_var(&result);
    4333                 : 
    4334           14600 :     return res;
    4335                 : }
    4336 ECB             : 
    4337                 : Datum
    4338 CBC      760051 : int4_numeric(PG_FUNCTION_ARGS)
    4339                 : {
    4340          760051 :     int32       val = PG_GETARG_INT32(0);
    4341                 : 
    4342 GIC      760051 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4343                 : }
    4344                 : 
    4345                 : int32
    4346            2777 : numeric_int4_opt_error(Numeric num, bool *have_error)
    4347                 : {
    4348 ECB             :     NumericVar  x;
    4349                 :     int32       result;
    4350                 : 
    4351 GIC        2777 :     if (have_error)
    4352             144 :         *have_error = false;
    4353                 : 
    4354            2777 :     if (NUMERIC_IS_SPECIAL(num))
    4355                 :     {
    4356 CBC           9 :         if (have_error)
    4357                 :         {
    4358 UIC           0 :             *have_error = true;
    4359 LBC           0 :             return 0;
    4360                 :         }
    4361                 :         else
    4362 ECB             :         {
    4363 GIC           9 :             if (NUMERIC_IS_NAN(num))
    4364 CBC           3 :                 ereport(ERROR,
    4365 ECB             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4366                 :                          errmsg("cannot convert NaN to %s", "integer")));
    4367 EUB             :             else
    4368 GBC           6 :                 ereport(ERROR,
    4369                 :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4370                 :                          errmsg("cannot convert infinity to %s", "integer")));
    4371                 :         }
    4372                 :     }
    4373                 : 
    4374                 :     /* Convert to variable format, then convert to int4 */
    4375 GIC        2768 :     init_var_from_num(num, &x);
    4376 ECB             : 
    4377 GIC        2768 :     if (!numericvar_to_int32(&x, &result))
    4378                 :     {
    4379              18 :         if (have_error)
    4380                 :         {
    4381              12 :             *have_error = true;
    4382              12 :             return 0;
    4383                 :         }
    4384                 :         else
    4385                 :         {
    4386               6 :             ereport(ERROR,
    4387 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4388                 :                      errmsg("integer out of range")));
    4389                 :         }
    4390                 :     }
    4391                 : 
    4392 CBC        2750 :     return result;
    4393                 : }
    4394                 : 
    4395                 : Datum
    4396 GIC        2633 : numeric_int4(PG_FUNCTION_ARGS)
    4397                 : {
    4398 CBC        2633 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4399                 : 
    4400            2633 :     PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
    4401                 : }
    4402                 : 
    4403                 : /*
    4404                 :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4405                 :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4406                 :  * The input NumericVar is *not* free'd.
    4407                 :  */
    4408                 : static bool
    4409 GIC        3137 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4410                 : {
    4411                 :     int64       val;
    4412                 : 
    4413            3137 :     if (!numericvar_to_int64(var, &val))
    4414 UIC           0 :         return false;
    4415 ECB             : 
    4416 GIC        3137 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4417 CBC          18 :         return false;
    4418                 : 
    4419                 :     /* Down-convert to int4 */
    4420 GBC        3119 :     *result = (int32) val;
    4421                 : 
    4422 CBC        3119 :     return true;
    4423 ECB             : }
    4424                 : 
    4425                 : Datum
    4426 GIC        6378 : int8_numeric(PG_FUNCTION_ARGS)
    4427 ECB             : {
    4428 GIC        6378 :     int64       val = PG_GETARG_INT64(0);
    4429 ECB             : 
    4430 GIC        6378 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4431                 : }
    4432                 : 
    4433 ECB             : 
    4434                 : Datum
    4435 CBC         258 : numeric_int8(PG_FUNCTION_ARGS)
    4436                 : {
    4437             258 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4438                 :     NumericVar  x;
    4439                 :     int64       result;
    4440                 : 
    4441             258 :     if (NUMERIC_IS_SPECIAL(num))
    4442                 :     {
    4443 GIC           9 :         if (NUMERIC_IS_NAN(num))
    4444               3 :             ereport(ERROR,
    4445                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4446 ECB             :                      errmsg("cannot convert NaN to %s", "bigint")));
    4447                 :         else
    4448 GIC           6 :             ereport(ERROR,
    4449 ECB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4450                 :                      errmsg("cannot convert infinity to %s", "bigint")));
    4451                 :     }
    4452                 : 
    4453 EUB             :     /* Convert to variable format and thence to int8 */
    4454 GBC         249 :     init_var_from_num(num, &x);
    4455                 : 
    4456 GIC         249 :     if (!numericvar_to_int64(&x, &result))
    4457              24 :         ereport(ERROR,
    4458 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4459                 :                  errmsg("bigint out of range")));
    4460                 : 
    4461 GIC         225 :     PG_RETURN_INT64(result);
    4462                 : }
    4463 ECB             : 
    4464                 : 
    4465                 : Datum
    4466 GIC           3 : int2_numeric(PG_FUNCTION_ARGS)
    4467                 : {
    4468               3 :     int16       val = PG_GETARG_INT16(0);
    4469                 : 
    4470 CBC           3 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4471                 : }
    4472 ECB             : 
    4473                 : 
    4474                 : Datum
    4475 GIC          48 : numeric_int2(PG_FUNCTION_ARGS)
    4476 ECB             : {
    4477 CBC          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4478                 :     NumericVar  x;
    4479                 :     int64       val;
    4480                 :     int16       result;
    4481 ECB             : 
    4482 GIC          48 :     if (NUMERIC_IS_SPECIAL(num))
    4483                 :     {
    4484               9 :         if (NUMERIC_IS_NAN(num))
    4485               3 :             ereport(ERROR,
    4486                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4487 ECB             :                      errmsg("cannot convert NaN to %s", "smallint")));
    4488                 :         else
    4489 GIC           6 :             ereport(ERROR,
    4490                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4491 ECB             :                      errmsg("cannot convert infinity to %s", "smallint")));
    4492                 :     }
    4493                 : 
    4494                 :     /* Convert to variable format and thence to int8 */
    4495 CBC          39 :     init_var_from_num(num, &x);
    4496                 : 
    4497 GIC          39 :     if (!numericvar_to_int64(&x, &val))
    4498 UIC           0 :         ereport(ERROR,
    4499                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4500                 :                  errmsg("smallint out of range")));
    4501                 : 
    4502 GIC          39 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4503               6 :         ereport(ERROR,
    4504 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4505                 :                  errmsg("smallint out of range")));
    4506                 : 
    4507                 :     /* Down-convert to int2 */
    4508 CBC          33 :     result = (int16) val;
    4509 EUB             : 
    4510 GIC          33 :     PG_RETURN_INT16(result);
    4511 ECB             : }
    4512                 : 
    4513                 : 
    4514                 : Datum
    4515 CBC         417 : float8_numeric(PG_FUNCTION_ARGS)
    4516                 : {
    4517             417 :     float8      val = PG_GETARG_FLOAT8(0);
    4518                 :     Numeric     res;
    4519                 :     NumericVar  result;
    4520                 :     char        buf[DBL_DIG + 100];
    4521                 :     const char *endptr;
    4522 ECB             : 
    4523 GIC         417 :     if (isnan(val))
    4524 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4525                 : 
    4526             414 :     if (isinf(val))
    4527                 :     {
    4528 GIC           6 :         if (val < 0)
    4529               3 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4530                 :         else
    4531 CBC           3 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4532                 :     }
    4533 ECB             : 
    4534 GIC         408 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4535                 : 
    4536             408 :     init_var(&result);
    4537 ECB             : 
    4538                 :     /* Assume we need not worry about leading/trailing spaces */
    4539 GNC         408 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4540 ECB             : 
    4541 GIC         408 :     res = make_result(&result);
    4542                 : 
    4543             408 :     free_var(&result);
    4544 ECB             : 
    4545 GIC         408 :     PG_RETURN_NUMERIC(res);
    4546                 : }
    4547                 : 
    4548                 : 
    4549                 : Datum
    4550 CBC      259429 : numeric_float8(PG_FUNCTION_ARGS)
    4551                 : {
    4552          259429 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4553 ECB             :     char       *tmp;
    4554                 :     Datum       result;
    4555                 : 
    4556 GIC      259429 :     if (NUMERIC_IS_SPECIAL(num))
    4557 ECB             :     {
    4558 GIC          39 :         if (NUMERIC_IS_PINF(num))
    4559              12 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4560              27 :         else if (NUMERIC_IS_NINF(num))
    4561              12 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4562 ECB             :         else
    4563 GIC          15 :             PG_RETURN_FLOAT8(get_float8_nan());
    4564 ECB             :     }
    4565                 : 
    4566 CBC      259390 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4567                 :                                               NumericGetDatum(num)));
    4568                 : 
    4569 GIC      259390 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
    4570                 : 
    4571 CBC      259390 :     pfree(tmp);
    4572                 : 
    4573          259390 :     PG_RETURN_DATUM(result);
    4574                 : }
    4575                 : 
    4576                 : 
    4577                 : /*
    4578 ECB             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4579                 :  *
    4580                 :  * (internal helper function, not directly callable from SQL)
    4581                 :  */
    4582                 : Datum
    4583 GIC        1433 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4584                 : {
    4585 CBC        1433 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4586                 :     double      val;
    4587                 : 
    4588 GIC        1433 :     if (NUMERIC_IS_SPECIAL(num))
    4589                 :     {
    4590 UIC           0 :         if (NUMERIC_IS_PINF(num))
    4591 LBC           0 :             val = HUGE_VAL;
    4592 UIC           0 :         else if (NUMERIC_IS_NINF(num))
    4593 LBC           0 :             val = -HUGE_VAL;
    4594 EUB             :         else
    4595 UIC           0 :             val = get_float8_nan();
    4596                 :     }
    4597                 :     else
    4598 ECB             :     {
    4599                 :         NumericVar  x;
    4600                 : 
    4601 GIC        1433 :         init_var_from_num(num, &x);
    4602            1433 :         val = numericvar_to_double_no_overflow(&x);
    4603                 :     }
    4604 ECB             : 
    4605 GIC        1433 :     PG_RETURN_FLOAT8(val);
    4606 ECB             : }
    4607                 : 
    4608                 : Datum
    4609 GIC       10788 : float4_numeric(PG_FUNCTION_ARGS)
    4610                 : {
    4611 CBC       10788 :     float4      val = PG_GETARG_FLOAT4(0);
    4612                 :     Numeric     res;
    4613 ECB             :     NumericVar  result;
    4614                 :     char        buf[FLT_DIG + 100];
    4615                 :     const char *endptr;
    4616                 : 
    4617 GIC       10788 :     if (isnan(val))
    4618               3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4619                 : 
    4620 CBC       10785 :     if (isinf(val))
    4621 ECB             :     {
    4622 GIC           6 :         if (val < 0)
    4623 CBC           3 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4624                 :         else
    4625               3 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4626 ECB             :     }
    4627                 : 
    4628 CBC       10779 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4629                 : 
    4630 GIC       10779 :     init_var(&result);
    4631 ECB             : 
    4632                 :     /* Assume we need not worry about leading/trailing spaces */
    4633 GNC       10779 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4634                 : 
    4635 GIC       10779 :     res = make_result(&result);
    4636 ECB             : 
    4637 GIC       10779 :     free_var(&result);
    4638 ECB             : 
    4639 GIC       10779 :     PG_RETURN_NUMERIC(res);
    4640 ECB             : }
    4641                 : 
    4642                 : 
    4643                 : Datum
    4644 GIC        1090 : numeric_float4(PG_FUNCTION_ARGS)
    4645                 : {
    4646            1090 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4647 ECB             :     char       *tmp;
    4648                 :     Datum       result;
    4649                 : 
    4650 GIC        1090 :     if (NUMERIC_IS_SPECIAL(num))
    4651                 :     {
    4652              39 :         if (NUMERIC_IS_PINF(num))
    4653 CBC          12 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4654 GIC          27 :         else if (NUMERIC_IS_NINF(num))
    4655 CBC          12 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4656 ECB             :         else
    4657 CBC          15 :             PG_RETURN_FLOAT4(get_float4_nan());
    4658 ECB             :     }
    4659                 : 
    4660 CBC        1051 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4661                 :                                               NumericGetDatum(num)));
    4662                 : 
    4663            1051 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
    4664                 : 
    4665 GIC        1051 :     pfree(tmp);
    4666 ECB             : 
    4667 GIC        1051 :     PG_RETURN_DATUM(result);
    4668 ECB             : }
    4669                 : 
    4670                 : 
    4671                 : Datum
    4672 GIC          45 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4673                 : {
    4674              45 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4675                 :     NumericVar  x;
    4676                 :     XLogRecPtr  result;
    4677                 : 
    4678              45 :     if (NUMERIC_IS_SPECIAL(num))
    4679                 :     {
    4680 CBC           3 :         if (NUMERIC_IS_NAN(num))
    4681 GIC           3 :             ereport(ERROR,
    4682 ECB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4683                 :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4684                 :         else
    4685 LBC           0 :             ereport(ERROR,
    4686                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4687 EUB             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4688                 :     }
    4689                 : 
    4690                 :     /* Convert to variable format and thence to pg_lsn */
    4691 GIC          42 :     init_var_from_num(num, &x);
    4692 EUB             : 
    4693 GIC          42 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4694              12 :         ereport(ERROR,
    4695                 :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4696                 :                  errmsg("pg_lsn out of range")));
    4697                 : 
    4698 CBC          30 :     PG_RETURN_LSN(result);
    4699 ECB             : }
    4700                 : 
    4701                 : 
    4702                 : /* ----------------------------------------------------------------------
    4703                 :  *
    4704                 :  * Aggregate functions
    4705                 :  *
    4706                 :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4707                 :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4708                 :  * context.  The digit buffers for the NumericVars will be there too.
    4709                 :  *
    4710                 :  * On platforms which support 128-bit integers some aggregates instead use a
    4711                 :  * 128-bit integer based transition datatype to speed up calculations.
    4712                 :  *
    4713                 :  * ----------------------------------------------------------------------
    4714                 :  */
    4715                 : 
    4716                 : typedef struct NumericAggState
    4717                 : {
    4718                 :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4719                 :     MemoryContext agg_context;  /* context we're calculating in */
    4720                 :     int64       N;              /* count of processed numbers */
    4721                 :     NumericSumAccum sumX;       /* sum of processed numbers */
    4722                 :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4723                 :     int         maxScale;       /* maximum scale seen so far */
    4724                 :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4725                 :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4726                 :     int64       NaNcount;       /* count of NaN values */
    4727                 :     int64       pInfcount;      /* count of +Inf values */
    4728                 :     int64       nInfcount;      /* count of -Inf values */
    4729                 : } NumericAggState;
    4730                 : 
    4731                 : #define NA_TOTAL_COUNT(na) \
    4732                 :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4733                 : 
    4734                 : /*
    4735                 :  * Prepare state data for a numeric aggregate function that needs to compute
    4736                 :  * sum, count and optionally sum of squares of the input.
    4737                 :  */
    4738                 : static NumericAggState *
    4739 GIC       85568 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4740                 : {
    4741 ECB             :     NumericAggState *state;
    4742                 :     MemoryContext agg_context;
    4743                 :     MemoryContext old_context;
    4744                 : 
    4745 GIC       85568 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4746 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4747 ECB             : 
    4748 GIC       85568 :     old_context = MemoryContextSwitchTo(agg_context);
    4749 ECB             : 
    4750 CBC       85568 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4751           85568 :     state->calcSumX2 = calcSumX2;
    4752           85568 :     state->agg_context = agg_context;
    4753                 : 
    4754           85568 :     MemoryContextSwitchTo(old_context);
    4755                 : 
    4756 GIC       85568 :     return state;
    4757 ECB             : }
    4758                 : 
    4759                 : /*
    4760                 :  * Like makeNumericAggState(), but allocate the state in the current memory
    4761                 :  * context.
    4762                 :  */
    4763                 : static NumericAggState *
    4764 CBC          40 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4765                 : {
    4766                 :     NumericAggState *state;
    4767                 : 
    4768 GIC          40 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4769 CBC          40 :     state->calcSumX2 = calcSumX2;
    4770 GIC          40 :     state->agg_context = CurrentMemoryContext;
    4771 ECB             : 
    4772 GIC          40 :     return state;
    4773                 : }
    4774                 : 
    4775 ECB             : /*
    4776                 :  * Accumulate a new input value for numeric aggregate functions.
    4777                 :  */
    4778                 : static void
    4779 GIC     1056776 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4780                 : {
    4781                 :     NumericVar  X;
    4782 EUB             :     NumericVar  X2;
    4783                 :     MemoryContext old_context;
    4784                 : 
    4785                 :     /* Count NaN/infinity inputs separately from all else */
    4786 GIC     1056776 :     if (NUMERIC_IS_SPECIAL(newval))
    4787                 :     {
    4788 CBC          81 :         if (NUMERIC_IS_PINF(newval))
    4789 GIC          36 :             state->pInfcount++;
    4790 CBC          45 :         else if (NUMERIC_IS_NINF(newval))
    4791              18 :             state->nInfcount++;
    4792                 :         else
    4793 GIC          27 :             state->NaNcount++;
    4794              81 :         return;
    4795 ECB             :     }
    4796                 : 
    4797                 :     /* load processed number in short-lived context */
    4798 GIC     1056695 :     init_var_from_num(newval, &X);
    4799                 : 
    4800                 :     /*
    4801                 :      * Track the highest input dscale that we've seen, to support inverse
    4802                 :      * transitions (see do_numeric_discard).
    4803                 :      */
    4804         1056695 :     if (X.dscale > state->maxScale)
    4805                 :     {
    4806              78 :         state->maxScale = X.dscale;
    4807              78 :         state->maxScaleCount = 1;
    4808                 :     }
    4809         1056617 :     else if (X.dscale == state->maxScale)
    4810         1056599 :         state->maxScaleCount++;
    4811                 : 
    4812                 :     /* if we need X^2, calculate that in short-lived context */
    4813         1056695 :     if (state->calcSumX2)
    4814                 :     {
    4815          120366 :         init_var(&X2);
    4816          120366 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4817                 :     }
    4818                 : 
    4819                 :     /* The rest of this needs to work in the aggregate context */
    4820         1056695 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4821                 : 
    4822         1056695 :     state->N++;
    4823                 : 
    4824                 :     /* Accumulate sums */
    4825         1056695 :     accum_sum_add(&(state->sumX), &X);
    4826                 : 
    4827         1056695 :     if (state->calcSumX2)
    4828          120366 :         accum_sum_add(&(state->sumX2), &X2);
    4829                 : 
    4830         1056695 :     MemoryContextSwitchTo(old_context);
    4831                 : }
    4832                 : 
    4833                 : /*
    4834                 :  * Attempt to remove an input value from the aggregated state.
    4835                 :  *
    4836 ECB             :  * If the value cannot be removed then the function will return false; the
    4837                 :  * possible reasons for failing are described below.
    4838                 :  *
    4839                 :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    4840                 :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    4841                 :  * won't be able to tell what the new aggregated value's dscale should be.
    4842                 :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    4843 EUB             :  * have been zero if we'd really aggregated only 2.
    4844                 :  *
    4845 ECB             :  * Note: alternatively, we could count the number of inputs with each possible
    4846                 :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    4847                 :  */
    4848                 : static bool
    4849 CBC         171 : do_numeric_discard(NumericAggState *state, Numeric newval)
    4850                 : {
    4851 ECB             :     NumericVar  X;
    4852                 :     NumericVar  X2;
    4853                 :     MemoryContext old_context;
    4854                 : 
    4855                 :     /* Count NaN/infinity inputs separately from all else */
    4856 GIC         171 :     if (NUMERIC_IS_SPECIAL(newval))
    4857                 :     {
    4858               3 :         if (NUMERIC_IS_PINF(newval))
    4859 UIC           0 :             state->pInfcount--;
    4860 GIC           3 :         else if (NUMERIC_IS_NINF(newval))
    4861 LBC           0 :             state->nInfcount--;
    4862                 :         else
    4863 GIC           3 :             state->NaNcount--;
    4864               3 :         return true;
    4865 ECB             :     }
    4866                 : 
    4867                 :     /* load processed number in short-lived context */
    4868 GIC         168 :     init_var_from_num(newval, &X);
    4869 ECB             : 
    4870                 :     /*
    4871                 :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    4872                 :      * Removing the last input with that dscale would require us to recompute
    4873                 :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    4874                 :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    4875                 :      * and force the aggregation to be redone from scratch.
    4876                 :      */
    4877 GIC         168 :     if (X.dscale == state->maxScale)
    4878                 :     {
    4879             168 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    4880                 :         {
    4881                 :             /*
    4882                 :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    4883 ECB             :              * above zero anyway
    4884                 :              */
    4885 CBC         159 :             state->maxScaleCount--;
    4886 ECB             :         }
    4887 CBC           9 :         else if (state->N == 1)
    4888 ECB             :         {
    4889                 :             /* No remaining non-NaN inputs at all, so reset maxScale */
    4890 CBC           6 :             state->maxScale = 0;
    4891               6 :             state->maxScaleCount = 0;
    4892                 :         }
    4893                 :         else
    4894                 :         {
    4895 ECB             :             /* Correct new maxScale is uncertain, must fail */
    4896 GIC           3 :             return false;
    4897                 :         }
    4898                 :     }
    4899                 : 
    4900                 :     /* if we need X^2, calculate that in short-lived context */
    4901 CBC         165 :     if (state->calcSumX2)
    4902                 :     {
    4903             144 :         init_var(&X2);
    4904             144 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4905                 :     }
    4906 ECB             : 
    4907                 :     /* The rest of this needs to work in the aggregate context */
    4908 GIC         165 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4909                 : 
    4910 CBC         165 :     if (state->N-- > 1)
    4911                 :     {
    4912 ECB             :         /* Negate X, to subtract it from the sum */
    4913 CBC         156 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    4914 GIC         156 :         accum_sum_add(&(state->sumX), &X);
    4915                 : 
    4916             156 :         if (state->calcSumX2)
    4917 ECB             :         {
    4918                 :             /* Negate X^2. X^2 is always positive */
    4919 CBC         144 :             X2.sign = NUMERIC_NEG;
    4920 GIC         144 :             accum_sum_add(&(state->sumX2), &X2);
    4921                 :         }
    4922 ECB             :     }
    4923                 :     else
    4924                 :     {
    4925                 :         /* Zero the sums */
    4926 GIC           9 :         Assert(state->N == 0);
    4927 ECB             : 
    4928 GIC           9 :         accum_sum_reset(&state->sumX);
    4929               9 :         if (state->calcSumX2)
    4930 UIC           0 :             accum_sum_reset(&state->sumX2);
    4931                 :     }
    4932                 : 
    4933 GIC         165 :     MemoryContextSwitchTo(old_context);
    4934                 : 
    4935             165 :     return true;
    4936                 : }
    4937                 : 
    4938                 : /*
    4939                 :  * Generic transition function for numeric aggregates that require sumX2.
    4940                 :  */
    4941                 : Datum
    4942             321 : numeric_accum(PG_FUNCTION_ARGS)
    4943                 : {
    4944                 :     NumericAggState *state;
    4945                 : 
    4946 CBC         321 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    4947                 : 
    4948                 :     /* Create the state data on the first call */
    4949 GIC         321 :     if (state == NULL)
    4950              87 :         state = makeNumericAggState(fcinfo, true);
    4951                 : 
    4952             321 :     if (!PG_ARGISNULL(1))
    4953 CBC         312 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    4954                 : 
    4955             321 :     PG_RETURN_POINTER(state);
    4956 EUB             : }
    4957 ECB             : 
    4958 EUB             : /*
    4959                 :  * Generic combine function for numeric aggregates which require sumX2
    4960 ECB             :  */
    4961                 : Datum
    4962 GIC          17 : numeric_combine(PG_FUNCTION_ARGS)
    4963                 : {
    4964                 :     NumericAggState *state1;
    4965 ECB             :     NumericAggState *state2;
    4966                 :     MemoryContext agg_context;
    4967                 :     MemoryContext old_context;
    4968                 : 
    4969 GIC          17 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4970 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4971                 : 
    4972 GIC          17 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    4973              17 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    4974 ECB             : 
    4975 GIC          17 :     if (state2 == NULL)
    4976 LBC           0 :         PG_RETURN_POINTER(state1);
    4977                 : 
    4978                 :     /* manually copy all fields from state2 to state1 */
    4979 GIC          17 :     if (state1 == NULL)
    4980                 :     {
    4981               9 :         old_context = MemoryContextSwitchTo(agg_context);
    4982 ECB             : 
    4983 GIC           9 :         state1 = makeNumericAggStateCurrentContext(true);
    4984 CBC           9 :         state1->N = state2->N;
    4985 GIC           9 :         state1->NaNcount = state2->NaNcount;
    4986               9 :         state1->pInfcount = state2->pInfcount;
    4987 CBC           9 :         state1->nInfcount = state2->nInfcount;
    4988               9 :         state1->maxScale = state2->maxScale;
    4989 GIC           9 :         state1->maxScaleCount = state2->maxScaleCount;
    4990                 : 
    4991               9 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    4992               9 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    4993 ECB             : 
    4994 GIC           9 :         MemoryContextSwitchTo(old_context);
    4995                 : 
    4996               9 :         PG_RETURN_POINTER(state1);
    4997                 :     }
    4998 ECB             : 
    4999 GIC           8 :     state1->N += state2->N;
    5000 CBC           8 :     state1->NaNcount += state2->NaNcount;
    5001               8 :     state1->pInfcount += state2->pInfcount;
    5002 GIC           8 :     state1->nInfcount += state2->nInfcount;
    5003                 : 
    5004               8 :     if (state2->N > 0)
    5005 ECB             :     {
    5006                 :         /*
    5007                 :          * These are currently only needed for moving aggregates, but let's do
    5008                 :          * the right thing anyway...
    5009                 :          */
    5010 CBC           8 :         if (state2->maxScale > state1->maxScale)
    5011 ECB             :         {
    5012 UIC           0 :             state1->maxScale = state2->maxScale;
    5013 LBC           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5014                 :         }
    5015 GIC           8 :         else if (state2->maxScale == state1->maxScale)
    5016 CBC           8 :             state1->maxScaleCount += state2->maxScaleCount;
    5017 ECB             : 
    5018                 :         /* The rest of this needs to work in the aggregate context */
    5019 GIC           8 :         old_context = MemoryContextSwitchTo(agg_context);
    5020                 : 
    5021                 :         /* Accumulate sums */
    5022               8 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5023 CBC           8 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5024                 : 
    5025               8 :         MemoryContextSwitchTo(old_context);
    5026 ECB             :     }
    5027 GBC           8 :     PG_RETURN_POINTER(state1);
    5028                 : }
    5029                 : 
    5030 ECB             : /*
    5031                 :  * Generic transition function for numeric aggregates that don't require sumX2.
    5032                 :  */
    5033                 : Datum
    5034 GIC      936404 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5035                 : {
    5036                 :     NumericAggState *state;
    5037                 : 
    5038          936404 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5039 ECB             : 
    5040                 :     /* Create the state data on the first call */
    5041 GIC      936404 :     if (state == NULL)
    5042           85452 :         state = makeNumericAggState(fcinfo, false);
    5043 ECB             : 
    5044 GIC      936404 :     if (!PG_ARGISNULL(1))
    5045          936374 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5046 ECB             : 
    5047 CBC      936404 :     PG_RETURN_POINTER(state);
    5048                 : }
    5049 ECB             : 
    5050                 : /*
    5051                 :  * Combine function for numeric aggregates which don't require sumX2
    5052                 :  */
    5053                 : Datum
    5054 GIC          11 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5055                 : {
    5056                 :     NumericAggState *state1;
    5057                 :     NumericAggState *state2;
    5058                 :     MemoryContext agg_context;
    5059 ECB             :     MemoryContext old_context;
    5060                 : 
    5061 GIC          11 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5062 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5063                 : 
    5064 GIC          11 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5065              11 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5066 ECB             : 
    5067 GBC          11 :     if (state2 == NULL)
    5068 UIC           0 :         PG_RETURN_POINTER(state1);
    5069 ECB             : 
    5070                 :     /* manually copy all fields from state2 to state1 */
    5071 GIC          11 :     if (state1 == NULL)
    5072 ECB             :     {
    5073 GBC           3 :         old_context = MemoryContextSwitchTo(agg_context);
    5074                 : 
    5075 GIC           3 :         state1 = makeNumericAggStateCurrentContext(false);
    5076 CBC           3 :         state1->N = state2->N;
    5077 GIC           3 :         state1->NaNcount = state2->NaNcount;
    5078 CBC           3 :         state1->pInfcount = state2->pInfcount;
    5079 GIC           3 :         state1->nInfcount = state2->nInfcount;
    5080 CBC           3 :         state1->maxScale = state2->maxScale;
    5081               3 :         state1->maxScaleCount = state2->maxScaleCount;
    5082 ECB             : 
    5083 CBC           3 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5084 ECB             : 
    5085 CBC           3 :         MemoryContextSwitchTo(old_context);
    5086 ECB             : 
    5087 GIC           3 :         PG_RETURN_POINTER(state1);
    5088 ECB             :     }
    5089                 : 
    5090 GIC           8 :     state1->N += state2->N;
    5091 CBC           8 :     state1->NaNcount += state2->NaNcount;
    5092 GIC           8 :     state1->pInfcount += state2->pInfcount;
    5093 CBC           8 :     state1->nInfcount += state2->nInfcount;
    5094                 : 
    5095 GIC           8 :     if (state2->N > 0)
    5096 ECB             :     {
    5097                 :         /*
    5098                 :          * These are currently only needed for moving aggregates, but let's do
    5099                 :          * the right thing anyway...
    5100                 :          */
    5101 CBC           8 :         if (state2->maxScale > state1->maxScale)
    5102                 :         {
    5103 UIC           0 :             state1->maxScale = state2->maxScale;
    5104               0 :             state1->maxScaleCount = state2->maxScaleCount;
    5105                 :         }
    5106 GIC           8 :         else if (state2->maxScale == state1->maxScale)
    5107 CBC           8 :             state1->maxScaleCount += state2->maxScaleCount;
    5108                 : 
    5109 EUB             :         /* The rest of this needs to work in the aggregate context */
    5110 GBC           8 :         old_context = MemoryContextSwitchTo(agg_context);
    5111                 : 
    5112 ECB             :         /* Accumulate sums */
    5113 CBC           8 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5114                 : 
    5115 GIC           8 :         MemoryContextSwitchTo(old_context);
    5116 ECB             :     }
    5117 GIC           8 :     PG_RETURN_POINTER(state1);
    5118                 : }
    5119 ECB             : 
    5120                 : /*
    5121                 :  * numeric_avg_serialize
    5122                 :  *      Serialize NumericAggState for numeric aggregates that don't require
    5123                 :  *      sumX2.
    5124                 :  */
    5125                 : Datum
    5126 GIC          11 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5127                 : {
    5128                 :     NumericAggState *state;
    5129                 :     StringInfoData buf;
    5130                 :     bytea      *result;
    5131 ECB             :     NumericVar  tmp_var;
    5132                 : 
    5133                 :     /* Ensure we disallow calling when not in aggregate context */
    5134 GIC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
    5135 LBC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5136                 : 
    5137 GIC          11 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5138 ECB             : 
    5139 CBC          11 :     init_var(&tmp_var);
    5140                 : 
    5141              11 :     pq_begintypsend(&buf);
    5142 ECB             : 
    5143                 :     /* N */
    5144 CBC          11 :     pq_sendint64(&buf, state->N);
    5145                 : 
    5146                 :     /* sumX */
    5147 GIC          11 :     accum_sum_final(&state->sumX, &tmp_var);
    5148              11 :     numericvar_serialize(&buf, &tmp_var);
    5149                 : 
    5150                 :     /* maxScale */
    5151 CBC          11 :     pq_sendint32(&buf, state->maxScale);
    5152                 : 
    5153                 :     /* maxScaleCount */
    5154 GIC          11 :     pq_sendint64(&buf, state->maxScaleCount);
    5155                 : 
    5156                 :     /* NaNcount */
    5157              11 :     pq_sendint64(&buf, state->NaNcount);
    5158 ECB             : 
    5159 EUB             :     /* pInfcount */
    5160 GIC          11 :     pq_sendint64(&buf, state->pInfcount);
    5161 ECB             : 
    5162                 :     /* nInfcount */
    5163 GIC          11 :     pq_sendint64(&buf, state->nInfcount);
    5164 ECB             : 
    5165 GBC          11 :     result = pq_endtypsend(&buf);
    5166                 : 
    5167 GIC          11 :     free_var(&tmp_var);
    5168 ECB             : 
    5169 GIC          11 :     PG_RETURN_BYTEA_P(result);
    5170 ECB             : }
    5171                 : 
    5172                 : /*
    5173                 :  * numeric_avg_deserialize
    5174                 :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5175                 :  *      don't require sumX2.
    5176                 :  */
    5177                 : Datum
    5178 CBC          11 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5179                 : {
    5180 ECB             :     bytea      *sstate;
    5181                 :     NumericAggState *result;
    5182                 :     StringInfoData buf;
    5183                 :     NumericVar  tmp_var;
    5184                 : 
    5185 GIC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
    5186 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5187 ECB             : 
    5188 CBC          11 :     sstate = PG_GETARG_BYTEA_PP(0);
    5189 ECB             : 
    5190 CBC          11 :     init_var(&tmp_var);
    5191                 : 
    5192 ECB             :     /*
    5193                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
    5194                 :      * standard recv-function infrastructure.
    5195                 :      */
    5196 GIC          11 :     initStringInfo(&buf);
    5197              22 :     appendBinaryStringInfo(&buf,
    5198 CBC          22 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
    5199                 : 
    5200 GBC          11 :     result = makeNumericAggStateCurrentContext(false);
    5201 EUB             : 
    5202                 :     /* N */
    5203 CBC          11 :     result->N = pq_getmsgint64(&buf);
    5204 ECB             : 
    5205                 :     /* sumX */
    5206 GIC          11 :     numericvar_deserialize(&buf, &tmp_var);
    5207 CBC          11 :     accum_sum_add(&(result->sumX), &tmp_var);
    5208                 : 
    5209                 :     /* maxScale */
    5210              11 :     result->maxScale = pq_getmsgint(&buf, 4);
    5211                 : 
    5212 ECB             :     /* maxScaleCount */
    5213 GIC          11 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5214 ECB             : 
    5215                 :     /* NaNcount */
    5216 GIC          11 :     result->NaNcount = pq_getmsgint64(&buf);
    5217                 : 
    5218                 :     /* pInfcount */
    5219              11 :     result->pInfcount = pq_getmsgint64(&buf);
    5220                 : 
    5221                 :     /* nInfcount */
    5222              11 :     result->nInfcount = pq_getmsgint64(&buf);
    5223 ECB             : 
    5224 GIC          11 :     pq_getmsgend(&buf);
    5225              11 :     pfree(buf.data);
    5226                 : 
    5227              11 :     free_var(&tmp_var);
    5228                 : 
    5229              11 :     PG_RETURN_POINTER(result);
    5230                 : }
    5231 ECB             : 
    5232 EUB             : /*
    5233                 :  * numeric_serialize
    5234 ECB             :  *      Serialization function for NumericAggState for numeric aggregates that
    5235                 :  *      require sumX2.
    5236                 :  */
    5237                 : Datum
    5238 CBC          17 : numeric_serialize(PG_FUNCTION_ARGS)
    5239                 : {
    5240                 :     NumericAggState *state;
    5241 ECB             :     StringInfoData buf;
    5242                 :     bytea      *result;
    5243                 :     NumericVar  tmp_var;
    5244                 : 
    5245                 :     /* Ensure we disallow calling when not in aggregate context */
    5246 GIC          17 :     if (!AggCheckCallContext(fcinfo, NULL))
    5247 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5248 ECB             : 
    5249 GIC          17 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5250                 : 
    5251 CBC          17 :     init_var(&tmp_var);
    5252                 : 
    5253 GIC          17 :     pq_begintypsend(&buf);
    5254 ECB             : 
    5255                 :     /* N */
    5256 GIC          17 :     pq_sendint64(&buf, state->N);
    5257 ECB             : 
    5258                 :     /* sumX */
    5259 GIC          17 :     accum_sum_final(&state->sumX, &tmp_var);
    5260 CBC          17 :     numericvar_serialize(&buf, &tmp_var);
    5261                 : 
    5262 ECB             :     /* sumX2 */
    5263 GIC          17 :     accum_sum_final(&state->sumX2, &tmp_var);
    5264 CBC          17 :     numericvar_serialize(&buf, &tmp_var);
    5265                 : 
    5266 ECB             :     /* maxScale */
    5267 GIC          17 :     pq_sendint32(&buf, state->maxScale);
    5268                 : 
    5269                 :     /* maxScaleCount */
    5270              17 :     pq_sendint64(&buf, state->maxScaleCount);
    5271                 : 
    5272                 :     /* NaNcount */
    5273              17 :     pq_sendint64(&buf, state->NaNcount);
    5274                 : 
    5275 ECB             :     /* pInfcount */
    5276 GIC          17 :     pq_sendint64(&buf, state->pInfcount);
    5277                 : 
    5278                 :     /* nInfcount */
    5279              17 :     pq_sendint64(&buf, state->nInfcount);
    5280                 : 
    5281              17 :     result = pq_endtypsend(&buf);
    5282 ECB             : 
    5283 GBC          17 :     free_var(&tmp_var);
    5284                 : 
    5285 CBC          17 :     PG_RETURN_BYTEA_P(result);
    5286                 : }
    5287 ECB             : 
    5288                 : /*
    5289                 :  * numeric_deserialize
    5290                 :  *      Deserialization function for NumericAggState for numeric aggregates that
    5291                 :  *      require sumX2.
    5292                 :  */
    5293                 : Datum
    5294 CBC          17 : numeric_deserialize(PG_FUNCTION_ARGS)
    5295 ECB             : {
    5296                 :     bytea      *sstate;
    5297                 :     NumericAggState *result;
    5298                 :     StringInfoData buf;
    5299                 :     NumericVar  tmp_var;
    5300                 : 
    5301 GIC          17 :     if (!AggCheckCallContext(fcinfo, NULL))
    5302 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5303 ECB             : 
    5304 CBC          17 :     sstate = PG_GETARG_BYTEA_PP(0);
    5305                 : 
    5306 GIC          17 :     init_var(&tmp_var);
    5307 ECB             : 
    5308                 :     /*
    5309                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
    5310                 :      * standard recv-function infrastructure.
    5311                 :      */
    5312 GIC          17 :     initStringInfo(&buf);
    5313 CBC          34 :     appendBinaryStringInfo(&buf,
    5314 GIC          34 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
    5315                 : 
    5316 CBC          17 :     result = makeNumericAggStateCurrentContext(false);
    5317                 : 
    5318                 :     /* N */
    5319              17 :     result->N = pq_getmsgint64(&buf);
    5320                 : 
    5321 ECB             :     /* sumX */
    5322 CBC          17 :     numericvar_deserialize(&buf, &tmp_var);
    5323 GIC          17 :     accum_sum_add(&(result->sumX), &tmp_var);
    5324 ECB             : 
    5325                 :     /* sumX2 */
    5326 CBC          17 :     numericvar_deserialize(&buf, &tmp_var);
    5327 GIC          17 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5328                 : 
    5329                 :     /* maxScale */
    5330              17 :     result->maxScale = pq_getmsgint(&buf, 4);
    5331                 : 
    5332                 :     /* maxScaleCount */
    5333              17 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5334                 : 
    5335 ECB             :     /* NaNcount */
    5336 GIC          17 :     result->NaNcount = pq_getmsgint64(&buf);
    5337                 : 
    5338                 :     /* pInfcount */
    5339              17 :     result->pInfcount = pq_getmsgint64(&buf);
    5340                 : 
    5341                 :     /* nInfcount */
    5342              17 :     result->nInfcount = pq_getmsgint64(&buf);
    5343 ECB             : 
    5344 GBC          17 :     pq_getmsgend(&buf);
    5345 GIC          17 :     pfree(buf.data);
    5346 ECB             : 
    5347 GIC          17 :     free_var(&tmp_var);
    5348 ECB             : 
    5349 GIC          17 :     PG_RETURN_POINTER(result);
    5350 ECB             : }
    5351                 : 
    5352                 : /*
    5353                 :  * Generic inverse transition function for numeric aggregates
    5354                 :  * (with or without requirement for X^2).
    5355                 :  */
    5356                 : Datum
    5357 CBC         114 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5358                 : {
    5359                 :     NumericAggState *state;
    5360 ECB             : 
    5361 CBC         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5362                 : 
    5363                 :     /* Should not get here with no state */
    5364             114 :     if (state == NULL)
    5365 UIC           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5366                 : 
    5367 CBC         114 :     if (!PG_ARGISNULL(1))
    5368                 :     {
    5369                 :         /* If we fail to perform the inverse transition, return NULL */
    5370              99 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5371 GIC           3 :             PG_RETURN_NULL();
    5372                 :     }
    5373 ECB             : 
    5374 GIC         111 :     PG_RETURN_POINTER(state);
    5375                 : }
    5376 ECB             : 
    5377                 : 
    5378                 : /*
    5379                 :  * Integer data types in general use Numeric accumulators to share code
    5380                 :  * and avoid risk of overflow.
    5381                 :  *
    5382                 :  * However for performance reasons optimized special-purpose accumulator
    5383                 :  * routines are used when possible.
    5384                 :  *
    5385                 :  * On platforms with 128-bit integer support, the 128-bit routines will be
    5386                 :  * used when sum(X) or sum(X*X) fit into 128-bit.
    5387                 :  *
    5388                 :  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
    5389                 :  * accumulators will be used for SUM and AVG of these data types.
    5390                 :  */
    5391                 : 
    5392                 : #ifdef HAVE_INT128
    5393                 : typedef struct Int128AggState
    5394                 : {
    5395                 :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5396                 :     int64       N;              /* count of processed numbers */
    5397                 :     int128      sumX;           /* sum of processed numbers */
    5398                 :     int128      sumX2;          /* sum of squares of processed numbers */
    5399 EUB             : } Int128AggState;
    5400                 : 
    5401 ECB             : /*
    5402                 :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5403                 :  * sum, count and optionally sum of squares of the input.
    5404                 :  */
    5405                 : static Int128AggState *
    5406 GIC         322 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5407                 : {
    5408                 :     Int128AggState *state;
    5409 ECB             :     MemoryContext agg_context;
    5410                 :     MemoryContext old_context;
    5411                 : 
    5412 GIC         322 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5413 LBC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5414                 : 
    5415 GIC         322 :     old_context = MemoryContextSwitchTo(agg_context);
    5416 ECB             : 
    5417 GIC         322 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5418             322 :     state->calcSumX2 = calcSumX2;
    5419 ECB             : 
    5420 CBC         322 :     MemoryContextSwitchTo(old_context);
    5421                 : 
    5422 GIC         322 :     return state;
    5423 ECB             : }
    5424                 : 
    5425                 : /*
    5426                 :  * Like makeInt128AggState(), but allocate the state in the current memory
    5427                 :  * context.
    5428                 :  */
    5429                 : static Int128AggState *
    5430 CBC          19 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5431                 : {
    5432                 :     Int128AggState *state;
    5433 ECB             : 
    5434 GIC          19 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5435              19 :     state->calcSumX2 = calcSumX2;
    5436 ECB             : 
    5437 GIC          19 :     return state;
    5438                 : }
    5439 ECB             : 
    5440                 : /*
    5441                 :  * Accumulate a new input value for 128-bit aggregate functions.
    5442                 :  */
    5443                 : static void
    5444 CBC      276265 : do_int128_accum(Int128AggState *state, int128 newval)
    5445                 : {
    5446          276265 :     if (state->calcSumX2)
    5447 GIC      121180 :         state->sumX2 += newval * newval;
    5448                 : 
    5449          276265 :     state->sumX += newval;
    5450          276265 :     state->N++;
    5451          276265 : }
    5452                 : 
    5453                 : /*
    5454 ECB             :  * Remove an input value from the aggregated state.
    5455                 :  */
    5456                 : static void
    5457 GIC         156 : do_int128_discard(Int128AggState *state, int128 newval)
    5458 ECB             : {
    5459 GIC         156 :     if (state->calcSumX2)
    5460             144 :         state->sumX2 -= newval * newval;
    5461 ECB             : 
    5462 GBC         156 :     state->sumX -= newval;
    5463 GIC         156 :     state->N--;
    5464 CBC         156 : }
    5465                 : 
    5466                 : typedef Int128AggState PolyNumAggState;
    5467 ECB             : #define makePolyNumAggState makeInt128AggState
    5468                 : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
    5469                 : #else
    5470                 : typedef NumericAggState PolyNumAggState;
    5471                 : #define makePolyNumAggState makeNumericAggState
    5472                 : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
    5473                 : #endif
    5474                 : 
    5475                 : Datum
    5476 GIC          99 : int2_accum(PG_FUNCTION_ARGS)
    5477                 : {
    5478                 :     PolyNumAggState *state;
    5479                 : 
    5480              99 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5481                 : 
    5482                 :     /* Create the state data on the first call */
    5483              99 :     if (state == NULL)
    5484              18 :         state = makePolyNumAggState(fcinfo, true);
    5485                 : 
    5486              99 :     if (!PG_ARGISNULL(1))
    5487                 :     {
    5488                 : #ifdef HAVE_INT128
    5489              90 :         do_int128_accum(state, (int128) PG_GETARG_INT16(1));
    5490                 : #else
    5491                 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
    5492                 : #endif
    5493                 :     }
    5494                 : 
    5495              99 :     PG_RETURN_POINTER(state);
    5496                 : }
    5497                 : 
    5498                 : Datum
    5499          121099 : int4_accum(PG_FUNCTION_ARGS)
    5500                 : {
    5501                 :     PolyNumAggState *state;
    5502                 : 
    5503 CBC      121099 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5504                 : 
    5505                 :     /* Create the state data on the first call */
    5506 GIC      121099 :     if (state == NULL)
    5507              36 :         state = makePolyNumAggState(fcinfo, true);
    5508                 : 
    5509 CBC      121099 :     if (!PG_ARGISNULL(1))
    5510 EUB             :     {
    5511                 : #ifdef HAVE_INT128
    5512 CBC      121090 :         do_int128_accum(state, (int128) PG_GETARG_INT32(1));
    5513                 : #else
    5514 ECB             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
    5515                 : #endif
    5516                 :     }
    5517                 : 
    5518 GIC      121099 :     PG_RETURN_POINTER(state);
    5519 ECB             : }
    5520                 : 
    5521                 : Datum
    5522 GIC      120099 : int8_accum(PG_FUNCTION_ARGS)
    5523                 : {
    5524                 :     NumericAggState *state;
    5525                 : 
    5526          120099 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5527 ECB             : 
    5528                 :     /* Create the state data on the first call */
    5529 GIC      120099 :     if (state == NULL)
    5530              29 :         state = makeNumericAggState(fcinfo, true);
    5531 ECB             : 
    5532 CBC      120099 :     if (!PG_ARGISNULL(1))
    5533 GIC      120090 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5534 ECB             : 
    5535 GIC      120099 :     PG_RETURN_POINTER(state);
    5536                 : }
    5537                 : 
    5538                 : /*
    5539                 :  * Combine function for numeric aggregates which require sumX2
    5540                 :  */
    5541 ECB             : Datum
    5542 GIC           8 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5543 ECB             : {
    5544                 :     PolyNumAggState *state1;
    5545                 :     PolyNumAggState *state2;
    5546                 :     MemoryContext agg_context;
    5547                 :     MemoryContext old_context;
    5548                 : 
    5549 GIC           8 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5550 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5551                 : 
    5552 GIC           8 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5553               8 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5554 ECB             : 
    5555 GIC           8 :     if (state2 == NULL)
    5556 LBC           0 :         PG_RETURN_POINTER(state1);
    5557 ECB             : 
    5558                 :     /* manually copy all fields from state2 to state1 */
    5559 CBC           8 :     if (state1 == NULL)
    5560 ECB             :     {
    5561 CBC           3 :         old_context = MemoryContextSwitchTo(agg_context);
    5562                 : 
    5563 GIC           3 :         state1 = makePolyNumAggState(fcinfo, true);
    5564               3 :         state1->N = state2->N;
    5565                 : 
    5566                 : #ifdef HAVE_INT128
    5567               3 :         state1->sumX = state2->sumX;
    5568               3 :         state1->sumX2 = state2->sumX2;
    5569                 : #else
    5570                 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5571                 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5572                 : #endif
    5573 ECB             : 
    5574 GIC           3 :         MemoryContextSwitchTo(old_context);
    5575                 : 
    5576               3 :         PG_RETURN_POINTER(state1);
    5577 ECB             :     }
    5578                 : 
    5579 GIC           5 :     if (state2->N > 0)
    5580 ECB             :     {
    5581 CBC           5 :         state1->N += state2->N;
    5582                 : 
    5583 ECB             : #ifdef HAVE_INT128
    5584 GIC           5 :         state1->sumX += state2->sumX;
    5585               5 :         state1->sumX2 += state2->sumX2;
    5586 ECB             : #else
    5587                 :         /* The rest of this needs to work in the aggregate context */
    5588                 :         old_context = MemoryContextSwitchTo(agg_context);
    5589                 : 
    5590                 :         /* Accumulate sums */
    5591                 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5592                 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5593                 : 
    5594                 :         MemoryContextSwitchTo(old_context);
    5595                 : #endif
    5596                 : 
    5597                 :     }
    5598 GIC           5 :     PG_RETURN_POINTER(state1);
    5599                 : }
    5600 ECB             : 
    5601                 : /*
    5602                 :  * numeric_poly_serialize
    5603                 :  *      Serialize PolyNumAggState into bytea for aggregate functions which
    5604                 :  *      require sumX2.
    5605                 :  */
    5606                 : Datum
    5607 GIC           8 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5608                 : {
    5609 ECB             :     PolyNumAggState *state;
    5610                 :     StringInfoData buf;
    5611                 :     bytea      *result;
    5612                 :     NumericVar  tmp_var;
    5613                 : 
    5614                 :     /* Ensure we disallow calling when not in aggregate context */
    5615 CBC           8 :     if (!AggCheckCallContext(fcinfo, NULL))
    5616 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5617                 : 
    5618 GIC           8 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5619 ECB             : 
    5620                 :     /*
    5621                 :      * If the platform supports int128 then sumX and sumX2 will be a 128 bit
    5622                 :      * integer type. Here we'll convert that into a numeric type so that the
    5623                 :      * combine state is in the same format for both int128 enabled machines
    5624                 :      * and machines which don't support that type. The logic here is that one
    5625                 :      * day we might like to send these over to another server for further
    5626                 :      * processing and we want a standard format to work with.
    5627                 :      */
    5628                 : 
    5629 CBC           8 :     init_var(&tmp_var);
    5630 ECB             : 
    5631 GIC           8 :     pq_begintypsend(&buf);
    5632 ECB             : 
    5633                 :     /* N */
    5634 GIC           8 :     pq_sendint64(&buf, state->N);
    5635                 : 
    5636                 :     /* sumX */
    5637                 : #ifdef HAVE_INT128
    5638               8 :     int128_to_numericvar(state->sumX, &tmp_var);
    5639 ECB             : #else
    5640                 :     accum_sum_final(&state->sumX, &tmp_var);
    5641                 : #endif
    5642 GIC           8 :     numericvar_serialize(&buf, &tmp_var);
    5643                 : 
    5644                 :     /* sumX2 */
    5645                 : #ifdef HAVE_INT128
    5646 CBC           8 :     int128_to_numericvar(state->sumX2, &tmp_var);
    5647 EUB             : #else
    5648                 :     accum_sum_final(&state->sumX2, &tmp_var);
    5649 ECB             : #endif
    5650 CBC           8 :     numericvar_serialize(&buf, &tmp_var);
    5651                 : 
    5652               8 :     result = pq_endtypsend(&buf);
    5653 EUB             : 
    5654 GIC           8 :     free_var(&tmp_var);
    5655                 : 
    5656 CBC           8 :     PG_RETURN_BYTEA_P(result);
    5657                 : }
    5658 ECB             : 
    5659                 : /*
    5660                 :  * numeric_poly_deserialize
    5661                 :  *      Deserialize PolyNumAggState from bytea for aggregate functions which
    5662                 :  *      require sumX2.
    5663                 :  */
    5664                 : Datum
    5665 CBC           8 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5666                 : {
    5667                 :     bytea      *sstate;
    5668                 :     PolyNumAggState *result;
    5669                 :     StringInfoData buf;
    5670                 :     NumericVar  tmp_var;
    5671 ECB             : 
    5672 GIC           8 :     if (!AggCheckCallContext(fcinfo, NULL))
    5673 LBC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5674                 : 
    5675 GIC           8 :     sstate = PG_GETARG_BYTEA_PP(0);
    5676 ECB             : 
    5677 GIC           8 :     init_var(&tmp_var);
    5678 ECB             : 
    5679                 :     /*
    5680                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
    5681                 :      * standard recv-function infrastructure.
    5682                 :      */
    5683 GIC           8 :     initStringInfo(&buf);
    5684              16 :     appendBinaryStringInfo(&buf,
    5685              16 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
    5686                 : 
    5687               8 :     result = makePolyNumAggStateCurrentContext(false);
    5688                 : 
    5689                 :     /* N */
    5690               8 :     result->N = pq_getmsgint64(&buf);
    5691                 : 
    5692                 :     /* sumX */
    5693               8 :     numericvar_deserialize(&buf, &tmp_var);
    5694                 : #ifdef HAVE_INT128
    5695 CBC           8 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5696                 : #else
    5697                 :     accum_sum_add(&result->sumX, &tmp_var);
    5698                 : #endif
    5699                 : 
    5700                 :     /* sumX2 */
    5701 GIC           8 :     numericvar_deserialize(&buf, &tmp_var);
    5702                 : #ifdef HAVE_INT128
    5703               8 :     numericvar_to_int128(&tmp_var, &result->sumX2);
    5704 ECB             : #else
    5705                 :     accum_sum_add(&result->sumX2, &tmp_var);
    5706                 : #endif
    5707                 : 
    5708 GIC           8 :     pq_getmsgend(&buf);
    5709               8 :     pfree(buf.data);
    5710                 : 
    5711               8 :     free_var(&tmp_var);
    5712 ECB             : 
    5713 GBC           8 :     PG_RETURN_POINTER(result);
    5714                 : }
    5715 ECB             : 
    5716                 : /*
    5717                 :  * Transition function for int8 input when we don't need sumX2.
    5718                 :  */
    5719                 : Datum
    5720 GIC      155559 : int8_avg_accum(PG_FUNCTION_ARGS)
    5721                 : {
    5722                 :     PolyNumAggState *state;
    5723                 : 
    5724          155559 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5725                 : 
    5726 ECB             :     /* Create the state data on the first call */
    5727 GIC      155559 :     if (state == NULL)
    5728 CBC         259 :         state = makePolyNumAggState(fcinfo, false);
    5729                 : 
    5730 GIC      155559 :     if (!PG_ARGISNULL(1))
    5731 ECB             :     {
    5732                 : #ifdef HAVE_INT128
    5733 GIC      155085 :         do_int128_accum(state, (int128) PG_GETARG_INT64(1));
    5734                 : #else
    5735 ECB             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5736                 : #endif
    5737                 :     }
    5738                 : 
    5739 CBC      155559 :     PG_RETURN_POINTER(state);
    5740                 : }
    5741                 : 
    5742                 : /*
    5743 ECB             :  * Combine function for PolyNumAggState for aggregates which don't require
    5744                 :  * sumX2
    5745                 :  */
    5746                 : Datum
    5747 CBC          11 : int8_avg_combine(PG_FUNCTION_ARGS)
    5748                 : {
    5749 ECB             :     PolyNumAggState *state1;
    5750                 :     PolyNumAggState *state2;
    5751                 :     MemoryContext agg_context;
    5752                 :     MemoryContext old_context;
    5753                 : 
    5754 GIC          11 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5755 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5756                 : 
    5757 GIC          11 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5758              11 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5759                 : 
    5760              11 :     if (state2 == NULL)
    5761 UIC           0 :         PG_RETURN_POINTER(state1);
    5762 ECB             : 
    5763                 :     /* manually copy all fields from state2 to state1 */
    5764 GIC          11 :     if (state1 == NULL)
    5765                 :     {
    5766               6 :         old_context = MemoryContextSwitchTo(agg_context);
    5767                 : 
    5768               6 :         state1 = makePolyNumAggState(fcinfo, false);
    5769 CBC           6 :         state1->N = state2->N;
    5770 EUB             : 
    5771                 : #ifdef HAVE_INT128
    5772 CBC           6 :         state1->sumX = state2->sumX;
    5773                 : #else
    5774 ECB             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5775                 : #endif
    5776 GIC           6 :         MemoryContextSwitchTo(old_context);
    5777                 : 
    5778               6 :         PG_RETURN_POINTER(state1);
    5779                 :     }
    5780 ECB             : 
    5781 CBC           5 :     if (state2->N > 0)
    5782 ECB             :     {
    5783 GIC           5 :         state1->N += state2->N;
    5784 ECB             : 
    5785                 : #ifdef HAVE_INT128
    5786 GIC           5 :         state1->sumX += state2->sumX;
    5787 ECB             : #else
    5788                 :         /* The rest of this needs to work in the aggregate context */
    5789                 :         old_context = MemoryContextSwitchTo(agg_context);
    5790                 : 
    5791                 :         /* Accumulate sums */
    5792                 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5793                 : 
    5794                 :         MemoryContextSwitchTo(old_context);
    5795                 : #endif
    5796                 : 
    5797                 :     }
    5798 CBC           5 :     PG_RETURN_POINTER(state1);
    5799                 : }
    5800 ECB             : 
    5801                 : /*
    5802                 :  * int8_avg_serialize
    5803                 :  *      Serialize PolyNumAggState into bytea using the standard
    5804                 :  *      recv-function infrastructure.
    5805                 :  */
    5806                 : Datum
    5807 GIC          11 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5808 ECB             : {
    5809                 :     PolyNumAggState *state;
    5810                 :     StringInfoData buf;
    5811                 :     bytea      *result;
    5812                 :     NumericVar  tmp_var;
    5813                 : 
    5814                 :     /* Ensure we disallow calling when not in aggregate context */
    5815 GIC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
    5816 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5817 ECB             : 
    5818 GIC          11 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5819                 : 
    5820                 :     /*
    5821 ECB             :      * If the platform supports int128 then sumX will be a 128 integer type.
    5822                 :      * Here we'll convert that into a numeric type so that the combine state
    5823                 :      * is in the same format for both int128 enabled machines and machines
    5824                 :      * which don't support that type. The logic here is that one day we might
    5825                 :      * like to send these over to another server for further processing and we
    5826                 :      * want a standard format to work with.
    5827                 :      */
    5828                 : 
    5829 GIC          11 :     init_var(&tmp_var);
    5830 ECB             : 
    5831 GIC          11 :     pq_begintypsend(&buf);
    5832                 : 
    5833                 :     /* N */
    5834              11 :     pq_sendint64(&buf, state->N);
    5835                 : 
    5836 ECB             :     /* sumX */
    5837                 : #ifdef HAVE_INT128
    5838 GIC          11 :     int128_to_numericvar(state->sumX, &tmp_var);
    5839                 : #else
    5840                 :     accum_sum_final(&state->sumX, &tmp_var);
    5841                 : #endif
    5842              11 :     numericvar_serialize(&buf, &tmp_var);
    5843                 : 
    5844 CBC          11 :     result = pq_endtypsend(&buf);
    5845                 : 
    5846 GIC          11 :     free_var(&tmp_var);
    5847                 : 
    5848              11 :     PG_RETURN_BYTEA_P(result);
    5849                 : }
    5850                 : 
    5851 ECB             : /*
    5852 EUB             :  * int8_avg_deserialize
    5853                 :  *      Deserialize bytea back into PolyNumAggState.
    5854 ECB             :  */
    5855                 : Datum
    5856 GIC          11 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    5857 ECB             : {
    5858 EUB             :     bytea      *sstate;
    5859                 :     PolyNumAggState *result;
    5860                 :     StringInfoData buf;
    5861 ECB             :     NumericVar  tmp_var;
    5862                 : 
    5863 CBC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
    5864 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5865 ECB             : 
    5866 CBC          11 :     sstate = PG_GETARG_BYTEA_PP(0);
    5867                 : 
    5868 GIC          11 :     init_var(&tmp_var);
    5869 ECB             : 
    5870                 :     /*
    5871                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
    5872                 :      * standard recv-function infrastructure.
    5873                 :      */
    5874 GIC          11 :     initStringInfo(&buf);
    5875 CBC          22 :     appendBinaryStringInfo(&buf,
    5876 GIC          22 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
    5877                 : 
    5878 CBC          11 :     result = makePolyNumAggStateCurrentContext(false);
    5879                 : 
    5880 ECB             :     /* N */
    5881 GIC          11 :     result->N = pq_getmsgint64(&buf);
    5882                 : 
    5883 ECB             :     /* sumX */
    5884 GIC          11 :     numericvar_deserialize(&buf, &tmp_var);
    5885                 : #ifdef HAVE_INT128
    5886              11 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5887                 : #else
    5888                 :     accum_sum_add(&result->sumX, &tmp_var);
    5889                 : #endif
    5890                 : 
    5891              11 :     pq_getmsgend(&buf);
    5892              11 :     pfree(buf.data);
    5893                 : 
    5894              11 :     free_var(&tmp_var);
    5895 ECB             : 
    5896 GIC          11 :     PG_RETURN_POINTER(result);
    5897                 : }
    5898                 : 
    5899                 : /*
    5900                 :  * Inverse transition functions to go with the above.
    5901                 :  */
    5902                 : 
    5903                 : Datum
    5904 CBC          81 : int2_accum_inv(PG_FUNCTION_ARGS)
    5905                 : {
    5906                 :     PolyNumAggState *state;
    5907                 : 
    5908 GIC          81 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5909                 : 
    5910                 :     /* Should not get here with no state */
    5911              81 :     if (state == NULL)
    5912 LBC           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    5913 EUB             : 
    5914 GIC          81 :     if (!PG_ARGISNULL(1))
    5915 ECB             :     {
    5916                 : #ifdef HAVE_INT128
    5917 GIC          72 :         do_int128_discard(state, (int128) PG_GETARG_INT16(1));
    5918                 : #else
    5919                 :         /* Should never fail, all inputs have dscale 0 */
    5920                 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
    5921                 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5922                 : #endif
    5923                 :     }
    5924                 : 
    5925              81 :     PG_RETURN_POINTER(state);
    5926 ECB             : }
    5927                 : 
    5928                 : Datum
    5929 GIC          81 : int4_accum_inv(PG_FUNCTION_ARGS)
    5930                 : {
    5931 ECB             :     PolyNumAggState *state;
    5932                 : 
    5933 GIC          81 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5934                 : 
    5935 ECB             :     /* Should not get here with no state */
    5936 GIC          81 :     if (state == NULL)
    5937 UIC           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    5938                 : 
    5939 CBC          81 :     if (!PG_ARGISNULL(1))
    5940                 :     {
    5941 ECB             : #ifdef HAVE_INT128
    5942 GIC          72 :         do_int128_discard(state, (int128) PG_GETARG_INT32(1));
    5943 ECB             : #else
    5944                 :         /* Should never fail, all inputs have dscale 0 */
    5945                 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
    5946                 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5947                 : #endif
    5948                 :     }
    5949                 : 
    5950 GIC          81 :     PG_RETURN_POINTER(state);
    5951                 : }
    5952                 : 
    5953 ECB             : Datum
    5954 GIC          81 : int8_accum_inv(PG_FUNCTION_ARGS)
    5955                 : {
    5956                 :     NumericAggState *state;
    5957                 : 
    5958              81 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5959                 : 
    5960 ECB             :     /* Should not get here with no state */
    5961 GBC          81 :     if (state == NULL)
    5962 UIC           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    5963 ECB             : 
    5964 GIC          81 :     if (!PG_ARGISNULL(1))
    5965 ECB             :     {
    5966                 :         /* Should never fail, all inputs have dscale 0 */
    5967 GIC          72 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    5968 UIC           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5969                 :     }
    5970                 : 
    5971 CBC          81 :     PG_RETURN_POINTER(state);
    5972 ECB             : }
    5973                 : 
    5974                 : Datum
    5975 CBC          18 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    5976                 : {
    5977                 :     PolyNumAggState *state;
    5978 ECB             : 
    5979 GIC          18 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5980                 : 
    5981 ECB             :     /* Should not get here with no state */
    5982 GIC          18 :     if (state == NULL)
    5983 LBC           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    5984                 : 
    5985 GIC          18 :     if (!PG_ARGISNULL(1))
    5986                 :     {
    5987                 : #ifdef HAVE_INT128
    5988 CBC          12 :         do_int128_discard(state, (int128) PG_GETARG_INT64(1));
    5989 ECB             : #else
    5990                 :         /* Should never fail, all inputs have dscale 0 */
    5991                 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    5992                 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5993                 : #endif
    5994                 :     }
    5995                 : 
    5996 GIC          18 :     PG_RETURN_POINTER(state);
    5997                 : }
    5998                 : 
    5999                 : Datum
    6000             371 : numeric_poly_sum(PG_FUNCTION_ARGS)
    6001 ECB             : {
    6002                 : #ifdef HAVE_INT128
    6003                 :     PolyNumAggState *state;
    6004                 :     Numeric     res;
    6005                 :     NumericVar  result;
    6006                 : 
    6007 GIC         371 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6008 ECB             : 
    6009 EUB             :     /* If there were no non-null inputs, return NULL */
    6010 GIC         371 :     if (state == NULL || state->N == 0)
    6011 CBC          12 :         PG_RETURN_NULL();
    6012                 : 
    6013 GIC         359 :     init_var(&result);
    6014 ECB             : 
    6015 GIC         359 :     int128_to_numericvar(state->sumX, &result);
    6016                 : 
    6017             359 :     res = make_result(&result);
    6018                 : 
    6019             359 :     free_var(&result);
    6020                 : 
    6021             359 :     PG_RETURN_NUMERIC(res);
    6022 ECB             : #else
    6023                 :     return numeric_sum(fcinfo);
    6024                 : #endif
    6025                 : }
    6026                 : 
    6027                 : Datum
    6028 GIC          18 : numeric_poly_avg(PG_FUNCTION_ARGS)
    6029                 : {
    6030 ECB             : #ifdef HAVE_INT128
    6031                 :     PolyNumAggState *state;
    6032                 :     NumericVar  result;
    6033                 :     Datum       countd,
    6034 EUB             :                 sumd;
    6035                 : 
    6036 CBC          18 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6037                 : 
    6038                 :     /* If there were no non-null inputs, return NULL */
    6039              18 :     if (state == NULL || state->N == 0)
    6040 GIC           9 :         PG_RETURN_NULL();
    6041                 : 
    6042               9 :     init_var(&result);
    6043                 : 
    6044               9 :     int128_to_numericvar(state->sumX, &result);
    6045                 : 
    6046               9 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    6047 CBC           9 :     sumd = NumericGetDatum(make_result(&result));
    6048                 : 
    6049 GIC           9 :     free_var(&result);
    6050                 : 
    6051 CBC           9 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6052                 : #else
    6053                 :     return numeric_avg(fcinfo);
    6054                 : #endif
    6055 ECB             : }
    6056                 : 
    6057                 : Datum
    6058 CBC          39 : numeric_avg(PG_FUNCTION_ARGS)
    6059 EUB             : {
    6060                 :     NumericAggState *state;
    6061 ECB             :     Datum       N_datum;
    6062                 :     Datum       sumX_datum;
    6063                 :     NumericVar  sumX_var;
    6064                 : 
    6065 GBC          39 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6066                 : 
    6067                 :     /* If there were no non-null inputs, return NULL */
    6068 CBC          39 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6069 GIC           9 :         PG_RETURN_NULL();
    6070                 : 
    6071              30 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6072 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6073                 : 
    6074                 :     /* adding plus and minus infinities gives NaN */
    6075 GIC          27 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6076 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6077 GIC          24 :     if (state->pInfcount > 0)
    6078               9 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6079 CBC          15 :     if (state->nInfcount > 0)
    6080 GBC           3 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6081                 : 
    6082 CBC          12 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    6083                 : 
    6084 GIC          12 :     init_var(&sumX_var);
    6085 CBC          12 :     accum_sum_final(&state->sumX, &sumX_var);
    6086 GIC          12 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    6087              12 :     free_var(&sumX_var);
    6088                 : 
    6089              12 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    6090                 : }
    6091                 : 
    6092                 : Datum
    6093 CBC       85453 : numeric_sum(PG_FUNCTION_ARGS)
    6094                 : {
    6095                 :     NumericAggState *state;
    6096                 :     NumericVar  sumX_var;
    6097 ECB             :     Numeric     result;
    6098                 : 
    6099 GIC       85453 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6100                 : 
    6101                 :     /* If there were no non-null inputs, return NULL */
    6102           85453 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6103               9 :         PG_RETURN_NULL();
    6104 ECB             : 
    6105 GIC       85444 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6106               9 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6107 ECB             : 
    6108                 :     /* adding plus and minus infinities gives NaN */
    6109 GIC       85435 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6110 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6111 GIC       85432 :     if (state->pInfcount > 0)
    6112 CBC           9 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6113 GIC       85423 :     if (state->nInfcount > 0)
    6114 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6115                 : 
    6116           85420 :     init_var(&sumX_var);
    6117 GIC       85420 :     accum_sum_final(&state->sumX, &sumX_var);
    6118 CBC       85420 :     result = make_result(&sumX_var);
    6119 GIC       85420 :     free_var(&sumX_var);
    6120                 : 
    6121           85420 :     PG_RETURN_NUMERIC(result);
    6122                 : }
    6123                 : 
    6124                 : /*
    6125 ECB             :  * Workhorse routine for the standard deviance and variance
    6126                 :  * aggregates. 'state' is aggregate's transition state.
    6127                 :  * 'variance' specifies whether we should calculate the
    6128                 :  * variance or the standard deviation. 'sample' indicates whether the
    6129                 :  * caller is interested in the sample or the population
    6130                 :  * variance/stddev.
    6131                 :  *
    6132                 :  * If appropriate variance statistic is undefined for the input,
    6133                 :  * *is_null is set to true and NULL is returned.
    6134                 :  */
    6135                 : static Numeric
    6136 CBC         493 : numeric_stddev_internal(NumericAggState *state,
    6137 ECB             :                         bool variance, bool sample,
    6138                 :                         bool *is_null)
    6139                 : {
    6140                 :     Numeric     res;
    6141                 :     NumericVar  vN,
    6142                 :                 vsumX,
    6143                 :                 vsumX2,
    6144                 :                 vNminus1;
    6145                 :     int64       totCount;
    6146                 :     int         rscale;
    6147                 : 
    6148                 :     /*
    6149                 :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6150                 :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6151                 :      * and infinities count as normal inputs for this purpose).
    6152                 :      */
    6153 GIC         493 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6154                 :     {
    6155 LBC           0 :         *is_null = true;
    6156 UIC           0 :         return NULL;
    6157                 :     }
    6158                 : 
    6159 GIC         493 :     if (sample && totCount <= 1)
    6160                 :     {
    6161              66 :         *is_null = true;
    6162 CBC          66 :         return NULL;
    6163                 :     }
    6164                 : 
    6165             427 :     *is_null = false;
    6166 ECB             : 
    6167                 :     /*
    6168                 :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6169                 :      * float8 functions, any infinity input produces NaN output.
    6170                 :      */
    6171 GIC         427 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6172 CBC          27 :         return make_result(&const_nan);
    6173 ECB             : 
    6174                 :     /* OK, normal calculation applies */
    6175 CBC         400 :     init_var(&vN);
    6176             400 :     init_var(&vsumX);
    6177             400 :     init_var(&vsumX2);
    6178                 : 
    6179             400 :     int64_to_numericvar(state->N, &vN);
    6180 GIC         400 :     accum_sum_final(&(state->sumX), &vsumX);
    6181 CBC         400 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6182 ECB             : 
    6183 CBC         400 :     init_var(&vNminus1);
    6184             400 :     sub_var(&vN, &const_one, &vNminus1);
    6185                 : 
    6186 ECB             :     /* compute rscale for mul_var calls */
    6187 GIC         400 :     rscale = vsumX.dscale * 2;
    6188                 : 
    6189             400 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6190 CBC         400 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6191 GIC         400 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6192                 : 
    6193             400 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6194                 :     {
    6195                 :         /* Watch out for roundoff error producing a negative numerator */
    6196 CBC          40 :         res = make_result(&const_zero);
    6197                 :     }
    6198                 :     else
    6199 ECB             :     {
    6200 CBC         360 :         if (sample)
    6201 GIC         246 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6202 ECB             :         else
    6203 CBC         114 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6204 GIC         360 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6205             360 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true);  /* variance */
    6206 CBC         360 :         if (!variance)
    6207             189 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6208 ECB             : 
    6209 CBC         360 :         res = make_result(&vsumX);
    6210 ECB             :     }
    6211                 : 
    6212 GIC         400 :     free_var(&vNminus1);
    6213 CBC         400 :     free_var(&vsumX);
    6214             400 :     free_var(&vsumX2);
    6215 ECB             : 
    6216 CBC         400 :     return res;
    6217                 : }
    6218 ECB             : 
    6219                 : Datum
    6220 GIC          90 : numeric_var_samp(PG_FUNCTION_ARGS)
    6221                 : {
    6222                 :     NumericAggState *state;
    6223                 :     Numeric     res;
    6224                 :     bool        is_null;
    6225                 : 
    6226              90 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6227                 : 
    6228              90 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6229                 : 
    6230              90 :     if (is_null)
    6231              21 :         PG_RETURN_NULL();
    6232                 :     else
    6233 CBC          69 :         PG_RETURN_NUMERIC(res);
    6234                 : }
    6235                 : 
    6236                 : Datum
    6237 GIC          87 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6238                 : {
    6239                 :     NumericAggState *state;
    6240                 :     Numeric     res;
    6241                 :     bool        is_null;
    6242                 : 
    6243              87 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6244                 : 
    6245              87 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6246                 : 
    6247              87 :     if (is_null)
    6248              21 :         PG_RETURN_NULL();
    6249                 :     else
    6250 CBC          66 :         PG_RETURN_NUMERIC(res);
    6251                 : }
    6252 EUB             : 
    6253                 : Datum
    6254 GIC          57 : numeric_var_pop(PG_FUNCTION_ARGS)
    6255                 : {
    6256 ECB             :     NumericAggState *state;
    6257                 :     Numeric     res;
    6258                 :     bool        is_null;
    6259                 : 
    6260 GIC          57 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6261                 : 
    6262 CBC          57 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6263                 : 
    6264 GIC          57 :     if (is_null)
    6265 UIC           0 :         PG_RETURN_NULL();
    6266                 :     else
    6267 GIC          57 :         PG_RETURN_NUMERIC(res);
    6268 ECB             : }
    6269                 : 
    6270                 : Datum
    6271 GIC          48 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6272 ECB             : {
    6273                 :     NumericAggState *state;
    6274                 :     Numeric     res;
    6275                 :     bool        is_null;
    6276                 : 
    6277 CBC          48 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6278 ECB             : 
    6279 GIC          48 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6280 ECB             : 
    6281 CBC          48 :     if (is_null)
    6282 UIC           0 :         PG_RETURN_NULL();
    6283                 :     else
    6284 CBC          48 :         PG_RETURN_NUMERIC(res);
    6285                 : }
    6286 ECB             : 
    6287                 : #ifdef HAVE_INT128
    6288                 : static Numeric
    6289 GIC         211 : numeric_poly_stddev_internal(Int128AggState *state,
    6290 ECB             :                              bool variance, bool sample,
    6291                 :                              bool *is_null)
    6292                 : {
    6293                 :     NumericAggState numstate;
    6294                 :     Numeric     res;
    6295                 : 
    6296                 :     /* Initialize an empty agg state */
    6297 CBC         211 :     memset(&numstate, 0, sizeof(NumericAggState));
    6298 ECB             : 
    6299 GIC         211 :     if (state)
    6300 ECB             :     {
    6301                 :         NumericVar  tmp_var;
    6302                 : 
    6303 CBC         211 :         numstate.N = state->N;
    6304 ECB             : 
    6305 GIC         211 :         init_var(&tmp_var);
    6306 ECB             : 
    6307 GIC         211 :         int128_to_numericvar(state->sumX, &tmp_var);
    6308             211 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6309 ECB             : 
    6310 CBC         211 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6311             211 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6312                 : 
    6313             211 :         free_var(&tmp_var);
    6314                 :     }
    6315                 : 
    6316 GIC         211 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6317 ECB             : 
    6318 GIC         211 :     if (numstate.sumX.ndigits > 0)
    6319                 :     {
    6320             211 :         pfree(numstate.sumX.pos_digits);
    6321             211 :         pfree(numstate.sumX.neg_digits);
    6322                 :     }
    6323 CBC         211 :     if (numstate.sumX2.ndigits > 0)
    6324                 :     {
    6325             211 :         pfree(numstate.sumX2.pos_digits);
    6326 GIC         211 :         pfree(numstate.sumX2.neg_digits);
    6327 ECB             :     }
    6328                 : 
    6329 GIC         211 :     return res;
    6330 ECB             : }
    6331                 : #endif
    6332                 : 
    6333                 : Datum
    6334 CBC          63 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6335                 : {
    6336                 : #ifdef HAVE_INT128
    6337                 :     PolyNumAggState *state;
    6338                 :     Numeric     res;
    6339                 :     bool        is_null;
    6340 ECB             : 
    6341 GIC          63 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6342 ECB             : 
    6343 GIC          63 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6344 ECB             : 
    6345 CBC          63 :     if (is_null)
    6346 GIC          12 :         PG_RETURN_NULL();
    6347 ECB             :     else
    6348 GIC          51 :         PG_RETURN_NUMERIC(res);
    6349                 : #else
    6350                 :     return numeric_var_samp(fcinfo);
    6351 ECB             : #endif
    6352                 : }
    6353                 : 
    6354                 : Datum
    6355 GIC          82 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6356                 : {
    6357 ECB             : #ifdef HAVE_INT128
    6358                 :     PolyNumAggState *state;
    6359                 :     Numeric     res;
    6360                 :     bool        is_null;
    6361                 : 
    6362 GBC          82 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6363                 : 
    6364 CBC          82 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6365                 : 
    6366 GIC          82 :     if (is_null)
    6367              12 :         PG_RETURN_NULL();
    6368 ECB             :     else
    6369 GIC          70 :         PG_RETURN_NUMERIC(res);
    6370                 : #else
    6371                 :     return numeric_stddev_samp(fcinfo);
    6372                 : #endif
    6373                 : }
    6374 ECB             : 
    6375                 : Datum
    6376 CBC          30 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6377                 : {
    6378 ECB             : #ifdef HAVE_INT128
    6379 EUB             :     PolyNumAggState *state;
    6380                 :     Numeric     res;
    6381 ECB             :     bool        is_null;
    6382                 : 
    6383 GIC          30 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6384                 : 
    6385              30 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6386 ECB             : 
    6387 GIC          30 :     if (is_null)
    6388 UIC           0 :         PG_RETURN_NULL();
    6389                 :     else
    6390 GIC          30 :         PG_RETURN_NUMERIC(res);
    6391                 : #else
    6392                 :     return numeric_var_pop(fcinfo);
    6393                 : #endif
    6394 ECB             : }
    6395                 : 
    6396                 : Datum
    6397 GIC          36 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6398                 : {
    6399                 : #ifdef HAVE_INT128
    6400 ECB             :     PolyNumAggState *state;
    6401                 :     Numeric     res;
    6402                 :     bool        is_null;
    6403                 : 
    6404 CBC          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6405 ECB             : 
    6406 GIC          36 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6407 ECB             : 
    6408 CBC          36 :     if (is_null)
    6409 UIC           0 :         PG_RETURN_NULL();
    6410 ECB             :     else
    6411 GIC          36 :         PG_RETURN_NUMERIC(res);
    6412                 : #else
    6413 ECB             :     return numeric_stddev_pop(fcinfo);
    6414                 : #endif
    6415                 : }
    6416                 : 
    6417                 : /*
    6418                 :  * SUM transition functions for integer datatypes.
    6419                 :  *
    6420                 :  * To avoid overflow, we use accumulators wider than the input datatype.
    6421                 :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6422                 :  * inputs, we use int8 accumulators which should be sufficient for practical
    6423                 :  * purposes.  (The latter two therefore don't really belong in this file,
    6424                 :  * but we keep them here anyway.)
    6425                 :  *
    6426                 :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6427                 :  * the initial condition of the transition data value needs to be NULL. This
    6428                 :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6429                 :  * data value into the transition data: it doesn't know how to do the type
    6430                 :  * conversion.  The upshot is that these routines have to be marked non-strict
    6431                 :  * and handle substitution of the first non-null input themselves.
    6432                 :  *
    6433                 :  * Note: these functions are used only in plain aggregation mode.
    6434                 :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6435                 :  */
    6436                 : 
    6437                 : Datum
    6438 CBC          12 : int2_sum(PG_FUNCTION_ARGS)
    6439                 : {
    6440 ECB             :     int64       newval;
    6441                 : 
    6442 CBC          12 :     if (PG_ARGISNULL(0))
    6443 ECB             :     {
    6444                 :         /* No non-null input seen so far... */
    6445 CBC           3 :         if (PG_ARGISNULL(1))
    6446 UIC           0 :             PG_RETURN_NULL();   /* still no non-null */
    6447                 :         /* This is the first non-null input. */
    6448 GIC           3 :         newval = (int64) PG_GETARG_INT16(1);
    6449               3 :         PG_RETURN_INT64(newval);
    6450                 :     }
    6451                 : 
    6452 ECB             :     /*
    6453                 :      * If we're invoked as an aggregate, we can cheat and modify our first
    6454                 :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6455                 :      * the new value of the transition variable. (If int8 is pass-by-value,
    6456                 :      * then of course this is useless as well as incorrect, so just ifdef it
    6457                 :      * out.)
    6458                 :      */
    6459                 : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6460                 :     if (AggCheckCallContext(fcinfo, NULL))
    6461                 :     {
    6462                 :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6463                 : 
    6464                 :         /* Leave the running sum unchanged in the new input is null */
    6465                 :         if (!PG_ARGISNULL(1))
    6466                 :             *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
    6467                 : 
    6468                 :         PG_RETURN_POINTER(oldsum);
    6469                 :     }
    6470                 :     else
    6471                 : #endif
    6472                 :     {
    6473 CBC           9 :         int64       oldsum = PG_GETARG_INT64(0);
    6474                 : 
    6475                 :         /* Leave sum unchanged if new input is null. */
    6476 GIC           9 :         if (PG_ARGISNULL(1))
    6477 UIC           0 :             PG_RETURN_INT64(oldsum);
    6478                 : 
    6479                 :         /* OK to do the addition. */
    6480 CBC           9 :         newval = oldsum + (int64) PG_GETARG_INT16(1);
    6481                 : 
    6482               9 :         PG_RETURN_INT64(newval);
    6483                 :     }
    6484 ECB             : }
    6485 EUB             : 
    6486                 : Datum
    6487 CBC     1697126 : int4_sum(PG_FUNCTION_ARGS)
    6488                 : {
    6489                 :     int64       newval;
    6490                 : 
    6491 GIC     1697126 :     if (PG_ARGISNULL(0))
    6492                 :     {
    6493                 :         /* No non-null input seen so far... */
    6494 CBC       43227 :         if (PG_ARGISNULL(1))
    6495 GIC         493 :             PG_RETURN_NULL();   /* still no non-null */
    6496                 :         /* This is the first non-null input. */
    6497           42734 :         newval = (int64) PG_GETARG_INT32(1);
    6498           42734 :         PG_RETURN_INT64(newval);
    6499                 :     }
    6500                 : 
    6501 ECB             :     /*
    6502                 :      * If we're invoked as an aggregate, we can cheat and modify our first
    6503                 :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6504                 :      * the new value of the transition variable. (If int8 is pass-by-value,
    6505                 :      * then of course this is useless as well as incorrect, so just ifdef it
    6506 EUB             :      * out.)
    6507                 :      */
    6508 ECB             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6509                 :     if (AggCheckCallContext(fcinfo, NULL))
    6510                 :     {
    6511                 :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6512                 : 
    6513                 :         /* Leave the running sum unchanged in the new input is null */
    6514                 :         if (!PG_ARGISNULL(1))
    6515                 :             *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
    6516                 : 
    6517                 :         PG_RETURN_POINTER(oldsum);
    6518                 :     }
    6519                 :     else
    6520                 : #endif
    6521                 :     {
    6522 GIC     1653899 :         int64       oldsum = PG_GETARG_INT64(0);
    6523                 : 
    6524                 :         /* Leave sum unchanged if new input is null. */
    6525         1653899 :         if (PG_ARGISNULL(1))
    6526             437 :             PG_RETURN_INT64(oldsum);
    6527                 : 
    6528                 :         /* OK to do the addition. */
    6529         1653462 :         newval = oldsum + (int64) PG_GETARG_INT32(1);
    6530                 : 
    6531         1653462 :         PG_RETURN_INT64(newval);
    6532                 :     }
    6533                 : }
    6534                 : 
    6535 ECB             : /*
    6536                 :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6537                 :  */
    6538                 : Datum
    6539 LBC           0 : int8_sum(PG_FUNCTION_ARGS)
    6540                 : {
    6541                 :     Numeric     oldsum;
    6542 ECB             : 
    6543 UBC           0 :     if (PG_ARGISNULL(0))
    6544                 :     {
    6545 ECB             :         /* No non-null input seen so far... */
    6546 LBC           0 :         if (PG_ARGISNULL(1))
    6547 UIC           0 :             PG_RETURN_NULL();   /* still no non-null */
    6548                 :         /* This is the first non-null input. */
    6549               0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6550                 :     }
    6551                 : 
    6552                 :     /*
    6553                 :      * Note that we cannot special-case the aggregate case here, as we do for
    6554                 :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6555                 :      * our first parameter in-place.
    6556                 :      */
    6557                 : 
    6558               0 :     oldsum = PG_GETARG_NUMERIC(0);
    6559                 : 
    6560                 :     /* Leave sum unchanged if new input is null. */
    6561               0 :     if (PG_ARGISNULL(1))
    6562               0 :         PG_RETURN_NUMERIC(oldsum);
    6563                 : 
    6564                 :     /* OK to do the addition. */
    6565               0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6566                 :                                         NumericGetDatum(oldsum),
    6567                 :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6568                 : }
    6569                 : 
    6570 ECB             : 
    6571                 : /*
    6572                 :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6573                 :  * is a two-element int8 array, holding count and sum.
    6574 EUB             :  *
    6575                 :  * These functions are also used for sum(int2) and sum(int4) when
    6576                 :  * operating in moving-aggregate mode, since for correct inverse transitions
    6577 ECB             :  * we need to count the inputs.
    6578                 :  */
    6579                 : 
    6580                 : typedef struct Int8TransTypeData
    6581                 : {
    6582                 :     int64       count;
    6583                 :     int64       sum;
    6584                 : } Int8TransTypeData;
    6585                 : 
    6586                 : Datum
    6587 GIC          21 : int2_avg_accum(PG_FUNCTION_ARGS)
    6588 ECB             : {
    6589                 :     ArrayType  *transarray;
    6590 GIC          21 :     int16       newval = PG_GETARG_INT16(1);
    6591 ECB             :     Int8TransTypeData *transdata;
    6592                 : 
    6593                 :     /*
    6594                 :      * If we're invoked as an aggregate, we can cheat and modify our first
    6595                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6596                 :      * a copy of it before scribbling on it.
    6597                 :      */
    6598 GIC          21 :     if (AggCheckCallContext(fcinfo, NULL))
    6599              21 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6600                 :     else
    6601 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6602                 : 
    6603 GIC          21 :     if (ARR_HASNULL(transarray) ||
    6604              21 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6605 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
    6606                 : 
    6607 GIC          21 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6608              21 :     transdata->count++;
    6609              21 :     transdata->sum += newval;
    6610                 : 
    6611              21 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6612                 : }
    6613                 : 
    6614                 : Datum
    6615         1326402 : int4_avg_accum(PG_FUNCTION_ARGS)
    6616                 : {
    6617                 :     ArrayType  *transarray;
    6618         1326402 :     int32       newval = PG_GETARG_INT32(1);
    6619 ECB             :     Int8TransTypeData *transdata;
    6620                 : 
    6621                 :     /*
    6622                 :      * If we're invoked as an aggregate, we can cheat and modify our first
    6623                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6624                 :      * a copy of it before scribbling on it.
    6625                 :      */
    6626 CBC     1326402 :     if (AggCheckCallContext(fcinfo, NULL))
    6627 GIC     1326402 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6628 ECB             :     else
    6629 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6630                 : 
    6631 GIC     1326402 :     if (ARR_HASNULL(transarray) ||
    6632         1326402 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6633 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
    6634                 : 
    6635 GIC     1326402 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6636 GBC     1326402 :     transdata->count++;
    6637 GIC     1326402 :     transdata->sum += newval;
    6638                 : 
    6639         1326402 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6640 EUB             : }
    6641                 : 
    6642                 : Datum
    6643 GBC        1973 : int4_avg_combine(PG_FUNCTION_ARGS)
    6644 EUB             : {
    6645                 :     ArrayType  *transarray1;
    6646                 :     ArrayType  *transarray2;
    6647                 :     Int8TransTypeData *state1;
    6648                 :     Int8TransTypeData *state2;
    6649                 : 
    6650 GIC        1973 :     if (!AggCheckCallContext(fcinfo, NULL))
    6651 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6652                 : 
    6653 GIC        1973 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6654            1973 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6655 EUB             : 
    6656 GIC        1973 :     if (ARR_HASNULL(transarray1) ||
    6657            1973 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6658 UBC           0 :         elog(ERROR, "expected 2-element int8 array");
    6659 EUB             : 
    6660 GIC        1973 :     if (ARR_HASNULL(transarray2) ||
    6661            1973 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6662 UBC           0 :         elog(ERROR, "expected 2-element int8 array");
    6663                 : 
    6664 GIC        1973 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6665            1973 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6666                 : 
    6667            1973 :     state1->count += state2->count;
    6668            1973 :     state1->sum += state2->sum;
    6669                 : 
    6670            1973 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6671                 : }
    6672                 : 
    6673                 : Datum
    6674               6 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6675                 : {
    6676                 :     ArrayType  *transarray;
    6677               6 :     int16       newval = PG_GETARG_INT16(1);
    6678                 :     Int8TransTypeData *transdata;
    6679                 : 
    6680                 :     /*
    6681                 :      * If we're invoked as an aggregate, we can cheat and modify our first
    6682                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6683                 :      * a copy of it before scribbling on it.
    6684 ECB             :      */
    6685 GIC           6 :     if (AggCheckCallContext(fcinfo, NULL))
    6686               6 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6687 ECB             :     else
    6688 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6689                 : 
    6690 GIC           6 :     if (ARR_HASNULL(transarray) ||
    6691               6 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6692 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
    6693                 : 
    6694 GIC           6 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6695 CBC           6 :     transdata->count--;
    6696               6 :     transdata->sum -= newval;
    6697                 : 
    6698 GBC           6 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6699                 : }
    6700 ECB             : 
    6701                 : Datum
    6702 GBC         726 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6703                 : {
    6704 ECB             :     ArrayType  *transarray;
    6705 CBC         726 :     int32       newval = PG_GETARG_INT32(1);
    6706 ECB             :     Int8TransTypeData *transdata;
    6707                 : 
    6708                 :     /*
    6709                 :      * If we're invoked as an aggregate, we can cheat and modify our first
    6710                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6711                 :      * a copy of it before scribbling on it.
    6712                 :      */
    6713 GIC         726 :     if (AggCheckCallContext(fcinfo, NULL))
    6714             726 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6715 ECB             :     else
    6716 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6717                 : 
    6718 GIC         726 :     if (ARR_HASNULL(transarray) ||
    6719             726 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6720 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
    6721                 : 
    6722 GIC         726 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6723 CBC         726 :     transdata->count--;
    6724             726 :     transdata->sum -= newval;
    6725                 : 
    6726 GBC         726 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6727                 : }
    6728 ECB             : 
    6729                 : Datum
    6730 GBC        5363 : int8_avg(PG_FUNCTION_ARGS)
    6731                 : {
    6732 CBC        5363 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6733 ECB             :     Int8TransTypeData *transdata;
    6734                 :     Datum       countd,
    6735                 :                 sumd;
    6736                 : 
    6737 GIC        5363 :     if (ARR_HASNULL(transarray) ||
    6738            5363 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6739 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
    6740 CBC        5363 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6741                 : 
    6742                 :     /* SQL defines AVG of no values to be NULL */
    6743 GIC        5363 :     if (transdata->count == 0)
    6744              59 :         PG_RETURN_NULL();
    6745                 : 
    6746            5304 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6747 CBC        5304 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6748 EUB             : 
    6749 GIC        5304 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6750 ECB             : }
    6751                 : 
    6752                 : /*
    6753                 :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6754                 :  * final function for both.
    6755 EUB             :  */
    6756                 : Datum
    6757 CBC        2766 : int2int4_sum(PG_FUNCTION_ARGS)
    6758 ECB             : {
    6759 GBC        2766 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6760                 :     Int8TransTypeData *transdata;
    6761 ECB             : 
    6762 CBC        2766 :     if (ARR_HASNULL(transarray) ||
    6763 GIC        2766 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6764 LBC           0 :         elog(ERROR, "expected 2-element int8 array");
    6765 CBC        2766 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6766                 : 
    6767 ECB             :     /* SQL defines SUM of no values to be NULL */
    6768 GIC        2766 :     if (transdata->count == 0)
    6769             249 :         PG_RETURN_NULL();
    6770                 : 
    6771 CBC        2517 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6772                 : }
    6773                 : 
    6774 ECB             : 
    6775                 : /* ----------------------------------------------------------------------
    6776                 :  *
    6777                 :  * Debug support
    6778                 :  *
    6779                 :  * ----------------------------------------------------------------------
    6780                 :  */
    6781                 : 
    6782                 : #ifdef NUMERIC_DEBUG
    6783                 : 
    6784                 : /*
    6785 EUB             :  * dump_numeric() - Dump a value in the db storage format for debugging
    6786                 :  */
    6787 ECB             : static void
    6788                 : dump_numeric(const char *str, Numeric num)
    6789 EUB             : {
    6790                 :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6791 ECB             :     int         ndigits;
    6792                 :     int         i;
    6793                 : 
    6794                 :     ndigits = NUMERIC_NDIGITS(num);
    6795                 : 
    6796                 :     printf("%s: NUMERIC w=%d d=%d ", str,
    6797                 :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6798                 :     switch (NUMERIC_SIGN(num))
    6799                 :     {
    6800                 :         case NUMERIC_POS:
    6801                 :             printf("POS");
    6802                 :             break;
    6803                 :         case NUMERIC_NEG:
    6804                 :             printf("NEG");
    6805                 :             break;
    6806                 :         case NUMERIC_NAN:
    6807                 :             printf("NaN");
    6808                 :             break;
    6809                 :         case NUMERIC_PINF:
    6810                 :             printf("Infinity");
    6811                 :             break;
    6812                 :         case NUMERIC_NINF:
    6813 EUB             :             printf("-Infinity");
    6814                 :             break;
    6815 ECB             :         default:
    6816                 :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    6817 EUB             :             break;
    6818                 :     }
    6819 ECB             : 
    6820                 :     for (i = 0; i < ndigits; i++)
    6821                 :         printf(" %0*d", DEC_DIGITS, digits[i]);
    6822                 :     printf("\n");
    6823                 : }
    6824                 : 
    6825                 : 
    6826                 : /*
    6827                 :  * dump_var() - Dump a value in the variable format for debugging
    6828                 :  */
    6829                 : static void
    6830                 : dump_var(const char *str, NumericVar *var)
    6831                 : {
    6832                 :     int         i;
    6833                 : 
    6834                 :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    6835                 :     switch (var->sign)
    6836 EUB             :     {
    6837 ECB             :         case NUMERIC_POS:
    6838                 :             printf("POS");
    6839                 :             break;
    6840                 :         case NUMERIC_NEG:
    6841                 :             printf("NEG");
    6842                 :             break;
    6843                 :         case NUMERIC_NAN:
    6844                 :             printf("NaN");
    6845                 :             break;
    6846                 :         case NUMERIC_PINF:
    6847                 :             printf("Infinity");
    6848                 :             break;
    6849                 :         case NUMERIC_NINF:
    6850                 :             printf("-Infinity");
    6851                 :             break;
    6852                 :         default:
    6853                 :             printf("SIGN=0x%x", var->sign);
    6854                 :             break;
    6855                 :     }
    6856                 : 
    6857                 :     for (i = 0; i < var->ndigits; i++)
    6858                 :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    6859                 : 
    6860                 :     printf("\n");
    6861 EUB             : }
    6862 ECB             : #endif                          /* NUMERIC_DEBUG */
    6863                 : 
    6864                 : 
    6865                 : /* ----------------------------------------------------------------------
    6866                 :  *
    6867                 :  * Local functions follow
    6868                 :  *
    6869                 :  * In general, these do not support "special" (NaN or infinity) inputs;
    6870                 :  * callers should handle those possibilities first.
    6871                 :  * (There are one or two exceptions, noted in their header comments.)
    6872                 :  *
    6873                 :  * ----------------------------------------------------------------------
    6874                 :  */
    6875                 : 
    6876                 : 
    6877                 : /*
    6878                 :  * alloc_var() -
    6879                 :  *
    6880                 :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    6881                 :  */
    6882                 : static void
    6883 GIC     1409144 : alloc_var(NumericVar *var, int ndigits)
    6884                 : {
    6885         1409144 :     digitbuf_free(var->buf);
    6886         1409144 :     var->buf = digitbuf_alloc(ndigits + 1);
    6887         1409144 :     var->buf[0] = 0;         /* spare digit for rounding */
    6888         1409144 :     var->digits = var->buf + 1;
    6889         1409144 :     var->ndigits = ndigits;
    6890         1409144 : }
    6891                 : 
    6892                 : 
    6893                 : /*
    6894                 :  * free_var() -
    6895                 :  *
    6896                 :  *  Return the digit buffer of a variable to the free pool
    6897                 :  */
    6898                 : static void
    6899         1610031 : free_var(NumericVar *var)
    6900                 : {
    6901         1610031 :     digitbuf_free(var->buf);
    6902         1610031 :     var->buf = NULL;
    6903         1610031 :     var->digits = NULL;
    6904         1610031 :     var->sign = NUMERIC_NAN;
    6905         1610031 : }
    6906                 : 
    6907                 : 
    6908                 : /*
    6909                 :  * zero_var() -
    6910                 :  *
    6911                 :  *  Set a variable to ZERO.
    6912                 :  *  Note: its dscale is not touched.
    6913                 :  */
    6914                 : static void
    6915           20247 : zero_var(NumericVar *var)
    6916                 : {
    6917           20247 :     digitbuf_free(var->buf);
    6918           20247 :     var->buf = NULL;
    6919           20247 :     var->digits = NULL;
    6920           20247 :     var->ndigits = 0;
    6921           20247 :     var->weight = 0;         /* by convention; doesn't really matter */
    6922           20247 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    6923           20247 : }
    6924                 : 
    6925                 : 
    6926                 : /*
    6927                 :  * set_var_from_str()
    6928                 :  *
    6929                 :  *  Parse a string and put the number into a variable
    6930                 :  *
    6931                 :  * This function does not handle leading or trailing spaces.  It returns
    6932                 :  * the end+1 position parsed into *endptr, so that caller can check for
    6933                 :  * trailing spaces/garbage if deemed necessary.
    6934                 :  *
    6935                 :  * cp is the place to actually start parsing; str is what to use in error
    6936                 :  * reports.  (Typically cp would be the same except advanced over spaces.)
    6937                 :  *
    6938                 :  * Returns true on success, false on failure (if escontext points to an
    6939                 :  * ErrorSaveContext; otherwise errors are thrown).
    6940                 :  */
    6941                 : static bool
    6942 GNC       57675 : set_var_from_str(const char *str, const char *cp,
    6943                 :                  NumericVar *dest, const char **endptr,
    6944                 :                  Node *escontext)
    6945                 : {
    6946 GIC       57675 :     bool        have_dp = false;
    6947                 :     int         i;
    6948                 :     unsigned char *decdigits;
    6949           57675 :     int         sign = NUMERIC_POS;
    6950           57675 :     int         dweight = -1;
    6951                 :     int         ddigits;
    6952           57675 :     int         dscale = 0;
    6953                 :     int         weight;
    6954                 :     int         ndigits;
    6955                 :     int         offset;
    6956                 :     NumericDigit *digits;
    6957                 : 
    6958                 :     /*
    6959                 :      * We first parse the string to extract decimal digits and determine the
    6960                 :      * correct decimal weight.  Then convert to NBASE representation.
    6961                 :      */
    6962           57675 :     switch (*cp)
    6963                 :     {
    6964 UIC           0 :         case '+':
    6965               0 :             sign = NUMERIC_POS;
    6966               0 :             cp++;
    6967               0 :             break;
    6968                 : 
    6969 GIC         150 :         case '-':
    6970             150 :             sign = NUMERIC_NEG;
    6971             150 :             cp++;
    6972             150 :             break;
    6973                 :     }
    6974                 : 
    6975           57675 :     if (*cp == '.')
    6976                 :     {
    6977             188 :         have_dp = true;
    6978             188 :         cp++;
    6979                 :     }
    6980                 : 
    6981           57675 :     if (!isdigit((unsigned char) *cp))
    6982 UNC           0 :         goto invalid_syntax;
    6983                 : 
    6984 CBC       57675 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    6985 ECB             : 
    6986                 :     /* leading padding for digit alignment later */
    6987 CBC       57675 :     memset(decdigits, 0, DEC_DIGITS);
    6988           57675 :     i = DEC_DIGITS;
    6989 ECB             : 
    6990 GIC      233925 :     while (*cp)
    6991                 :     {
    6992          176781 :         if (isdigit((unsigned char) *cp))
    6993                 :         {
    6994          168613 :             decdigits[i++] = *cp++ - '0';
    6995          168613 :             if (!have_dp)
    6996          137325 :                 dweight++;
    6997                 :             else
    6998 CBC       31288 :                 dscale++;
    6999                 :         }
    7000            8168 :         else if (*cp == '.')
    7001 ECB             :         {
    7002 CBC        7556 :             if (have_dp)
    7003 UNC           0 :                 goto invalid_syntax;
    7004 GIC        7556 :             have_dp = true;
    7005            7556 :             cp++;
    7006                 :             /* decimal point must not be followed by underscore */
    7007 GNC        7556 :             if (*cp == '_')
    7008               3 :                 goto invalid_syntax;
    7009                 :         }
    7010             612 :         else if (*cp == '_')
    7011                 :         {
    7012                 :             /* underscore must be followed by more digits */
    7013              93 :             cp++;
    7014              93 :             if (!isdigit((unsigned char) *cp))
    7015               9 :                 goto invalid_syntax;
    7016                 :         }
    7017                 :         else
    7018 GIC         519 :             break;
    7019                 :     }
    7020                 : 
    7021 CBC       57663 :     ddigits = i - DEC_DIGITS;
    7022                 :     /* trailing padding for digit alignment later */
    7023           57663 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    7024 ECB             : 
    7025                 :     /* Handle exponent, if any */
    7026 CBC       57663 :     if (*cp == 'e' || *cp == 'E')
    7027 ECB             :     {
    7028 GNC         501 :         int64       exponent = 0;
    7029             501 :         bool        neg = false;
    7030                 : 
    7031                 :         /*
    7032                 :          * At this point, dweight and dscale can't be more than about
    7033                 :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    7034                 :          * constraining the exponent similarly should be enough to prevent
    7035                 :          * integer overflow in this function.  If the value is too large to
    7036                 :          * fit in storage format, make_result() will complain about it later;
    7037                 :          * for consistency use the same ereport errcode/text as make_result().
    7038                 :          */
    7039                 : 
    7040                 :         /* exponent sign */
    7041             501 :         cp++;
    7042             501 :         if (*cp == '+')
    7043              77 :             cp++;
    7044             424 :         else if (*cp == '-')
    7045                 :         {
    7046             190 :             neg = true;
    7047             190 :             cp++;
    7048                 :         }
    7049                 : 
    7050                 :         /* exponent digits */
    7051             501 :         if (!isdigit((unsigned char) *cp))
    7052               3 :             goto invalid_syntax;
    7053                 : 
    7054            1521 :         while (*cp)
    7055                 :         {
    7056            1032 :             if (isdigit((unsigned char) *cp))
    7057                 :             {
    7058            1011 :                 exponent = exponent * 10 + (*cp++ - '0');
    7059            1011 :                 if (exponent > PG_INT32_MAX / 2)
    7060               3 :                     goto out_of_range;
    7061                 :             }
    7062              21 :             else if (*cp == '_')
    7063                 :             {
    7064                 :                 /* underscore must be followed by more digits */
    7065              21 :                 cp++;
    7066              21 :                 if (!isdigit((unsigned char) *cp))
    7067               6 :                     goto invalid_syntax;
    7068                 :             }
    7069                 :             else
    7070 UNC           0 :                 break;
    7071                 :         }
    7072                 : 
    7073 GNC         489 :         if (neg)
    7074             190 :             exponent = -exponent;
    7075                 : 
    7076 CBC         489 :         dweight += (int) exponent;
    7077 GIC         489 :         dscale -= (int) exponent;
    7078             489 :         if (dscale < 0)
    7079 CBC         197 :             dscale = 0;
    7080 ECB             :     }
    7081                 : 
    7082                 :     /*
    7083                 :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    7084                 :      * to determine the converted weight and ndigits.  offset is the number of
    7085                 :      * decimal zeroes to insert before the first given digit to have a
    7086                 :      * correctly aligned first NBASE digit.
    7087                 :      */
    7088 GIC       57651 :     if (dweight >= 0)
    7089           57324 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    7090                 :     else
    7091             327 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    7092 CBC       57651 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    7093 GIC       57651 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    7094 EUB             : 
    7095 GBC       57651 :     alloc_var(dest, ndigits);
    7096           57651 :     dest->sign = sign;
    7097           57651 :     dest->weight = weight;
    7098 GIC       57651 :     dest->dscale = dscale;
    7099 ECB             : 
    7100 CBC       57651 :     i = DEC_DIGITS - offset;
    7101           57651 :     digits = dest->digits;
    7102 ECB             : 
    7103 GIC      135687 :     while (ndigits-- > 0)
    7104                 :     {
    7105 ECB             : #if DEC_DIGITS == 4
    7106 GIC       78036 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    7107 CBC       78036 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    7108 ECB             : #elif DEC_DIGITS == 2
    7109                 :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    7110                 : #elif DEC_DIGITS == 1
    7111                 :         *digits++ = decdigits[i];
    7112 EUB             : #else
    7113                 : #error unsupported NBASE
    7114 ECB             : #endif
    7115 GIC       78036 :         i += DEC_DIGITS;
    7116                 :     }
    7117 ECB             : 
    7118 CBC       57651 :     pfree(decdigits);
    7119                 : 
    7120 ECB             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    7121 GIC       57651 :     strip_var(dest);
    7122 ECB             : 
    7123                 :     /* Return end+1 position for caller */
    7124 GNC       57651 :     *endptr = cp;
    7125                 : 
    7126           57651 :     return true;
    7127                 : 
    7128               3 : out_of_range:
    7129               3 :     ereturn(escontext, false,
    7130                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7131                 :              errmsg("value overflows numeric format")));
    7132                 : 
    7133              21 : invalid_syntax:
    7134              21 :     ereturn(escontext, false,
    7135                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7136                 :              errmsg("invalid input syntax for type %s: \"%s\"",
    7137                 :                     "numeric", str)));
    7138                 : }
    7139                 : 
    7140                 : 
    7141                 : /*
    7142                 :  * Return the numeric value of a single hex digit.
    7143                 :  */
    7144                 : static inline int
    7145             354 : xdigit_value(char dig)
    7146                 : {
    7147             447 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    7148             147 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    7149              54 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    7150                 : }
    7151                 : 
    7152                 : /*
    7153                 :  * set_var_from_non_decimal_integer_str()
    7154                 :  *
    7155                 :  *  Parse a string containing a non-decimal integer
    7156                 :  *
    7157                 :  * This function does not handle leading or trailing spaces.  It returns
    7158                 :  * the end+1 position parsed into *endptr, so that caller can check for
    7159                 :  * trailing spaces/garbage if deemed necessary.
    7160                 :  *
    7161                 :  * cp is the place to actually start parsing; str is what to use in error
    7162                 :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    7163                 :  * assumed to have already been parsed, so cp should point to the number's
    7164                 :  * first digit in the base specified.
    7165                 :  *
    7166                 :  * base is expected to be 2, 8 or 16.
    7167                 :  *
    7168                 :  * Returns true on success, false on failure (if escontext points to an
    7169                 :  * ErrorSaveContext; otherwise errors are thrown).
    7170                 :  */
    7171                 : static bool
    7172              78 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7173                 :                                      int base, NumericVar *dest,
    7174                 :                                      const char **endptr, Node *escontext)
    7175                 : {
    7176              78 :     const char *firstdigit = cp;
    7177                 :     int64       tmp;
    7178                 :     int64       mul;
    7179                 :     NumericVar  tmp_var;
    7180                 : 
    7181              78 :     init_var(&tmp_var);
    7182                 : 
    7183              78 :     zero_var(dest);
    7184                 : 
    7185                 :     /*
    7186                 :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7187                 :      * value of the digits in the group, and "mul" is base^n, where n is the
    7188                 :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7189                 :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7190                 :      */
    7191              78 :     tmp = 0;
    7192              78 :     mul = 1;
    7193                 : 
    7194              78 :     if (base == 16)
    7195                 :     {
    7196             414 :         while (*cp)
    7197                 :         {
    7198             399 :             if (isxdigit((unsigned char) *cp))
    7199                 :             {
    7200             354 :                 if (mul > PG_INT64_MAX / 16)
    7201                 :                 {
    7202                 :                     /* Add the contribution from this group of digits */
    7203              15 :                     int64_to_numericvar(mul, &tmp_var);
    7204              15 :                     mul_var(dest, &tmp_var, dest, 0);
    7205              15 :                     int64_to_numericvar(tmp, &tmp_var);
    7206              15 :                     add_var(dest, &tmp_var, dest);
    7207                 : 
    7208                 :                     /* Result will overflow if weight overflows int16 */
    7209              15 :                     if (dest->weight > SHRT_MAX)
    7210 UNC           0 :                         goto out_of_range;
    7211                 : 
    7212                 :                     /* Begin a new group */
    7213 GNC          15 :                     tmp = 0;
    7214              15 :                     mul = 1;
    7215                 :                 }
    7216                 : 
    7217             354 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7218             354 :                 mul = mul * 16;
    7219                 :             }
    7220              45 :             else if (*cp == '_')
    7221                 :             {
    7222                 :                 /* Underscore must be followed by more digits */
    7223              33 :                 cp++;
    7224              33 :                 if (!isxdigit((unsigned char) *cp))
    7225               9 :                     goto invalid_syntax;
    7226                 :             }
    7227                 :             else
    7228              12 :                 break;
    7229                 :         }
    7230                 :     }
    7231              42 :     else if (base == 8)
    7232                 :     {
    7233             318 :         while (*cp)
    7234                 :         {
    7235             303 :             if (*cp >= '0' && *cp <= '7')
    7236                 :             {
    7237             279 :                 if (mul > PG_INT64_MAX / 8)
    7238                 :                 {
    7239                 :                     /* Add the contribution from this group of digits */
    7240               9 :                     int64_to_numericvar(mul, &tmp_var);
    7241               9 :                     mul_var(dest, &tmp_var, dest, 0);
    7242               9 :                     int64_to_numericvar(tmp, &tmp_var);
    7243               9 :                     add_var(dest, &tmp_var, dest);
    7244                 : 
    7245                 :                     /* Result will overflow if weight overflows int16 */
    7246               9 :                     if (dest->weight > SHRT_MAX)
    7247 UNC           0 :                         goto out_of_range;
    7248                 : 
    7249                 :                     /* Begin a new group */
    7250 GNC           9 :                     tmp = 0;
    7251               9 :                     mul = 1;
    7252                 :                 }
    7253                 : 
    7254             279 :                 tmp = tmp * 8 + (*cp++ - '0');
    7255             279 :                 mul = mul * 8;
    7256                 :             }
    7257              24 :             else if (*cp == '_')
    7258                 :             {
    7259                 :                 /* Underscore must be followed by more digits */
    7260              18 :                 cp++;
    7261              18 :                 if (*cp < '0' || *cp > '7')
    7262 UNC           0 :                     goto invalid_syntax;
    7263                 :             }
    7264                 :             else
    7265 GNC           6 :                 break;
    7266                 :         }
    7267                 :     }
    7268              21 :     else if (base == 2)
    7269                 :     {
    7270             780 :         while (*cp)
    7271                 :         {
    7272             765 :             if (*cp >= '0' && *cp <= '1')
    7273                 :             {
    7274             708 :                 if (mul > PG_INT64_MAX / 2)
    7275                 :                 {
    7276                 :                     /* Add the contribution from this group of digits */
    7277               9 :                     int64_to_numericvar(mul, &tmp_var);
    7278               9 :                     mul_var(dest, &tmp_var, dest, 0);
    7279               9 :                     int64_to_numericvar(tmp, &tmp_var);
    7280               9 :                     add_var(dest, &tmp_var, dest);
    7281                 : 
    7282                 :                     /* Result will overflow if weight overflows int16 */
    7283               9 :                     if (dest->weight > SHRT_MAX)
    7284 UNC           0 :                         goto out_of_range;
    7285                 : 
    7286                 :                     /* Begin a new group */
    7287 GNC           9 :                     tmp = 0;
    7288               9 :                     mul = 1;
    7289                 :                 }
    7290                 : 
    7291             708 :                 tmp = tmp * 2 + (*cp++ - '0');
    7292             708 :                 mul = mul * 2;
    7293                 :             }
    7294              57 :             else if (*cp == '_')
    7295                 :             {
    7296                 :                 /* Underscore must be followed by more digits */
    7297              51 :                 cp++;
    7298              51 :                 if (*cp < '0' || *cp > '1')
    7299 UNC           0 :                     goto invalid_syntax;
    7300                 :             }
    7301                 :             else
    7302 GNC           6 :                 break;
    7303                 :         }
    7304                 :     }
    7305                 :     else
    7306                 :         /* Should never happen; treat as invalid input */
    7307 UNC           0 :         goto invalid_syntax;
    7308                 : 
    7309                 :     /* Check that we got at least one digit */
    7310 GNC          69 :     if (unlikely(cp == firstdigit))
    7311 UNC           0 :         goto invalid_syntax;
    7312                 : 
    7313                 :     /* Add the contribution from the final group of digits */
    7314 GNC          69 :     int64_to_numericvar(mul, &tmp_var);
    7315              69 :     mul_var(dest, &tmp_var, dest, 0);
    7316              69 :     int64_to_numericvar(tmp, &tmp_var);
    7317              69 :     add_var(dest, &tmp_var, dest);
    7318                 : 
    7319              69 :     if (dest->weight > SHRT_MAX)
    7320 UNC           0 :         goto out_of_range;
    7321                 : 
    7322 GNC          69 :     dest->sign = sign;
    7323                 : 
    7324              69 :     free_var(&tmp_var);
    7325                 : 
    7326                 :     /* Return end+1 position for caller */
    7327              69 :     *endptr = cp;
    7328                 : 
    7329              69 :     return true;
    7330                 : 
    7331 UNC           0 : out_of_range:
    7332               0 :     ereturn(escontext, false,
    7333                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7334                 :              errmsg("value overflows numeric format")));
    7335                 : 
    7336 GNC           9 : invalid_syntax:
    7337               9 :     ereturn(escontext, false,
    7338                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7339                 :              errmsg("invalid input syntax for type %s: \"%s\"",
    7340                 :                     "numeric", str)));
    7341 ECB             : }
    7342                 : 
    7343                 : 
    7344                 : /*
    7345                 :  * set_var_from_num() -
    7346                 :  *
    7347                 :  *  Convert the packed db format into a variable
    7348                 :  */
    7349 EUB             : static void
    7350 CBC        6184 : set_var_from_num(Numeric num, NumericVar *dest)
    7351 ECB             : {
    7352                 :     int         ndigits;
    7353                 : 
    7354 CBC        6184 :     ndigits = NUMERIC_NDIGITS(num);
    7355                 : 
    7356            6184 :     alloc_var(dest, ndigits);
    7357                 : 
    7358 GIC        6184 :     dest->weight = NUMERIC_WEIGHT(num);
    7359 CBC        6184 :     dest->sign = NUMERIC_SIGN(num);
    7360            6184 :     dest->dscale = NUMERIC_DSCALE(num);
    7361 ECB             : 
    7362 GIC        6184 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7363            6184 : }
    7364 ECB             : 
    7365                 : 
    7366                 : /*
    7367                 :  * init_var_from_num() -
    7368                 :  *
    7369                 :  *  Initialize a variable from packed db format. The digits array is not
    7370                 :  *  copied, which saves some cycles when the resulting var is not modified.
    7371                 :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7372                 :  *  other value to it (with set_var_* functions, or by using the var as the
    7373                 :  *  destination of a function like add_var())
    7374                 :  *
    7375                 :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7376                 :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7377                 :  *  propagate to the original Numeric! It's OK to use it as the destination
    7378                 :  *  argument of one of the calculational functions, though.
    7379                 :  */
    7380                 : static void
    7381 GIC     2426534 : init_var_from_num(Numeric num, NumericVar *dest)
    7382                 : {
    7383         2426534 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7384         2426534 :     dest->weight = NUMERIC_WEIGHT(num);
    7385         2426534 :     dest->sign = NUMERIC_SIGN(num);
    7386         2426534 :     dest->dscale = NUMERIC_DSCALE(num);
    7387 CBC     2426534 :     dest->digits = NUMERIC_DIGITS(num);
    7388         2426534 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7389         2426534 : }
    7390 ECB             : 
    7391                 : 
    7392                 : /*
    7393                 :  * set_var_from_var() -
    7394                 :  *
    7395                 :  *  Copy one variable into another
    7396                 :  */
    7397                 : static void
    7398 CBC       16592 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7399                 : {
    7400 ECB             :     NumericDigit *newbuf;
    7401                 : 
    7402 CBC       16592 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7403 GIC       16592 :     newbuf[0] = 0;              /* spare digit for rounding */
    7404 CBC       16592 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7405           16185 :         memcpy(newbuf + 1, value->digits,
    7406           16185 :                value->ndigits * sizeof(NumericDigit));
    7407                 : 
    7408           16592 :     digitbuf_free(dest->buf);
    7409                 : 
    7410 GIC       16592 :     memmove(dest, value, sizeof(NumericVar));
    7411 CBC       16592 :     dest->buf = newbuf;
    7412           16592 :     dest->digits = newbuf + 1;
    7413           16592 : }
    7414                 : 
    7415                 : 
    7416 EUB             : /*
    7417                 :  * get_str_from_var() -
    7418                 :  *
    7419 ECB             :  *  Convert a var to text representation (guts of numeric_out).
    7420                 :  *  The var is displayed to the number of digits indicated by its dscale.
    7421                 :  *  Returns a palloc'd string.
    7422                 :  */
    7423                 : static char *
    7424 CBC      394256 : get_str_from_var(const NumericVar *var)
    7425 ECB             : {
    7426                 :     int         dscale;
    7427                 :     char       *str;
    7428                 :     char       *cp;
    7429                 :     char       *endcp;
    7430                 :     int         i;
    7431                 :     int         d;
    7432                 :     NumericDigit dig;
    7433                 : 
    7434                 : #if DEC_DIGITS > 1
    7435                 :     NumericDigit d1;
    7436                 : #endif
    7437                 : 
    7438 CBC      394256 :     dscale = var->dscale;
    7439 ECB             : 
    7440                 :     /*
    7441                 :      * Allocate space for the result.
    7442                 :      *
    7443                 :      * i is set to the # of decimal digits before decimal point. dscale is the
    7444                 :      * # of decimal digits we will print after decimal point. We may generate
    7445                 :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7446                 :      * need room for sign, decimal point, null terminator.
    7447                 :      */
    7448 GIC      394256 :     i = (var->weight + 1) * DEC_DIGITS;
    7449 CBC      394256 :     if (i <= 0)
    7450 GIC       69223 :         i = 1;
    7451                 : 
    7452 CBC      394256 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7453          394256 :     cp = str;
    7454                 : 
    7455                 :     /*
    7456                 :      * Output a dash for negative values
    7457                 :      */
    7458 GIC      394256 :     if (var->sign == NUMERIC_NEG)
    7459            2395 :         *cp++ = '-';
    7460                 : 
    7461 ECB             :     /*
    7462                 :      * Output all digits before the decimal point
    7463                 :      */
    7464 CBC      394256 :     if (var->weight < 0)
    7465                 :     {
    7466 GIC       69223 :         d = var->weight + 1;
    7467 CBC       69223 :         *cp++ = '0';
    7468                 :     }
    7469                 :     else
    7470 ECB             :     {
    7471 GIC      697166 :         for (d = 0; d <= var->weight; d++)
    7472 ECB             :         {
    7473 GIC      372133 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7474 ECB             :             /* In the first digit, suppress extra leading decimal zeroes */
    7475                 : #if DEC_DIGITS == 4
    7476                 :             {
    7477 GIC      372133 :                 bool        putit = (d > 0);
    7478                 : 
    7479 CBC      372133 :                 d1 = dig / 1000;
    7480          372133 :                 dig -= d1 * 1000;
    7481 GIC      372133 :                 putit |= (d1 > 0);
    7482          372133 :                 if (putit)
    7483           49883 :                     *cp++ = d1 + '0';
    7484          372133 :                 d1 = dig / 100;
    7485          372133 :                 dig -= d1 * 100;
    7486          372133 :                 putit |= (d1 > 0);
    7487          372133 :                 if (putit)
    7488          252072 :                     *cp++ = d1 + '0';
    7489          372133 :                 d1 = dig / 10;
    7490          372133 :                 dig -= d1 * 10;
    7491 CBC      372133 :                 putit |= (d1 > 0);
    7492 GIC      372133 :                 if (putit)
    7493 CBC      315238 :                     *cp++ = d1 + '0';
    7494          372133 :                 *cp++ = dig + '0';
    7495 ECB             :             }
    7496                 : #elif DEC_DIGITS == 2
    7497                 :             d1 = dig / 10;
    7498                 :             dig -= d1 * 10;
    7499                 :             if (d1 > 0 || d > 0)
    7500                 :                 *cp++ = d1 + '0';
    7501                 :             *cp++ = dig + '0';
    7502                 : #elif DEC_DIGITS == 1
    7503                 :             *cp++ = dig + '0';
    7504                 : #else
    7505                 : #error unsupported NBASE
    7506                 : #endif
    7507                 :         }
    7508                 :     }
    7509                 : 
    7510                 :     /*
    7511                 :      * If requested, output a decimal point and all the digits that follow it.
    7512                 :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7513                 :      * needed.
    7514                 :      */
    7515 GIC      394256 :     if (dscale > 0)
    7516                 :     {
    7517          320706 :         *cp++ = '.';
    7518 CBC      320706 :         endcp = cp + dscale;
    7519 GIC      945684 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7520                 :         {
    7521          624978 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7522 ECB             : #if DEC_DIGITS == 4
    7523 GIC      624978 :             d1 = dig / 1000;
    7524          624978 :             dig -= d1 * 1000;
    7525          624978 :             *cp++ = d1 + '0';
    7526          624978 :             d1 = dig / 100;
    7527 CBC      624978 :             dig -= d1 * 100;
    7528 GIC      624978 :             *cp++ = d1 + '0';
    7529 CBC      624978 :             d1 = dig / 10;
    7530 GIC      624978 :             dig -= d1 * 10;
    7531          624978 :             *cp++ = d1 + '0';
    7532          624978 :             *cp++ = dig + '0';
    7533                 : #elif DEC_DIGITS == 2
    7534                 :             d1 = dig / 10;
    7535                 :             dig -= d1 * 10;
    7536                 :             *cp++ = d1 + '0';
    7537 ECB             :             *cp++ = dig + '0';
    7538                 : #elif DEC_DIGITS == 1
    7539                 :             *cp++ = dig + '0';
    7540                 : #else
    7541                 : #error unsupported NBASE
    7542                 : #endif
    7543                 :         }
    7544 CBC      320706 :         cp = endcp;
    7545                 :     }
    7546 ECB             : 
    7547                 :     /*
    7548                 :      * terminate the string and return it
    7549                 :      */
    7550 CBC      394256 :     *cp = '\0';
    7551          394256 :     return str;
    7552 ECB             : }
    7553                 : 
    7554                 : /*
    7555                 :  * get_str_from_var_sci() -
    7556 EUB             :  *
    7557                 :  *  Convert a var to a normalised scientific notation text representation.
    7558                 :  *  This function does the heavy lifting for numeric_out_sci().
    7559 ECB             :  *
    7560                 :  *  This notation has the general form a * 10^b, where a is known as the
    7561                 :  *  "significand" and b is known as the "exponent".
    7562                 :  *
    7563                 :  *  Because we can't do superscript in ASCII (and because we want to copy
    7564                 :  *  printf's behaviour) we display the exponent using E notation, with a
    7565                 :  *  minimum of two exponent digits.
    7566                 :  *
    7567                 :  *  For example, the value 1234 could be output as 1.2e+03.
    7568                 :  *
    7569                 :  *  We assume that the exponent can fit into an int32.
    7570                 :  *
    7571                 :  *  rscale is the number of decimal digits desired after the decimal point in
    7572                 :  *  the output, negative values will be treated as meaning zero.
    7573                 :  *
    7574                 :  *  Returns a palloc'd string.
    7575                 :  */
    7576                 : static char *
    7577 CBC         108 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7578                 : {
    7579 ECB             :     int32       exponent;
    7580                 :     NumericVar  tmp_var;
    7581                 :     size_t      len;
    7582                 :     char       *str;
    7583                 :     char       *sig_out;
    7584                 : 
    7585 GIC         108 :     if (rscale < 0)
    7586 LBC           0 :         rscale = 0;
    7587 ECB             : 
    7588                 :     /*
    7589                 :      * Determine the exponent of this number in normalised form.
    7590                 :      *
    7591                 :      * This is the exponent required to represent the number with only one
    7592                 :      * significant digit before the decimal place.
    7593 EUB             :      */
    7594 GIC         108 :     if (var->ndigits > 0)
    7595                 :     {
    7596 CBC          99 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7597 ECB             : 
    7598                 :         /*
    7599                 :          * Compensate for leading decimal zeroes in the first numeric digit by
    7600                 :          * decrementing the exponent.
    7601                 :          */
    7602 GIC          99 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7603 ECB             :     }
    7604                 :     else
    7605                 :     {
    7606                 :         /*
    7607                 :          * If var has no digits, then it must be zero.
    7608 EUB             :          *
    7609                 :          * Zero doesn't technically have a meaningful exponent in normalised
    7610                 :          * notation, but we just display the exponent as zero for consistency
    7611 ECB             :          * of output.
    7612                 :          */
    7613 GIC           9 :         exponent = 0;
    7614 ECB             :     }
    7615                 : 
    7616                 :     /*
    7617                 :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7618                 :      * decimal digits in the process.
    7619                 :      */
    7620 CBC         108 :     init_var(&tmp_var);
    7621                 : 
    7622 GIC         108 :     power_ten_int(exponent, &tmp_var);
    7623 CBC         108 :     div_var(var, &tmp_var, &tmp_var, rscale, true);
    7624             108 :     sig_out = get_str_from_var(&tmp_var);
    7625 ECB             : 
    7626 CBC         108 :     free_var(&tmp_var);
    7627                 : 
    7628                 :     /*
    7629 ECB             :      * Allocate space for the result.
    7630 EUB             :      *
    7631                 :      * In addition to the significand, we need room for the exponent
    7632                 :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7633 ECB             :      * exponent itself, and of course the null terminator.
    7634                 :      */
    7635 GIC         108 :     len = strlen(sig_out) + 13;
    7636             108 :     str = palloc(len);
    7637 CBC         108 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7638 ECB             : 
    7639 GIC         108 :     pfree(sig_out);
    7640 ECB             : 
    7641 GIC         108 :     return str;
    7642                 : }
    7643 ECB             : 
    7644                 : 
    7645 EUB             : /*
    7646                 :  * numericvar_serialize - serialize NumericVar to binary format
    7647                 :  *
    7648 ECB             :  * At variable level, no checks are performed on the weight or dscale, allowing
    7649                 :  * us to pass around intermediate values with higher precision than supported
    7650                 :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7651                 :  * which use 16-bit integers for these fields.
    7652                 :  */
    7653 EUB             : static void
    7654 GIC          72 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7655                 : {
    7656 ECB             :     int         i;
    7657 EUB             : 
    7658 GIC          72 :     pq_sendint32(buf, var->ndigits);
    7659              72 :     pq_sendint32(buf, var->weight);
    7660 CBC          72 :     pq_sendint32(buf, var->sign);
    7661              72 :     pq_sendint32(buf, var->dscale);
    7662          318965 :     for (i = 0; i < var->ndigits; i++)
    7663          318893 :         pq_sendint16(buf, var->digits[i]);
    7664 GIC          72 : }
    7665 ECB             : 
    7666 EUB             : /*
    7667                 :  * numericvar_deserialize - deserialize binary format to NumericVar
    7668 ECB             :  */
    7669                 : static void
    7670 CBC          72 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7671                 : {
    7672                 :     int         len,
    7673 ECB             :                 i;
    7674                 : 
    7675 CBC          72 :     len = pq_getmsgint(buf, sizeof(int32));
    7676                 : 
    7677 GBC          72 :     alloc_var(var, len);        /* sets var->ndigits */
    7678 EUB             : 
    7679 GIC          72 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7680              72 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7681              72 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7682 CBC      318965 :     for (i = 0; i < len; i++)
    7683          318893 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7684 GIC          72 : }
    7685                 : 
    7686                 : 
    7687                 : /*
    7688                 :  * duplicate_numeric() - copy a packed-format Numeric
    7689                 :  *
    7690                 :  * This will handle NaN and Infinity cases.
    7691                 :  */
    7692                 : static Numeric
    7693            5102 : duplicate_numeric(Numeric num)
    7694                 : {
    7695                 :     Numeric     res;
    7696 ECB             : 
    7697 GIC        5102 :     res = (Numeric) palloc(VARSIZE(num));
    7698            5102 :     memcpy(res, num, VARSIZE(num));
    7699            5102 :     return res;
    7700 ECB             : }
    7701                 : 
    7702                 : /*
    7703                 :  * make_result_opt_error() -
    7704                 :  *
    7705                 :  *  Create the packed db numeric format in palloc()'d memory from
    7706                 :  *  a variable.  This will handle NaN and Infinity cases.
    7707                 :  *
    7708                 :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
    7709                 :  *  NULL is returned.  This is helpful when caller needs to handle errors.
    7710                 :  */
    7711                 : static Numeric
    7712 GIC     1559439 : make_result_opt_error(const NumericVar *var, bool *have_error)
    7713                 : {
    7714                 :     Numeric     result;
    7715         1559439 :     NumericDigit *digits = var->digits;
    7716         1559439 :     int         weight = var->weight;
    7717         1559439 :     int         sign = var->sign;
    7718                 :     int         n;
    7719                 :     Size        len;
    7720                 : 
    7721         1559439 :     if (have_error)
    7722           46557 :         *have_error = false;
    7723                 : 
    7724         1559439 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7725                 :     {
    7726                 :         /*
    7727 ECB             :          * Verify valid special value.  This could be just an Assert, perhaps,
    7728                 :          * but it seems worthwhile to expend a few cycles to ensure that we
    7729                 :          * never write any nonzero reserved bits to disk.
    7730                 :          */
    7731 CBC        2595 :         if (!(sign == NUMERIC_NAN ||
    7732 ECB             :               sign == NUMERIC_PINF ||
    7733                 :               sign == NUMERIC_NINF))
    7734 LBC           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7735 ECB             : 
    7736 GIC        2595 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7737                 : 
    7738            2595 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7739            2595 :         result->choice.n_header = sign;
    7740                 :         /* the header word is all we need */
    7741                 : 
    7742                 :         dump_numeric("make_result()", result);
    7743            2595 :         return result;
    7744 ECB             :     }
    7745                 : 
    7746 GIC     1556844 :     n = var->ndigits;
    7747                 : 
    7748 ECB             :     /* truncate leading zeroes */
    7749 CBC     1556856 :     while (n > 0 && *digits == 0)
    7750 ECB             :     {
    7751 CBC          12 :         digits++;
    7752              12 :         weight--;
    7753 GIC          12 :         n--;
    7754 ECB             :     }
    7755                 :     /* truncate trailing zeroes */
    7756 CBC     1599425 :     while (n > 0 && digits[n - 1] == 0)
    7757           42581 :         n--;
    7758 ECB             : 
    7759                 :     /* If zero result, force to weight=0 and positive sign */
    7760 GIC     1556844 :     if (n == 0)
    7761                 :     {
    7762           46384 :         weight = 0;
    7763           46384 :         sign = NUMERIC_POS;
    7764                 :     }
    7765                 : 
    7766                 :     /* Build the result */
    7767         1556844 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7768                 :     {
    7769         1555977 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7770 CBC     1555977 :         result = (Numeric) palloc(len);
    7771 GIC     1555977 :         SET_VARSIZE(result, len);
    7772         1555977 :         result->choice.n_short.n_header =
    7773                 :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7774                 :              : NUMERIC_SHORT)
    7775         1555977 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7776         1555977 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7777         1555977 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7778                 :     }
    7779                 :     else
    7780                 :     {
    7781             867 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7782             867 :         result = (Numeric) palloc(len);
    7783             867 :         SET_VARSIZE(result, len);
    7784 CBC         867 :         result->choice.n_long.n_sign_dscale =
    7785 GIC         867 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7786             867 :         result->choice.n_long.n_weight = weight;
    7787                 :     }
    7788                 : 
    7789         1556844 :     Assert(NUMERIC_NDIGITS(result) == n);
    7790         1556844 :     if (n > 0)
    7791         1510460 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7792                 : 
    7793                 :     /* Check for overflow of int16 fields */
    7794 CBC     1556844 :     if (NUMERIC_WEIGHT(result) != weight ||
    7795         1556832 :         NUMERIC_DSCALE(result) != var->dscale)
    7796 ECB             :     {
    7797 GIC          12 :         if (have_error)
    7798 ECB             :         {
    7799 CBC           9 :             *have_error = true;
    7800 GIC           9 :             return NULL;
    7801                 :         }
    7802                 :         else
    7803                 :         {
    7804 CBC           3 :             ereport(ERROR,
    7805 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7806                 :                      errmsg("value overflows numeric format")));
    7807                 :         }
    7808                 :     }
    7809                 : 
    7810                 :     dump_numeric("make_result()", result);
    7811 GIC     1556832 :     return result;
    7812 ECB             : }
    7813                 : 
    7814                 : 
    7815                 : /*
    7816                 :  * make_result() -
    7817                 :  *
    7818                 :  *  An interface to make_result_opt_error() without "have_error" argument.
    7819                 :  */
    7820                 : static Numeric
    7821 GIC     1029101 : make_result(const NumericVar *var)
    7822                 : {
    7823 CBC     1029101 :     return make_result_opt_error(var, NULL);
    7824                 : }
    7825 ECB             : 
    7826                 : 
    7827                 : /*
    7828                 :  * apply_typmod() -
    7829                 :  *
    7830                 :  *  Do bounds checking and rounding according to the specified typmod.
    7831                 :  *  Note that this is only applied to normal finite values.
    7832                 :  *
    7833                 :  * Returns true on success, false on failure (if escontext points to an
    7834                 :  * ErrorSaveContext; otherwise errors are thrown).
    7835                 :  */
    7836                 : static bool
    7837 GNC       48764 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    7838 ECB             : {
    7839                 :     int         precision;
    7840                 :     int         scale;
    7841                 :     int         maxdigits;
    7842                 :     int         ddigits;
    7843                 :     int         i;
    7844                 : 
    7845                 :     /* Do nothing if we have an invalid typmod */
    7846 GIC       48764 :     if (!is_valid_numeric_typmod(typmod))
    7847 GNC       46461 :         return true;
    7848                 : 
    7849 GIC        2303 :     precision = numeric_typmod_precision(typmod);
    7850            2303 :     scale = numeric_typmod_scale(typmod);
    7851            2303 :     maxdigits = precision - scale;
    7852                 : 
    7853                 :     /* Round to target scale (and set var->dscale) */
    7854            2303 :     round_var(var, scale);
    7855                 : 
    7856                 :     /* but don't allow var->dscale to be negative */
    7857            2303 :     if (var->dscale < 0)
    7858              54 :         var->dscale = 0;
    7859                 : 
    7860                 :     /*
    7861                 :      * Check for overflow - note we can't do this before rounding, because
    7862                 :      * rounding could raise the weight.  Also note that the var's weight could
    7863                 :      * be inflated by leading zeroes, which will be stripped before storage
    7864 ECB             :      * but perhaps might not have been yet. In any case, we must recognize a
    7865                 :      * true zero, whose weight doesn't mean anything.
    7866                 :      */
    7867 CBC        2303 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    7868            2303 :     if (ddigits > maxdigits)
    7869                 :     {
    7870 ECB             :         /* Determine true weight; and check for all-zero result */
    7871 GIC         175 :         for (i = 0; i < var->ndigits; i++)
    7872 ECB             :         {
    7873 CBC         168 :             NumericDigit dig = var->digits[i];
    7874 ECB             : 
    7875 CBC         168 :             if (dig)
    7876 ECB             :             {
    7877                 :                 /* Adjust for any high-order decimal zero digits */
    7878                 : #if DEC_DIGITS == 4
    7879 CBC         168 :                 if (dig < 10)
    7880             108 :                     ddigits -= 3;
    7881              60 :                 else if (dig < 100)
    7882 GIC          30 :                     ddigits -= 2;
    7883              30 :                 else if (dig < 1000)
    7884              21 :                     ddigits -= 1;
    7885                 : #elif DEC_DIGITS == 2
    7886                 :                 if (dig < 10)
    7887                 :                     ddigits -= 1;
    7888                 : #elif DEC_DIGITS == 1
    7889                 :                 /* no adjustment */
    7890                 : #else
    7891                 : #error unsupported NBASE
    7892                 : #endif
    7893 CBC         168 :                 if (ddigits > maxdigits)
    7894 GNC          36 :                     ereturn(escontext, false,
    7895                 :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7896                 :                              errmsg("numeric field overflow"),
    7897                 :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    7898                 :                                        precision, scale,
    7899 ECB             :                     /* Display 10^0 as 1 */
    7900                 :                                        maxdigits ? "10^" : "",
    7901                 :                                        maxdigits ? maxdigits : 1
    7902                 :                                        )));
    7903 GIC         132 :                 break;
    7904                 :             }
    7905 UIC           0 :             ddigits -= DEC_DIGITS;
    7906                 :         }
    7907                 :     }
    7908                 : 
    7909 GNC        2267 :     return true;
    7910                 : }
    7911                 : 
    7912                 : /*
    7913                 :  * apply_typmod_special() -
    7914                 :  *
    7915                 :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    7916                 :  *  For convenience of most callers, the value is presented in packed form.
    7917                 :  *
    7918                 :  * Returns true on success, false on failure (if escontext points to an
    7919                 :  * ErrorSaveContext; otherwise errors are thrown).
    7920                 :  */
    7921                 : static bool
    7922             796 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    7923                 : {
    7924                 :     int         precision;
    7925                 :     int         scale;
    7926                 : 
    7927 GIC         796 :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    7928                 : 
    7929                 :     /*
    7930                 :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    7931 ECB             :      * but it's a longstanding behavior.  Inf is rejected if we have any
    7932                 :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    7933                 :      * any finite number of digits.
    7934                 :      */
    7935 GIC         796 :     if (NUMERIC_IS_NAN(num))
    7936 GNC         367 :         return true;
    7937                 : 
    7938                 :     /* Do nothing if we have a default typmod (-1) */
    7939 CBC         429 :     if (!is_valid_numeric_typmod(typmod))
    7940 GNC         420 :         return true;
    7941                 : 
    7942 GIC           9 :     precision = numeric_typmod_precision(typmod);
    7943               9 :     scale = numeric_typmod_scale(typmod);
    7944                 : 
    7945 GNC           9 :     ereturn(escontext, false,
    7946                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7947                 :              errmsg("numeric field overflow"),
    7948 ECB             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    7949                 :                        precision, scale)));
    7950                 : }
    7951                 : 
    7952                 : 
    7953                 : /*
    7954                 :  * Convert numeric to int8, rounding if needed.
    7955                 :  *
    7956                 :  * If overflow, return false (no error is raised).  Return true if okay.
    7957                 :  */
    7958                 : static bool
    7959 GIC        3932 : numericvar_to_int64(const NumericVar *var, int64 *result)
    7960                 : {
    7961                 :     NumericDigit *digits;
    7962                 :     int         ndigits;
    7963                 :     int         weight;
    7964                 :     int         i;
    7965                 :     int64       val;
    7966                 :     bool        neg;
    7967 ECB             :     NumericVar  rounded;
    7968                 : 
    7969                 :     /* Round to nearest integer */
    7970 GIC        3932 :     init_var(&rounded);
    7971            3932 :     set_var_from_var(var, &rounded);
    7972            3932 :     round_var(&rounded, 0);
    7973                 : 
    7974 ECB             :     /* Check for zero input */
    7975 GIC        3932 :     strip_var(&rounded);
    7976 CBC        3932 :     ndigits = rounded.ndigits;
    7977            3932 :     if (ndigits == 0)
    7978 ECB             :     {
    7979 GIC         176 :         *result = 0;
    7980 CBC         176 :         free_var(&rounded);
    7981 GIC         176 :         return true;
    7982                 :     }
    7983                 : 
    7984                 :     /*
    7985                 :      * For input like 10000000000, we must treat stripped digits as real. So
    7986                 :      * the loop assumes there are weight+1 digits before the decimal point.
    7987                 :      */
    7988            3756 :     weight = rounded.weight;
    7989 CBC        3756 :     Assert(weight >= 0 && ndigits <= weight + 1);
    7990 ECB             : 
    7991                 :     /*
    7992                 :      * Construct the result. To avoid issues with converting a value
    7993                 :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    7994                 :      * bit two's complement integer), accumulate value as a negative number.
    7995                 :      */
    7996 GIC        3756 :     digits = rounded.digits;
    7997            3756 :     neg = (rounded.sign == NUMERIC_NEG);
    7998            3756 :     val = -digits[0];
    7999            5336 :     for (i = 1; i <= weight; i++)
    8000                 :     {
    8001            1595 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    8002                 :         {
    8003               6 :             free_var(&rounded);
    8004               6 :             return false;
    8005                 :         }
    8006                 : 
    8007            1589 :         if (i < ndigits)
    8008 ECB             :         {
    8009 GIC        1484 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    8010                 :             {
    8011               9 :                 free_var(&rounded);
    8012 CBC           9 :                 return false;
    8013 ECB             :             }
    8014                 :         }
    8015                 :     }
    8016                 : 
    8017 CBC        3741 :     free_var(&rounded);
    8018 ECB             : 
    8019 GIC        3741 :     if (!neg)
    8020                 :     {
    8021            3438 :         if (unlikely(val == PG_INT64_MIN))
    8022              12 :             return false;
    8023            3426 :         val = -val;
    8024 ECB             :     }
    8025 GIC        3729 :     *result = val;
    8026                 : 
    8027            3729 :     return true;
    8028                 : }
    8029 ECB             : 
    8030                 : /*
    8031                 :  * Convert int8 value to numeric.
    8032                 :  */
    8033                 : static void
    8034 CBC      922207 : int64_to_numericvar(int64 val, NumericVar *var)
    8035 ECB             : {
    8036                 :     uint64      uval,
    8037                 :                 newuval;
    8038                 :     NumericDigit *ptr;
    8039                 :     int         ndigits;
    8040                 : 
    8041                 :     /* int64 can require at most 19 decimal digits; add one for safety */
    8042 GIC      922207 :     alloc_var(var, 20 / DEC_DIGITS);
    8043          922207 :     if (val < 0)
    8044                 :     {
    8045             733 :         var->sign = NUMERIC_NEG;
    8046             733 :         uval = -val;
    8047 ECB             :     }
    8048                 :     else
    8049                 :     {
    8050 GIC      921474 :         var->sign = NUMERIC_POS;
    8051 CBC      921474 :         uval = val;
    8052 ECB             :     }
    8053 CBC      922207 :     var->dscale = 0;
    8054 GIC      922207 :     if (val == 0)
    8055                 :     {
    8056           17041 :         var->ndigits = 0;
    8057           17041 :         var->weight = 0;
    8058           17041 :         return;
    8059                 :     }
    8060          905166 :     ptr = var->digits + var->ndigits;
    8061          905166 :     ndigits = 0;
    8062                 :     do
    8063                 :     {
    8064         1057117 :         ptr--;
    8065         1057117 :         ndigits++;
    8066 CBC     1057117 :         newuval = uval / NBASE;
    8067 GIC     1057117 :         *ptr = uval - newuval * NBASE;
    8068         1057117 :         uval = newuval;
    8069 CBC     1057117 :     } while (uval);
    8070          905166 :     var->digits = ptr;
    8071          905166 :     var->ndigits = ndigits;
    8072 GIC      905166 :     var->weight = ndigits - 1;
    8073                 : }
    8074                 : 
    8075 ECB             : /*
    8076                 :  * Convert numeric to uint64, rounding if needed.
    8077                 :  *
    8078                 :  * If overflow, return false (no error is raised).  Return true if okay.
    8079                 :  */
    8080                 : static bool
    8081 GIC          42 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    8082                 : {
    8083                 :     NumericDigit *digits;
    8084                 :     int         ndigits;
    8085 ECB             :     int         weight;
    8086                 :     int         i;
    8087                 :     uint64      val;
    8088 EUB             :     NumericVar  rounded;
    8089                 : 
    8090 ECB             :     /* Round to nearest integer */
    8091 GIC          42 :     init_var(&rounded);
    8092 CBC          42 :     set_var_from_var(var, &rounded);
    8093              42 :     round_var(&rounded, 0);
    8094                 : 
    8095                 :     /* Check for zero input */
    8096 GIC          42 :     strip_var(&rounded);
    8097 CBC          42 :     ndigits = rounded.ndigits;
    8098 GIC          42 :     if (ndigits == 0)
    8099                 :     {
    8100 CBC           9 :         *result = 0;
    8101 GIC           9 :         free_var(&rounded);
    8102               9 :         return true;
    8103 ECB             :     }
    8104                 : 
    8105                 :     /* Check for negative input */
    8106 CBC          33 :     if (rounded.sign == NUMERIC_NEG)
    8107 ECB             :     {
    8108 GIC           6 :         free_var(&rounded);
    8109               6 :         return false;
    8110 ECB             :     }
    8111                 : 
    8112                 :     /*
    8113                 :      * For input like 10000000000, we must treat stripped digits as real. So
    8114                 :      * the loop assumes there are weight+1 digits before the decimal point.
    8115                 :      */
    8116 CBC          27 :     weight = rounded.weight;
    8117              27 :     Assert(weight >= 0 && ndigits <= weight + 1);
    8118                 : 
    8119                 :     /* Construct the result */
    8120 GIC          27 :     digits = rounded.digits;
    8121 CBC          27 :     val = digits[0];
    8122 GIC          93 :     for (i = 1; i <= weight; i++)
    8123 ECB             :     {
    8124 CBC          72 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    8125 ECB             :         {
    8126 LBC           0 :             free_var(&rounded);
    8127 UIC           0 :             return false;
    8128                 :         }
    8129 ECB             : 
    8130 CBC          72 :         if (i < ndigits)
    8131 ECB             :         {
    8132 GIC          72 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    8133                 :             {
    8134               6 :                 free_var(&rounded);
    8135 CBC           6 :                 return false;
    8136 ECB             :             }
    8137                 :         }
    8138                 :     }
    8139                 : 
    8140 CBC          21 :     free_var(&rounded);
    8141                 : 
    8142 GIC          21 :     *result = val;
    8143 ECB             : 
    8144 CBC          21 :     return true;
    8145 ECB             : }
    8146                 : 
    8147                 : #ifdef HAVE_INT128
    8148                 : /*
    8149                 :  * Convert numeric to int128, rounding if needed.
    8150                 :  *
    8151                 :  * If overflow, return false (no error is raised).  Return true if okay.
    8152                 :  */
    8153                 : static bool
    8154 CBC          27 : numericvar_to_int128(const NumericVar *var, int128 *result)
    8155                 : {
    8156                 :     NumericDigit *digits;
    8157                 :     int         ndigits;
    8158 ECB             :     int         weight;
    8159                 :     int         i;
    8160                 :     int128      val,
    8161                 :                 oldval;
    8162                 :     bool        neg;
    8163                 :     NumericVar  rounded;
    8164                 : 
    8165                 :     /* Round to nearest integer */
    8166 GIC          27 :     init_var(&rounded);
    8167              27 :     set_var_from_var(var, &rounded);
    8168              27 :     round_var(&rounded, 0);
    8169                 : 
    8170                 :     /* Check for zero input */
    8171              27 :     strip_var(&rounded);
    8172              27 :     ndigits = rounded.ndigits;
    8173              27 :     if (ndigits == 0)
    8174                 :     {
    8175 LBC           0 :         *result = 0;
    8176 UIC           0 :         free_var(&rounded);
    8177 LBC           0 :         return true;
    8178                 :     }
    8179                 : 
    8180                 :     /*
    8181                 :      * For input like 10000000000, we must treat stripped digits as real. So
    8182                 :      * the loop assumes there are weight+1 digits before the decimal point.
    8183                 :      */
    8184 GIC          27 :     weight = rounded.weight;
    8185              27 :     Assert(weight >= 0 && ndigits <= weight + 1);
    8186                 : 
    8187                 :     /* Construct the result */
    8188              27 :     digits = rounded.digits;
    8189              27 :     neg = (rounded.sign == NUMERIC_NEG);
    8190              27 :     val = digits[0];
    8191 CBC          65 :     for (i = 1; i <= weight; i++)
    8192                 :     {
    8193 GIC          38 :         oldval = val;
    8194              38 :         val *= NBASE;
    8195              38 :         if (i < ndigits)
    8196              35 :             val += digits[i];
    8197                 : 
    8198                 :         /*
    8199                 :          * The overflow check is a bit tricky because we want to accept
    8200 ECB             :          * INT128_MIN, which will overflow the positive accumulator.  We can
    8201                 :          * detect this case easily though because INT128_MIN is the only
    8202                 :          * nonzero value for which -val == val (on a two's complement machine,
    8203                 :          * anyway).
    8204                 :          */
    8205 CBC          38 :         if ((val / NBASE) != oldval)    /* possible overflow? */
    8206                 :         {
    8207 UIC           0 :             if (!neg || (-val) != val || val == 0 || oldval < 0)
    8208 ECB             :             {
    8209 UIC           0 :                 free_var(&rounded);
    8210               0 :                 return false;
    8211 ECB             :             }
    8212                 :         }
    8213                 :     }
    8214                 : 
    8215 GIC          27 :     free_var(&rounded);
    8216                 : 
    8217              27 :     *result = neg ? -val : val;
    8218              27 :     return true;
    8219                 : }
    8220                 : 
    8221 ECB             : /*
    8222                 :  * Convert 128 bit integer to numeric.
    8223                 :  */
    8224                 : static void
    8225 CBC        4270 : int128_to_numericvar(int128 val, NumericVar *var)
    8226                 : {
    8227 ECB             :     uint128     uval,
    8228                 :                 newuval;
    8229                 :     NumericDigit *ptr;
    8230                 :     int         ndigits;
    8231                 : 
    8232                 :     /* int128 can require at most 39 decimal digits; add one for safety */
    8233 CBC        4270 :     alloc_var(var, 40 / DEC_DIGITS);
    8234            4270 :     if (val < 0)
    8235 ECB             :     {
    8236 LBC           0 :         var->sign = NUMERIC_NEG;
    8237               0 :         uval = -val;
    8238 ECB             :     }
    8239                 :     else
    8240                 :     {
    8241 GIC        4270 :         var->sign = NUMERIC_POS;
    8242            4270 :         uval = val;
    8243                 :     }
    8244            4270 :     var->dscale = 0;
    8245            4270 :     if (val == 0)
    8246                 :     {
    8247 CBC          55 :         var->ndigits = 0;
    8248              55 :         var->weight = 0;
    8249 GIC          55 :         return;
    8250                 :     }
    8251            4215 :     ptr = var->digits + var->ndigits;
    8252            4215 :     ndigits = 0;
    8253                 :     do
    8254                 :     {
    8255           22460 :         ptr--;
    8256           22460 :         ndigits++;
    8257 CBC       22460 :         newuval = uval / NBASE;
    8258 GIC       22460 :         *ptr = uval - newuval * NBASE;
    8259 GBC       22460 :         uval = newuval;
    8260 GIC       22460 :     } while (uval);
    8261            4215 :     var->digits = ptr;
    8262            4215 :     var->ndigits = ndigits;
    8263 CBC        4215 :     var->weight = ndigits - 1;
    8264                 : }
    8265                 : #endif
    8266                 : 
    8267                 : /*
    8268                 :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    8269                 :  */
    8270                 : static double
    8271 GIC        1616 : numericvar_to_double_no_overflow(const NumericVar *var)
    8272                 : {
    8273                 :     char       *tmp;
    8274                 :     double      val;
    8275                 :     char       *endptr;
    8276 ECB             : 
    8277 GIC        1616 :     tmp = get_str_from_var(var);
    8278                 : 
    8279                 :     /* unlike float8in, we ignore ERANGE from strtod */
    8280            1616 :     val = strtod(tmp, &endptr);
    8281 CBC        1616 :     if (*endptr != '\0')
    8282                 :     {
    8283                 :         /* shouldn't happen ... */
    8284 UIC           0 :         ereport(ERROR,
    8285                 :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8286                 :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8287                 :                         "double precision", tmp)));
    8288                 :     }
    8289 ECB             : 
    8290 CBC        1616 :     pfree(tmp);
    8291                 : 
    8292 GIC        1616 :     return val;
    8293 ECB             : }
    8294                 : 
    8295                 : 
    8296                 : /*
    8297                 :  * cmp_var() -
    8298                 :  *
    8299                 :  *  Compare two values on variable level.  We assume zeroes have been
    8300                 :  *  truncated to no digits.
    8301                 :  */
    8302                 : static int
    8303 GIC        8383 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8304                 : {
    8305           16766 :     return cmp_var_common(var1->digits, var1->ndigits,
    8306            8383 :                           var1->weight, var1->sign,
    8307            8383 :                           var2->digits, var2->ndigits,
    8308            8383 :                           var2->weight, var2->sign);
    8309                 : }
    8310                 : 
    8311                 : /*
    8312                 :  * cmp_var_common() -
    8313 ECB             :  *
    8314                 :  *  Main routine of cmp_var(). This function can be used by both
    8315                 :  *  NumericVar and Numeric.
    8316                 :  */
    8317                 : static int
    8318 GIC     3222052 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8319                 :                int var1weight, int var1sign,
    8320                 :                const NumericDigit *var2digits, int var2ndigits,
    8321                 :                int var2weight, int var2sign)
    8322                 : {
    8323         3222052 :     if (var1ndigits == 0)
    8324 ECB             :     {
    8325 CBC       97023 :         if (var2ndigits == 0)
    8326           82991 :             return 0;
    8327 GIC       14032 :         if (var2sign == NUMERIC_NEG)
    8328            2131 :             return 1;
    8329 CBC       11901 :         return -1;
    8330 ECB             :     }
    8331 CBC     3125029 :     if (var2ndigits == 0)
    8332                 :     {
    8333           15929 :         if (var1sign == NUMERIC_POS)
    8334           12455 :             return 1;
    8335            3474 :         return -1;
    8336                 :     }
    8337                 : 
    8338 GIC     3109100 :     if (var1sign == NUMERIC_POS)
    8339                 :     {
    8340         3082035 :         if (var2sign == NUMERIC_NEG)
    8341            5575 :             return 1;
    8342 CBC     3076460 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8343 ECB             :                               var2digits, var2ndigits, var2weight);
    8344                 :     }
    8345                 : 
    8346 GIC       27065 :     if (var2sign == NUMERIC_POS)
    8347            6281 :         return -1;
    8348                 : 
    8349           20784 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8350 ECB             :                           var1digits, var1ndigits, var1weight);
    8351                 : }
    8352                 : 
    8353                 : 
    8354                 : /*
    8355                 :  * add_var() -
    8356                 :  *
    8357                 :  *  Full version of add functionality on variable level (handling signs).
    8358                 :  *  result might point to one of the operands too without danger.
    8359                 :  */
    8360                 : static void
    8361 CBC      231922 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8362                 : {
    8363 ECB             :     /*
    8364                 :      * Decide on the signs of the two variables what to do
    8365                 :      */
    8366 CBC      231922 :     if (var1->sign == NUMERIC_POS)
    8367                 :     {
    8368 GIC      231139 :         if (var2->sign == NUMERIC_POS)
    8369                 :         {
    8370                 :             /*
    8371 ECB             :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8372                 :              */
    8373 CBC      144592 :             add_abs(var1, var2, result);
    8374 GIC      144592 :             result->sign = NUMERIC_POS;
    8375 ECB             :         }
    8376                 :         else
    8377                 :         {
    8378                 :             /*
    8379                 :              * var1 is positive, var2 is negative Must compare absolute values
    8380                 :              */
    8381 CBC       86547 :             switch (cmp_abs(var1, var2))
    8382                 :             {
    8383 GIC          16 :                 case 0:
    8384                 :                     /* ----------
    8385                 :                      * ABS(var1) == ABS(var2)
    8386                 :                      * result = ZERO
    8387                 :                      * ----------
    8388 ECB             :                      */
    8389 GIC          16 :                     zero_var(result);
    8390              16 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8391              16 :                     break;
    8392                 : 
    8393           86387 :                 case 1:
    8394                 :                     /* ----------
    8395                 :                      * ABS(var1) > ABS(var2)
    8396 ECB             :                      * result = +(ABS(var1) - ABS(var2))
    8397                 :                      * ----------
    8398                 :                      */
    8399 CBC       86387 :                     sub_abs(var1, var2, result);
    8400           86387 :                     result->sign = NUMERIC_POS;
    8401 GIC       86387 :                     break;
    8402                 : 
    8403             144 :                 case -1:
    8404 ECB             :                     /* ----------
    8405                 :                      * ABS(var1) < ABS(var2)
    8406                 :                      * result = -(ABS(var2) - ABS(var1))
    8407                 :                      * ----------
    8408                 :                      */
    8409 GIC         144 :                     sub_abs(var2, var1, result);
    8410 CBC         144 :                     result->sign = NUMERIC_NEG;
    8411             144 :                     break;
    8412 ECB             :             }
    8413                 :         }
    8414                 :     }
    8415                 :     else
    8416                 :     {
    8417 GIC         783 :         if (var2->sign == NUMERIC_POS)
    8418 ECB             :         {
    8419                 :             /* ----------
    8420                 :              * var1 is negative, var2 is positive
    8421                 :              * Must compare absolute values
    8422                 :              * ----------
    8423                 :              */
    8424 CBC         234 :             switch (cmp_abs(var1, var2))
    8425 ECB             :             {
    8426 CBC          15 :                 case 0:
    8427                 :                     /* ----------
    8428                 :                      * ABS(var1) == ABS(var2)
    8429                 :                      * result = ZERO
    8430                 :                      * ----------
    8431                 :                      */
    8432 GIC          15 :                     zero_var(result);
    8433              15 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8434              15 :                     break;
    8435 ECB             : 
    8436 GIC         147 :                 case 1:
    8437                 :                     /* ----------
    8438                 :                      * ABS(var1) > ABS(var2)
    8439                 :                      * result = -(ABS(var1) - ABS(var2))
    8440                 :                      * ----------
    8441                 :                      */
    8442             147 :                     sub_abs(var1, var2, result);
    8443             147 :                     result->sign = NUMERIC_NEG;
    8444             147 :                     break;
    8445 ECB             : 
    8446 CBC          72 :                 case -1:
    8447 ECB             :                     /* ----------
    8448                 :                      * ABS(var1) < ABS(var2)
    8449                 :                      * result = +(ABS(var2) - ABS(var1))
    8450                 :                      * ----------
    8451                 :                      */
    8452 CBC          72 :                     sub_abs(var2, var1, result);
    8453 GIC          72 :                     result->sign = NUMERIC_POS;
    8454 CBC          72 :                     break;
    8455 ECB             :             }
    8456                 :         }
    8457                 :         else
    8458                 :         {
    8459                 :             /* ----------
    8460                 :              * Both are negative
    8461                 :              * result = -(ABS(var1) + ABS(var2))
    8462                 :              * ----------
    8463                 :              */
    8464 GIC         549 :             add_abs(var1, var2, result);
    8465             549 :             result->sign = NUMERIC_NEG;
    8466                 :         }
    8467                 :     }
    8468          231922 : }
    8469                 : 
    8470 ECB             : 
    8471                 : /*
    8472                 :  * sub_var() -
    8473                 :  *
    8474                 :  *  Full version of sub functionality on variable level (handling signs).
    8475                 :  *  result might point to one of the operands too without danger.
    8476                 :  */
    8477                 : static void
    8478 CBC       57346 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8479                 : {
    8480 EUB             :     /*
    8481                 :      * Decide on the signs of the two variables what to do
    8482                 :      */
    8483 GIC       57346 :     if (var1->sign == NUMERIC_POS)
    8484 ECB             :     {
    8485 GIC       55961 :         if (var2->sign == NUMERIC_NEG)
    8486 ECB             :         {
    8487                 :             /* ----------
    8488                 :              * var1 is positive, var2 is negative
    8489                 :              * result = +(ABS(var1) + ABS(var2))
    8490                 :              * ----------
    8491                 :              */
    8492 GIC        3026 :             add_abs(var1, var2, result);
    8493            3026 :             result->sign = NUMERIC_POS;
    8494 ECB             :         }
    8495                 :         else
    8496                 :         {
    8497                 :             /* ----------
    8498                 :              * Both are positive
    8499                 :              * Must compare absolute values
    8500                 :              * ----------
    8501                 :              */
    8502 GIC       52935 :             switch (cmp_abs(var1, var2))
    8503                 :             {
    8504           14959 :                 case 0:
    8505                 :                     /* ----------
    8506                 :                      * ABS(var1) == ABS(var2)
    8507                 :                      * result = ZERO
    8508 ECB             :                      * ----------
    8509                 :                      */
    8510 GIC       14959 :                     zero_var(result);
    8511           14959 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8512           14959 :                     break;
    8513                 : 
    8514           37713 :                 case 1:
    8515                 :                     /* ----------
    8516                 :                      * ABS(var1) > ABS(var2)
    8517                 :                      * result = +(ABS(var1) - ABS(var2))
    8518                 :                      * ----------
    8519                 :                      */
    8520 CBC       37713 :                     sub_abs(var1, var2, result);
    8521           37713 :                     result->sign = NUMERIC_POS;
    8522           37713 :                     break;
    8523                 : 
    8524 GIC         263 :                 case -1:
    8525 ECB             :                     /* ----------
    8526                 :                      * ABS(var1) < ABS(var2)
    8527                 :                      * result = -(ABS(var2) - ABS(var1))
    8528                 :                      * ----------
    8529 EUB             :                      */
    8530 GBC         263 :                     sub_abs(var2, var1, result);
    8531             263 :                     result->sign = NUMERIC_NEG;
    8532 GIC         263 :                     break;
    8533                 :             }
    8534                 :         }
    8535                 :     }
    8536                 :     else
    8537                 :     {
    8538 CBC        1385 :         if (var2->sign == NUMERIC_NEG)
    8539 ECB             :         {
    8540                 :             /* ----------
    8541                 :              * Both are negative
    8542                 :              * Must compare absolute values
    8543                 :              * ----------
    8544                 :              */
    8545 CBC        1160 :             switch (cmp_abs(var1, var2))
    8546                 :             {
    8547              83 :                 case 0:
    8548 ECB             :                     /* ----------
    8549                 :                      * ABS(var1) == ABS(var2)
    8550                 :                      * result = ZERO
    8551                 :                      * ----------
    8552                 :                      */
    8553 GIC          83 :                     zero_var(result);
    8554              83 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8555              83 :                     break;
    8556                 : 
    8557             117 :                 case 1:
    8558                 :                     /* ----------
    8559 ECB             :                      * ABS(var1) > ABS(var2)
    8560                 :                      * result = -(ABS(var1) - ABS(var2))
    8561 EUB             :                      * ----------
    8562                 :                      */
    8563 GBC         117 :                     sub_abs(var1, var2, result);
    8564             117 :                     result->sign = NUMERIC_NEG;
    8565 GIC         117 :                     break;
    8566                 : 
    8567             960 :                 case -1:
    8568                 :                     /* ----------
    8569 ECB             :                      * ABS(var1) < ABS(var2)
    8570                 :                      * result = +(ABS(var2) - ABS(var1))
    8571                 :                      * ----------
    8572                 :                      */
    8573 GIC         960 :                     sub_abs(var2, var1, result);
    8574             960 :                     result->sign = NUMERIC_POS;
    8575             960 :                     break;
    8576                 :             }
    8577                 :         }
    8578                 :         else
    8579 ECB             :         {
    8580                 :             /* ----------
    8581                 :              * var1 is negative, var2 is positive
    8582                 :              * result = -(ABS(var1) + ABS(var2))
    8583                 :              * ----------
    8584                 :              */
    8585 GIC         225 :             add_abs(var1, var2, result);
    8586             225 :             result->sign = NUMERIC_NEG;
    8587 ECB             :         }
    8588                 :     }
    8589 GIC       57346 : }
    8590 EUB             : 
    8591                 : 
    8592                 : /*
    8593                 :  * mul_var() -
    8594                 :  *
    8595 ECB             :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8596                 :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8597                 :  */
    8598                 : static void
    8599 CBC      413936 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8600                 :         int rscale)
    8601 ECB             : {
    8602                 :     int         res_ndigits;
    8603                 :     int         res_sign;
    8604                 :     int         res_weight;
    8605                 :     int         maxdigits;
    8606                 :     int        *dig;
    8607                 :     int         carry;
    8608                 :     int         maxdig;
    8609                 :     int         newdig;
    8610                 :     int         var1ndigits;
    8611                 :     int         var2ndigits;
    8612                 :     NumericDigit *var1digits;
    8613                 :     NumericDigit *var2digits;
    8614                 :     NumericDigit *res_digits;
    8615                 :     int         i,
    8616                 :                 i1,
    8617                 :                 i2;
    8618                 : 
    8619                 :     /*
    8620                 :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8621                 :      * performance because the inner multiplication loop is much simpler than
    8622                 :      * the outer loop, so it's better to have a smaller number of iterations
    8623                 :      * of the outer loop.  This also reduces the number of times that the
    8624                 :      * accumulator array needs to be normalized.
    8625                 :      */
    8626 GIC      413936 :     if (var1->ndigits > var2->ndigits)
    8627                 :     {
    8628            6599 :         const NumericVar *tmp = var1;
    8629                 : 
    8630            6599 :         var1 = var2;
    8631 CBC        6599 :         var2 = tmp;
    8632                 :     }
    8633                 : 
    8634 ECB             :     /* copy these values into local vars for speed in inner loop */
    8635 CBC      413936 :     var1ndigits = var1->ndigits;
    8636 GIC      413936 :     var2ndigits = var2->ndigits;
    8637          413936 :     var1digits = var1->digits;
    8638 GBC      413936 :     var2digits = var2->digits;
    8639                 : 
    8640 GIC      413936 :     if (var1ndigits == 0 || var2ndigits == 0)
    8641                 :     {
    8642                 :         /* one or both inputs is zero; so is result */
    8643             856 :         zero_var(result);
    8644 CBC         856 :         result->dscale = rscale;
    8645 GIC         856 :         return;
    8646 ECB             :     }
    8647                 : 
    8648                 :     /* Determine result sign and (maximum possible) weight */
    8649 GIC      413080 :     if (var1->sign == var2->sign)
    8650          411815 :         res_sign = NUMERIC_POS;
    8651                 :     else
    8652            1265 :         res_sign = NUMERIC_NEG;
    8653          413080 :     res_weight = var1->weight + var2->weight + 2;
    8654                 : 
    8655                 :     /*
    8656                 :      * Determine the number of result digits to compute.  If the exact result
    8657 ECB             :      * would have more than rscale fractional digits, truncate the computation
    8658                 :      * with MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that
    8659                 :      * would only contribute to the right of that.  (This will give the exact
    8660                 :      * rounded-to-rscale answer unless carries out of the ignored positions
    8661                 :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8662                 :      *
    8663                 :      * Note: an exact computation could not produce more than var1ndigits +
    8664                 :      * var2ndigits digits, but we allocate one extra output digit in case
    8665                 :      * rscale-driven rounding produces a carry out of the highest exact digit.
    8666                 :      */
    8667 GIC      413080 :     res_ndigits = var1ndigits + var2ndigits + 1;
    8668          413080 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8669                 :         MUL_GUARD_DIGITS;
    8670          413080 :     res_ndigits = Min(res_ndigits, maxdigits);
    8671                 : 
    8672 CBC      413080 :     if (res_ndigits < 3)
    8673                 :     {
    8674                 :         /* All input digits will be ignored; so result is zero */
    8675 GIC           6 :         zero_var(result);
    8676               6 :         result->dscale = rscale;
    8677 CBC           6 :         return;
    8678                 :     }
    8679 ECB             : 
    8680                 :     /*
    8681                 :      * We do the arithmetic in an array "dig[]" of signed int's.  Since
    8682                 :      * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
    8683                 :      * to avoid normalizing carries immediately.
    8684                 :      *
    8685                 :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8686                 :      * threatens to exceed INT_MAX, we take the time to propagate carries.
    8687                 :      * Furthermore, we need to ensure that overflow doesn't occur during the
    8688                 :      * carry propagation passes either.  The carry values could be as much as
    8689                 :      * INT_MAX/NBASE, so really we must normalize when digits threaten to
    8690                 :      * exceed INT_MAX - INT_MAX/NBASE.
    8691                 :      *
    8692                 :      * To avoid overflow in maxdig itself, it actually represents the max
    8693                 :      * possible value divided by NBASE-1, ie, at the top of the loop it is
    8694                 :      * known that no dig[] entry exceeds maxdig * (NBASE-1).
    8695                 :      */
    8696 CBC      413074 :     dig = (int *) palloc0(res_ndigits * sizeof(int));
    8697 GIC      413074 :     maxdig = 0;
    8698                 : 
    8699                 :     /*
    8700 ECB             :      * The least significant digits of var1 should be ignored if they don't
    8701                 :      * contribute directly to the first res_ndigits digits of the result that
    8702                 :      * we are computing.
    8703                 :      *
    8704                 :      * Digit i1 of var1 and digit i2 of var2 are multiplied and added to digit
    8705                 :      * i1+i2+2 of the accumulator array, so we need only consider digits of
    8706                 :      * var1 for which i1 <= res_ndigits - 3.
    8707                 :      */
    8708 GIC     2314082 :     for (i1 = Min(var1ndigits - 1, res_ndigits - 3); i1 >= 0; i1--)
    8709                 :     {
    8710         1901008 :         NumericDigit var1digit = var1digits[i1];
    8711                 : 
    8712         1901008 :         if (var1digit == 0)
    8713         1179720 :             continue;
    8714                 : 
    8715 ECB             :         /* Time to normalize? */
    8716 GIC      721288 :         maxdig += var1digit;
    8717          721288 :         if (maxdig > (INT_MAX - INT_MAX / NBASE) / (NBASE - 1))
    8718                 :         {
    8719                 :             /* Yes, do it */
    8720 CBC        4572 :             carry = 0;
    8721 GIC    22905348 :             for (i = res_ndigits - 1; i >= 0; i--)
    8722 ECB             :             {
    8723 GIC    22900776 :                 newdig = dig[i] + carry;
    8724        22900776 :                 if (newdig >= NBASE)
    8725                 :                 {
    8726        11532801 :                     carry = newdig / NBASE;
    8727 CBC    11532801 :                     newdig -= carry * NBASE;
    8728 ECB             :                 }
    8729                 :                 else
    8730 GIC    11367975 :                     carry = 0;
    8731        22900776 :                 dig[i] = newdig;
    8732                 :             }
    8733            4572 :             Assert(carry == 0);
    8734                 :             /* Reset maxdig to indicate new worst-case */
    8735 CBC        4572 :             maxdig = 1 + var1digit;
    8736                 :         }
    8737 ECB             : 
    8738                 :         /*
    8739                 :          * Add the appropriate multiple of var2 into the accumulator.
    8740                 :          *
    8741                 :          * As above, digits of var2 can be ignored if they don't contribute,
    8742                 :          * so we only include digits for which i1+i2+2 < res_ndigits.
    8743                 :          *
    8744                 :          * This inner loop is the performance bottleneck for multiplication,
    8745                 :          * so we want to keep it simple enough so that it can be
    8746                 :          * auto-vectorized.  Accordingly, process the digits left-to-right
    8747                 :          * even though schoolbook multiplication would suggest right-to-left.
    8748                 :          * Since we aren't propagating carries in this loop, the order does
    8749                 :          * not matter.
    8750                 :          */
    8751                 :         {
    8752 GIC      721288 :             int         i2limit = Min(var2ndigits, res_ndigits - i1 - 2);
    8753 CBC      721288 :             int        *dig_i1_2 = &dig[i1 + 2];
    8754 ECB             : 
    8755 CBC   249555590 :             for (i2 = 0; i2 < i2limit; i2++)
    8756 GIC   248834302 :                 dig_i1_2[i2] += var1digit * var2digits[i2];
    8757 ECB             :         }
    8758                 :     }
    8759                 : 
    8760                 :     /*
    8761                 :      * Now we do a final carry propagation pass to normalize the result, which
    8762                 :      * we combine with storing the result digits into the output. Note that
    8763                 :      * this is still done at full precision w/guard digits.
    8764                 :      */
    8765 CBC      413074 :     alloc_var(result, res_ndigits);
    8766 GIC      413074 :     res_digits = result->digits;
    8767          413074 :     carry = 0;
    8768         5114614 :     for (i = res_ndigits - 1; i >= 0; i--)
    8769                 :     {
    8770         4701540 :         newdig = dig[i] + carry;
    8771 CBC     4701540 :         if (newdig >= NBASE)
    8772                 :         {
    8773 GIC      991510 :             carry = newdig / NBASE;
    8774          991510 :             newdig -= carry * NBASE;
    8775                 :         }
    8776                 :         else
    8777         3710030 :             carry = 0;
    8778 CBC     4701540 :         res_digits[i] = newdig;
    8779                 :     }
    8780          413074 :     Assert(carry == 0);
    8781                 : 
    8782 GIC      413074 :     pfree(dig);
    8783                 : 
    8784                 :     /*
    8785                 :      * Finally, round the result to the requested precision.
    8786 ECB             :      */
    8787 CBC      413074 :     result->weight = res_weight;
    8788          413074 :     result->sign = res_sign;
    8789                 : 
    8790 ECB             :     /* Round to target rscale (and set result->dscale) */
    8791 GIC      413074 :     round_var(result, rscale);
    8792                 : 
    8793                 :     /* Strip leading and trailing zeroes */
    8794          413074 :     strip_var(result);
    8795                 : }
    8796 ECB             : 
    8797                 : 
    8798                 : /*
    8799                 :  * div_var() -
    8800                 :  *
    8801                 :  *  Division on variable level. Quotient of var1 / var2 is stored in result.
    8802                 :  *  The quotient is figured to exactly rscale fractional digits.
    8803                 :  *  If round is true, it is rounded at the rscale'th digit; if false, it
    8804                 :  *  is truncated (towards zero) at that digit.
    8805                 :  */
    8806                 : static void
    8807 CBC       88565 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8808 ECB             :         int rscale, bool round)
    8809                 : {
    8810                 :     int         div_ndigits;
    8811                 :     int         res_ndigits;
    8812                 :     int         res_sign;
    8813                 :     int         res_weight;
    8814                 :     int         carry;
    8815                 :     int         borrow;
    8816                 :     int         divisor1;
    8817                 :     int         divisor2;
    8818                 :     NumericDigit *dividend;
    8819                 :     NumericDigit *divisor;
    8820                 :     NumericDigit *res_digits;
    8821                 :     int         i;
    8822                 :     int         j;
    8823                 : 
    8824                 :     /* copy these values into local vars for speed in inner loop */
    8825 GIC       88565 :     int         var1ndigits = var1->ndigits;
    8826           88565 :     int         var2ndigits = var2->ndigits;
    8827                 : 
    8828                 :     /*
    8829                 :      * First of all division by zero check; we must not be handed an
    8830                 :      * unnormalized divisor.
    8831                 :      */
    8832 CBC       88565 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    8833 GIC          28 :         ereport(ERROR,
    8834                 :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    8835                 :                  errmsg("division by zero")));
    8836                 : 
    8837 ECB             :     /*
    8838                 :      * If the divisor has just one or two digits, delegate to div_var_int(),
    8839                 :      * which uses fast short division.
    8840                 :      *
    8841                 :      * Similarly, on platforms with 128-bit integer support, delegate to
    8842                 :      * div_var_int64() for divisors with three or four digits.
    8843                 :      */
    8844 GIC       88537 :     if (var2ndigits <= 2)
    8845                 :     {
    8846                 :         int         idivisor;
    8847                 :         int         idivisor_weight;
    8848                 : 
    8849 CBC       86823 :         idivisor = var2->digits[0];
    8850           86823 :         idivisor_weight = var2->weight;
    8851 GIC       86823 :         if (var2ndigits == 2)
    8852                 :         {
    8853            1545 :             idivisor = idivisor * NBASE + var2->digits[1];
    8854            1545 :             idivisor_weight--;
    8855                 :         }
    8856           86823 :         if (var2->sign == NUMERIC_NEG)
    8857             243 :             idivisor = -idivisor;
    8858                 : 
    8859 CBC       86823 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    8860 GIC       86823 :         return;
    8861 ECB             :     }
    8862                 : #ifdef HAVE_INT128
    8863 GNC        1714 :     if (var2ndigits <= 4)
    8864                 :     {
    8865                 :         int64       idivisor;
    8866                 :         int         idivisor_weight;
    8867                 : 
    8868             243 :         idivisor = var2->digits[0];
    8869             243 :         idivisor_weight = var2->weight;
    8870             912 :         for (i = 1; i < var2ndigits; i++)
    8871                 :         {
    8872             669 :             idivisor = idivisor * NBASE + var2->digits[i];
    8873             669 :             idivisor_weight--;
    8874                 :         }
    8875             243 :         if (var2->sign == NUMERIC_NEG)
    8876              60 :             idivisor = -idivisor;
    8877                 : 
    8878             243 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    8879             243 :         return;
    8880                 :     }
    8881                 : #endif
    8882                 : 
    8883                 :     /*
    8884                 :      * Otherwise, perform full long division.
    8885                 :      */
    8886                 : 
    8887 ECB             :     /* Result zero check */
    8888 CBC        1471 :     if (var1ndigits == 0)
    8889 ECB             :     {
    8890 GIC          12 :         zero_var(result);
    8891 CBC          12 :         result->dscale = rscale;
    8892 GIC          12 :         return;
    8893                 :     }
    8894                 : 
    8895                 :     /*
    8896                 :      * Determine the result sign, weight and number of digits to calculate.
    8897 ECB             :      * The weight figured here is correct if the emitted quotient has no
    8898                 :      * leading zero digits; otherwise strip_var() will fix things up.
    8899                 :      */
    8900 GIC        1459 :     if (var1->sign == var2->sign)
    8901 CBC        1429 :         res_sign = NUMERIC_POS;
    8902                 :     else
    8903 GIC          30 :         res_sign = NUMERIC_NEG;
    8904            1459 :     res_weight = var1->weight - var2->weight;
    8905                 :     /* The number of accurate result digits we need to produce: */
    8906            1459 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    8907 ECB             :     /* ... but always at least 1 */
    8908 CBC        1459 :     res_ndigits = Max(res_ndigits, 1);
    8909 ECB             :     /* If rounding needed, figure one more digit to ensure correct result */
    8910 GIC        1459 :     if (round)
    8911            1459 :         res_ndigits++;
    8912                 : 
    8913                 :     /*
    8914                 :      * The working dividend normally requires res_ndigits + var2ndigits
    8915 ECB             :      * digits, but make it at least var1ndigits so we can load all of var1
    8916                 :      * into it.  (There will be an additional digit dividend[0] in the
    8917                 :      * dividend space, but for consistency with Knuth's notation we don't
    8918                 :      * count that in div_ndigits.)
    8919                 :      */
    8920 GIC        1459 :     div_ndigits = res_ndigits + var2ndigits;
    8921            1459 :     div_ndigits = Max(div_ndigits, var1ndigits);
    8922 ECB             : 
    8923                 :     /*
    8924                 :      * We need a workspace with room for the working dividend (div_ndigits+1
    8925                 :      * digits) plus room for the possibly-normalized divisor (var2ndigits
    8926                 :      * digits).  It is convenient also to have a zero at divisor[0] with the
    8927                 :      * actual divisor data in divisor[1 .. var2ndigits].  Transferring the
    8928                 :      * digits into the workspace also allows us to realloc the result (which
    8929                 :      * might be the same as either input var) before we begin the main loop.
    8930                 :      * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
    8931                 :      * any additional dividend positions beyond var1ndigits, start out 0.
    8932                 :      */
    8933                 :     dividend = (NumericDigit *)
    8934 CBC        1459 :         palloc0((div_ndigits + var2ndigits + 2) * sizeof(NumericDigit));
    8935 GIC        1459 :     divisor = dividend + (div_ndigits + 1);
    8936            1459 :     memcpy(dividend + 1, var1->digits, var1ndigits * sizeof(NumericDigit));
    8937            1459 :     memcpy(divisor + 1, var2->digits, var2ndigits * sizeof(NumericDigit));
    8938                 : 
    8939                 :     /*
    8940 ECB             :      * Now we can realloc the result to hold the generated quotient digits.
    8941                 :      */
    8942 CBC        1459 :     alloc_var(result, res_ndigits);
    8943 GIC        1459 :     res_digits = result->digits;
    8944 ECB             : 
    8945                 :     /*
    8946                 :      * The full multiple-place algorithm is taken from Knuth volume 2,
    8947                 :      * Algorithm 4.3.1D.
    8948                 :      *
    8949                 :      * We need the first divisor digit to be >= NBASE/2.  If it isn't, make it
    8950                 :      * so by scaling up both the divisor and dividend by the factor "d".  (The
    8951                 :      * reason for allocating dividend[0] above is to leave room for possible
    8952                 :      * carry here.)
    8953                 :      */
    8954 GIC        1459 :     if (divisor[1] < HALF_NBASE)
    8955                 :     {
    8956            1459 :         int         d = NBASE / (divisor[1] + 1);
    8957                 : 
    8958            1459 :         carry = 0;
    8959           12548 :         for (i = var2ndigits; i > 0; i--)
    8960                 :         {
    8961           11089 :             carry += divisor[i] * d;
    8962 CBC       11089 :             divisor[i] = carry % NBASE;
    8963           11089 :             carry = carry / NBASE;
    8964                 :         }
    8965 GIC        1459 :         Assert(carry == 0);
    8966 CBC        1459 :         carry = 0;
    8967                 :         /* at this point only var1ndigits of dividend can be nonzero */
    8968 GIC       12994 :         for (i = var1ndigits; i >= 0; i--)
    8969                 :         {
    8970           11535 :             carry += dividend[i] * d;
    8971           11535 :             dividend[i] = carry % NBASE;
    8972           11535 :             carry = carry / NBASE;
    8973                 :         }
    8974            1459 :         Assert(carry == 0);
    8975            1459 :         Assert(divisor[1] >= HALF_NBASE);
    8976 ECB             :     }
    8977                 :     /* First 2 divisor digits are used repeatedly in main loop */
    8978 GIC        1459 :     divisor1 = divisor[1];
    8979            1459 :     divisor2 = divisor[2];
    8980                 : 
    8981                 :     /*
    8982                 :      * Begin the main loop.  Each iteration of this loop produces the j'th
    8983                 :      * quotient digit by dividing dividend[j .. j + var2ndigits] by the
    8984                 :      * divisor; this is essentially the same as the common manual procedure
    8985                 :      * for long division.
    8986                 :      */
    8987           11521 :     for (j = 0; j < res_ndigits; j++)
    8988                 :     {
    8989                 :         /* Estimate quotient digit from the first two dividend digits */
    8990           10062 :         int         next2digits = dividend[j] * NBASE + dividend[j + 1];
    8991                 :         int         qhat;
    8992                 : 
    8993                 :         /*
    8994                 :          * If next2digits are 0, then quotient digit must be 0 and there's no
    8995                 :          * need to adjust the working dividend.  It's worth testing here to
    8996                 :          * fall out ASAP when processing trailing zeroes in a dividend.
    8997                 :          */
    8998           10062 :         if (next2digits == 0)
    8999                 :         {
    9000              36 :             res_digits[j] = 0;
    9001              36 :             continue;
    9002                 :         }
    9003 ECB             : 
    9004 GIC       10026 :         if (dividend[j] == divisor1)
    9005 CBC          60 :             qhat = NBASE - 1;
    9006                 :         else
    9007            9966 :             qhat = next2digits / divisor1;
    9008 ECB             : 
    9009                 :         /*
    9010                 :          * Adjust quotient digit if it's too large.  Knuth proves that after
    9011                 :          * this step, the quotient digit will be either correct or just one
    9012                 :          * too large.  (Note: it's OK to use dividend[j+2] here because we
    9013                 :          * know the divisor length is at least 2.)
    9014                 :          */
    9015 CBC       10026 :         while (divisor2 * qhat >
    9016 GIC       11672 :                (next2digits - qhat * divisor1) * NBASE + dividend[j + 2])
    9017 CBC        1646 :             qhat--;
    9018                 : 
    9019                 :         /* As above, need do nothing more when quotient digit is 0 */
    9020           10026 :         if (qhat > 0)
    9021 ECB             :         {
    9022 CBC        8818 :             NumericDigit *dividend_j = &dividend[j];
    9023                 : 
    9024                 :             /*
    9025                 :              * Multiply the divisor by qhat, and subtract that from the
    9026 ECB             :              * working dividend.  The multiplication and subtraction are
    9027                 :              * folded together here, noting that qhat <= NBASE (since it might
    9028                 :              * be one too large), and so the intermediate result "tmp_result"
    9029                 :              * is in the range [-NBASE^2, NBASE - 1], and "borrow" is in the
    9030                 :              * range [0, NBASE].
    9031                 :              */
    9032 GIC        8818 :             borrow = 0;
    9033           87086 :             for (i = var2ndigits; i >= 0; i--)
    9034                 :             {
    9035                 :                 int         tmp_result;
    9036                 : 
    9037           78268 :                 tmp_result = dividend_j[i] - borrow - divisor[i] * qhat;
    9038           78268 :                 borrow = (NBASE - 1 - tmp_result) / NBASE;
    9039           78268 :                 dividend_j[i] = tmp_result + borrow * NBASE;
    9040                 :             }
    9041                 : 
    9042                 :             /*
    9043                 :              * If we got a borrow out of the top dividend digit, then indeed
    9044 ECB             :              * qhat was one too large.  Fix it, and add back the divisor to
    9045                 :              * correct the working dividend.  (Knuth proves that this will
    9046                 :              * occur only about 3/NBASE of the time; hence, it's a good idea
    9047                 :              * to test this code with small NBASE to be sure this section gets
    9048                 :              * exercised.)
    9049                 :              */
    9050 GIC        8818 :             if (borrow)
    9051                 :             {
    9052 CBC          13 :                 qhat--;
    9053              13 :                 carry = 0;
    9054            1154 :                 for (i = var2ndigits; i >= 0; i--)
    9055                 :                 {
    9056 GIC        1141 :                     carry += dividend_j[i] + divisor[i];
    9057            1141 :                     if (carry >= NBASE)
    9058                 :                     {
    9059            1047 :                         dividend_j[i] = carry - NBASE;
    9060            1047 :                         carry = 1;
    9061                 :                     }
    9062                 :                     else
    9063                 :                     {
    9064              94 :                         dividend_j[i] = carry;
    9065              94 :                         carry = 0;
    9066                 :                     }
    9067                 :                 }
    9068                 :                 /* A carry should occur here to cancel the borrow above */
    9069              13 :                 Assert(carry == 1);
    9070                 :             }
    9071                 :         }
    9072                 : 
    9073 ECB             :         /* And we're done with this quotient digit */
    9074 CBC       10026 :         res_digits[j] = qhat;
    9075                 :     }
    9076                 : 
    9077 GIC        1459 :     pfree(dividend);
    9078                 : 
    9079                 :     /*
    9080                 :      * Finally, round or truncate the result to the requested precision.
    9081                 :      */
    9082            1459 :     result->weight = res_weight;
    9083            1459 :     result->sign = res_sign;
    9084                 : 
    9085 ECB             :     /* Round or truncate to target rscale (and set result->dscale) */
    9086 GIC        1459 :     if (round)
    9087 CBC        1459 :         round_var(result, rscale);
    9088                 :     else
    9089 LBC           0 :         trunc_var(result, rscale);
    9090 ECB             : 
    9091                 :     /* Strip leading and trailing zeroes */
    9092 GIC        1459 :     strip_var(result);
    9093 ECB             : }
    9094                 : 
    9095                 : 
    9096                 : /*
    9097                 :  * div_var_fast() -
    9098                 :  *
    9099                 :  *  This has the same API as div_var, but is implemented using the division
    9100                 :  *  algorithm from the "FM" library, rather than Knuth's schoolbook-division
    9101                 :  *  approach.  This is significantly faster but can produce inaccurate
    9102                 :  *  results, because it sometimes has to propagate rounding to the left,
    9103                 :  *  and so we can never be entirely sure that we know the requested digits
    9104                 :  *  exactly.  We compute DIV_GUARD_DIGITS extra digits, but there is
    9105                 :  *  no certainty that that's enough.  We use this only in the transcendental
    9106                 :  *  function calculation routines, where everything is approximate anyway.
    9107                 :  *
    9108                 :  *  Although we provide a "round" argument for consistency with div_var,
    9109                 :  *  it is unwise to use this function with round=false.  In truncation mode
    9110                 :  *  it is possible to get a result with no significant digits, for example
    9111                 :  *  with rscale=0 we might compute 0.99999... and truncate that to 0 when
    9112                 :  *  the correct answer is 1.
    9113                 :  */
    9114                 : static void
    9115 GIC        2901 : div_var_fast(const NumericVar *var1, const NumericVar *var2,
    9116                 :              NumericVar *result, int rscale, bool round)
    9117                 : {
    9118                 :     int         div_ndigits;
    9119                 :     int         load_ndigits;
    9120                 :     int         res_sign;
    9121                 :     int         res_weight;
    9122                 :     int        *div;
    9123                 :     int         qdigit;
    9124                 :     int         carry;
    9125                 :     int         maxdiv;
    9126                 :     int         newdig;
    9127                 :     NumericDigit *res_digits;
    9128                 :     double      fdividend,
    9129 ECB             :                 fdivisor,
    9130                 :                 fdivisorinverse,
    9131                 :                 fquotient;
    9132                 :     int         qi;
    9133                 :     int         i;
    9134                 : 
    9135                 :     /* copy these values into local vars for speed in inner loop */
    9136 GIC        2901 :     int         var1ndigits = var1->ndigits;
    9137            2901 :     int         var2ndigits = var2->ndigits;
    9138            2901 :     NumericDigit *var1digits = var1->digits;
    9139            2901 :     NumericDigit *var2digits = var2->digits;
    9140                 : 
    9141                 :     /*
    9142 ECB             :      * First of all division by zero check; we must not be handed an
    9143                 :      * unnormalized divisor.
    9144                 :      */
    9145 CBC        2901 :     if (var2ndigits == 0 || var2digits[0] == 0)
    9146 GIC           3 :         ereport(ERROR,
    9147 ECB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    9148                 :                  errmsg("division by zero")));
    9149                 : 
    9150                 :     /*
    9151                 :      * If the divisor has just one or two digits, delegate to div_var_int(),
    9152                 :      * which uses fast short division.
    9153                 :      *
    9154                 :      * Similarly, on platforms with 128-bit integer support, delegate to
    9155                 :      * div_var_int64() for divisors with three or four digits.
    9156                 :      */
    9157 CBC        2898 :     if (var2ndigits <= 2)
    9158 ECB             :     {
    9159                 :         int         idivisor;
    9160                 :         int         idivisor_weight;
    9161                 : 
    9162 CBC         207 :         idivisor = var2->digits[0];
    9163 GIC         207 :         idivisor_weight = var2->weight;
    9164             207 :         if (var2ndigits == 2)
    9165                 :         {
    9166 UIC           0 :             idivisor = idivisor * NBASE + var2->digits[1];
    9167 LBC           0 :             idivisor_weight--;
    9168 ECB             :         }
    9169 GIC         207 :         if (var2->sign == NUMERIC_NEG)
    9170 UIC           0 :             idivisor = -idivisor;
    9171 ECB             : 
    9172 GIC         207 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    9173             207 :         return;
    9174 ECB             :     }
    9175                 : #ifdef HAVE_INT128
    9176 GNC        2691 :     if (var2ndigits <= 4)
    9177                 :     {
    9178                 :         int64       idivisor;
    9179                 :         int         idivisor_weight;
    9180                 : 
    9181              21 :         idivisor = var2->digits[0];
    9182              21 :         idivisor_weight = var2->weight;
    9183              75 :         for (i = 1; i < var2ndigits; i++)
    9184                 :         {
    9185              54 :             idivisor = idivisor * NBASE + var2->digits[i];
    9186              54 :             idivisor_weight--;
    9187                 :         }
    9188              21 :         if (var2->sign == NUMERIC_NEG)
    9189 UNC           0 :             idivisor = -idivisor;
    9190                 : 
    9191 GNC          21 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    9192              21 :         return;
    9193                 :     }
    9194                 : #endif
    9195                 : 
    9196                 :     /*
    9197                 :      * Otherwise, perform full long division.
    9198                 :      */
    9199                 : 
    9200                 :     /* Result zero check */
    9201 GIC        2670 :     if (var1ndigits == 0)
    9202                 :     {
    9203               6 :         zero_var(result);
    9204               6 :         result->dscale = rscale;
    9205               6 :         return;
    9206                 :     }
    9207 ECB             : 
    9208                 :     /*
    9209                 :      * Determine the result sign, weight and number of digits to calculate
    9210                 :      */
    9211 GIC        2664 :     if (var1->sign == var2->sign)
    9212            2628 :         res_sign = NUMERIC_POS;
    9213                 :     else
    9214              36 :         res_sign = NUMERIC_NEG;
    9215            2664 :     res_weight = var1->weight - var2->weight + 1;
    9216                 :     /* The number of accurate result digits we need to produce: */
    9217            2664 :     div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9218                 :     /* Add guard digits for roundoff error */
    9219            2664 :     div_ndigits += DIV_GUARD_DIGITS;
    9220            2664 :     if (div_ndigits < DIV_GUARD_DIGITS)
    9221 UIC           0 :         div_ndigits = DIV_GUARD_DIGITS;
    9222                 : 
    9223                 :     /*
    9224                 :      * We do the arithmetic in an array "div[]" of signed int's.  Since
    9225 ECB             :      * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
    9226                 :      * to avoid normalizing carries immediately.
    9227                 :      *
    9228                 :      * We start with div[] containing one zero digit followed by the
    9229                 :      * dividend's digits (plus appended zeroes to reach the desired precision
    9230                 :      * including guard digits).  Each step of the main loop computes an
    9231                 :      * (approximate) quotient digit and stores it into div[], removing one
    9232                 :      * position of dividend space.  A final pass of carry propagation takes
    9233                 :      * care of any mistaken quotient digits.
    9234                 :      *
    9235                 :      * Note that div[] doesn't necessarily contain all of the digits from the
    9236                 :      * dividend --- the desired precision plus guard digits might be less than
    9237                 :      * the dividend's precision.  This happens, for example, in the square
    9238                 :      * root algorithm, where we typically divide a 2N-digit number by an
    9239                 :      * N-digit number, and only require a result with N digits of precision.
    9240                 :      */
    9241 GIC        2664 :     div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
    9242            2664 :     load_ndigits = Min(div_ndigits, var1ndigits);
    9243           36354 :     for (i = 0; i < load_ndigits; i++)
    9244 CBC       33690 :         div[i + 1] = var1digits[i];
    9245                 : 
    9246                 :     /*
    9247                 :      * We estimate each quotient digit using floating-point arithmetic, taking
    9248                 :      * the first four digits of the (current) dividend and divisor.  This must
    9249 ECB             :      * be float to avoid overflow.  The quotient digits will generally be off
    9250                 :      * by no more than one from the exact answer.
    9251                 :      */
    9252 GIC        2664 :     fdivisor = (double) var2digits[0];
    9253 CBC       10656 :     for (i = 1; i < 4; i++)
    9254 ECB             :     {
    9255 GIC        7992 :         fdivisor *= NBASE;
    9256 CBC        7992 :         if (i < var2ndigits)
    9257            7992 :             fdivisor += (double) var2digits[i];
    9258                 :     }
    9259            2664 :     fdivisorinverse = 1.0 / fdivisor;
    9260 ECB             : 
    9261                 :     /*
    9262                 :      * maxdiv tracks the maximum possible absolute value of any div[] entry;
    9263                 :      * when this threatens to exceed INT_MAX, we take the time to propagate
    9264                 :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    9265                 :      * during the carry propagation passes either.  The carry values may have
    9266                 :      * an absolute value as high as INT_MAX/NBASE + 1, so really we must
    9267                 :      * normalize when digits threaten to exceed INT_MAX - INT_MAX/NBASE - 1.
    9268                 :      *
    9269                 :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9270                 :      * value divided by NBASE-1, ie, at the top of the loop it is known that
    9271                 :      * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
    9272                 :      *
    9273                 :      * Actually, though, that holds good only for div[] entries after div[qi];
    9274                 :      * the adjustment done at the bottom of the loop may cause div[qi + 1] to
    9275                 :      * exceed the maxdiv limit, so that div[qi] in the next iteration is
    9276                 :      * beyond the limit.  This does not cause problems, as explained below.
    9277                 :      */
    9278 CBC        2664 :     maxdiv = 1;
    9279 ECB             : 
    9280                 :     /*
    9281                 :      * Outer loop computes next quotient digit, which will go into div[qi]
    9282                 :      */
    9283 GIC       45144 :     for (qi = 0; qi < div_ndigits; qi++)
    9284                 :     {
    9285                 :         /* Approximate the current dividend value */
    9286           42480 :         fdividend = (double) div[qi];
    9287          169920 :         for (i = 1; i < 4; i++)
    9288 ECB             :         {
    9289 GIC      127440 :             fdividend *= NBASE;
    9290 CBC      127440 :             if (qi + i <= div_ndigits)
    9291          119448 :                 fdividend += (double) div[qi + i];
    9292 ECB             :         }
    9293                 :         /* Compute the (approximate) quotient digit */
    9294 GIC       42480 :         fquotient = fdividend * fdivisorinverse;
    9295           42480 :         qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
    9296               3 :             (((int) fquotient) - 1);    /* truncate towards -infinity */
    9297                 : 
    9298           42480 :         if (qdigit != 0)
    9299                 :         {
    9300 ECB             :             /* Do we need to normalize now? */
    9301 GNC       37983 :             maxdiv += abs(qdigit);
    9302 GIC       37983 :             if (maxdiv > (INT_MAX - INT_MAX / NBASE - 1) / (NBASE - 1))
    9303 ECB             :             {
    9304                 :                 /*
    9305                 :                  * Yes, do it.  Note that if var2ndigits is much smaller than
    9306                 :                  * div_ndigits, we can save a significant amount of effort
    9307                 :                  * here by noting that we only need to normalise those div[]
    9308                 :                  * entries touched where prior iterations subtracted multiples
    9309                 :                  * of the divisor.
    9310                 :                  */
    9311 CBC          48 :                 carry = 0;
    9312 GIC         948 :                 for (i = Min(qi + var2ndigits - 2, div_ndigits); i > qi; i--)
    9313                 :                 {
    9314             900 :                     newdig = div[i] + carry;
    9315             900 :                     if (newdig < 0)
    9316                 :                     {
    9317             900 :                         carry = -((-newdig - 1) / NBASE) - 1;
    9318             900 :                         newdig -= carry * NBASE;
    9319                 :                     }
    9320 LBC           0 :                     else if (newdig >= NBASE)
    9321 ECB             :                     {
    9322 UIC           0 :                         carry = newdig / NBASE;
    9323               0 :                         newdig -= carry * NBASE;
    9324                 :                     }
    9325                 :                     else
    9326               0 :                         carry = 0;
    9327 GIC         900 :                     div[i] = newdig;
    9328                 :                 }
    9329              48 :                 newdig = div[qi] + carry;
    9330              48 :                 div[qi] = newdig;
    9331                 : 
    9332                 :                 /*
    9333                 :                  * All the div[] digits except possibly div[qi] are now in the
    9334 ECB             :                  * range 0..NBASE-1.  We do not need to consider div[qi] in
    9335                 :                  * the maxdiv value anymore, so we can reset maxdiv to 1.
    9336                 :                  */
    9337 CBC          48 :                 maxdiv = 1;
    9338                 : 
    9339                 :                 /*
    9340                 :                  * Recompute the quotient digit since new info may have
    9341                 :                  * propagated into the top four dividend digits
    9342 ECB             :                  */
    9343 CBC          48 :                 fdividend = (double) div[qi];
    9344 GIC         192 :                 for (i = 1; i < 4; i++)
    9345                 :                 {
    9346             144 :                     fdividend *= NBASE;
    9347             144 :                     if (qi + i <= div_ndigits)
    9348             144 :                         fdividend += (double) div[qi + i];
    9349                 :                 }
    9350                 :                 /* Compute the (approximate) quotient digit */
    9351              48 :                 fquotient = fdividend * fdivisorinverse;
    9352              48 :                 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
    9353 UIC           0 :                     (((int) fquotient) - 1);    /* truncate towards -infinity */
    9354 GNC          48 :                 maxdiv += abs(qdigit);
    9355                 :             }
    9356 ECB             : 
    9357                 :             /*
    9358                 :              * Subtract off the appropriate multiple of the divisor.
    9359                 :              *
    9360                 :              * The digits beyond div[qi] cannot overflow, because we know they
    9361                 :              * will fall within the maxdiv limit.  As for div[qi] itself, note
    9362                 :              * that qdigit is approximately trunc(div[qi] / vardigits[0]),
    9363                 :              * which would make the new value simply div[qi] mod vardigits[0].
    9364                 :              * The lower-order terms in qdigit can change this result by not
    9365                 :              * more than about twice INT_MAX/NBASE, so overflow is impossible.
    9366                 :              *
    9367                 :              * This inner loop is the performance bottleneck for division, so
    9368                 :              * code it in the same way as the inner loop of mul_var() so that
    9369                 :              * it can be auto-vectorized.  We cast qdigit to NumericDigit
    9370                 :              * before multiplying to allow the compiler to generate more
    9371                 :              * efficient code (using 16-bit multiplication), which is safe
    9372                 :              * since we know that the quotient digit is off by at most one, so
    9373                 :              * there is no overflow risk.
    9374                 :              */
    9375 CBC       37983 :             if (qdigit != 0)
    9376                 :             {
    9377 GIC       37983 :                 int         istop = Min(var2ndigits, div_ndigits - qi + 1);
    9378 CBC       37983 :                 int        *div_qi = &div[qi];
    9379 ECB             : 
    9380 GIC      465018 :                 for (i = 0; i < istop; i++)
    9381          427035 :                     div_qi[i] -= ((NumericDigit) qdigit) * var2digits[i];
    9382                 :             }
    9383                 :         }
    9384                 : 
    9385                 :         /*
    9386                 :          * The dividend digit we are about to replace might still be nonzero.
    9387 ECB             :          * Fold it into the next digit position.
    9388                 :          *
    9389                 :          * There is no risk of overflow here, although proving that requires
    9390                 :          * some care.  Much as with the argument for div[qi] not overflowing,
    9391                 :          * if we consider the first two terms in the numerator and denominator
    9392                 :          * of qdigit, we can see that the final value of div[qi + 1] will be
    9393                 :          * approximately a remainder mod (vardigits[0]*NBASE + vardigits[1]).
    9394                 :          * Accounting for the lower-order terms is a bit complicated but ends
    9395                 :          * up adding not much more than INT_MAX/NBASE to the possible range.
    9396                 :          * Thus, div[qi + 1] cannot overflow here, and in its role as div[qi]
    9397                 :          * in the next loop iteration, it can't be large enough to cause
    9398                 :          * overflow in the carry propagation step (if any), either.
    9399                 :          *
    9400                 :          * But having said that: div[qi] can be more than INT_MAX/NBASE, as
    9401                 :          * noted above, which means that the product div[qi] * NBASE *can*
    9402                 :          * overflow.  When that happens, adding it to div[qi + 1] will always
    9403                 :          * cause a canceling overflow so that the end result is correct.  We
    9404                 :          * could avoid the intermediate overflow by doing the multiplication
    9405                 :          * and addition in int64 arithmetic, but so far there appears no need.
    9406                 :          */
    9407 CBC       42480 :         div[qi + 1] += div[qi] * NBASE;
    9408                 : 
    9409 GIC       42480 :         div[qi] = qdigit;
    9410                 :     }
    9411                 : 
    9412                 :     /*
    9413                 :      * Approximate and store the last quotient digit (div[div_ndigits])
    9414                 :      */
    9415 CBC        2664 :     fdividend = (double) div[qi];
    9416           10656 :     for (i = 1; i < 4; i++)
    9417            7992 :         fdividend *= NBASE;
    9418 GIC        2664 :     fquotient = fdividend * fdivisorinverse;
    9419            2664 :     qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
    9420 LBC           0 :         (((int) fquotient) - 1);    /* truncate towards -infinity */
    9421 GIC        2664 :     div[qi] = qdigit;
    9422 ECB             : 
    9423                 :     /*
    9424                 :      * Because the quotient digits might be off by one, some of them might be
    9425                 :      * -1 or NBASE at this point.  The represented value is correct in a
    9426                 :      * mathematical sense, but it doesn't look right.  We do a final carry
    9427                 :      * propagation pass to normalize the digits, which we combine with storing
    9428                 :      * the result digits into the output.  Note that this is still done at
    9429                 :      * full precision w/guard digits.
    9430                 :      */
    9431 GIC        2664 :     alloc_var(result, div_ndigits + 1);
    9432 CBC        2664 :     res_digits = result->digits;
    9433            2664 :     carry = 0;
    9434 GIC       47808 :     for (i = div_ndigits; i >= 0; i--)
    9435                 :     {
    9436           45144 :         newdig = div[i] + carry;
    9437 CBC       45144 :         if (newdig < 0)
    9438 ECB             :         {
    9439 CBC           6 :             carry = -((-newdig - 1) / NBASE) - 1;
    9440 GIC           6 :             newdig -= carry * NBASE;
    9441                 :         }
    9442           45138 :         else if (newdig >= NBASE)
    9443                 :         {
    9444             174 :             carry = newdig / NBASE;
    9445             174 :             newdig -= carry * NBASE;
    9446                 :         }
    9447                 :         else
    9448           44964 :             carry = 0;
    9449           45144 :         res_digits[i] = newdig;
    9450 ECB             :     }
    9451 GIC        2664 :     Assert(carry == 0);
    9452 ECB             : 
    9453 CBC        2664 :     pfree(div);
    9454 ECB             : 
    9455                 :     /*
    9456                 :      * Finally, round the result to the requested precision.
    9457                 :      */
    9458 GIC        2664 :     result->weight = res_weight;
    9459 CBC        2664 :     result->sign = res_sign;
    9460 ECB             : 
    9461                 :     /* Round to target rscale (and set result->dscale) */
    9462 GIC        2664 :     if (round)
    9463             405 :         round_var(result, rscale);
    9464 ECB             :     else
    9465 CBC        2259 :         trunc_var(result, rscale);
    9466                 : 
    9467                 :     /* Strip leading and trailing zeroes */
    9468 GIC        2664 :     strip_var(result);
    9469 ECB             : }
    9470                 : 
    9471                 : 
    9472                 : /*
    9473                 :  * div_var_int() -
    9474                 :  *
    9475                 :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9476                 :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9477                 :  */
    9478                 : static void
    9479 GIC       96609 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9480                 :             NumericVar *result, int rscale, bool round)
    9481                 : {
    9482 CBC       96609 :     NumericDigit *var_digits = var->digits;
    9483           96609 :     int         var_ndigits = var->ndigits;
    9484                 :     int         res_sign;
    9485                 :     int         res_weight;
    9486 ECB             :     int         res_ndigits;
    9487                 :     NumericDigit *res_buf;
    9488                 :     NumericDigit *res_digits;
    9489 EUB             :     uint32      divisor;
    9490                 :     int         i;
    9491                 : 
    9492 ECB             :     /* Guard against division by zero */
    9493 GIC       96609 :     if (ival == 0)
    9494 UIC           0 :         ereport(ERROR,
    9495                 :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9496                 :                 errmsg("division by zero"));
    9497                 : 
    9498                 :     /* Result zero check */
    9499 GIC       96609 :     if (var_ndigits == 0)
    9500                 :     {
    9501            1141 :         zero_var(result);
    9502            1141 :         result->dscale = rscale;
    9503            1141 :         return;
    9504                 :     }
    9505                 : 
    9506                 :     /*
    9507                 :      * Determine the result sign, weight and number of digits to calculate.
    9508                 :      * The weight figured here is correct if the emitted quotient has no
    9509                 :      * leading zero digits; otherwise strip_var() will fix things up.
    9510                 :      */
    9511           95468 :     if (var->sign == NUMERIC_POS)
    9512           94055 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9513                 :     else
    9514            1413 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9515 CBC       95468 :     res_weight = var->weight - ival_weight;
    9516                 :     /* The number of accurate result digits we need to produce: */
    9517 GIC       95468 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9518                 :     /* ... but always at least 1 */
    9519           95468 :     res_ndigits = Max(res_ndigits, 1);
    9520                 :     /* If rounding needed, figure one more digit to ensure correct result */
    9521           95468 :     if (round)
    9522           68459 :         res_ndigits++;
    9523                 : 
    9524           95468 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9525           95468 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9526           95468 :     res_digits = res_buf + 1;
    9527                 : 
    9528                 :     /*
    9529                 :      * Now compute the quotient digits.  This is the short division algorithm
    9530                 :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9531                 :      * allow the divisor to exceed the internal base.
    9532                 :      *
    9533                 :      * In this algorithm, the carry from one digit to the next is at most
    9534                 :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9535                 :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9536 ECB             :      * integer if this exceeds UINT_MAX.
    9537                 :      */
    9538 GNC       95468 :     divisor = abs(ival);
    9539 ECB             : 
    9540 GIC       95468 :     if (divisor <= UINT_MAX / NBASE)
    9541                 :     {
    9542                 :         /* carry cannot overflow 32 bits */
    9543           94217 :         uint32      carry = 0;
    9544                 : 
    9545 CBC      945778 :         for (i = 0; i < res_ndigits; i++)
    9546 ECB             :         {
    9547 GIC      851561 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9548          851561 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9549          851561 :             carry = carry % divisor;
    9550                 :         }
    9551                 :     }
    9552                 :     else
    9553                 :     {
    9554                 :         /* carry may exceed 32 bits */
    9555            1251 :         uint64      carry = 0;
    9556                 : 
    9557 CBC        4086 :         for (i = 0; i < res_ndigits; i++)
    9558                 :         {
    9559 GIC        2835 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9560            2835 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9561            2835 :             carry = carry % divisor;
    9562 ECB             :         }
    9563                 :     }
    9564                 : 
    9565                 :     /* Store the quotient in result */
    9566 GBC       95468 :     digitbuf_free(result->buf);
    9567           95468 :     result->ndigits = res_ndigits;
    9568 GIC       95468 :     result->buf = res_buf;
    9569 CBC       95468 :     result->digits = res_digits;
    9570 GBC       95468 :     result->weight = res_weight;
    9571 GIC       95468 :     result->sign = res_sign;
    9572 ECB             : 
    9573                 :     /* Round or truncate to target rscale (and set result->dscale) */
    9574 GIC       95468 :     if (round)
    9575           68459 :         round_var(result, rscale);
    9576 ECB             :     else
    9577 GIC       27009 :         trunc_var(result, rscale);
    9578                 : 
    9579                 :     /* Strip leading/trailing zeroes */
    9580           95468 :     strip_var(result);
    9581 ECB             : }
    9582                 : 
    9583                 : 
    9584                 : #ifdef HAVE_INT128
    9585                 : /*
    9586                 :  * div_var_int64() -
    9587                 :  *
    9588                 :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
    9589                 :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9590                 :  *
    9591                 :  *  This duplicates the logic in div_var_int(), so any changes made there
    9592                 :  *  should be made here too.
    9593                 :  */
    9594                 : static void
    9595 GNC         264 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
    9596                 :               NumericVar *result, int rscale, bool round)
    9597                 : {
    9598             264 :     NumericDigit *var_digits = var->digits;
    9599             264 :     int         var_ndigits = var->ndigits;
    9600                 :     int         res_sign;
    9601                 :     int         res_weight;
    9602                 :     int         res_ndigits;
    9603                 :     NumericDigit *res_buf;
    9604                 :     NumericDigit *res_digits;
    9605                 :     uint64      divisor;
    9606                 :     int         i;
    9607                 : 
    9608                 :     /* Guard against division by zero */
    9609             264 :     if (ival == 0)
    9610 UNC           0 :         ereport(ERROR,
    9611                 :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9612                 :                 errmsg("division by zero"));
    9613                 : 
    9614                 :     /* Result zero check */
    9615 GNC         264 :     if (var_ndigits == 0)
    9616                 :     {
    9617              48 :         zero_var(result);
    9618              48 :         result->dscale = rscale;
    9619              48 :         return;
    9620                 :     }
    9621                 : 
    9622                 :     /*
    9623                 :      * Determine the result sign, weight and number of digits to calculate.
    9624                 :      * The weight figured here is correct if the emitted quotient has no
    9625                 :      * leading zero digits; otherwise strip_var() will fix things up.
    9626                 :      */
    9627             216 :     if (var->sign == NUMERIC_POS)
    9628             129 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9629                 :     else
    9630              87 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9631             216 :     res_weight = var->weight - ival_weight;
    9632                 :     /* The number of accurate result digits we need to produce: */
    9633             216 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9634                 :     /* ... but always at least 1 */
    9635             216 :     res_ndigits = Max(res_ndigits, 1);
    9636                 :     /* If rounding needed, figure one more digit to ensure correct result */
    9637             216 :     if (round)
    9638             216 :         res_ndigits++;
    9639                 : 
    9640             216 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9641             216 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9642             216 :     res_digits = res_buf + 1;
    9643                 : 
    9644                 :     /*
    9645                 :      * Now compute the quotient digits.  This is the short division algorithm
    9646                 :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9647                 :      * allow the divisor to exceed the internal base.
    9648                 :      *
    9649                 :      * In this algorithm, the carry from one digit to the next is at most
    9650                 :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9651                 :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
    9652                 :      * integer if this exceeds PG_UINT64_MAX.
    9653                 :      */
    9654             216 :     divisor = i64abs(ival);
    9655                 : 
    9656             216 :     if (divisor <= PG_UINT64_MAX / NBASE)
    9657                 :     {
    9658                 :         /* carry cannot overflow 64 bits */
    9659             168 :         uint64      carry = 0;
    9660                 : 
    9661            1721 :         for (i = 0; i < res_ndigits; i++)
    9662                 :         {
    9663            1553 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9664            1553 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9665            1553 :             carry = carry % divisor;
    9666                 :         }
    9667                 :     }
    9668                 :     else
    9669                 :     {
    9670                 :         /* carry may exceed 64 bits */
    9671              48 :         uint128     carry = 0;
    9672                 : 
    9673             516 :         for (i = 0; i < res_ndigits; i++)
    9674                 :         {
    9675             468 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9676             468 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9677             468 :             carry = carry % divisor;
    9678                 :         }
    9679                 :     }
    9680                 : 
    9681                 :     /* Store the quotient in result */
    9682             216 :     digitbuf_free(result->buf);
    9683             216 :     result->ndigits = res_ndigits;
    9684             216 :     result->buf = res_buf;
    9685             216 :     result->digits = res_digits;
    9686             216 :     result->weight = res_weight;
    9687             216 :     result->sign = res_sign;
    9688                 : 
    9689                 :     /* Round or truncate to target rscale (and set result->dscale) */
    9690             216 :     if (round)
    9691             216 :         round_var(result, rscale);
    9692                 :     else
    9693 UNC           0 :         trunc_var(result, rscale);
    9694                 : 
    9695                 :     /* Strip leading/trailing zeroes */
    9696 GNC         216 :     strip_var(result);
    9697                 : }
    9698                 : #endif
    9699                 : 
    9700                 : 
    9701                 : /*
    9702 ECB             :  * Default scale selection for division
    9703                 :  *
    9704                 :  * Returns the appropriate result scale for the division result.
    9705                 :  */
    9706 EUB             : static int
    9707 GIC       61415 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
    9708 ECB             : {
    9709                 :     int         weight1,
    9710                 :                 weight2,
    9711                 :                 qweight,
    9712                 :                 i;
    9713                 :     NumericDigit firstdigit1,
    9714                 :                 firstdigit2;
    9715                 :     int         rscale;
    9716                 : 
    9717                 :     /*
    9718                 :      * The result scale of a division isn't specified in any SQL standard. For
    9719                 :      * PostgreSQL we select a result scale that will give at least
    9720                 :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
    9721                 :      * result no less accurate than float8; but use a scale not less than
    9722                 :      * either input's display scale.
    9723                 :      */
    9724                 : 
    9725                 :     /* Get the actual (normalized) weight and first digit of each input */
    9726                 : 
    9727 GIC       61415 :     weight1 = 0;                /* values to use if var1 is zero */
    9728 CBC       61415 :     firstdigit1 = 0;
    9729           61415 :     for (i = 0; i < var1->ndigits; i++)
    9730                 :     {
    9731           60559 :         firstdigit1 = var1->digits[i];
    9732           60559 :         if (firstdigit1 != 0)
    9733                 :         {
    9734           60559 :             weight1 = var1->weight - i;
    9735 GIC       60559 :             break;
    9736 ECB             :         }
    9737                 :     }
    9738 EUB             : 
    9739 GIC       61415 :     weight2 = 0;                /* values to use if var2 is zero */
    9740           61415 :     firstdigit2 = 0;
    9741           61415 :     for (i = 0; i < var2->ndigits; i++)
    9742                 :     {
    9743           61390 :         firstdigit2 = var2->digits[i];
    9744           61390 :         if (firstdigit2 != 0)
    9745                 :         {
    9746           61390 :             weight2 = var2->weight - i;
    9747           61390 :             break;
    9748                 :         }
    9749                 :     }
    9750                 : 
    9751                 :     /*
    9752                 :      * Estimate weight of quotient.  If the two first digits are equal, we
    9753                 :      * can't be sure, but assume that var1 is less than var2.
    9754                 :      */
    9755           61415 :     qweight = weight1 - weight2;
    9756           61415 :     if (firstdigit1 <= firstdigit2)
    9757           55625 :         qweight--;
    9758 ECB             : 
    9759                 :     /* Select result scale */
    9760 CBC       61415 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
    9761           61415 :     rscale = Max(rscale, var1->dscale);
    9762 GIC       61415 :     rscale = Max(rscale, var2->dscale);
    9763           61415 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    9764           61415 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    9765                 : 
    9766           61415 :     return rscale;
    9767                 : }
    9768                 : 
    9769 ECB             : 
    9770                 : /*
    9771                 :  * mod_var() -
    9772                 :  *
    9773                 :  *  Calculate the modulo of two numerics at variable level
    9774                 :  */
    9775                 : static void
    9776 CBC       26484 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9777                 : {
    9778                 :     NumericVar  tmp;
    9779                 : 
    9780 GIC       26484 :     init_var(&tmp);
    9781                 : 
    9782                 :     /* ---------
    9783                 :      * We do this using the equation
    9784                 :      *      mod(x,y) = x - trunc(x/y)*y
    9785                 :      * div_var can be persuaded to give us trunc(x/y) directly.
    9786                 :      * ----------
    9787                 :      */
    9788           26484 :     div_var(var1, var2, &tmp, 0, false);
    9789                 : 
    9790           26478 :     mul_var(var2, &tmp, &tmp, var2->dscale);
    9791                 : 
    9792           26478 :     sub_var(var1, &tmp, result);
    9793                 : 
    9794           26478 :     free_var(&tmp);
    9795 CBC       26478 : }
    9796                 : 
    9797                 : 
    9798                 : /*
    9799                 :  * div_mod_var() -
    9800 ECB             :  *
    9801                 :  *  Calculate the truncated integer quotient and numeric remainder of two
    9802                 :  *  numeric variables.  The remainder is precise to var2's dscale.
    9803                 :  */
    9804                 : static void
    9805 GIC        2259 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
    9806 ECB             :             NumericVar *quot, NumericVar *rem)
    9807                 : {
    9808                 :     NumericVar  q;
    9809                 :     NumericVar  r;
    9810                 : 
    9811 CBC        2259 :     init_var(&q);
    9812            2259 :     init_var(&r);
    9813 ECB             : 
    9814                 :     /*
    9815                 :      * Use div_var_fast() to get an initial estimate for the integer quotient.
    9816                 :      * This might be inaccurate (per the warning in div_var_fast's comments),
    9817                 :      * but we can correct it below.
    9818                 :      */
    9819 CBC        2259 :     div_var_fast(var1, var2, &q, 0, false);
    9820                 : 
    9821                 :     /* Compute initial estimate of remainder using the quotient estimate. */
    9822 GIC        2259 :     mul_var(var2, &q, &r, var2->dscale);
    9823            2259 :     sub_var(var1, &r, &r);
    9824                 : 
    9825                 :     /*
    9826                 :      * Adjust the results if necessary --- the remainder should have the same
    9827                 :      * sign as var1, and its absolute value should be less than the absolute
    9828 ECB             :      * value of var2.
    9829                 :      */
    9830 GIC        2259 :     while (r.ndigits != 0 && r.sign != var1->sign)
    9831 ECB             :     {
    9832                 :         /* The absolute value of the quotient is too large */
    9833 UIC           0 :         if (var1->sign == var2->sign)
    9834 ECB             :         {
    9835 LBC           0 :             sub_var(&q, &const_one, &q);
    9836 UIC           0 :             add_var(&r, var2, &r);
    9837 EUB             :         }
    9838                 :         else
    9839                 :         {
    9840 UBC           0 :             add_var(&q, &const_one, &q);
    9841 UIC           0 :             sub_var(&r, var2, &r);
    9842                 :         }
    9843 EUB             :     }
    9844 ECB             : 
    9845 GIC        2259 :     while (cmp_abs(&r, var2) >= 0)
    9846 ECB             :     {
    9847                 :         /* The absolute value of the quotient is too small */
    9848 UIC           0 :         if (var1->sign == var2->sign)
    9849                 :         {
    9850               0 :             add_var(&q, &const_one, &q);
    9851               0 :             sub_var(&r, var2, &r);
    9852                 :         }
    9853                 :         else
    9854 ECB             :         {
    9855 UIC           0 :             sub_var(&q, &const_one, &q);
    9856               0 :             add_var(&r, var2, &r);
    9857                 :         }
    9858                 :     }
    9859                 : 
    9860 CBC        2259 :     set_var_from_var(&q, quot);
    9861            2259 :     set_var_from_var(&r, rem);
    9862                 : 
    9863            2259 :     free_var(&q);
    9864            2259 :     free_var(&r);
    9865            2259 : }
    9866                 : 
    9867                 : 
    9868 ECB             : /*
    9869                 :  * ceil_var() -
    9870 EUB             :  *
    9871 ECB             :  *  Return the smallest integer greater than or equal to the argument
    9872                 :  *  on variable level
    9873                 :  */
    9874                 : static void
    9875 GIC         102 : ceil_var(const NumericVar *var, NumericVar *result)
    9876                 : {
    9877                 :     NumericVar  tmp;
    9878                 : 
    9879             102 :     init_var(&tmp);
    9880             102 :     set_var_from_var(var, &tmp);
    9881                 : 
    9882             102 :     trunc_var(&tmp, 0);
    9883                 : 
    9884             102 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
    9885              30 :         add_var(&tmp, &const_one, &tmp);
    9886                 : 
    9887             102 :     set_var_from_var(&tmp, result);
    9888             102 :     free_var(&tmp);
    9889             102 : }
    9890                 : 
    9891                 : 
    9892 ECB             : /*
    9893                 :  * floor_var() -
    9894                 :  *
    9895                 :  *  Return the largest integer equal to or less than the argument
    9896                 :  *  on variable level
    9897                 :  */
    9898                 : static void
    9899 GIC         288 : floor_var(const NumericVar *var, NumericVar *result)
    9900                 : {
    9901                 :     NumericVar  tmp;
    9902                 : 
    9903             288 :     init_var(&tmp);
    9904             288 :     set_var_from_var(var, &tmp);
    9905                 : 
    9906             288 :     trunc_var(&tmp, 0);
    9907                 : 
    9908             288 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
    9909              15 :         sub_var(&tmp, &const_one, &tmp);
    9910                 : 
    9911             288 :     set_var_from_var(&tmp, result);
    9912             288 :     free_var(&tmp);
    9913             288 : }
    9914                 : 
    9915                 : 
    9916                 : /*
    9917                 :  * gcd_var() -
    9918                 :  *
    9919                 :  *  Calculate the greatest common divisor of two numerics at variable level
    9920                 :  */
    9921                 : static void
    9922             111 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9923                 : {
    9924 ECB             :     int         res_dscale;
    9925                 :     int         cmp;
    9926                 :     NumericVar  tmp_arg;
    9927                 :     NumericVar  mod;
    9928                 : 
    9929 GIC         111 :     res_dscale = Max(var1->dscale, var2->dscale);
    9930                 : 
    9931                 :     /*
    9932 ECB             :      * Arrange for var1 to be the number with the greater absolute value.
    9933                 :      *
    9934                 :      * This would happen automatically in the loop below, but avoids an
    9935                 :      * expensive modulo operation.
    9936                 :      */
    9937 GBC         111 :     cmp = cmp_abs(var1, var2);
    9938 CBC         111 :     if (cmp < 0)
    9939                 :     {
    9940 GIC          42 :         const NumericVar *tmp = var1;
    9941                 : 
    9942              42 :         var1 = var2;
    9943              42 :         var2 = tmp;
    9944                 :     }
    9945                 : 
    9946                 :     /*
    9947                 :      * Also avoid the taking the modulo if the inputs have the same absolute
    9948 ECB             :      * value, or if the smaller input is zero.
    9949                 :      */
    9950 CBC         111 :     if (cmp == 0 || var2->ndigits == 0)
    9951 ECB             :     {
    9952 GIC          36 :         set_var_from_var(var1, result);
    9953 CBC          36 :         result->sign = NUMERIC_POS;
    9954              36 :         result->dscale = res_dscale;
    9955 GIC          36 :         return;
    9956 ECB             :     }
    9957                 : 
    9958 GIC          75 :     init_var(&tmp_arg);
    9959 CBC          75 :     init_var(&mod);
    9960                 : 
    9961 ECB             :     /* Use the Euclidean algorithm to find the GCD */
    9962 CBC          75 :     set_var_from_var(var1, &tmp_arg);
    9963 GIC          75 :     set_var_from_var(var2, result);
    9964                 : 
    9965 ECB             :     for (;;)
    9966                 :     {
    9967                 :         /* this loop can take a while, so allow it to be interrupted */
    9968 CBC         294 :         CHECK_FOR_INTERRUPTS();
    9969                 : 
    9970             294 :         mod_var(&tmp_arg, result, &mod);
    9971 GIC         294 :         if (mod.ndigits == 0)
    9972              75 :             break;
    9973             219 :         set_var_from_var(result, &tmp_arg);
    9974             219 :         set_var_from_var(&mod, result);
    9975 ECB             :     }
    9976 CBC          75 :     result->sign = NUMERIC_POS;
    9977 GIC          75 :     result->dscale = res_dscale;
    9978                 : 
    9979 CBC          75 :     free_var(&tmp_arg);
    9980              75 :     free_var(&mod);
    9981                 : }
    9982 ECB             : 
    9983                 : 
    9984                 : /*
    9985                 :  * sqrt_var() -
    9986                 :  *
    9987                 :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
    9988                 :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
    9989                 :  *  point.
    9990                 :  */
    9991                 : static void
    9992 GIC        2097 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
    9993                 : {
    9994                 :     int         stat;
    9995                 :     int         res_weight;
    9996 ECB             :     int         res_ndigits;
    9997                 :     int         src_ndigits;
    9998                 :     int         step;
    9999                 :     int         ndigits[32];
   10000                 :     int         blen;
   10001                 :     int64       arg_int64;
   10002                 :     int         src_idx;
   10003                 :     int64       s_int64;
   10004                 :     int64       r_int64;
   10005                 :     NumericVar  s_var;
   10006                 :     NumericVar  r_var;
   10007                 :     NumericVar  a0_var;
   10008                 :     NumericVar  a1_var;
   10009                 :     NumericVar  q_var;
   10010                 :     NumericVar  u_var;
   10011 EUB             : 
   10012 GIC        2097 :     stat = cmp_var(arg, &const_zero);
   10013            2097 :     if (stat == 0)
   10014                 :     {
   10015               9 :         zero_var(result);
   10016 CBC           9 :         result->dscale = rscale;
   10017 GIC           9 :         return;
   10018 ECB             :     }
   10019                 : 
   10020                 :     /*
   10021                 :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
   10022                 :      * SQLSTATE error code if the operand is negative.
   10023                 :      */
   10024 GIC        2088 :     if (stat < 0)
   10025               3 :         ereport(ERROR,
   10026                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10027                 :                  errmsg("cannot take square root of a negative number")));
   10028 ECB             : 
   10029 CBC        2085 :     init_var(&s_var);
   10030 GIC        2085 :     init_var(&r_var);
   10031 CBC        2085 :     init_var(&a0_var);
   10032            2085 :     init_var(&a1_var);
   10033 GIC        2085 :     init_var(&q_var);
   10034 CBC        2085 :     init_var(&u_var);
   10035                 : 
   10036 ECB             :     /*
   10037                 :      * The result weight is half the input weight, rounded towards minus
   10038                 :      * infinity --- res_weight = floor(arg->weight / 2).
   10039                 :      */
   10040 GIC        2085 :     if (arg->weight >= 0)
   10041 CBC        1929 :         res_weight = arg->weight / 2;
   10042 ECB             :     else
   10043 CBC         156 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10044                 : 
   10045                 :     /*
   10046                 :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10047                 :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10048                 :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10049                 :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10050                 :      */
   10051 GIC        2085 :     if (rscale + 1 >= 0)
   10052            2085 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10053                 :     else
   10054 UIC           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10055 CBC        2085 :     res_ndigits = Max(res_ndigits, 1);
   10056                 : 
   10057 ECB             :     /*
   10058                 :      * Number of source NBASE digits logically required to produce a result
   10059                 :      * with this precision --- every digit before the decimal point, plus 2
   10060                 :      * for each result digit after the decimal point (or minus 2 for each
   10061                 :      * result digit we round before the decimal point).
   10062                 :      */
   10063 GIC        2085 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10064 CBC        2085 :     src_ndigits = Max(src_ndigits, 1);
   10065 ECB             : 
   10066                 :     /* ----------
   10067                 :      * From this point on, we treat the input and the result as integers and
   10068                 :      * compute the integer square root and remainder using the Karatsuba
   10069                 :      * Square Root algorithm, which may be written recursively as follows:
   10070                 :      *
   10071                 :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10072                 :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10073                 :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10074                 :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10075                 :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10076                 :      *      Let s = s*b + q
   10077                 :      *      Let r = u*b + a0 - q^2
   10078                 :      *      If r < 0 Then
   10079                 :      *          Let r = r + s
   10080                 :      *          Let s = s - 1
   10081                 :      *          Let r = r + s
   10082                 :      *      Return (s,r)
   10083                 :      *
   10084                 :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10085                 :      * RR-3805, November 1999.  At the time of writing this was available
   10086                 :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10087                 :      *
   10088                 :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10089                 :      * "choose a base b such that n requires at least four base-b digits to
   10090                 :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10091                 :      * than b".  For optimal performance, b should have approximately a
   10092                 :      * quarter the number of digits in the input, so that the outer square
   10093                 :      * root computes roughly twice as many digits as the inner one.  For
   10094                 :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10095                 :      *
   10096                 :      * We implement the algorithm iteratively rather than recursively, to
   10097                 :      * allow the working variables to be reused.  With this approach, each
   10098                 :      * digit of the input is read precisely once --- src_idx tracks the number
   10099                 :      * of input digits used so far.
   10100                 :      *
   10101                 :      * The array ndigits[] holds the number of NBASE digits of the input that
   10102                 :      * will have been used at the end of each iteration, which roughly doubles
   10103                 :      * each time.  Note that the array elements are stored in reverse order,
   10104                 :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10105                 :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10106                 :      * the square root of the 3 most significant NBASE digits.
   10107                 :      *
   10108                 :      * In each iteration, we choose blen to be the largest integer for which
   10109                 :      * the input number has a3 >= b/4, when written in the form above.  In
   10110                 :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10111                 :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10112                 :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10113                 :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10114                 :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10115                 :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10116                 :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10117                 :      * the first input digit.
   10118                 :      *
   10119                 :      * Additionally, we can put an upper bound on the number of steps required
   10120                 :      * as follows --- suppose that the number of source digits is an n-bit
   10121                 :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10122                 :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10123                 :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10124                 :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10125                 :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10126                 :      * This pattern repeats, and in the worst case the array ndigits[] will
   10127 EUB             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10128                 :      * will require n steps.  Therefore, since all digit array sizes are
   10129                 :      * signed 32-bit integers, the number of steps required is guaranteed to
   10130                 :      * be less than 32.
   10131                 :      * ----------
   10132 ECB             :      */
   10133 GIC        2085 :     step = 0;
   10134 CBC        9981 :     while ((ndigits[step] = src_ndigits) > 4)
   10135 ECB             :     {
   10136                 :         /* Choose b so that a3 >= b/4, as described above */
   10137 GIC        7896 :         blen = src_ndigits / 4;
   10138            7896 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10139             162 :             blen--;
   10140                 : 
   10141                 :         /* Number of digits in the next step (inner square root) */
   10142            7896 :         src_ndigits -= 2 * blen;
   10143            7896 :         step++;
   10144 ECB             :     }
   10145                 : 
   10146                 :     /*
   10147                 :      * First iteration (innermost square root and remainder):
   10148                 :      *
   10149                 :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10150                 :      * has at most 9 decimal digits, so estimate it using double precision
   10151                 :      * arithmetic, which will in fact almost certainly return the correct
   10152                 :      * result with no further correction required.
   10153                 :      */
   10154 CBC        2085 :     arg_int64 = arg->digits[0];
   10155            6657 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10156                 :     {
   10157            4572 :         arg_int64 *= NBASE;
   10158            4572 :         if (src_idx < arg->ndigits)
   10159            3843 :             arg_int64 += arg->digits[src_idx];
   10160                 :     }
   10161                 : 
   10162 GIC        2085 :     s_int64 = (int64) sqrt((double) arg_int64);
   10163            2085 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10164                 : 
   10165                 :     /*
   10166                 :      * Use Newton's method to correct the result, if necessary.
   10167                 :      *
   10168                 :      * This uses integer division with truncation to compute the truncated
   10169                 :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10170                 :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10171 ECB             :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10172                 :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10173                 :      * checking the remainder.
   10174                 :      */
   10175 GIC        2085 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10176 ECB             :     {
   10177 UIC           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10178 LBC           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10179                 :     }
   10180 ECB             : 
   10181                 :     /*
   10182                 :      * Iterations with src_ndigits <= 8:
   10183                 :      *
   10184                 :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10185                 :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10186                 :      * input no longer does) and we can continue to compute using int64
   10187                 :      * variables to avoid more expensive numeric computations.
   10188                 :      *
   10189                 :      * It is fairly easy to see that there is no risk of the intermediate
   10190                 :      * values below overflowing 64-bit integers.  In the worst case, the
   10191                 :      * previous iteration will have computed a 3-digit square root (of a
   10192                 :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10193                 :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10194                 :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10195                 :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10196                 :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10197                 :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10198                 :      * in 64-bit integers.
   10199                 :      */
   10200 CBC        2085 :     step--;
   10201            5283 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10202 ECB             :     {
   10203                 :         int         b;
   10204                 :         int         a0;
   10205                 :         int         a1;
   10206                 :         int         i;
   10207                 :         int64       numer;
   10208                 :         int64       denom;
   10209                 :         int64       q;
   10210 EUB             :         int64       u;
   10211                 : 
   10212 GIC        3198 :         blen = (src_ndigits - src_idx) / 2;
   10213 ECB             : 
   10214                 :         /* Extract a1 and a0, and compute b */
   10215 GIC        3198 :         a0 = 0;
   10216            3198 :         a1 = 0;
   10217            3198 :         b = 1;
   10218                 : 
   10219            6468 :         for (i = 0; i < blen; i++, src_idx++)
   10220                 :         {
   10221            3270 :             b *= NBASE;
   10222            3270 :             a1 *= NBASE;
   10223            3270 :             if (src_idx < arg->ndigits)
   10224 CBC        2400 :                 a1 += arg->digits[src_idx];
   10225                 :         }
   10226                 : 
   10227 GIC        6468 :         for (i = 0; i < blen; i++, src_idx++)
   10228                 :         {
   10229            3270 :             a0 *= NBASE;
   10230            3270 :             if (src_idx < arg->ndigits)
   10231            2322 :                 a0 += arg->digits[src_idx];
   10232                 :         }
   10233                 : 
   10234                 :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10235            3198 :         numer = r_int64 * b + a1;
   10236            3198 :         denom = 2 * s_int64;
   10237            3198 :         q = numer / denom;
   10238            3198 :         u = numer - q * denom;
   10239                 : 
   10240                 :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10241            3198 :         s_int64 = s_int64 * b + q;
   10242            3198 :         r_int64 = u * b + a0 - q * q;
   10243                 : 
   10244 CBC        3198 :         if (r_int64 < 0)
   10245 ECB             :         {
   10246                 :             /* s is too large by 1; set r += s, s--, r += s */
   10247 GIC         105 :             r_int64 += s_int64;
   10248 CBC         105 :             s_int64--;
   10249             105 :             r_int64 += s_int64;
   10250                 :         }
   10251 ECB             : 
   10252 CBC        3198 :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10253 GIC        3198 :         step--;
   10254                 :     }
   10255                 : 
   10256 ECB             :     /*
   10257                 :      * On platforms with 128-bit integer support, we can further delay the
   10258                 :      * need to use numeric variables.
   10259                 :      */
   10260                 : #ifdef HAVE_INT128
   10261 CBC        2085 :     if (step >= 0)
   10262                 :     {
   10263 ECB             :         int128      s_int128;
   10264                 :         int128      r_int128;
   10265                 : 
   10266 GIC        2085 :         s_int128 = s_int64;
   10267            2085 :         r_int128 = r_int64;
   10268                 : 
   10269                 :         /*
   10270                 :          * Iterations with src_ndigits <= 16:
   10271                 :          *
   10272 ECB             :          * The result fits in an int128 (even though the input doesn't) so we
   10273                 :          * use int128 variables to avoid more expensive numeric computations.
   10274                 :          */
   10275 GIC        4524 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10276                 :         {
   10277 ECB             :             int64       b;
   10278                 :             int64       a0;
   10279                 :             int64       a1;
   10280                 :             int64       i;
   10281                 :             int128      numer;
   10282                 :             int128      denom;
   10283                 :             int128      q;
   10284                 :             int128      u;
   10285                 : 
   10286 GIC        2439 :             blen = (src_ndigits - src_idx) / 2;
   10287                 : 
   10288                 :             /* Extract a1 and a0, and compute b */
   10289            2439 :             a0 = 0;
   10290            2439 :             a1 = 0;
   10291            2439 :             b = 1;
   10292                 : 
   10293 CBC        8040 :             for (i = 0; i < blen; i++, src_idx++)
   10294                 :             {
   10295 GIC        5601 :                 b *= NBASE;
   10296            5601 :                 a1 *= NBASE;
   10297 CBC        5601 :                 if (src_idx < arg->ndigits)
   10298 GIC        3303 :                     a1 += arg->digits[src_idx];
   10299                 :             }
   10300                 : 
   10301            8040 :             for (i = 0; i < blen; i++, src_idx++)
   10302                 :             {
   10303            5601 :                 a0 *= NBASE;
   10304            5601 :                 if (src_idx < arg->ndigits)
   10305 CBC        2235 :                     a0 += arg->digits[src_idx];
   10306                 :             }
   10307 ECB             : 
   10308                 :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10309 CBC        2439 :             numer = r_int128 * b + a1;
   10310 GIC        2439 :             denom = 2 * s_int128;
   10311 CBC        2439 :             q = numer / denom;
   10312            2439 :             u = numer - q * denom;
   10313                 : 
   10314                 :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10315 GIC        2439 :             s_int128 = s_int128 * b + q;
   10316            2439 :             r_int128 = u * b + a0 - q * q;
   10317                 : 
   10318            2439 :             if (r_int128 < 0)
   10319                 :             {
   10320                 :                 /* s is too large by 1; set r += s, s--, r += s */
   10321              96 :                 r_int128 += s_int128;
   10322 CBC          96 :                 s_int128--;
   10323 GIC          96 :                 r_int128 += s_int128;
   10324                 :             }
   10325                 : 
   10326            2439 :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10327            2439 :             step--;
   10328 ECB             :         }
   10329                 : 
   10330                 :         /*
   10331                 :          * All remaining iterations require numeric variables.  Convert the
   10332                 :          * integer values to NumericVar and continue.  Note that in the final
   10333                 :          * iteration we don't need the remainder, so we can save a few cycles
   10334                 :          * there by not fully computing it.
   10335                 :          */
   10336 CBC        2085 :         int128_to_numericvar(s_int128, &s_var);
   10337 GIC        2085 :         if (step >= 0)
   10338            1362 :             int128_to_numericvar(r_int128, &r_var);
   10339 ECB             :     }
   10340                 :     else
   10341                 :     {
   10342 UIC           0 :         int64_to_numericvar(s_int64, &s_var);
   10343                 :         /* step < 0, so we certainly don't need r */
   10344                 :     }
   10345                 : #else                           /* !HAVE_INT128 */
   10346                 :     int64_to_numericvar(s_int64, &s_var);
   10347 ECB             :     if (step >= 0)
   10348                 :         int64_to_numericvar(r_int64, &r_var);
   10349                 : #endif                          /* HAVE_INT128 */
   10350 EUB             : 
   10351                 :     /*
   10352                 :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10353                 :      * use numeric variables.
   10354                 :      */
   10355 GIC        4344 :     while (step >= 0)
   10356                 :     {
   10357 EUB             :         int         tmp_len;
   10358                 : 
   10359 GIC        2259 :         src_ndigits = ndigits[step];
   10360            2259 :         blen = (src_ndigits - src_idx) / 2;
   10361                 : 
   10362 ECB             :         /* Extract a1 and a0 */
   10363 GIC        2259 :         if (src_idx < arg->ndigits)
   10364                 :         {
   10365 GBC         756 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10366 GIC         756 :             alloc_var(&a1_var, tmp_len);
   10367 GBC         756 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10368 EUB             :                    tmp_len * sizeof(NumericDigit));
   10369 GIC         756 :             a1_var.weight = blen - 1;
   10370             756 :             a1_var.sign = NUMERIC_POS;
   10371             756 :             a1_var.dscale = 0;
   10372 GBC         756 :             strip_var(&a1_var);
   10373 EUB             :         }
   10374                 :         else
   10375                 :         {
   10376 GIC        1503 :             zero_var(&a1_var);
   10377 CBC        1503 :             a1_var.dscale = 0;
   10378 ECB             :         }
   10379 GIC        2259 :         src_idx += blen;
   10380 ECB             : 
   10381 CBC        2259 :         if (src_idx < arg->ndigits)
   10382 ECB             :         {
   10383 GIC         756 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10384             756 :             alloc_var(&a0_var, tmp_len);
   10385             756 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10386                 :                    tmp_len * sizeof(NumericDigit));
   10387             756 :             a0_var.weight = blen - 1;
   10388             756 :             a0_var.sign = NUMERIC_POS;
   10389             756 :             a0_var.dscale = 0;
   10390             756 :             strip_var(&a0_var);
   10391                 :         }
   10392 ECB             :         else
   10393                 :         {
   10394 GIC        1503 :             zero_var(&a0_var);
   10395            1503 :             a0_var.dscale = 0;
   10396 ECB             :         }
   10397 CBC        2259 :         src_idx += blen;
   10398                 : 
   10399 ECB             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10400 GIC        2259 :         set_var_from_var(&r_var, &q_var);
   10401 CBC        2259 :         q_var.weight += blen;
   10402            2259 :         add_var(&q_var, &a1_var, &q_var);
   10403 GIC        2259 :         add_var(&s_var, &s_var, &u_var);
   10404 CBC        2259 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10405 ECB             : 
   10406                 :         /* Compute s = s*b + q */
   10407 GIC        2259 :         s_var.weight += blen;
   10408            2259 :         add_var(&s_var, &q_var, &s_var);
   10409                 : 
   10410                 :         /*
   10411                 :          * Compute r = u*b + a0 - q^2.
   10412                 :          *
   10413                 :          * In the final iteration, we don't actually need r; we just need to
   10414                 :          * know whether it is negative, so that we know whether to adjust s.
   10415                 :          * So instead of the final subtraction we can just compare.
   10416 ECB             :          */
   10417 GIC        2259 :         u_var.weight += blen;
   10418            2259 :         add_var(&u_var, &a0_var, &u_var);
   10419            2259 :         mul_var(&q_var, &q_var, &q_var, 0);
   10420 ECB             : 
   10421 CBC        2259 :         if (step > 0)
   10422                 :         {
   10423 ECB             :             /* Need r for later iterations */
   10424 GIC         897 :             sub_var(&u_var, &q_var, &r_var);
   10425 CBC         897 :             if (r_var.sign == NUMERIC_NEG)
   10426 ECB             :             {
   10427                 :                 /* s is too large by 1; set r += s, s--, r += s */
   10428 CBC          60 :                 add_var(&r_var, &s_var, &r_var);
   10429              60 :                 sub_var(&s_var, &const_one, &s_var);
   10430              60 :                 add_var(&r_var, &s_var, &r_var);
   10431                 :             }
   10432                 :         }
   10433                 :         else
   10434                 :         {
   10435                 :             /* Don't need r anymore, except to test if s is too large by 1 */
   10436 GIC        1362 :             if (cmp_var(&u_var, &q_var) < 0)
   10437              18 :                 sub_var(&s_var, &const_one, &s_var);
   10438                 :         }
   10439 ECB             : 
   10440 GIC        2259 :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10441            2259 :         step--;
   10442                 :     }
   10443                 : 
   10444                 :     /*
   10445                 :      * Construct the final result, rounding it to the requested precision.
   10446 ECB             :      */
   10447 GIC        2085 :     set_var_from_var(&s_var, result);
   10448            2085 :     result->weight = res_weight;
   10449            2085 :     result->sign = NUMERIC_POS;
   10450                 : 
   10451                 :     /* Round to target rscale (and set result->dscale) */
   10452            2085 :     round_var(result, rscale);
   10453                 : 
   10454 ECB             :     /* Strip leading and trailing zeroes */
   10455 CBC        2085 :     strip_var(result);
   10456                 : 
   10457            2085 :     free_var(&s_var);
   10458 GIC        2085 :     free_var(&r_var);
   10459 CBC        2085 :     free_var(&a0_var);
   10460            2085 :     free_var(&a1_var);
   10461 GIC        2085 :     free_var(&q_var);
   10462            2085 :     free_var(&u_var);
   10463                 : }
   10464                 : 
   10465                 : 
   10466                 : /*
   10467 ECB             :  * exp_var() -
   10468                 :  *
   10469                 :  *  Raise e to the power of x, computed to rscale fractional digits
   10470                 :  */
   10471                 : static void
   10472 CBC          90 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10473                 : {
   10474                 :     NumericVar  x;
   10475 ECB             :     NumericVar  elem;
   10476                 :     int         ni;
   10477                 :     double      val;
   10478                 :     int         dweight;
   10479                 :     int         ndiv2;
   10480                 :     int         sig_digits;
   10481                 :     int         local_rscale;
   10482                 : 
   10483 GIC          90 :     init_var(&x);
   10484              90 :     init_var(&elem);
   10485 ECB             : 
   10486 GIC          90 :     set_var_from_var(arg, &x);
   10487 ECB             : 
   10488                 :     /*
   10489                 :      * Estimate the dweight of the result using floating point arithmetic, so
   10490                 :      * that we can choose an appropriate local rscale for the calculation.
   10491                 :      */
   10492 GIC          90 :     val = numericvar_to_double_no_overflow(&x);
   10493 ECB             : 
   10494                 :     /* Guard against overflow/underflow */
   10495                 :     /* If you change this limit, see also power_var()'s limit */
   10496 GNC          90 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10497 ECB             :     {
   10498 GIC           3 :         if (val > 0)
   10499 UIC           0 :             ereport(ERROR,
   10500                 :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10501                 :                      errmsg("value overflows numeric format")));
   10502 GIC           3 :         zero_var(result);
   10503               3 :         result->dscale = rscale;
   10504               3 :         return;
   10505                 :     }
   10506                 : 
   10507                 :     /* decimal weight = log10(e^x) = x * log10(e) */
   10508              87 :     dweight = (int) (val * 0.434294481903252);
   10509 ECB             : 
   10510                 :     /*
   10511                 :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10512                 :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10513                 :      *
   10514                 :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10515                 :      * means that ndiv2 <= 20 here.
   10516                 :      */
   10517 GNC          87 :     if (fabs(val) > 0.01)
   10518                 :     {
   10519 GIC          72 :         ndiv2 = 1;
   10520              72 :         val /= 2;
   10521                 : 
   10522 GNC         909 :         while (fabs(val) > 0.01)
   10523                 :         {
   10524 GIC         837 :             ndiv2++;
   10525             837 :             val /= 2;
   10526                 :         }
   10527                 : 
   10528              72 :         local_rscale = x.dscale + ndiv2;
   10529 CBC          72 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10530 ECB             :     }
   10531                 :     else
   10532 CBC          15 :         ndiv2 = 0;
   10533 ECB             : 
   10534                 :     /*
   10535                 :      * Set the scale for the Taylor series expansion.  The final result has
   10536                 :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10537                 :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10538                 :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10539                 :      * extra digits of precision (plus a few more for good measure).
   10540                 :      */
   10541 CBC          87 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10542              87 :     sig_digits = Max(sig_digits, 0) + 8;
   10543                 : 
   10544 GIC          87 :     local_rscale = sig_digits - 1;
   10545                 : 
   10546 ECB             :     /*
   10547                 :      * Use the Taylor series
   10548                 :      *
   10549                 :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10550                 :      *
   10551                 :      * Given the limited range of x, this should converge reasonably quickly.
   10552                 :      * We run the series until the terms fall below the local_rscale limit.
   10553                 :      */
   10554 GIC          87 :     add_var(&const_one, &x, result);
   10555                 : 
   10556              87 :     mul_var(&x, &x, &elem, local_rscale);
   10557 CBC          87 :     ni = 2;
   10558              87 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10559                 : 
   10560            2496 :     while (elem.ndigits != 0)
   10561                 :     {
   10562 GIC        2409 :         add_var(result, &elem, result);
   10563                 : 
   10564            2409 :         mul_var(&elem, &x, &elem, local_rscale);
   10565            2409 :         ni++;
   10566            2409 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10567                 :     }
   10568 ECB             : 
   10569                 :     /*
   10570                 :      * Compensate for the argument range reduction.  Since the weight of the
   10571 EUB             :      * result doubles with each multiplication, we can reduce the local rscale
   10572 ECB             :      * as we proceed.
   10573                 :      */
   10574 GIC         996 :     while (ndiv2-- > 0)
   10575                 :     {
   10576             909 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   10577             909 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10578             909 :         mul_var(result, result, result, local_rscale);
   10579                 :     }
   10580 ECB             : 
   10581                 :     /* Round to requested rscale */
   10582 GIC          87 :     round_var(result, rscale);
   10583                 : 
   10584              87 :     free_var(&x);
   10585              87 :     free_var(&elem);
   10586                 : }
   10587                 : 
   10588                 : 
   10589                 : /*
   10590                 :  * Estimate the dweight of the most significant decimal digit of the natural
   10591                 :  * logarithm of a number.
   10592                 :  *
   10593                 :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   10594                 :  * determine the appropriate rscale when computing natural logarithms.
   10595                 :  *
   10596                 :  * Note: many callers call this before range-checking the input.  Therefore,
   10597                 :  * we must be robust against values that are invalid to apply ln() to.
   10598                 :  * We don't wish to throw an error here, so just return zero in such cases.
   10599                 :  */
   10600                 : static int
   10601             369 : estimate_ln_dweight(const NumericVar *var)
   10602                 : {
   10603                 :     int         ln_dweight;
   10604                 : 
   10605                 :     /* Caller should fail on ln(negative), but for the moment return zero */
   10606             369 :     if (var->sign != NUMERIC_POS)
   10607              21 :         return 0;
   10608                 : 
   10609             657 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   10610             309 :         cmp_var(var, &const_one_point_one) <= 0)
   10611              45 :     {
   10612                 :         /*
   10613                 :          * 0.9 <= var <= 1.1
   10614                 :          *
   10615                 :          * ln(var) has a negative weight (possibly very large).  To get a
   10616                 :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   10617                 :          */
   10618                 :         NumericVar  x;
   10619                 : 
   10620              45 :         init_var(&x);
   10621              45 :         sub_var(var, &const_one, &x);
   10622                 : 
   10623              45 :         if (x.ndigits > 0)
   10624                 :         {
   10625                 :             /* Use weight of most significant decimal digit of x */
   10626              21 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   10627                 :         }
   10628                 :         else
   10629                 :         {
   10630                 :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   10631              24 :             ln_dweight = 0;
   10632                 :         }
   10633                 : 
   10634              45 :         free_var(&x);
   10635                 :     }
   10636                 :     else
   10637                 :     {
   10638                 :         /*
   10639                 :          * Estimate the logarithm using the first couple of digits from the
   10640                 :          * input number.  This will give an accurate result whenever the input
   10641                 :          * is not too close to 1.
   10642                 :          */
   10643             303 :         if (var->ndigits > 0)
   10644                 :         {
   10645                 :             int         digits;
   10646                 :             int         dweight;
   10647                 :             double      ln_var;
   10648                 : 
   10649             282 :             digits = var->digits[0];
   10650 CBC         282 :             dweight = var->weight * DEC_DIGITS;
   10651 ECB             : 
   10652 GIC         282 :             if (var->ndigits > 1)
   10653                 :             {
   10654 CBC         171 :                 digits = digits * NBASE + var->digits[1];
   10655             171 :                 dweight -= DEC_DIGITS;
   10656 ECB             :             }
   10657                 : 
   10658                 :             /*----------
   10659                 :              * We have var ~= digits * 10^dweight
   10660                 :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   10661                 :              *----------
   10662                 :              */
   10663 GIC         282 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   10664 GNC         282 :             ln_dweight = (int) log10(fabs(ln_var));
   10665                 :         }
   10666                 :         else
   10667                 :         {
   10668                 :             /* Caller should fail on ln(0), but for the moment return zero */
   10669 GIC          21 :             ln_dweight = 0;
   10670                 :         }
   10671 ECB             :     }
   10672                 : 
   10673 GIC         348 :     return ln_dweight;
   10674 ECB             : }
   10675                 : 
   10676                 : 
   10677                 : /*
   10678                 :  * ln_var() -
   10679                 :  *
   10680                 :  *  Compute the natural log of x
   10681                 :  */
   10682                 : static void
   10683 GIC         417 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   10684                 : {
   10685                 :     NumericVar  x;
   10686                 :     NumericVar  xx;
   10687                 :     int         ni;
   10688                 :     NumericVar  elem;
   10689                 :     NumericVar  fact;
   10690                 :     int         nsqrt;
   10691                 :     int         local_rscale;
   10692 ECB             :     int         cmp;
   10693                 : 
   10694 GBC         417 :     cmp = cmp_var(arg, &const_zero);
   10695             417 :     if (cmp == 0)
   10696 GIC          21 :         ereport(ERROR,
   10697                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10698                 :                  errmsg("cannot take logarithm of zero")));
   10699             396 :     else if (cmp < 0)
   10700              18 :         ereport(ERROR,
   10701                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10702                 :                  errmsg("cannot take logarithm of a negative number")));
   10703                 : 
   10704             378 :     init_var(&x);
   10705             378 :     init_var(&xx);
   10706             378 :     init_var(&elem);
   10707             378 :     init_var(&fact);
   10708                 : 
   10709             378 :     set_var_from_var(arg, &x);
   10710             378 :     set_var_from_var(&const_two, &fact);
   10711                 : 
   10712                 :     /*
   10713                 :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   10714                 :      *
   10715                 :      * The final logarithm will have up to around rscale+6 significant digits.
   10716                 :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   10717 ECB             :      * rscale as we work so that we keep this many significant digits at each
   10718                 :      * step (plus a few more for good measure).
   10719                 :      *
   10720                 :      * Note that we allow local_rscale < 0 during this input reduction
   10721                 :      * process, which implies rounding before the decimal point.  sqrt_var()
   10722                 :      * explicitly supports this, and it significantly reduces the work
   10723                 :      * required to reduce very large inputs to the required range.  Once the
   10724                 :      * input reduction is complete, x.weight will be 0 and its display scale
   10725                 :      * will be non-negative again.
   10726                 :      */
   10727 GIC         378 :     nsqrt = 0;
   10728             534 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   10729 ECB             :     {
   10730 GIC         156 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10731             156 :         sqrt_var(&x, &x, local_rscale);
   10732 CBC         156 :         mul_var(&fact, &const_two, &fact, 0);
   10733             156 :         nsqrt++;
   10734 ECB             :     }
   10735 GIC        2064 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   10736 ECB             :     {
   10737 GIC        1686 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10738 CBC        1686 :         sqrt_var(&x, &x, local_rscale);
   10739            1686 :         mul_var(&fact, &const_two, &fact, 0);
   10740            1686 :         nsqrt++;
   10741 ECB             :     }
   10742                 : 
   10743                 :     /*
   10744                 :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   10745                 :      *
   10746                 :      * z + z^3/3 + z^5/5 + ...
   10747                 :      *
   10748                 :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   10749                 :      * due to the above range-reduction of x.
   10750                 :      *
   10751                 :      * The convergence of this is not as fast as one would like, but is
   10752                 :      * tolerable given that z is small.
   10753                 :      *
   10754                 :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   10755                 :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   10756                 :      * digits of precision (plus a few more for good measure).
   10757                 :      */
   10758 CBC         378 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   10759 ECB             : 
   10760 GIC         378 :     sub_var(&x, &const_one, result);
   10761 CBC         378 :     add_var(&x, &const_one, &elem);
   10762 GIC         378 :     div_var_fast(result, &elem, result, local_rscale, true);
   10763             378 :     set_var_from_var(result, &xx);
   10764 CBC         378 :     mul_var(result, result, &x, local_rscale);
   10765 ECB             : 
   10766 CBC         378 :     ni = 1;
   10767                 : 
   10768                 :     for (;;)
   10769 ECB             :     {
   10770 CBC        7011 :         ni += 2;
   10771 GIC        7011 :         mul_var(&xx, &x, &xx, local_rscale);
   10772            7011 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   10773                 : 
   10774            7011 :         if (elem.ndigits == 0)
   10775             378 :             break;
   10776                 : 
   10777            6633 :         add_var(result, &elem, result);
   10778 ECB             : 
   10779 GIC        6633 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   10780 UIC           0 :             break;
   10781                 :     }
   10782                 : 
   10783 ECB             :     /* Compensate for argument range reduction, round to requested rscale */
   10784 CBC         378 :     mul_var(result, &fact, result, rscale);
   10785                 : 
   10786 GIC         378 :     free_var(&x);
   10787             378 :     free_var(&xx);
   10788             378 :     free_var(&elem);
   10789             378 :     free_var(&fact);
   10790             378 : }
   10791                 : 
   10792 ECB             : 
   10793                 : /*
   10794                 :  * log_var() -
   10795                 :  *
   10796                 :  *  Compute the logarithm of num in a given base.
   10797                 :  *
   10798                 :  *  Note: this routine chooses dscale of the result.
   10799                 :  */
   10800                 : static void
   10801 GIC         108 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   10802                 : {
   10803 ECB             :     NumericVar  ln_base;
   10804                 :     NumericVar  ln_num;
   10805                 :     int         ln_base_dweight;
   10806                 :     int         ln_num_dweight;
   10807                 :     int         result_dweight;
   10808                 :     int         rscale;
   10809                 :     int         ln_base_rscale;
   10810                 :     int         ln_num_rscale;
   10811                 : 
   10812 CBC         108 :     init_var(&ln_base);
   10813             108 :     init_var(&ln_num);
   10814 ECB             : 
   10815                 :     /* Estimated dweights of ln(base), ln(num) and the final result */
   10816 GIC         108 :     ln_base_dweight = estimate_ln_dweight(base);
   10817             108 :     ln_num_dweight = estimate_ln_dweight(num);
   10818 CBC         108 :     result_dweight = ln_num_dweight - ln_base_dweight;
   10819                 : 
   10820 ECB             :     /*
   10821                 :      * Select the scale of the result so that it will have at least
   10822                 :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   10823                 :      * input's display scale.
   10824                 :      */
   10825 GIC         108 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   10826 CBC         108 :     rscale = Max(rscale, base->dscale);
   10827             108 :     rscale = Max(rscale, num->dscale);
   10828             108 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10829             108 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10830                 : 
   10831                 :     /*
   10832 ECB             :      * Set the scales for ln(base) and ln(num) so that they each have more
   10833                 :      * significant digits than the final result.
   10834                 :      */
   10835 CBC         108 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   10836 GIC         108 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10837                 : 
   10838 CBC         108 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   10839             108 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10840 ECB             : 
   10841                 :     /* Form natural logarithms */
   10842 GIC         108 :     ln_var(base, &ln_base, ln_base_rscale);
   10843 CBC          96 :     ln_var(num, &ln_num, ln_num_rscale);
   10844 ECB             : 
   10845                 :     /* Divide and round to the required scale */
   10846 GIC          81 :     div_var_fast(&ln_num, &ln_base, result, rscale, true);
   10847                 : 
   10848              78 :     free_var(&ln_num);
   10849              78 :     free_var(&ln_base);
   10850              78 : }
   10851                 : 
   10852                 : 
   10853 ECB             : /*
   10854                 :  * power_var() -
   10855                 :  *
   10856                 :  *  Raise base to the power of exp
   10857                 :  *
   10858                 :  *  Note: this routine chooses dscale of the result.
   10859 EUB             :  */
   10860                 : static void
   10861 GIC         570 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   10862                 : {
   10863                 :     int         res_sign;
   10864                 :     NumericVar  abs_base;
   10865                 :     NumericVar  ln_base;
   10866                 :     NumericVar  ln_num;
   10867                 :     int         ln_dweight;
   10868                 :     int         rscale;
   10869                 :     int         sig_digits;
   10870                 :     int         local_rscale;
   10871                 :     double      val;
   10872 ECB             : 
   10873                 :     /* If exp can be represented as an integer, use power_var_int */
   10874 GIC         570 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   10875                 :     {
   10876 ECB             :         /* exact integer, but does it fit in int? */
   10877                 :         int64       expval64;
   10878                 : 
   10879 GIC         507 :         if (numericvar_to_int64(exp, &expval64))
   10880 ECB             :         {
   10881 GIC         504 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   10882 ECB             :             {
   10883                 :                 /* Okay, use power_var_int */
   10884 GNC         489 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   10885 GIC         483 :                 return;
   10886                 :             }
   10887                 :         }
   10888 ECB             :     }
   10889                 : 
   10890                 :     /*
   10891                 :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   10892                 :      * handled by power_var_int().
   10893                 :      */
   10894 GIC          81 :     if (cmp_var(base, &const_zero) == 0)
   10895 ECB             :     {
   10896 CBC           9 :         set_var_from_var(&const_zero, result);
   10897               9 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   10898 GIC           9 :         return;
   10899 ECB             :     }
   10900                 : 
   10901 CBC          72 :     init_var(&abs_base);
   10902              72 :     init_var(&ln_base);
   10903 GIC          72 :     init_var(&ln_num);
   10904                 : 
   10905                 :     /*
   10906 ECB             :      * If base is negative, insist that exp be an integer.  The result is then
   10907                 :      * positive if exp is even and negative if exp is odd.
   10908                 :      */
   10909 CBC          72 :     if (base->sign == NUMERIC_NEG)
   10910                 :     {
   10911                 :         /*
   10912 ECB             :          * Check that exp is an integer.  This error code is defined by the
   10913                 :          * SQL standard, and matches other errors in numeric_power().
   10914                 :          */
   10915 CBC          18 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   10916               9 :             ereport(ERROR,
   10917                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10918                 :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   10919 ECB             : 
   10920                 :         /* Test if exp is odd or even */
   10921 GIC           9 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   10922               6 :             (exp->digits[exp->ndigits - 1] & 1))
   10923               3 :             res_sign = NUMERIC_NEG;
   10924                 :         else
   10925               6 :             res_sign = NUMERIC_POS;
   10926                 : 
   10927                 :         /* Then work with abs(base) below */
   10928               9 :         set_var_from_var(base, &abs_base);
   10929 CBC           9 :         abs_base.sign = NUMERIC_POS;
   10930               9 :         base = &abs_base;
   10931 ECB             :     }
   10932                 :     else
   10933 CBC          54 :         res_sign = NUMERIC_POS;
   10934                 : 
   10935                 :     /*----------
   10936 ECB             :      * Decide on the scale for the ln() calculation.  For this we need an
   10937                 :      * estimate of the weight of the result, which we obtain by doing an
   10938                 :      * initial low-precision calculation of exp * ln(base).
   10939                 :      *
   10940                 :      * We want result = e ^ (exp * ln(base))
   10941                 :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   10942                 :      *
   10943                 :      * We also perform a crude overflow test here so that we can exit early if
   10944                 :      * the full-precision result is sure to overflow, and to guard against
   10945                 :      * integer overflow when determining the scale for the real calculation.
   10946                 :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   10947                 :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   10948                 :      * Since the values here are only approximations, we apply a small fuzz
   10949                 :      * factor to this overflow test and let exp_var() determine the exact
   10950                 :      * overflow threshold so that it is consistent for all inputs.
   10951                 :      *----------
   10952                 :      */
   10953 CBC          63 :     ln_dweight = estimate_ln_dweight(base);
   10954                 : 
   10955                 :     /*
   10956                 :      * Set the scale for the low-precision calculation, computing ln(base) to
   10957                 :      * around 8 significant digits.  Note that ln_dweight may be as small as
   10958                 :      * -SHRT_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE here.
   10959 ECB             :      */
   10960 CBC          63 :     local_rscale = 8 - ln_dweight;
   10961              63 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10962                 : 
   10963 GIC          63 :     ln_var(base, &ln_base, local_rscale);
   10964 ECB             : 
   10965 GIC          63 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   10966                 : 
   10967 CBC          63 :     val = numericvar_to_double_no_overflow(&ln_num);
   10968                 : 
   10969 ECB             :     /* initial overflow/underflow test with fuzz factor */
   10970 GNC          63 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   10971 ECB             :     {
   10972 CBC           3 :         if (val > 0)
   10973 LBC           0 :             ereport(ERROR,
   10974 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10975                 :                      errmsg("value overflows numeric format")));
   10976 GIC           3 :         zero_var(result);
   10977               3 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   10978               3 :         return;
   10979                 :     }
   10980                 : 
   10981              60 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   10982                 : 
   10983                 :     /* choose the result scale */
   10984 CBC          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   10985 GIC          60 :     rscale = Max(rscale, base->dscale);
   10986              60 :     rscale = Max(rscale, exp->dscale);
   10987              60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10988              60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10989                 : 
   10990                 :     /* significant digits required in the result */
   10991              60 :     sig_digits = rscale + (int) val;
   10992              60 :     sig_digits = Max(sig_digits, 0);
   10993                 : 
   10994                 :     /* set the scale for the real exp * ln(base) calculation */
   10995 CBC          60 :     local_rscale = sig_digits - ln_dweight + 8;
   10996              60 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10997                 : 
   10998 ECB             :     /* and do the real calculation */
   10999                 : 
   11000 GIC          60 :     ln_var(base, &ln_base, local_rscale);
   11001                 : 
   11002              60 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11003                 : 
   11004 CBC          60 :     exp_var(&ln_num, result, rscale);
   11005                 : 
   11006 GIC          60 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   11007               3 :         result->sign = NUMERIC_NEG;
   11008 ECB             : 
   11009 GIC          60 :     free_var(&ln_num);
   11010 CBC          60 :     free_var(&ln_base);
   11011 GBC          60 :     free_var(&abs_base);
   11012                 : }
   11013                 : 
   11014 ECB             : /*
   11015                 :  * power_var_int() -
   11016                 :  *
   11017                 :  *  Raise base to the power of exp, where exp is an integer.
   11018                 :  *
   11019                 :  *  Note: this routine chooses dscale of the result.
   11020                 :  */
   11021                 : static void
   11022 GNC         489 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   11023                 :               NumericVar *result)
   11024                 : {
   11025                 :     double      f;
   11026                 :     int         p;
   11027                 :     int         i;
   11028                 :     int         rscale;
   11029                 :     int         sig_digits;
   11030                 :     unsigned int mask;
   11031                 :     bool        neg;
   11032                 :     NumericVar  base_prod;
   11033 ECB             :     int         local_rscale;
   11034                 : 
   11035                 :     /*
   11036                 :      * Choose the result scale.  For this we need an estimate of the decimal
   11037                 :      * weight of the result, which we obtain by approximating using double
   11038                 :      * precision arithmetic.
   11039                 :      *
   11040                 :      * We also perform crude overflow/underflow tests here so that we can exit
   11041                 :      * early if the result is sure to overflow/underflow, and to guard against
   11042                 :      * integer overflow when choosing the result scale.
   11043                 :      */
   11044 GNC         489 :     if (base->ndigits != 0)
   11045                 :     {
   11046                 :         /*----------
   11047                 :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11048                 :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11049                 :          *----------
   11050                 :          */
   11051             474 :         f = base->digits[0];
   11052             474 :         p = base->weight * DEC_DIGITS;
   11053                 : 
   11054             516 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11055                 :         {
   11056              42 :             f = f * NBASE + base->digits[i];
   11057              42 :             p -= DEC_DIGITS;
   11058                 :         }
   11059                 : 
   11060             474 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11061                 :     }
   11062                 :     else
   11063              15 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11064                 : 
   11065                 :     /* overflow/underflow tests with fuzz factors */
   11066             489 :     if (f > (SHRT_MAX + 1) * DEC_DIGITS)
   11067               6 :         ereport(ERROR,
   11068                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11069                 :                  errmsg("value overflows numeric format")));
   11070             483 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11071                 :     {
   11072               6 :         zero_var(result);
   11073               6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11074              93 :         return;
   11075                 :     }
   11076                 : 
   11077                 :     /*
   11078                 :      * Choose the result scale in the same way as power_var(), so it has at
   11079                 :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11080                 :      * either input's display scale.
   11081                 :      */
   11082             477 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11083             477 :     rscale = Max(rscale, base->dscale);
   11084             477 :     rscale = Max(rscale, exp_dscale);
   11085             477 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11086             477 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11087                 : 
   11088 ECB             :     /* Handle some common special cases, as well as corner cases */
   11089 CBC         477 :     switch (exp)
   11090                 :     {
   11091              33 :         case 0:
   11092                 : 
   11093 ECB             :             /*
   11094                 :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11095                 :              * it as 1 because most programming languages do this. SQL:2003
   11096                 :              * also requires a return value of 1.
   11097                 :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11098                 :              */
   11099 GIC          33 :             set_var_from_var(&const_one, result);
   11100              33 :             result->dscale = rscale; /* no need to round */
   11101 CBC          33 :             return;
   11102 GIC          21 :         case 1:
   11103              21 :             set_var_from_var(base, result);
   11104              21 :             round_var(result, rscale);
   11105              21 :             return;
   11106              12 :         case -1:
   11107              12 :             div_var(&const_one, base, result, rscale, true);
   11108              12 :             return;
   11109              21 :         case 2:
   11110 CBC          21 :             mul_var(base, base, result, rscale);
   11111              21 :             return;
   11112 GIC         390 :         default:
   11113 CBC         390 :             break;
   11114                 :     }
   11115                 : 
   11116                 :     /* Handle the special case where the base is zero */
   11117 GIC         390 :     if (base->ndigits == 0)
   11118                 :     {
   11119 UIC           0 :         if (exp < 0)
   11120               0 :             ereport(ERROR,
   11121                 :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11122                 :                      errmsg("division by zero")));
   11123 LBC           0 :         zero_var(result);
   11124 UIC           0 :         result->dscale = rscale;
   11125 LBC           0 :         return;
   11126 ECB             :     }
   11127                 : 
   11128                 :     /*
   11129                 :      * The general case repeatedly multiplies base according to the bit
   11130                 :      * pattern of exp.
   11131                 :      *
   11132                 :      * The local rscale used for each multiplication is varied to keep a fixed
   11133                 :      * number of significant digits, sufficient to give the required result
   11134                 :      * scale.
   11135                 :      */
   11136                 : 
   11137                 :     /*
   11138                 :      * Approximate number of significant digits in the result.  Note that the
   11139                 :      * underflow test above, together with the choice of rscale, ensures that
   11140                 :      * this approximation is necessarily > 0.
   11141                 :      */
   11142 CBC         390 :     sig_digits = 1 + rscale + (int) f;
   11143                 : 
   11144                 :     /*
   11145                 :      * The multiplications to produce the result may introduce an error of up
   11146                 :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11147 ECB             :      * of precision (plus a few more for good measure).
   11148                 :      */
   11149 GIC         390 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11150 ECB             : 
   11151                 :     /*
   11152                 :      * Now we can proceed with the multiplications.
   11153                 :      */
   11154 GIC         390 :     neg = (exp < 0);
   11155 GNC         390 :     mask = abs(exp);
   11156                 : 
   11157 GIC         390 :     init_var(&base_prod);
   11158             390 :     set_var_from_var(base, &base_prod);
   11159                 : 
   11160             390 :     if (mask & 1)
   11161 CBC         195 :         set_var_from_var(base, result);
   11162 ECB             :     else
   11163 GIC         195 :         set_var_from_var(&const_one, result);
   11164 ECB             : 
   11165 GIC        2100 :     while ((mask >>= 1) > 0)
   11166                 :     {
   11167 ECB             :         /*
   11168                 :          * Do the multiplications using rscales large enough to hold the
   11169                 :          * results to the required number of significant digits, but don't
   11170                 :          * waste time by exceeding the scales of the numbers themselves.
   11171                 :          */
   11172 CBC        1710 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11173 GIC        1710 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11174            1710 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11175 ECB             : 
   11176 GIC        1710 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11177                 : 
   11178            1710 :         if (mask & 1)
   11179                 :         {
   11180            1137 :             local_rscale = sig_digits -
   11181            1137 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11182            1137 :             local_rscale = Min(local_rscale,
   11183                 :                                base_prod.dscale + result->dscale);
   11184 CBC        1137 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11185                 : 
   11186 GIC        1137 :             mul_var(&base_prod, result, result, local_rscale);
   11187                 :         }
   11188                 : 
   11189                 :         /*
   11190 ECB             :          * When abs(base) > 1, the number of digits to the left of the decimal
   11191                 :          * point in base_prod doubles at each iteration, so if exp is large we
   11192                 :          * could easily spend large amounts of time and memory space doing the
   11193                 :          * multiplications.  But once the weight exceeds what will fit in
   11194                 :          * int16, the final result is guaranteed to overflow (or underflow, if
   11195                 :          * exp < 0), so we can give up before wasting too many cycles.
   11196                 :          */
   11197 GIC        1710 :         if (base_prod.weight > SHRT_MAX || result->weight > SHRT_MAX)
   11198                 :         {
   11199                 :             /* overflow, unless neg, in which case result should be 0 */
   11200 UIC           0 :             if (!neg)
   11201               0 :                 ereport(ERROR,
   11202                 :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11203                 :                          errmsg("value overflows numeric format")));
   11204 LBC           0 :             zero_var(result);
   11205               0 :             neg = false;
   11206 UIC           0 :             break;
   11207                 :         }
   11208                 :     }
   11209                 : 
   11210 CBC         390 :     free_var(&base_prod);
   11211                 : 
   11212                 :     /* Compensate for input sign, and round to requested rscale */
   11213 GIC         390 :     if (neg)
   11214 CBC         183 :         div_var_fast(&const_one, result, result, rscale, true);
   11215                 :     else
   11216 GIC         207 :         round_var(result, rscale);
   11217                 : }
   11218                 : 
   11219                 : /*
   11220                 :  * power_ten_int() -
   11221                 :  *
   11222                 :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11223                 :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11224 ECB             :  */
   11225                 : static void
   11226 GIC         108 : power_ten_int(int exp, NumericVar *result)
   11227                 : {
   11228                 :     /* Construct the result directly, starting from 10^0 = 1 */
   11229             108 :     set_var_from_var(&const_one, result);
   11230                 : 
   11231                 :     /* Scale needed to represent the result exactly */
   11232             108 :     result->dscale = exp < 0 ? -exp : 0;
   11233                 : 
   11234                 :     /* Base-NBASE weight of result and remaining exponent */
   11235 CBC         108 :     if (exp >= 0)
   11236              75 :         result->weight = exp / DEC_DIGITS;
   11237 ECB             :     else
   11238 GIC          33 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11239                 : 
   11240 CBC         108 :     exp -= result->weight * DEC_DIGITS;
   11241 ECB             : 
   11242                 :     /* Final adjustment of the result's single NBASE digit */
   11243 GIC         273 :     while (exp-- > 0)
   11244             165 :         result->digits[0] *= 10;
   11245 CBC         108 : }
   11246 ECB             : 
   11247                 : 
   11248                 : /* ----------------------------------------------------------------------
   11249                 :  *
   11250                 :  * Following are the lowest level functions that operate unsigned
   11251                 :  * on the variable level
   11252                 :  *
   11253                 :  * ----------------------------------------------------------------------
   11254                 :  */
   11255                 : 
   11256                 : 
   11257                 : /* ----------
   11258                 :  * cmp_abs() -
   11259                 :  *
   11260                 :  *  Compare the absolute values of var1 and var2
   11261                 :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11262                 :  *              0  for ABS(var1) == ABS(var2)
   11263                 :  *              1  for ABS(var1) > ABS(var2)
   11264                 :  * ----------
   11265                 :  */
   11266                 : static int
   11267 GIC      143246 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11268 ECB             : {
   11269 CBC      286492 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11270 GIC      143246 :                           var2->digits, var2->ndigits, var2->weight);
   11271 ECB             : }
   11272                 : 
   11273                 : /* ----------
   11274                 :  * cmp_abs_common() -
   11275                 :  *
   11276                 :  *  Main routine of cmp_abs(). This function can be used by both
   11277                 :  *  NumericVar and Numeric.
   11278                 :  * ----------
   11279                 :  */
   11280                 : static int
   11281 CBC     3240490 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11282                 :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11283                 : {
   11284 GIC     3240490 :     int         i1 = 0;
   11285         3240490 :     int         i2 = 0;
   11286                 : 
   11287                 :     /* Check any digits before the first common digit */
   11288                 : 
   11289         3240490 :     while (var1weight > var2weight && i1 < var1ndigits)
   11290                 :     {
   11291           10088 :         if (var1digits[i1++] != 0)
   11292           10088 :             return 1;
   11293 UIC           0 :         var1weight--;
   11294                 :     }
   11295 GIC     3230402 :     while (var2weight > var1weight && i2 < var2ndigits)
   11296                 :     {
   11297            9038 :         if (var2digits[i2++] != 0)
   11298            9038 :             return -1;
   11299 LBC           0 :         var2weight--;
   11300                 :     }
   11301 ECB             : 
   11302                 :     /* At this point, either w1 == w2 or we've run out of digits */
   11303                 : 
   11304 CBC     3221364 :     if (var1weight == var2weight)
   11305 ECB             :     {
   11306 GIC     6029656 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11307 ECB             :         {
   11308 GIC     4011418 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11309                 : 
   11310         4011418 :             if (stat)
   11311 ECB             :             {
   11312 CBC     1203117 :                 if (stat > 0)
   11313          784631 :                     return 1;
   11314 GIC      418486 :                 return -1;
   11315 ECB             :             }
   11316                 :         }
   11317                 :     }
   11318                 : 
   11319                 :     /*
   11320                 :      * At this point, we've run out of digits on one side or the other; so any
   11321 EUB             :      * remaining nonzero digits imply that side is larger
   11322                 :      */
   11323 GIC     2018415 :     while (i1 < var1ndigits)
   11324                 :     {
   11325 CBC        1110 :         if (var1digits[i1++] != 0)
   11326 GIC         942 :             return 1;
   11327 ECB             :     }
   11328 CBC     2017431 :     while (i2 < var2ndigits)
   11329 ECB             :     {
   11330 CBC         402 :         if (var2digits[i2++] != 0)
   11331             276 :             return -1;
   11332                 :     }
   11333                 : 
   11334 GIC     2017029 :     return 0;
   11335                 : }
   11336                 : 
   11337                 : 
   11338                 : /*
   11339                 :  * add_abs() -
   11340                 :  *
   11341                 :  *  Add the absolute values of two variables into result.
   11342 ECB             :  *  result might point to one of the operands without danger.
   11343                 :  */
   11344                 : static void
   11345 GIC      148392 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11346                 : {
   11347                 :     NumericDigit *res_buf;
   11348                 :     NumericDigit *res_digits;
   11349                 :     int         res_ndigits;
   11350                 :     int         res_weight;
   11351                 :     int         res_rscale,
   11352                 :                 rscale1,
   11353 ECB             :                 rscale2;
   11354                 :     int         res_dscale;
   11355                 :     int         i,
   11356                 :                 i1,
   11357                 :                 i2;
   11358 CBC      148392 :     int         carry = 0;
   11359 ECB             : 
   11360                 :     /* copy these values into local vars for speed in inner loop */
   11361 GIC      148392 :     int         var1ndigits = var1->ndigits;
   11362          148392 :     int         var2ndigits = var2->ndigits;
   11363          148392 :     NumericDigit *var1digits = var1->digits;
   11364          148392 :     NumericDigit *var2digits = var2->digits;
   11365                 : 
   11366 CBC      148392 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11367 ECB             : 
   11368 CBC      148392 :     res_dscale = Max(var1->dscale, var2->dscale);
   11369 ECB             : 
   11370                 :     /* Note: here we are figuring rscale in base-NBASE digits */
   11371 GIC      148392 :     rscale1 = var1->ndigits - var1->weight - 1;
   11372          148392 :     rscale2 = var2->ndigits - var2->weight - 1;
   11373          148392 :     res_rscale = Max(rscale1, rscale2);
   11374                 : 
   11375          148392 :     res_ndigits = res_rscale + res_weight + 1;
   11376 CBC      148392 :     if (res_ndigits <= 0)
   11377 LBC           0 :         res_ndigits = 1;
   11378                 : 
   11379 CBC      148392 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11380          148392 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11381 GIC      148392 :     res_digits = res_buf + 1;
   11382                 : 
   11383 CBC      148392 :     i1 = res_rscale + var1->weight + 1;
   11384          148392 :     i2 = res_rscale + var2->weight + 1;
   11385 GIC     1594356 :     for (i = res_ndigits - 1; i >= 0; i--)
   11386                 :     {
   11387 CBC     1445964 :         i1--;
   11388 GIC     1445964 :         i2--;
   11389 CBC     1445964 :         if (i1 >= 0 && i1 < var1ndigits)
   11390          632497 :             carry += var1digits[i1];
   11391         1445964 :         if (i2 >= 0 && i2 < var2ndigits)
   11392 GIC      498901 :             carry += var2digits[i2];
   11393                 : 
   11394         1445964 :         if (carry >= NBASE)
   11395                 :         {
   11396          110947 :             res_digits[i] = carry - NBASE;
   11397          110947 :             carry = 1;
   11398                 :         }
   11399                 :         else
   11400                 :         {
   11401         1335017 :             res_digits[i] = carry;
   11402 CBC     1335017 :             carry = 0;
   11403                 :         }
   11404                 :     }
   11405                 : 
   11406 GIC      148392 :     Assert(carry == 0);         /* else we failed to allow for carry out */
   11407                 : 
   11408          148392 :     digitbuf_free(result->buf);
   11409          148392 :     result->ndigits = res_ndigits;
   11410          148392 :     result->buf = res_buf;
   11411          148392 :     result->digits = res_digits;
   11412          148392 :     result->weight = res_weight;
   11413          148392 :     result->dscale = res_dscale;
   11414                 : 
   11415 ECB             :     /* Remove leading/trailing zeroes */
   11416 GIC      148392 :     strip_var(result);
   11417          148392 : }
   11418                 : 
   11419                 : 
   11420 ECB             : /*
   11421                 :  * sub_abs()
   11422                 :  *
   11423                 :  *  Subtract the absolute value of var2 from the absolute value of var1
   11424                 :  *  and store in result. result might point to one of the operands
   11425                 :  *  without danger.
   11426                 :  *
   11427                 :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   11428                 :  */
   11429                 : static void
   11430 GIC      125803 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11431                 : {
   11432                 :     NumericDigit *res_buf;
   11433                 :     NumericDigit *res_digits;
   11434                 :     int         res_ndigits;
   11435 ECB             :     int         res_weight;
   11436                 :     int         res_rscale,
   11437                 :                 rscale1,
   11438                 :                 rscale2;
   11439                 :     int         res_dscale;
   11440                 :     int         i,
   11441                 :                 i1,
   11442                 :                 i2;
   11443 CBC      125803 :     int         borrow = 0;
   11444 ECB             : 
   11445                 :     /* copy these values into local vars for speed in inner loop */
   11446 GIC      125803 :     int         var1ndigits = var1->ndigits;
   11447          125803 :     int         var2ndigits = var2->ndigits;
   11448          125803 :     NumericDigit *var1digits = var1->digits;
   11449          125803 :     NumericDigit *var2digits = var2->digits;
   11450 ECB             : 
   11451 GIC      125803 :     res_weight = var1->weight;
   11452                 : 
   11453          125803 :     res_dscale = Max(var1->dscale, var2->dscale);
   11454                 : 
   11455                 :     /* Note: here we are figuring rscale in base-NBASE digits */
   11456 CBC      125803 :     rscale1 = var1->ndigits - var1->weight - 1;
   11457          125803 :     rscale2 = var2->ndigits - var2->weight - 1;
   11458 GIC      125803 :     res_rscale = Max(rscale1, rscale2);
   11459                 : 
   11460          125803 :     res_ndigits = res_rscale + res_weight + 1;
   11461          125803 :     if (res_ndigits <= 0)
   11462 LBC           0 :         res_ndigits = 1;
   11463 ECB             : 
   11464 CBC      125803 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11465 GIC      125803 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11466 CBC      125803 :     res_digits = res_buf + 1;
   11467                 : 
   11468 GIC      125803 :     i1 = res_rscale + var1->weight + 1;
   11469 CBC      125803 :     i2 = res_rscale + var2->weight + 1;
   11470         2143353 :     for (i = res_ndigits - 1; i >= 0; i--)
   11471 ECB             :     {
   11472 GIC     2017550 :         i1--;
   11473         2017550 :         i2--;
   11474 CBC     2017550 :         if (i1 >= 0 && i1 < var1ndigits)
   11475 GIC     1847994 :             borrow += var1digits[i1];
   11476         2017550 :         if (i2 >= 0 && i2 < var2ndigits)
   11477         1805219 :             borrow -= var2digits[i2];
   11478                 : 
   11479         2017550 :         if (borrow < 0)
   11480                 :         {
   11481          190584 :             res_digits[i] = borrow + NBASE;
   11482          190584 :             borrow = -1;
   11483                 :         }
   11484                 :         else
   11485                 :         {
   11486         1826966 :             res_digits[i] = borrow;
   11487         1826966 :             borrow = 0;
   11488                 :         }
   11489                 :     }
   11490                 : 
   11491          125803 :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   11492                 : 
   11493          125803 :     digitbuf_free(result->buf);
   11494 CBC      125803 :     result->ndigits = res_ndigits;
   11495 GIC      125803 :     result->buf = res_buf;
   11496          125803 :     result->digits = res_digits;
   11497          125803 :     result->weight = res_weight;
   11498          125803 :     result->dscale = res_dscale;
   11499                 : 
   11500                 :     /* Remove leading/trailing zeroes */
   11501 CBC      125803 :     strip_var(result);
   11502          125803 : }
   11503                 : 
   11504 ECB             : /*
   11505                 :  * round_var
   11506                 :  *
   11507                 :  * Round the value of a variable to no more than rscale decimal digits
   11508                 :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11509                 :  * rounding before the decimal point.
   11510                 :  */
   11511                 : static void
   11512 GIC      496023 : round_var(NumericVar *var, int rscale)
   11513 ECB             : {
   11514 GBC      496023 :     NumericDigit *digits = var->digits;
   11515                 :     int         di;
   11516                 :     int         ndigits;
   11517 ECB             :     int         carry;
   11518                 : 
   11519 CBC      496023 :     var->dscale = rscale;
   11520                 : 
   11521                 :     /* decimal digits wanted */
   11522          496023 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11523                 : 
   11524                 :     /*
   11525 ECB             :      * If di = 0, the value loses all digits, but could round up to 1 if its
   11526                 :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   11527                 :      */
   11528 CBC      496023 :     if (di < 0)
   11529 ECB             :     {
   11530 GIC          34 :         var->ndigits = 0;
   11531              34 :         var->weight = 0;
   11532 CBC          34 :         var->sign = NUMERIC_POS;
   11533 ECB             :     }
   11534                 :     else
   11535                 :     {
   11536                 :         /* NBASE digits wanted */
   11537 CBC      495989 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11538                 : 
   11539                 :         /* 0, or number of decimal digits to keep in last NBASE digit */
   11540 GIC      495989 :         di %= DEC_DIGITS;
   11541 ECB             : 
   11542 GIC      495989 :         if (ndigits < var->ndigits ||
   11543 CBC      409732 :             (ndigits == var->ndigits && di > 0))
   11544                 :         {
   11545          329635 :             var->ndigits = ndigits;
   11546                 : 
   11547 ECB             : #if DEC_DIGITS == 1
   11548                 :             /* di must be zero */
   11549                 :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11550                 : #else
   11551 CBC      329635 :             if (di == 0)
   11552           67146 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11553                 :             else
   11554                 :             {
   11555                 :                 /* Must round within last NBASE digit */
   11556                 :                 int         extra,
   11557                 :                             pow10;
   11558                 : 
   11559                 : #if DEC_DIGITS == 4
   11560 GIC      262489 :                 pow10 = round_powers[di];
   11561                 : #elif DEC_DIGITS == 2
   11562                 :                 pow10 = 10;
   11563 ECB             : #else
   11564                 : #error unsupported NBASE
   11565                 : #endif
   11566 GIC      262489 :                 extra = digits[--ndigits] % pow10;
   11567          262489 :                 digits[ndigits] -= extra;
   11568          262489 :                 carry = 0;
   11569          262489 :                 if (extra >= pow10 / 2)
   11570                 :                 {
   11571            9665 :                     pow10 += digits[ndigits];
   11572            9665 :                     if (pow10 >= NBASE)
   11573                 :                     {
   11574             406 :                         pow10 -= NBASE;
   11575             406 :                         carry = 1;
   11576                 :                     }
   11577            9665 :                     digits[ndigits] = pow10;
   11578                 :                 }
   11579                 :             }
   11580                 : #endif
   11581                 : 
   11582                 :             /* Propagate carry if needed */
   11583          347212 :             while (carry)
   11584                 :             {
   11585 CBC       17577 :                 carry += digits[--ndigits];
   11586 GIC       17577 :                 if (carry >= NBASE)
   11587                 :                 {
   11588           12387 :                     digits[ndigits] = carry - NBASE;
   11589           12387 :                     carry = 1;
   11590                 :                 }
   11591                 :                 else
   11592 ECB             :                 {
   11593 CBC        5190 :                     digits[ndigits] = carry;
   11594 GIC        5190 :                     carry = 0;
   11595 ECB             :                 }
   11596                 :             }
   11597                 : 
   11598 CBC      329635 :             if (ndigits < 0)
   11599                 :             {
   11600 GIC          45 :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   11601 CBC          45 :                 Assert(var->digits > var->buf);
   11602 GIC          45 :                 var->digits--;
   11603              45 :                 var->ndigits++;
   11604 CBC          45 :                 var->weight++;
   11605                 :             }
   11606                 :         }
   11607 ECB             :     }
   11608 CBC      496023 : }
   11609                 : 
   11610                 : /*
   11611 ECB             :  * trunc_var
   11612                 :  *
   11613                 :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   11614                 :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11615                 :  * truncation before the decimal point.
   11616                 :  */
   11617                 : static void
   11618 GIC       29884 : trunc_var(NumericVar *var, int rscale)
   11619                 : {
   11620                 :     int         di;
   11621                 :     int         ndigits;
   11622                 : 
   11623 CBC       29884 :     var->dscale = rscale;
   11624 ECB             : 
   11625                 :     /* decimal digits wanted */
   11626 CBC       29884 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11627 ECB             : 
   11628                 :     /*
   11629                 :      * If di <= 0, the value loses all digits.
   11630                 :      */
   11631 GIC       29884 :     if (di <= 0)
   11632 ECB             :     {
   11633 GIC          27 :         var->ndigits = 0;
   11634              27 :         var->weight = 0;
   11635              27 :         var->sign = NUMERIC_POS;
   11636                 :     }
   11637                 :     else
   11638                 :     {
   11639                 :         /* NBASE digits wanted */
   11640 CBC       29857 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11641 ECB             : 
   11642 CBC       29857 :         if (ndigits <= var->ndigits)
   11643 ECB             :         {
   11644 CBC       29761 :             var->ndigits = ndigits;
   11645 ECB             : 
   11646                 : #if DEC_DIGITS == 1
   11647                 :             /* no within-digit stuff to worry about */
   11648                 : #else
   11649                 :             /* 0, or number of decimal digits to keep in last NBASE digit */
   11650 CBC       29761 :             di %= DEC_DIGITS;
   11651 ECB             : 
   11652 CBC       29761 :             if (di > 0)
   11653 ECB             :             {
   11654                 :                 /* Must truncate within last NBASE digit */
   11655 GIC          41 :                 NumericDigit *digits = var->digits;
   11656                 :                 int         extra,
   11657                 :                             pow10;
   11658 ECB             : 
   11659                 : #if DEC_DIGITS == 4
   11660 GBC          41 :                 pow10 = round_powers[di];
   11661 EUB             : #elif DEC_DIGITS == 2
   11662                 :                 pow10 = 10;
   11663                 : #else
   11664                 : #error unsupported NBASE
   11665                 : #endif
   11666 GBC          41 :                 extra = digits[--ndigits] % pow10;
   11667 GIC          41 :                 digits[ndigits] -= extra;
   11668                 :             }
   11669                 : #endif
   11670                 :         }
   11671                 :     }
   11672           29884 : }
   11673                 : 
   11674                 : /*
   11675                 :  * strip_var
   11676                 :  *
   11677                 :  * Strip any leading and trailing zeroes from a numeric variable
   11678                 :  */
   11679                 : static void
   11680          938626 : strip_var(NumericVar *var)
   11681                 : {
   11682          938626 :     NumericDigit *digits = var->digits;
   11683 CBC      938626 :     int         ndigits = var->ndigits;
   11684                 : 
   11685                 :     /* Strip leading zeroes */
   11686 GIC     2226262 :     while (ndigits > 0 && *digits == 0)
   11687                 :     {
   11688         1287636 :         digits++;
   11689         1287636 :         var->weight--;
   11690 CBC     1287636 :         ndigits--;
   11691                 :     }
   11692                 : 
   11693                 :     /* Strip trailing zeroes */
   11694 GIC     1216040 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   11695 CBC      277414 :         ndigits--;
   11696 ECB             : 
   11697                 :     /* If it's zero, normalize the sign and weight */
   11698 CBC      938626 :     if (ndigits == 0)
   11699 ECB             :     {
   11700 GIC       12984 :         var->sign = NUMERIC_POS;
   11701 CBC       12984 :         var->weight = 0;
   11702 ECB             :     }
   11703                 : 
   11704 CBC      938626 :     var->digits = digits;
   11705 GIC      938626 :     var->ndigits = ndigits;
   11706 CBC      938626 : }
   11707                 : 
   11708                 : 
   11709                 : /* ----------------------------------------------------------------------
   11710                 :  *
   11711                 :  * Fast sum accumulator functions
   11712                 :  *
   11713 ECB             :  * ----------------------------------------------------------------------
   11714                 :  */
   11715                 : 
   11716                 : /*
   11717                 :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   11718                 :  * are not free'd.
   11719                 :  */
   11720                 : static void
   11721 CBC           9 : accum_sum_reset(NumericSumAccum *accum)
   11722 ECB             : {
   11723                 :     int         i;
   11724                 : 
   11725 CBC           9 :     accum->dscale = 0;
   11726 GIC          33 :     for (i = 0; i < accum->ndigits; i++)
   11727 ECB             :     {
   11728 GIC          24 :         accum->pos_digits[i] = 0;
   11729              24 :         accum->neg_digits[i] = 0;
   11730                 :     }
   11731               9 : }
   11732                 : 
   11733                 : /*
   11734                 :  * Accumulate a new value.
   11735                 :  */
   11736                 : static void
   11737         1177852 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   11738 ECB             : {
   11739                 :     int32      *accum_digits;
   11740                 :     int         i,
   11741 EUB             :                 val_i;
   11742                 :     int         val_ndigits;
   11743                 :     NumericDigit *val_digits;
   11744                 : 
   11745                 :     /*
   11746                 :      * If we have accumulated too many values since the last carry
   11747                 :      * propagation, do it now, to avoid overflowing.  (We could allow more
   11748                 :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   11749                 :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   11750                 :      * seldom, that the performance difference is negligible.)
   11751 ECB             :      */
   11752 GIC     1177852 :     if (accum->num_uncarried == NBASE - 1)
   11753              81 :         accum_sum_carry(accum);
   11754 ECB             : 
   11755                 :     /*
   11756                 :      * Adjust the weight or scale of the old value, so that it can accommodate
   11757                 :      * the new value.
   11758                 :      */
   11759 GIC     1177852 :     accum_sum_rescale(accum, val);
   11760                 : 
   11761                 :     /* */
   11762         1177852 :     if (val->sign == NUMERIC_POS)
   11763          877513 :         accum_digits = accum->pos_digits;
   11764                 :     else
   11765          300339 :         accum_digits = accum->neg_digits;
   11766                 : 
   11767 ECB             :     /* copy these values into local vars for speed in loop */
   11768 GIC     1177852 :     val_ndigits = val->ndigits;
   11769         1177852 :     val_digits = val->digits;
   11770 ECB             : 
   11771 GIC     1177852 :     i = accum->weight - val->weight;
   11772         5944973 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   11773 ECB             :     {
   11774 GIC     4767121 :         accum_digits[i] += (int32) val_digits[val_i];
   11775         4767121 :         i++;
   11776 ECB             :     }
   11777                 : 
   11778 GIC     1177852 :     accum->num_uncarried++;
   11779 CBC     1177852 : }
   11780                 : 
   11781 ECB             : /*
   11782                 :  * Propagate carries.
   11783                 :  */
   11784                 : static void
   11785 CBC       86382 : accum_sum_carry(NumericSumAccum *accum)
   11786 ECB             : {
   11787                 :     int         i;
   11788                 :     int         ndigits;
   11789                 :     int32      *dig;
   11790                 :     int32       carry;
   11791 GIC       86382 :     int32       newdig = 0;
   11792                 : 
   11793                 :     /*
   11794                 :      * If no new values have been added since last carry propagation, nothing
   11795                 :      * to do.
   11796                 :      */
   11797           86382 :     if (accum->num_uncarried == 0)
   11798              36 :         return;
   11799                 : 
   11800                 :     /*
   11801                 :      * We maintain that the weight of the accumulator is always one larger
   11802                 :      * than needed to hold the current value, before carrying, to make sure
   11803                 :      * there is enough space for the possible extra digit when carry is
   11804                 :      * propagated.  We cannot expand the buffer here, unless we require
   11805                 :      * callers of accum_sum_final() to switch to the right memory context.
   11806                 :      */
   11807           86346 :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   11808 ECB             : 
   11809 GIC       86346 :     ndigits = accum->ndigits;
   11810 ECB             : 
   11811                 :     /* Propagate carry in the positive sum */
   11812 GIC       86346 :     dig = accum->pos_digits;
   11813           86346 :     carry = 0;
   11814         1302779 :     for (i = ndigits - 1; i >= 0; i--)
   11815                 :     {
   11816         1216433 :         newdig = dig[i] + carry;
   11817         1216433 :         if (newdig >= NBASE)
   11818                 :         {
   11819           55407 :             carry = newdig / NBASE;
   11820           55407 :             newdig -= carry * NBASE;
   11821                 :         }
   11822 ECB             :         else
   11823 GIC     1161026 :             carry = 0;
   11824         1216433 :         dig[i] = newdig;
   11825 ECB             :     }
   11826                 :     /* Did we use up the digit reserved for carry propagation? */
   11827 GIC       86346 :     if (newdig > 0)
   11828            1321 :         accum->have_carry_space = false;
   11829                 : 
   11830 ECB             :     /* And the same for the negative sum */
   11831 GIC       86346 :     dig = accum->neg_digits;
   11832 CBC       86346 :     carry = 0;
   11833         1302779 :     for (i = ndigits - 1; i >= 0; i--)
   11834 EUB             :     {
   11835 GIC     1216433 :         newdig = dig[i] + carry;
   11836 CBC     1216433 :         if (newdig >= NBASE)
   11837                 :         {
   11838              99 :             carry = newdig / NBASE;
   11839              99 :             newdig -= carry * NBASE;
   11840 EUB             :         }
   11841                 :         else
   11842 GIC     1216334 :             carry = 0;
   11843         1216433 :         dig[i] = newdig;
   11844                 :     }
   11845 CBC       86346 :     if (newdig > 0)
   11846 GIC          15 :         accum->have_carry_space = false;
   11847 ECB             : 
   11848 GIC       86346 :     accum->num_uncarried = 0;
   11849 ECB             : }
   11850                 : 
   11851                 : /*
   11852                 :  * Re-scale accumulator to accommodate new value.
   11853                 :  *
   11854                 :  * If the new value has more digits than the current digit buffers in the
   11855                 :  * accumulator, enlarge the buffers.
   11856                 :  */
   11857                 : static void
   11858 GIC     1177852 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   11859                 : {
   11860         1177852 :     int         old_weight = accum->weight;
   11861         1177852 :     int         old_ndigits = accum->ndigits;
   11862                 :     int         accum_ndigits;
   11863                 :     int         accum_weight;
   11864 ECB             :     int         accum_rscale;
   11865                 :     int         val_rscale;
   11866                 : 
   11867 CBC     1177852 :     accum_weight = old_weight;
   11868 GIC     1177852 :     accum_ndigits = old_ndigits;
   11869 ECB             : 
   11870                 :     /*
   11871                 :      * Does the new value have a larger weight? If so, enlarge the buffers,
   11872                 :      * and shift the existing value to the new weight, by adding leading
   11873                 :      * zeros.
   11874                 :      *
   11875                 :      * We enforce that the accumulator always has a weight one larger than
   11876                 :      * needed for the inputs, so that we have space for an extra digit at the
   11877                 :      * final carry-propagation phase, if necessary.
   11878                 :      */
   11879 GIC     1177852 :     if (val->weight >= accum_weight)
   11880                 :     {
   11881          131114 :         accum_weight = val->weight + 1;
   11882          131114 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   11883                 :     }
   11884                 : 
   11885                 :     /*
   11886 ECB             :      * Even though the new value is small, we might've used up the space
   11887                 :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   11888                 :      * so, enlarge to make room for another one.
   11889                 :      */
   11890 GIC     1046738 :     else if (!accum->have_carry_space)
   11891                 :     {
   11892              37 :         accum_weight++;
   11893              37 :         accum_ndigits++;
   11894                 :     }
   11895                 : 
   11896                 :     /* Is the new value wider on the right side? */
   11897         1177852 :     accum_rscale = accum_ndigits - accum_weight - 1;
   11898         1177852 :     val_rscale = val->ndigits - val->weight - 1;
   11899 CBC     1177852 :     if (val_rscale > accum_rscale)
   11900 GIC       86123 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   11901                 : 
   11902 CBC     1177852 :     if (accum_ndigits != old_ndigits ||
   11903 ECB             :         accum_weight != old_weight)
   11904                 :     {
   11905                 :         int32      *new_pos_digits;
   11906                 :         int32      *new_neg_digits;
   11907                 :         int         weightdiff;
   11908                 : 
   11909 CBC      131298 :         weightdiff = accum_weight - old_weight;
   11910                 : 
   11911 GIC      131298 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   11912 CBC      131298 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   11913 ECB             : 
   11914 CBC      131298 :         if (accum->pos_digits)
   11915                 :         {
   11916           45210 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   11917 ECB             :                    old_ndigits * sizeof(int32));
   11918 GBC       45210 :             pfree(accum->pos_digits);
   11919                 : 
   11920 CBC       45210 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   11921 ECB             :                    old_ndigits * sizeof(int32));
   11922 CBC       45210 :             pfree(accum->neg_digits);
   11923                 :         }
   11924 ECB             : 
   11925 CBC      131298 :         accum->pos_digits = new_pos_digits;
   11926          131298 :         accum->neg_digits = new_neg_digits;
   11927                 : 
   11928          131298 :         accum->weight = accum_weight;
   11929          131298 :         accum->ndigits = accum_ndigits;
   11930 ECB             : 
   11931 CBC      131298 :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   11932          131298 :         accum->have_carry_space = true;
   11933 ECB             :     }
   11934                 : 
   11935 CBC     1177852 :     if (val->dscale > accum->dscale)
   11936 GIC         150 :         accum->dscale = val->dscale;
   11937 CBC     1177852 : }
   11938 ECB             : 
   11939                 : /*
   11940                 :  * Return the current value of the accumulator.  This perform final carry
   11941                 :  * propagation, and adds together the positive and negative sums.
   11942                 :  *
   11943                 :  * Unlike all the other routines, the caller is not required to switch to
   11944                 :  * the memory context that holds the accumulator.
   11945                 :  */
   11946                 : static void
   11947 CBC       86301 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   11948                 : {
   11949 ECB             :     int         i;
   11950                 :     NumericVar  pos_var;
   11951                 :     NumericVar  neg_var;
   11952                 : 
   11953 CBC       86301 :     if (accum->ndigits == 0)
   11954 ECB             :     {
   11955 UIC           0 :         set_var_from_var(&const_zero, result);
   11956               0 :         return;
   11957 ECB             :     }
   11958                 : 
   11959                 :     /* Perform final carry */
   11960 GIC       86301 :     accum_sum_carry(accum);
   11961                 : 
   11962                 :     /* Create NumericVars representing the positive and negative sums */
   11963           86301 :     init_var(&pos_var);
   11964           86301 :     init_var(&neg_var);
   11965                 : 
   11966           86301 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   11967           86301 :     pos_var.weight = neg_var.weight = accum->weight;
   11968           86301 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   11969           86301 :     pos_var.sign = NUMERIC_POS;
   11970           86301 :     neg_var.sign = NUMERIC_NEG;
   11971 ECB             : 
   11972 GIC       86301 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   11973           86301 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   11974                 : 
   11975         1302547 :     for (i = 0; i < accum->ndigits; i++)
   11976                 :     {
   11977         1216246 :         Assert(accum->pos_digits[i] < NBASE);
   11978         1216246 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   11979                 : 
   11980         1216246 :         Assert(accum->neg_digits[i] < NBASE);
   11981         1216246 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   11982                 :     }
   11983                 : 
   11984 ECB             :     /* And add them together */
   11985 GIC       86301 :     add_var(&pos_var, &neg_var, result);
   11986                 : 
   11987 ECB             :     /* Remove leading/trailing zeroes */
   11988 CBC       86301 :     strip_var(result);
   11989 ECB             : }
   11990                 : 
   11991                 : /*
   11992                 :  * Copy an accumulator's state.
   11993                 :  *
   11994                 :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   11995                 :  * freeing old values.
   11996                 :  */
   11997                 : static void
   11998 CBC          21 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   11999 ECB             : {
   12000 GIC          21 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12001 CBC          21 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12002 ECB             : 
   12003 GBC          21 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12004 GIC          21 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12005 CBC          21 :     dst->num_uncarried = src->num_uncarried;
   12006              21 :     dst->ndigits = src->ndigits;
   12007              21 :     dst->weight = src->weight;
   12008 GIC          21 :     dst->dscale = src->dscale;
   12009 CBC          21 : }
   12010 ECB             : 
   12011                 : /*
   12012                 :  * Add the current value of 'accum2' into 'accum'.
   12013                 :  */
   12014                 : static void
   12015 CBC          24 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12016 ECB             : {
   12017                 :     NumericVar  tmp_var;
   12018                 : 
   12019 GIC          24 :     init_var(&tmp_var);
   12020 ECB             : 
   12021 GIC          24 :     accum_sum_final(accum2, &tmp_var);
   12022 CBC          24 :     accum_sum_add(accum, &tmp_var);
   12023 ECB             : 
   12024 GIC          24 :     free_var(&tmp_var);
   12025              24 : }
        

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