LCOV - code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 94.6 % 3992 3775
Test Date: 2026-04-07 14:16:30 Functions: 99.1 % 211 209
Legend: Lines:     hit not hit

            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-2026, 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 "common/hashfn.h"
      30              : #include "common/int.h"
      31              : #include "common/int128.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 "optimizer/optimizer.h"
      39              : #include "utils/array.h"
      40              : #include "utils/builtins.h"
      41              : #include "utils/float.h"
      42              : #include "utils/guc.h"
      43              : #include "utils/numeric.h"
      44              : #include "utils/pg_lsn.h"
      45              : #include "utils/sortsupport.h"
      46              : 
      47              : /* ----------
      48              :  * Uncomment the following to enable compilation of dump_numeric()
      49              :  * and dump_var() and to get a dump of any result produced by make_result().
      50              :  * ----------
      51              :  */
      52              : /* #define NUMERIC_DEBUG */
      53              : 
      54              : 
      55              : /* ----------
      56              :  * Local data types
      57              :  *
      58              :  * Numeric values are represented in a base-NBASE floating point format.
      59              :  * Each "digit" ranges from 0 to NBASE-1.  The type NumericDigit is signed
      60              :  * and wide enough to store a digit.  We assume that NBASE*NBASE can fit in
      61              :  * an int.  Although the purely calculational routines could handle any even
      62              :  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
      63              :  * in NBASE a power of ten, so that I/O conversions and decimal rounding
      64              :  * are easy.  Also, it's actually more efficient if NBASE is rather less than
      65              :  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var to
      66              :  * postpone processing carries.
      67              :  *
      68              :  * Values of NBASE other than 10000 are considered of historical interest only
      69              :  * and are no longer supported in any sense; no mechanism exists for the client
      70              :  * to discover the base, so every client supporting binary mode expects the
      71              :  * base-10000 format.  If you plan to change this, also note the numeric
      72              :  * abbreviation code, which assumes NBASE=10000.
      73              :  * ----------
      74              :  */
      75              : 
      76              : #if 0
      77              : #define NBASE       10
      78              : #define HALF_NBASE  5
      79              : #define DEC_DIGITS  1           /* decimal digits per NBASE digit */
      80              : #define MUL_GUARD_DIGITS    4   /* these are measured in NBASE digits */
      81              : #define DIV_GUARD_DIGITS    8
      82              : 
      83              : typedef signed char NumericDigit;
      84              : #endif
      85              : 
      86              : #if 0
      87              : #define NBASE       100
      88              : #define HALF_NBASE  50
      89              : #define DEC_DIGITS  2           /* decimal digits per NBASE digit */
      90              : #define MUL_GUARD_DIGITS    3   /* these are measured in NBASE digits */
      91              : #define DIV_GUARD_DIGITS    6
      92              : 
      93              : typedef signed char NumericDigit;
      94              : #endif
      95              : 
      96              : #if 1
      97              : #define NBASE       10000
      98              : #define HALF_NBASE  5000
      99              : #define DEC_DIGITS  4           /* decimal digits per NBASE digit */
     100              : #define MUL_GUARD_DIGITS    2   /* these are measured in NBASE digits */
     101              : #define DIV_GUARD_DIGITS    4
     102              : 
     103              : typedef int16 NumericDigit;
     104              : #endif
     105              : 
     106              : #define NBASE_SQR   (NBASE * NBASE)
     107              : 
     108              : /*
     109              :  * The Numeric type as stored on disk.
     110              :  *
     111              :  * If the high bits of the first word of a NumericChoice (n_header, or
     112              :  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
     113              :  * numeric follows the NumericShort format; if they are NUMERIC_POS or
     114              :  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
     115              :  * the value is a NaN or Infinity.  We currently always store SPECIAL values
     116              :  * using just two bytes (i.e. only n_header), but previous releases used only
     117              :  * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
     118              :  * on disk if a database has been migrated using pg_upgrade.  In either case,
     119              :  * the low-order bits of a special value's header are reserved and currently
     120              :  * should always be set to zero.
     121              :  *
     122              :  * In the NumericShort format, the remaining 14 bits of the header word
     123              :  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
     124              :  * negative), 6 for dynamic scale, and 7 for weight.  In practice, most
     125              :  * commonly-encountered values can be represented this way.
     126              :  *
     127              :  * In the NumericLong format, the remaining 14 bits of the header word
     128              :  * (n_long.n_sign_dscale) represent the display scale; and the weight is
     129              :  * stored separately in n_weight.
     130              :  *
     131              :  * NOTE: by convention, values in the packed form have been stripped of
     132              :  * all leading and trailing zero digits (where a "digit" is of base NBASE).
     133              :  * In particular, if the value is zero, there will be no digits at all!
     134              :  * The weight is arbitrary in that case, but we normally set it to zero.
     135              :  */
     136              : 
     137              : struct NumericShort
     138              : {
     139              :     uint16      n_header;       /* Sign + display scale + weight */
     140              :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     141              : };
     142              : 
     143              : struct NumericLong
     144              : {
     145              :     uint16      n_sign_dscale;  /* Sign + display scale */
     146              :     int16       n_weight;       /* Weight of 1st digit  */
     147              :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     148              : };
     149              : 
     150              : union NumericChoice
     151              : {
     152              :     uint16      n_header;       /* Header word */
     153              :     struct NumericLong n_long;  /* Long form (4-byte header) */
     154              :     struct NumericShort n_short;    /* Short form (2-byte header) */
     155              : };
     156              : 
     157              : struct NumericData
     158              : {
     159              :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     160              :     union NumericChoice choice; /* choice of format */
     161              : };
     162              : 
     163              : 
     164              : /*
     165              :  * Interpretation of high bits.
     166              :  */
     167              : 
     168              : #define NUMERIC_SIGN_MASK   0xC000
     169              : #define NUMERIC_POS         0x0000
     170              : #define NUMERIC_NEG         0x4000
     171              : #define NUMERIC_SHORT       0x8000
     172              : #define NUMERIC_SPECIAL     0xC000
     173              : 
     174              : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
     175              : #define NUMERIC_IS_SHORT(n)     (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
     176              : #define NUMERIC_IS_SPECIAL(n)   (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
     177              : 
     178              : #define NUMERIC_HDRSZ   (VARHDRSZ + sizeof(uint16) + sizeof(int16))
     179              : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
     180              : 
     181              : /*
     182              :  * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
     183              :  * header; otherwise, we want the long one.  Instead of testing against each
     184              :  * value, we can just look at the high bit, for a slight efficiency gain.
     185              :  */
     186              : #define NUMERIC_HEADER_IS_SHORT(n)  (((n)->choice.n_header & 0x8000) != 0)
     187              : #define NUMERIC_HEADER_SIZE(n) \
     188              :     (VARHDRSZ + sizeof(uint16) + \
     189              :      (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
     190              : 
     191              : /*
     192              :  * Definitions for special values (NaN, positive infinity, negative infinity).
     193              :  *
     194              :  * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
     195              :  * infinity, 11 for negative infinity.  (This makes the sign bit match where
     196              :  * it is in a short-format value, though we make no use of that at present.)
     197              :  * We could mask off the remaining bits before testing the active bits, but
     198              :  * currently those bits must be zeroes, so masking would just add cycles.
     199              :  */
     200              : #define NUMERIC_EXT_SIGN_MASK   0xF000  /* high bits plus NaN/Inf flag bits */
     201              : #define NUMERIC_NAN             0xC000
     202              : #define NUMERIC_PINF            0xD000
     203              : #define NUMERIC_NINF            0xF000
     204              : #define NUMERIC_INF_SIGN_MASK   0x2000
     205              : 
     206              : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
     207              : #define NUMERIC_IS_NAN(n)       ((n)->choice.n_header == NUMERIC_NAN)
     208              : #define NUMERIC_IS_PINF(n)      ((n)->choice.n_header == NUMERIC_PINF)
     209              : #define NUMERIC_IS_NINF(n)      ((n)->choice.n_header == NUMERIC_NINF)
     210              : #define NUMERIC_IS_INF(n) \
     211              :     (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
     212              : 
     213              : /*
     214              :  * Short format definitions.
     215              :  */
     216              : 
     217              : #define NUMERIC_SHORT_SIGN_MASK         0x2000
     218              : #define NUMERIC_SHORT_DSCALE_MASK       0x1F80
     219              : #define NUMERIC_SHORT_DSCALE_SHIFT      7
     220              : #define NUMERIC_SHORT_DSCALE_MAX        \
     221              :     (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
     222              : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK  0x0040
     223              : #define NUMERIC_SHORT_WEIGHT_MASK       0x003F
     224              : #define NUMERIC_SHORT_WEIGHT_MAX        NUMERIC_SHORT_WEIGHT_MASK
     225              : #define NUMERIC_SHORT_WEIGHT_MIN        (-(NUMERIC_SHORT_WEIGHT_MASK+1))
     226              : 
     227              : /*
     228              :  * Extract sign, display scale, weight.  These macros extract field values
     229              :  * suitable for the NumericVar format from the Numeric (on-disk) format.
     230              :  *
     231              :  * Note that we don't trouble to ensure that dscale and weight read as zero
     232              :  * for an infinity; however, that doesn't matter since we never convert
     233              :  * "special" numerics to NumericVar form.  Only the constants defined below
     234              :  * (const_nan, etc) ever represent a non-finite value as a NumericVar.
     235              :  */
     236              : 
     237              : #define NUMERIC_DSCALE_MASK         0x3FFF
     238              : #define NUMERIC_DSCALE_MAX          NUMERIC_DSCALE_MASK
     239              : 
     240              : #define NUMERIC_SIGN(n) \
     241              :     (NUMERIC_IS_SHORT(n) ? \
     242              :         (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
     243              :          NUMERIC_NEG : NUMERIC_POS) : \
     244              :         (NUMERIC_IS_SPECIAL(n) ? \
     245              :          NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
     246              : #define NUMERIC_DSCALE(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     247              :     ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
     248              :         >> NUMERIC_SHORT_DSCALE_SHIFT \
     249              :     : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
     250              : #define NUMERIC_WEIGHT(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     251              :     (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
     252              :         ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
     253              :      | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
     254              :     : ((n)->choice.n_long.n_weight))
     255              : 
     256              : /*
     257              :  * Maximum weight of a stored Numeric value (based on the use of int16 for the
     258              :  * weight in NumericLong).  Note that intermediate values held in NumericVar
     259              :  * and NumericSumAccum variables may have much larger weights.
     260              :  */
     261              : #define NUMERIC_WEIGHT_MAX          PG_INT16_MAX
     262              : 
     263              : /* ----------
     264              :  * NumericVar is the format we use for arithmetic.  The digit-array part
     265              :  * is the same as the NumericData storage format, but the header is more
     266              :  * complex.
     267              :  *
     268              :  * The value represented by a NumericVar is determined by the sign, weight,
     269              :  * ndigits, and digits[] array.  If it is a "special" value (NaN or Inf)
     270              :  * then only the sign field matters; ndigits should be zero, and the weight
     271              :  * and dscale fields are ignored.
     272              :  *
     273              :  * Note: the first digit of a NumericVar's value is assumed to be multiplied
     274              :  * by NBASE ** weight.  Another way to say it is that there are weight+1
     275              :  * digits before the decimal point.  It is possible to have weight < 0.
     276              :  *
     277              :  * buf points at the physical start of the palloc'd digit buffer for the
     278              :  * NumericVar.  digits points at the first digit in actual use (the one
     279              :  * with the specified weight).  We normally leave an unused digit or two
     280              :  * (preset to zeroes) between buf and digits, so that there is room to store
     281              :  * a carry out of the top digit without reallocating space.  We just need to
     282              :  * decrement digits (and increment weight) to make room for the carry digit.
     283              :  * (There is no such extra space in a numeric value stored in the database,
     284              :  * only in a NumericVar in memory.)
     285              :  *
     286              :  * If buf is NULL then the digit buffer isn't actually palloc'd and should
     287              :  * not be freed --- see the constants below for an example.
     288              :  *
     289              :  * dscale, or display scale, is the nominal precision expressed as number
     290              :  * of digits after the decimal point (it must always be >= 0 at present).
     291              :  * dscale may be more than the number of physically stored fractional digits,
     292              :  * implying that we have suppressed storage of significant trailing zeroes.
     293              :  * It should never be less than the number of stored digits, since that would
     294              :  * imply hiding digits that are present.  NOTE that dscale is always expressed
     295              :  * in *decimal* digits, and so it may correspond to a fractional number of
     296              :  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
     297              :  *
     298              :  * rscale, or result scale, is the target precision for a computation.
     299              :  * Like dscale it is expressed as number of *decimal* digits after the decimal
     300              :  * point, and is always >= 0 at present.
     301              :  * Note that rscale is not stored in variables --- it's figured on-the-fly
     302              :  * from the dscales of the inputs.
     303              :  *
     304              :  * While we consistently use "weight" to refer to the base-NBASE weight of
     305              :  * a numeric value, it is convenient in some scale-related calculations to
     306              :  * make use of the base-10 weight (ie, the approximate log10 of the value).
     307              :  * To avoid confusion, such a decimal-units weight is called a "dweight".
     308              :  *
     309              :  * NB: All the variable-level functions are written in a style that makes it
     310              :  * possible to give one and the same variable as argument and destination.
     311              :  * This is feasible because the digit buffer is separate from the variable.
     312              :  * ----------
     313              :  */
     314              : typedef struct NumericVar
     315              : {
     316              :     int         ndigits;        /* # of digits in digits[] - can be 0! */
     317              :     int         weight;         /* weight of first digit */
     318              :     int         sign;           /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
     319              :     int         dscale;         /* display scale */
     320              :     NumericDigit *buf;          /* start of palloc'd space for digits[] */
     321              :     NumericDigit *digits;       /* base-NBASE digits */
     322              : } NumericVar;
     323              : 
     324              : 
     325              : /* ----------
     326              :  * Data for generate_series
     327              :  * ----------
     328              :  */
     329              : typedef struct
     330              : {
     331              :     NumericVar  current;
     332              :     NumericVar  stop;
     333              :     NumericVar  step;
     334              : } generate_series_numeric_fctx;
     335              : 
     336              : 
     337              : /* ----------
     338              :  * Sort support.
     339              :  * ----------
     340              :  */
     341              : typedef struct
     342              : {
     343              :     void       *buf;            /* buffer for short varlenas */
     344              :     int64       input_count;    /* number of non-null values seen */
     345              :     bool        estimating;     /* true if estimating cardinality */
     346              : 
     347              :     hyperLogLogState abbr_card; /* cardinality estimator */
     348              : } NumericSortSupport;
     349              : 
     350              : 
     351              : /* ----------
     352              :  * Fast sum accumulator.
     353              :  *
     354              :  * NumericSumAccum is used to implement SUM(), and other standard aggregates
     355              :  * that track the sum of input values.  It uses 32-bit integers to store the
     356              :  * digits, instead of the normal 16-bit integers (with NBASE=10000).  This
     357              :  * way, we can safely accumulate up to NBASE - 1 values without propagating
     358              :  * carry, before risking overflow of any of the digits.  'num_uncarried'
     359              :  * tracks how many values have been accumulated without propagating carry.
     360              :  *
     361              :  * Positive and negative values are accumulated separately, in 'pos_digits'
     362              :  * and 'neg_digits'.  This is simpler and faster than deciding whether to add
     363              :  * or subtract from the current value, for each new value (see sub_var() for
     364              :  * the logic we avoid by doing this).  Both buffers are of same size, and
     365              :  * have the same weight and scale.  In accum_sum_final(), the positive and
     366              :  * negative sums are added together to produce the final result.
     367              :  *
     368              :  * When a new value has a larger ndigits or weight than the accumulator
     369              :  * currently does, the accumulator is enlarged to accommodate the new value.
     370              :  * We normally have one zero digit reserved for carry propagation, and that
     371              :  * is indicated by the 'have_carry_space' flag.  When accum_sum_carry() uses
     372              :  * up the reserved digit, it clears the 'have_carry_space' flag.  The next
     373              :  * call to accum_sum_add() will enlarge the buffer, to make room for the
     374              :  * extra digit, and set the flag again.
     375              :  *
     376              :  * To initialize a new accumulator, simply reset all fields to zeros.
     377              :  *
     378              :  * The accumulator does not handle NaNs.
     379              :  * ----------
     380              :  */
     381              : typedef struct NumericSumAccum
     382              : {
     383              :     int         ndigits;
     384              :     int         weight;
     385              :     int         dscale;
     386              :     int         num_uncarried;
     387              :     bool        have_carry_space;
     388              :     int32      *pos_digits;
     389              :     int32      *neg_digits;
     390              : } NumericSumAccum;
     391              : 
     392              : 
     393              : /*
     394              :  * We define our own macros for packing and unpacking abbreviated-key
     395              :  * representations, just to have a notational indication that that's
     396              :  * what we're doing.  Now that sizeof(Datum) is always 8, we can rely
     397              :  * on fitting an int64 into Datum.
     398              :  *
     399              :  * The range of abbreviations for finite values is from +PG_INT64_MAX
     400              :  * to -PG_INT64_MAX.  NaN has the abbreviation PG_INT64_MIN, and we
     401              :  * define the sort ordering to make that work out properly (see further
     402              :  * comments below).  PINF and NINF share the abbreviations of the largest
     403              :  * and smallest finite abbreviation classes.
     404              :  */
     405              : #define NumericAbbrevGetDatum(X) Int64GetDatum(X)
     406              : #define DatumGetNumericAbbrev(X) DatumGetInt64(X)
     407              : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT64_MIN)
     408              : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT64_MAX)
     409              : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT64_MAX)
     410              : 
     411              : 
     412              : /* ----------
     413              :  * Some preinitialized constants
     414              :  * ----------
     415              :  */
     416              : static const NumericDigit const_zero_data[1] = {0};
     417              : static const NumericVar const_zero =
     418              : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
     419              : 
     420              : static const NumericDigit const_one_data[1] = {1};
     421              : static const NumericVar const_one =
     422              : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
     423              : 
     424              : static const NumericVar const_minus_one =
     425              : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
     426              : 
     427              : static const NumericDigit const_two_data[1] = {2};
     428              : static const NumericVar const_two =
     429              : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
     430              : 
     431              : #if DEC_DIGITS == 4
     432              : static const NumericDigit const_zero_point_nine_data[1] = {9000};
     433              : #elif DEC_DIGITS == 2
     434              : static const NumericDigit const_zero_point_nine_data[1] = {90};
     435              : #elif DEC_DIGITS == 1
     436              : static const NumericDigit const_zero_point_nine_data[1] = {9};
     437              : #endif
     438              : static const NumericVar const_zero_point_nine =
     439              : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
     440              : 
     441              : #if DEC_DIGITS == 4
     442              : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
     443              : #elif DEC_DIGITS == 2
     444              : static const NumericDigit const_one_point_one_data[2] = {1, 10};
     445              : #elif DEC_DIGITS == 1
     446              : static const NumericDigit const_one_point_one_data[2] = {1, 1};
     447              : #endif
     448              : static const NumericVar const_one_point_one =
     449              : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
     450              : 
     451              : static const NumericVar const_nan =
     452              : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
     453              : 
     454              : static const NumericVar const_pinf =
     455              : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
     456              : 
     457              : static const NumericVar const_ninf =
     458              : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
     459              : 
     460              : #if DEC_DIGITS == 4
     461              : static const int round_powers[4] = {0, 1000, 100, 10};
     462              : #endif
     463              : 
     464              : 
     465              : /* ----------
     466              :  * Local functions
     467              :  * ----------
     468              :  */
     469              : 
     470              : #ifdef NUMERIC_DEBUG
     471              : static void dump_numeric(const char *str, Numeric num);
     472              : static void dump_var(const char *str, NumericVar *var);
     473              : #else
     474              : #define dump_numeric(s,n)
     475              : #define dump_var(s,v)
     476              : #endif
     477              : 
     478              : #define digitbuf_alloc(ndigits)  \
     479              :     ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
     480              : #define digitbuf_free(buf)  \
     481              :     do { \
     482              :          if ((buf) != NULL) \
     483              :              pfree(buf); \
     484              :     } while (0)
     485              : 
     486              : #define init_var(v)     memset(v, 0, sizeof(NumericVar))
     487              : 
     488              : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
     489              :     (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
     490              : #define NUMERIC_NDIGITS(num) \
     491              :     ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
     492              : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
     493              :     ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
     494              :     (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
     495              :     (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
     496              : 
     497              : static void alloc_var(NumericVar *var, int ndigits);
     498              : static void free_var(NumericVar *var);
     499              : static void zero_var(NumericVar *var);
     500              : 
     501              : static bool set_var_from_str(const char *str, const char *cp,
     502              :                              NumericVar *dest, const char **endptr,
     503              :                              Node *escontext);
     504              : static bool set_var_from_non_decimal_integer_str(const char *str,
     505              :                                                  const char *cp, int sign,
     506              :                                                  int base, NumericVar *dest,
     507              :                                                  const char **endptr,
     508              :                                                  Node *escontext);
     509              : static void set_var_from_num(Numeric num, NumericVar *dest);
     510              : static void init_var_from_num(Numeric num, NumericVar *dest);
     511              : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
     512              : static char *get_str_from_var(const NumericVar *var);
     513              : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
     514              : 
     515              : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
     516              : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
     517              : 
     518              : static Numeric duplicate_numeric(Numeric num);
     519              : static Numeric make_result(const NumericVar *var);
     520              : static Numeric make_result_safe(const NumericVar *var, Node *escontext);
     521              : 
     522              : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
     523              : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
     524              : 
     525              : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
     526              : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
     527              : static void int64_to_numericvar(int64 val, NumericVar *var);
     528              : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
     529              : static void int128_to_numericvar(INT128 val, NumericVar *var);
     530              : static double numericvar_to_double_no_overflow(const NumericVar *var);
     531              : 
     532              : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
     533              : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
     534              : static int  numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
     535              : static int  numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
     536              : 
     537              : static Datum numeric_abbrev_convert_var(const NumericVar *var,
     538              :                                         NumericSortSupport *nss);
     539              : 
     540              : static int  cmp_numerics(Numeric num1, Numeric num2);
     541              : static int  cmp_var(const NumericVar *var1, const NumericVar *var2);
     542              : static int  cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
     543              :                            int var1weight, int var1sign,
     544              :                            const NumericDigit *var2digits, int var2ndigits,
     545              :                            int var2weight, int var2sign);
     546              : static void add_var(const NumericVar *var1, const NumericVar *var2,
     547              :                     NumericVar *result);
     548              : static void sub_var(const NumericVar *var1, const NumericVar *var2,
     549              :                     NumericVar *result);
     550              : static void mul_var(const NumericVar *var1, const NumericVar *var2,
     551              :                     NumericVar *result,
     552              :                     int rscale);
     553              : static void mul_var_short(const NumericVar *var1, const NumericVar *var2,
     554              :                           NumericVar *result);
     555              : static void div_var(const NumericVar *var1, const NumericVar *var2,
     556              :                     NumericVar *result, int rscale, bool round, bool exact);
     557              : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
     558              :                         NumericVar *result, int rscale, bool round);
     559              : #ifdef HAVE_INT128
     560              : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
     561              :                           NumericVar *result, int rscale, bool round);
     562              : #endif
     563              : static int  select_div_scale(const NumericVar *var1, const NumericVar *var2);
     564              : static void mod_var(const NumericVar *var1, const NumericVar *var2,
     565              :                     NumericVar *result);
     566              : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
     567              :                         NumericVar *quot, NumericVar *rem);
     568              : static void ceil_var(const NumericVar *var, NumericVar *result);
     569              : static void floor_var(const NumericVar *var, NumericVar *result);
     570              : 
     571              : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
     572              :                     NumericVar *result);
     573              : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
     574              : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
     575              : static int  estimate_ln_dweight(const NumericVar *var);
     576              : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
     577              : static void log_var(const NumericVar *base, const NumericVar *num,
     578              :                     NumericVar *result);
     579              : static void power_var(const NumericVar *base, const NumericVar *exp,
     580              :                       NumericVar *result);
     581              : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
     582              :                           NumericVar *result);
     583              : static void power_ten_int(int exp, NumericVar *result);
     584              : static void random_var(pg_prng_state *state, const NumericVar *rmin,
     585              :                        const NumericVar *rmax, NumericVar *result);
     586              : 
     587              : static int  cmp_abs(const NumericVar *var1, const NumericVar *var2);
     588              : static int  cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
     589              :                            int var1weight,
     590              :                            const NumericDigit *var2digits, int var2ndigits,
     591              :                            int var2weight);
     592              : static void add_abs(const NumericVar *var1, const NumericVar *var2,
     593              :                     NumericVar *result);
     594              : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
     595              :                     NumericVar *result);
     596              : static void round_var(NumericVar *var, int rscale);
     597              : static void trunc_var(NumericVar *var, int rscale);
     598              : static void strip_var(NumericVar *var);
     599              : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
     600              :                            const NumericVar *count_var,
     601              :                            NumericVar *result_var);
     602              : 
     603              : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
     604              : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
     605              : static void accum_sum_carry(NumericSumAccum *accum);
     606              : static void accum_sum_reset(NumericSumAccum *accum);
     607              : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
     608              : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
     609              : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
     610              : 
     611              : 
     612              : /* ----------------------------------------------------------------------
     613              :  *
     614              :  * Input-, output- and rounding-functions
     615              :  *
     616              :  * ----------------------------------------------------------------------
     617              :  */
     618              : 
     619              : 
     620              : /*
     621              :  * numeric_in() -
     622              :  *
     623              :  *  Input function for numeric data type
     624              :  */
     625              : Datum
     626       103741 : numeric_in(PG_FUNCTION_ARGS)
     627              : {
     628       103741 :     char       *str = PG_GETARG_CSTRING(0);
     629              : #ifdef NOT_USED
     630              :     Oid         typelem = PG_GETARG_OID(1);
     631              : #endif
     632       103741 :     int32       typmod = PG_GETARG_INT32(2);
     633       103741 :     Node       *escontext = fcinfo->context;
     634              :     Numeric     res;
     635              :     const char *cp;
     636              :     const char *numstart;
     637              :     int         sign;
     638              : 
     639              :     /* Skip leading spaces */
     640       103741 :     cp = str;
     641       120021 :     while (*cp)
     642              :     {
     643       120009 :         if (!isspace((unsigned char) *cp))
     644       103729 :             break;
     645        16280 :         cp++;
     646              :     }
     647              : 
     648              :     /*
     649              :      * Process the number's sign. This duplicates logic in set_var_from_str(),
     650              :      * but it's worth doing here, since it simplifies the handling of
     651              :      * infinities and non-decimal integers.
     652              :      */
     653       103741 :     numstart = cp;
     654       103741 :     sign = NUMERIC_POS;
     655              : 
     656       103741 :     if (*cp == '+')
     657           32 :         cp++;
     658       103709 :     else if (*cp == '-')
     659              :     {
     660         2496 :         sign = NUMERIC_NEG;
     661         2496 :         cp++;
     662              :     }
     663              : 
     664              :     /*
     665              :      * Check for NaN and infinities.  We recognize the same strings allowed by
     666              :      * float8in().
     667              :      *
     668              :      * Since all other legal inputs have a digit or a decimal point after the
     669              :      * sign, we need only check for NaN/infinity if that's not the case.
     670              :      */
     671       103741 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
     672              :     {
     673              :         /*
     674              :          * The number must be NaN or infinity; anything else can only be a
     675              :          * syntax error. Note that NaN mustn't have a sign.
     676              :          */
     677         1198 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     678              :         {
     679          396 :             res = make_result(&const_nan);
     680          396 :             cp = numstart + 3;
     681              :         }
     682          802 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     683              :         {
     684          337 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     685          337 :             cp += 8;
     686              :         }
     687          465 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
     688              :         {
     689          392 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     690          392 :             cp += 3;
     691              :         }
     692              :         else
     693           73 :             goto invalid_syntax;
     694              : 
     695              :         /*
     696              :          * Check for trailing junk; there should be nothing left but spaces.
     697              :          *
     698              :          * We intentionally do this check before applying the typmod because
     699              :          * we would like to throw any trailing-junk syntax error before any
     700              :          * semantic error resulting from apply_typmod_special().
     701              :          */
     702         1153 :         while (*cp)
     703              :         {
     704           28 :             if (!isspace((unsigned char) *cp))
     705            0 :                 goto invalid_syntax;
     706           28 :             cp++;
     707              :         }
     708              : 
     709         1125 :         if (!apply_typmod_special(res, typmod, escontext))
     710            0 :             PG_RETURN_NULL();
     711              :     }
     712              :     else
     713              :     {
     714              :         /*
     715              :          * We have a normal numeric value, which may be a non-decimal integer
     716              :          * or a regular decimal number.
     717              :          */
     718              :         NumericVar  value;
     719              :         int         base;
     720              : 
     721       102543 :         init_var(&value);
     722              : 
     723              :         /*
     724              :          * Determine the number's base by looking for a non-decimal prefix
     725              :          * indicator ("0x", "0o", or "0b").
     726              :          */
     727       102543 :         if (cp[0] == '0')
     728              :         {
     729        33400 :             switch (cp[1])
     730              :             {
     731           48 :                 case 'x':
     732              :                 case 'X':
     733           48 :                     base = 16;
     734           48 :                     break;
     735           28 :                 case 'o':
     736              :                 case 'O':
     737           28 :                     base = 8;
     738           28 :                     break;
     739           28 :                 case 'b':
     740              :                 case 'B':
     741           28 :                     base = 2;
     742           28 :                     break;
     743        33296 :                 default:
     744        33296 :                     base = 10;
     745              :             }
     746              :         }
     747              :         else
     748        69143 :             base = 10;
     749              : 
     750              :         /* Parse the rest of the number and apply the sign */
     751       102543 :         if (base == 10)
     752              :         {
     753       102439 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     754           16 :                 PG_RETURN_NULL();
     755       102407 :             value.sign = sign;
     756              :         }
     757              :         else
     758              :         {
     759          104 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
     760              :                                                       &value, &cp, escontext))
     761            0 :                 PG_RETURN_NULL();
     762              :         }
     763              : 
     764              :         /*
     765              :          * Should be nothing left but spaces. As above, throw any typmod error
     766              :          * after finishing syntax check.
     767              :          */
     768       102551 :         while (*cp)
     769              :         {
     770          100 :             if (!isspace((unsigned char) *cp))
     771           48 :                 goto invalid_syntax;
     772           52 :             cp++;
     773              :         }
     774              : 
     775       102451 :         if (!apply_typmod(&value, typmod, escontext))
     776           16 :             PG_RETURN_NULL();
     777              : 
     778       102435 :         res = make_result_safe(&value, escontext);
     779              : 
     780       102435 :         free_var(&value);
     781              :     }
     782              : 
     783       103560 :     PG_RETURN_NUMERIC(res);
     784              : 
     785          121 : invalid_syntax:
     786          121 :     ereturn(escontext, (Datum) 0,
     787              :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     788              :              errmsg("invalid input syntax for type %s: \"%s\"",
     789              :                     "numeric", str)));
     790              : }
     791              : 
     792              : 
     793              : /*
     794              :  * numeric_out() -
     795              :  *
     796              :  *  Output function for numeric data type
     797              :  */
     798              : Datum
     799       535502 : numeric_out(PG_FUNCTION_ARGS)
     800              : {
     801       535502 :     Numeric     num = PG_GETARG_NUMERIC(0);
     802              :     NumericVar  x;
     803              :     char       *str;
     804              : 
     805              :     /*
     806              :      * Handle NaN and infinities
     807              :      */
     808       535502 :     if (NUMERIC_IS_SPECIAL(num))
     809              :     {
     810         2344 :         if (NUMERIC_IS_PINF(num))
     811          688 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     812         1656 :         else if (NUMERIC_IS_NINF(num))
     813          436 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     814              :         else
     815         1220 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     816              :     }
     817              : 
     818              :     /*
     819              :      * Get the number in the variable format.
     820              :      */
     821       533158 :     init_var_from_num(num, &x);
     822              : 
     823       533158 :     str = get_str_from_var(&x);
     824              : 
     825       533158 :     PG_RETURN_CSTRING(str);
     826              : }
     827              : 
     828              : /*
     829              :  * numeric_is_nan() -
     830              :  *
     831              :  *  Is Numeric value a NaN?
     832              :  */
     833              : bool
     834         4339 : numeric_is_nan(Numeric num)
     835              : {
     836         4339 :     return NUMERIC_IS_NAN(num);
     837              : }
     838              : 
     839              : /*
     840              :  * numeric_is_inf() -
     841              :  *
     842              :  *  Is Numeric value an infinity?
     843              :  */
     844              : bool
     845          801 : numeric_is_inf(Numeric num)
     846              : {
     847          801 :     return NUMERIC_IS_INF(num);
     848              : }
     849              : 
     850              : /*
     851              :  * numeric_is_integral() -
     852              :  *
     853              :  *  Is Numeric value integral?
     854              :  */
     855              : static bool
     856           54 : numeric_is_integral(Numeric num)
     857              : {
     858              :     NumericVar  arg;
     859              : 
     860              :     /* Reject NaN, but infinities are considered integral */
     861           54 :     if (NUMERIC_IS_SPECIAL(num))
     862              :     {
     863           25 :         if (NUMERIC_IS_NAN(num))
     864            0 :             return false;
     865           25 :         return true;
     866              :     }
     867              : 
     868              :     /* Integral if there are no digits to the right of the decimal point */
     869           29 :     init_var_from_num(num, &arg);
     870              : 
     871           29 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
     872              : }
     873              : 
     874              : /*
     875              :  * make_numeric_typmod() -
     876              :  *
     877              :  *  Pack numeric precision and scale values into a typmod.  The upper 16 bits
     878              :  *  are used for the precision (though actually not all these bits are needed,
     879              :  *  since the maximum allowed precision is 1000).  The lower 16 bits are for
     880              :  *  the scale, but since the scale is constrained to the range [-1000, 1000],
     881              :  *  we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
     882              :  *  unset, for possible future use.
     883              :  *
     884              :  *  For purely historical reasons VARHDRSZ is then added to the result, thus
     885              :  *  the unused space in the upper 16 bits is not all as freely available as it
     886              :  *  might seem.  (We can't let the result overflow to a negative int32, as
     887              :  *  other parts of the system would interpret that as not-a-valid-typmod.)
     888              :  */
     889              : static inline int32
     890         1059 : make_numeric_typmod(int precision, int scale)
     891              : {
     892         1059 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
     893              : }
     894              : 
     895              : /*
     896              :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
     897              :  */
     898              : static inline bool
     899       119710 : is_valid_numeric_typmod(int32 typmod)
     900              : {
     901       119710 :     return typmod >= (int32) VARHDRSZ;
     902              : }
     903              : 
     904              : /*
     905              :  * numeric_typmod_precision() -
     906              :  *
     907              :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
     908              :  */
     909              : static inline int
     910        32907 : numeric_typmod_precision(int32 typmod)
     911              : {
     912        32907 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
     913              : }
     914              : 
     915              : /*
     916              :  * numeric_typmod_scale() -
     917              :  *
     918              :  *  Extract the scale from a numeric typmod --- see make_numeric_typmod().
     919              :  *
     920              :  *  Note that the scale may be negative, so we must do sign extension when
     921              :  *  unpacking it.  We do this using the bit hack (x^1024)-1024, which sign
     922              :  *  extends an 11-bit two's complement number x.
     923              :  */
     924              : static inline int
     925        28007 : numeric_typmod_scale(int32 typmod)
     926              : {
     927        28007 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
     928              : }
     929              : 
     930              : /*
     931              :  * numeric_maximum_size() -
     932              :  *
     933              :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
     934              :  */
     935              : int32
     936         4900 : numeric_maximum_size(int32 typmod)
     937              : {
     938              :     int         precision;
     939              :     int         numeric_digits;
     940              : 
     941         4900 :     if (!is_valid_numeric_typmod(typmod))
     942            0 :         return -1;
     943              : 
     944              :     /* precision (ie, max # of digits) is in upper bits of typmod */
     945         4900 :     precision = numeric_typmod_precision(typmod);
     946              : 
     947              :     /*
     948              :      * This formula computes the maximum number of NumericDigits we could need
     949              :      * in order to store the specified number of decimal digits. Because the
     950              :      * weight is stored as a number of NumericDigits rather than a number of
     951              :      * decimal digits, it's possible that the first NumericDigit will contain
     952              :      * only a single decimal digit.  Thus, the first two decimal digits can
     953              :      * require two NumericDigits to store, but it isn't until we reach
     954              :      * DEC_DIGITS + 2 decimal digits that we potentially need a third
     955              :      * NumericDigit.
     956              :      */
     957         4900 :     numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
     958              : 
     959              :     /*
     960              :      * In most cases, the size of a numeric will be smaller than the value
     961              :      * computed below, because the varlena header will typically get toasted
     962              :      * down to a single byte before being stored on disk, and it may also be
     963              :      * possible to use a short numeric header.  But our job here is to compute
     964              :      * the worst case.
     965              :      */
     966         4900 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
     967              : }
     968              : 
     969              : /*
     970              :  * numeric_out_sci() -
     971              :  *
     972              :  *  Output function for numeric data type in scientific notation.
     973              :  */
     974              : char *
     975          164 : numeric_out_sci(Numeric num, int scale)
     976              : {
     977              :     NumericVar  x;
     978              :     char       *str;
     979              : 
     980              :     /*
     981              :      * Handle NaN and infinities
     982              :      */
     983          164 :     if (NUMERIC_IS_SPECIAL(num))
     984              :     {
     985           12 :         if (NUMERIC_IS_PINF(num))
     986            4 :             return pstrdup("Infinity");
     987            8 :         else if (NUMERIC_IS_NINF(num))
     988            4 :             return pstrdup("-Infinity");
     989              :         else
     990            4 :             return pstrdup("NaN");
     991              :     }
     992              : 
     993          152 :     init_var_from_num(num, &x);
     994              : 
     995          152 :     str = get_str_from_var_sci(&x, scale);
     996              : 
     997          152 :     return str;
     998              : }
     999              : 
    1000              : /*
    1001              :  * numeric_normalize() -
    1002              :  *
    1003              :  *  Output function for numeric data type, suppressing insignificant trailing
    1004              :  *  zeroes and then any trailing decimal point.  The intent of this is to
    1005              :  *  produce strings that are equal if and only if the input numeric values
    1006              :  *  compare equal.
    1007              :  */
    1008              : char *
    1009        22529 : numeric_normalize(Numeric num)
    1010              : {
    1011              :     NumericVar  x;
    1012              :     char       *str;
    1013              :     int         last;
    1014              : 
    1015              :     /*
    1016              :      * Handle NaN and infinities
    1017              :      */
    1018        22529 :     if (NUMERIC_IS_SPECIAL(num))
    1019              :     {
    1020            0 :         if (NUMERIC_IS_PINF(num))
    1021            0 :             return pstrdup("Infinity");
    1022            0 :         else if (NUMERIC_IS_NINF(num))
    1023            0 :             return pstrdup("-Infinity");
    1024              :         else
    1025            0 :             return pstrdup("NaN");
    1026              :     }
    1027              : 
    1028        22529 :     init_var_from_num(num, &x);
    1029              : 
    1030        22529 :     str = get_str_from_var(&x);
    1031              : 
    1032              :     /* If there's no decimal point, there's certainly nothing to remove. */
    1033        22529 :     if (strchr(str, '.') != NULL)
    1034              :     {
    1035              :         /*
    1036              :          * Back up over trailing fractional zeroes.  Since there is a decimal
    1037              :          * point, this loop will terminate safely.
    1038              :          */
    1039           31 :         last = strlen(str) - 1;
    1040           62 :         while (str[last] == '0')
    1041           31 :             last--;
    1042              : 
    1043              :         /* We want to get rid of the decimal point too, if it's now last. */
    1044           31 :         if (str[last] == '.')
    1045           31 :             last--;
    1046              : 
    1047              :         /* Delete whatever we backed up over. */
    1048           31 :         str[last + 1] = '\0';
    1049              :     }
    1050              : 
    1051        22529 :     return str;
    1052              : }
    1053              : 
    1054              : /*
    1055              :  *      numeric_recv            - converts external binary format to numeric
    1056              :  *
    1057              :  * External format is a sequence of int16's:
    1058              :  * ndigits, weight, sign, dscale, NumericDigits.
    1059              :  */
    1060              : Datum
    1061           51 : numeric_recv(PG_FUNCTION_ARGS)
    1062              : {
    1063           51 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    1064              : 
    1065              : #ifdef NOT_USED
    1066              :     Oid         typelem = PG_GETARG_OID(1);
    1067              : #endif
    1068           51 :     int32       typmod = PG_GETARG_INT32(2);
    1069              :     NumericVar  value;
    1070              :     Numeric     res;
    1071              :     int         len,
    1072              :                 i;
    1073              : 
    1074           51 :     init_var(&value);
    1075              : 
    1076           51 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1077              : 
    1078           51 :     alloc_var(&value, len);
    1079              : 
    1080           51 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
    1081              :     /* we allow any int16 for weight --- OK? */
    1082              : 
    1083           51 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1084           51 :     if (!(value.sign == NUMERIC_POS ||
    1085            0 :           value.sign == NUMERIC_NEG ||
    1086            0 :           value.sign == NUMERIC_NAN ||
    1087            0 :           value.sign == NUMERIC_PINF ||
    1088            0 :           value.sign == NUMERIC_NINF))
    1089            0 :         ereport(ERROR,
    1090              :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1091              :                  errmsg("invalid sign in external \"numeric\" value")));
    1092              : 
    1093           51 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1094           51 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
    1095            0 :         ereport(ERROR,
    1096              :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1097              :                  errmsg("invalid scale in external \"numeric\" value")));
    1098              : 
    1099          137 :     for (i = 0; i < len; i++)
    1100              :     {
    1101           86 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
    1102              : 
    1103           86 :         if (d < 0 || d >= NBASE)
    1104            0 :             ereport(ERROR,
    1105              :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1106              :                      errmsg("invalid digit in external \"numeric\" value")));
    1107           86 :         value.digits[i] = d;
    1108              :     }
    1109              : 
    1110              :     /*
    1111              :      * If the given dscale would hide any digits, truncate those digits away.
    1112              :      * We could alternatively throw an error, but that would take a bunch of
    1113              :      * extra code (about as much as trunc_var involves), and it might cause
    1114              :      * client compatibility issues.  Be careful not to apply trunc_var to
    1115              :      * special values, as it could do the wrong thing; we don't need it
    1116              :      * anyway, since make_result will ignore all but the sign field.
    1117              :      *
    1118              :      * After doing that, be sure to check the typmod restriction.
    1119              :      */
    1120           51 :     if (value.sign == NUMERIC_POS ||
    1121            0 :         value.sign == NUMERIC_NEG)
    1122              :     {
    1123           51 :         trunc_var(&value, value.dscale);
    1124              : 
    1125           51 :         (void) apply_typmod(&value, typmod, NULL);
    1126              : 
    1127           51 :         res = make_result(&value);
    1128              :     }
    1129              :     else
    1130              :     {
    1131              :         /* apply_typmod_special wants us to make the Numeric first */
    1132            0 :         res = make_result(&value);
    1133              : 
    1134            0 :         (void) apply_typmod_special(res, typmod, NULL);
    1135              :     }
    1136              : 
    1137           51 :     free_var(&value);
    1138              : 
    1139           51 :     PG_RETURN_NUMERIC(res);
    1140              : }
    1141              : 
    1142              : /*
    1143              :  *      numeric_send            - converts numeric to binary format
    1144              :  */
    1145              : Datum
    1146           35 : numeric_send(PG_FUNCTION_ARGS)
    1147              : {
    1148           35 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1149              :     NumericVar  x;
    1150              :     StringInfoData buf;
    1151              :     int         i;
    1152              : 
    1153           35 :     init_var_from_num(num, &x);
    1154              : 
    1155           35 :     pq_begintypsend(&buf);
    1156              : 
    1157           35 :     pq_sendint16(&buf, x.ndigits);
    1158           35 :     pq_sendint16(&buf, x.weight);
    1159           35 :     pq_sendint16(&buf, x.sign);
    1160           35 :     pq_sendint16(&buf, x.dscale);
    1161           97 :     for (i = 0; i < x.ndigits; i++)
    1162           62 :         pq_sendint16(&buf, x.digits[i]);
    1163              : 
    1164           35 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    1165              : }
    1166              : 
    1167              : 
    1168              : /*
    1169              :  * numeric_support()
    1170              :  *
    1171              :  * Planner support function for the numeric() length coercion function.
    1172              :  *
    1173              :  * Flatten calls that solely represent increases in allowable precision.
    1174              :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
    1175              :  * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
    1176              :  * an unconstrained numeric to any constrained numeric is also unoptimizable.
    1177              :  */
    1178              : Datum
    1179          427 : numeric_support(PG_FUNCTION_ARGS)
    1180              : {
    1181          427 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1182          427 :     Node       *ret = NULL;
    1183              : 
    1184          427 :     if (IsA(rawreq, SupportRequestSimplify))
    1185              :     {
    1186          187 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
    1187          187 :         FuncExpr   *expr = req->fcall;
    1188              :         Node       *typmod;
    1189              : 
    1190              :         Assert(list_length(expr->args) >= 2);
    1191              : 
    1192          187 :         typmod = (Node *) lsecond(expr->args);
    1193              : 
    1194          187 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
    1195              :         {
    1196          187 :             Node       *source = (Node *) linitial(expr->args);
    1197          187 :             int32       old_typmod = exprTypmod(source);
    1198          187 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    1199          187 :             int32       old_scale = numeric_typmod_scale(old_typmod);
    1200          187 :             int32       new_scale = numeric_typmod_scale(new_typmod);
    1201          187 :             int32       old_precision = numeric_typmod_precision(old_typmod);
    1202          187 :             int32       new_precision = numeric_typmod_precision(new_typmod);
    1203              : 
    1204              :             /*
    1205              :              * If new_typmod is invalid, the destination is unconstrained;
    1206              :              * that's always OK.  If old_typmod is valid, the source is
    1207              :              * constrained, and we're OK if the scale is unchanged and the
    1208              :              * precision is not decreasing.  See further notes in function
    1209              :              * header comment.
    1210              :              */
    1211          374 :             if (!is_valid_numeric_typmod(new_typmod) ||
    1212          196 :                 (is_valid_numeric_typmod(old_typmod) &&
    1213            4 :                  new_scale == old_scale && new_precision >= old_precision))
    1214            4 :                 ret = relabel_to_typmod(source, new_typmod);
    1215              :         }
    1216              :     }
    1217              : 
    1218          427 :     PG_RETURN_POINTER(ret);
    1219              : }
    1220              : 
    1221              : /*
    1222              :  * numeric() -
    1223              :  *
    1224              :  *  This is a special function called by the Postgres database system
    1225              :  *  before a value is stored in a tuple's attribute. The precision and
    1226              :  *  scale of the attribute have to be applied on the value.
    1227              :  */
    1228              : Datum
    1229         8083 : numeric     (PG_FUNCTION_ARGS)
    1230              : {
    1231         8083 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1232         8083 :     int32       typmod = PG_GETARG_INT32(1);
    1233              :     Numeric     new;
    1234              :     int         precision;
    1235              :     int         scale;
    1236              :     int         ddigits;
    1237              :     int         maxdigits;
    1238              :     int         dscale;
    1239              :     NumericVar  var;
    1240              : 
    1241              :     /*
    1242              :      * Handle NaN and infinities: if apply_typmod_special doesn't complain,
    1243              :      * just return a copy of the input.
    1244              :      */
    1245         8083 :     if (NUMERIC_IS_SPECIAL(num))
    1246              :     {
    1247          172 :         if (!apply_typmod_special(num, typmod, fcinfo->context))
    1248            0 :             PG_RETURN_NULL();
    1249          160 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1250              :     }
    1251              : 
    1252              :     /*
    1253              :      * If the value isn't a valid type modifier, simply return a copy of the
    1254              :      * input value
    1255              :      */
    1256         7911 :     if (!is_valid_numeric_typmod(typmod))
    1257            0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1258              : 
    1259              :     /*
    1260              :      * Get the precision and scale out of the typmod value
    1261              :      */
    1262         7911 :     precision = numeric_typmod_precision(typmod);
    1263         7911 :     scale = numeric_typmod_scale(typmod);
    1264         7911 :     maxdigits = precision - scale;
    1265              : 
    1266              :     /* The target display scale is non-negative */
    1267         7911 :     dscale = Max(scale, 0);
    1268              : 
    1269              :     /*
    1270              :      * If the number is certainly in bounds and due to the target scale no
    1271              :      * rounding could be necessary, just make a copy of the input and modify
    1272              :      * its scale fields, unless the larger scale forces us to abandon the
    1273              :      * short representation.  (Note we assume the existing dscale is
    1274              :      * honest...)
    1275              :      */
    1276         7911 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1277         7911 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
    1278         4838 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
    1279            0 :             || !NUMERIC_IS_SHORT(num)))
    1280              :     {
    1281         4838 :         new = duplicate_numeric(num);
    1282         4838 :         if (NUMERIC_IS_SHORT(num))
    1283         4838 :             new->choice.n_short.n_header =
    1284         4838 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
    1285         4838 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
    1286              :         else
    1287            0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
    1288            0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
    1289         4838 :         PG_RETURN_NUMERIC(new);
    1290              :     }
    1291              : 
    1292              :     /*
    1293              :      * We really need to fiddle with things - unpack the number into a
    1294              :      * variable and let apply_typmod() do it.
    1295              :      */
    1296         3073 :     init_var(&var);
    1297              : 
    1298         3073 :     set_var_from_num(num, &var);
    1299         3073 :     if (!apply_typmod(&var, typmod, fcinfo->context))
    1300            0 :         PG_RETURN_NULL();
    1301         3033 :     new = make_result_safe(&var, fcinfo->context);
    1302              : 
    1303         3033 :     free_var(&var);
    1304              : 
    1305         3033 :     PG_RETURN_NUMERIC(new);
    1306              : }
    1307              : 
    1308              : Datum
    1309         1087 : numerictypmodin(PG_FUNCTION_ARGS)
    1310              : {
    1311         1087 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1312              :     int32      *tl;
    1313              :     int         n;
    1314              :     int32       typmod;
    1315              : 
    1316         1087 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1317              : 
    1318         1087 :     if (n == 2)
    1319              :     {
    1320         1075 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1321           12 :             ereport(ERROR,
    1322              :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1323              :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1324              :                             tl[0], NUMERIC_MAX_PRECISION)));
    1325         1063 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
    1326            8 :             ereport(ERROR,
    1327              :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1328              :                      errmsg("NUMERIC scale %d must be between %d and %d",
    1329              :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
    1330         1055 :         typmod = make_numeric_typmod(tl[0], tl[1]);
    1331              :     }
    1332           12 :     else if (n == 1)
    1333              :     {
    1334            4 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1335            0 :             ereport(ERROR,
    1336              :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1337              :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1338              :                             tl[0], NUMERIC_MAX_PRECISION)));
    1339              :         /* scale defaults to zero */
    1340            4 :         typmod = make_numeric_typmod(tl[0], 0);
    1341              :     }
    1342              :     else
    1343              :     {
    1344            8 :         ereport(ERROR,
    1345              :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1346              :                  errmsg("invalid NUMERIC type modifier")));
    1347              :         typmod = 0;             /* keep compiler quiet */
    1348              :     }
    1349              : 
    1350         1059 :     PG_RETURN_INT32(typmod);
    1351              : }
    1352              : 
    1353              : Datum
    1354          209 : numerictypmodout(PG_FUNCTION_ARGS)
    1355              : {
    1356          209 :     int32       typmod = PG_GETARG_INT32(0);
    1357          209 :     char       *res = (char *) palloc(64);
    1358              : 
    1359          209 :     if (is_valid_numeric_typmod(typmod))
    1360          209 :         snprintf(res, 64, "(%d,%d)",
    1361              :                  numeric_typmod_precision(typmod),
    1362              :                  numeric_typmod_scale(typmod));
    1363              :     else
    1364            0 :         *res = '\0';
    1365              : 
    1366          209 :     PG_RETURN_CSTRING(res);
    1367              : }
    1368              : 
    1369              : 
    1370              : /* ----------------------------------------------------------------------
    1371              :  *
    1372              :  * Sign manipulation, rounding and the like
    1373              :  *
    1374              :  * ----------------------------------------------------------------------
    1375              :  */
    1376              : 
    1377              : Datum
    1378        13004 : numeric_abs(PG_FUNCTION_ARGS)
    1379              : {
    1380        13004 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1381              :     Numeric     res;
    1382              : 
    1383              :     /*
    1384              :      * Do it the easy way directly on the packed format
    1385              :      */
    1386        13004 :     res = duplicate_numeric(num);
    1387              : 
    1388        13004 :     if (NUMERIC_IS_SHORT(num))
    1389        12960 :         res->choice.n_short.n_header =
    1390        12960 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
    1391           44 :     else if (NUMERIC_IS_SPECIAL(num))
    1392              :     {
    1393              :         /* This changes -Inf to Inf, and doesn't affect NaN */
    1394           12 :         res->choice.n_short.n_header =
    1395           12 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
    1396              :     }
    1397              :     else
    1398           32 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
    1399              : 
    1400        13004 :     PG_RETURN_NUMERIC(res);
    1401              : }
    1402              : 
    1403              : 
    1404              : Datum
    1405          623 : numeric_uminus(PG_FUNCTION_ARGS)
    1406              : {
    1407          623 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1408              :     Numeric     res;
    1409              : 
    1410              :     /*
    1411              :      * Do it the easy way directly on the packed format
    1412              :      */
    1413          623 :     res = duplicate_numeric(num);
    1414              : 
    1415          623 :     if (NUMERIC_IS_SPECIAL(num))
    1416              :     {
    1417              :         /* Flip the sign, if it's Inf or -Inf */
    1418           84 :         if (!NUMERIC_IS_NAN(num))
    1419           56 :             res->choice.n_short.n_header =
    1420           56 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
    1421              :     }
    1422              : 
    1423              :     /*
    1424              :      * The packed format is known to be totally zero digit trimmed always. So
    1425              :      * once we've eliminated specials, we can identify a zero by the fact that
    1426              :      * there are no digits at all. Do nothing to a zero.
    1427              :      */
    1428          539 :     else if (NUMERIC_NDIGITS(num) != 0)
    1429              :     {
    1430              :         /* Else, flip the sign */
    1431          463 :         if (NUMERIC_IS_SHORT(num))
    1432          463 :             res->choice.n_short.n_header =
    1433          463 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
    1434            0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
    1435            0 :             res->choice.n_long.n_sign_dscale =
    1436            0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
    1437              :         else
    1438            0 :             res->choice.n_long.n_sign_dscale =
    1439            0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
    1440              :     }
    1441              : 
    1442          623 :     PG_RETURN_NUMERIC(res);
    1443              : }
    1444              : 
    1445              : 
    1446              : Datum
    1447            0 : numeric_uplus(PG_FUNCTION_ARGS)
    1448              : {
    1449            0 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1450              : 
    1451            0 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
    1452              : }
    1453              : 
    1454              : 
    1455              : /*
    1456              :  * numeric_sign_internal() -
    1457              :  *
    1458              :  * Returns -1 if the argument is less than 0, 0 if the argument is equal
    1459              :  * to 0, and 1 if the argument is greater than zero.  Caller must have
    1460              :  * taken care of the NaN case, but we can handle infinities here.
    1461              :  */
    1462              : static int
    1463         2476 : numeric_sign_internal(Numeric num)
    1464              : {
    1465         2476 :     if (NUMERIC_IS_SPECIAL(num))
    1466              :     {
    1467              :         Assert(!NUMERIC_IS_NAN(num));
    1468              :         /* Must be Inf or -Inf */
    1469          223 :         if (NUMERIC_IS_PINF(num))
    1470          129 :             return 1;
    1471              :         else
    1472           94 :             return -1;
    1473              :     }
    1474              : 
    1475              :     /*
    1476              :      * The packed format is known to be totally zero digit trimmed always. So
    1477              :      * once we've eliminated specials, we can identify a zero by the fact that
    1478              :      * there are no digits at all.
    1479              :      */
    1480         2253 :     else if (NUMERIC_NDIGITS(num) == 0)
    1481          161 :         return 0;
    1482         2092 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
    1483          511 :         return -1;
    1484              :     else
    1485         1581 :         return 1;
    1486              : }
    1487              : 
    1488              : /*
    1489              :  * numeric_sign() -
    1490              :  *
    1491              :  * returns -1 if the argument is less than 0, 0 if the argument is equal
    1492              :  * to 0, and 1 if the argument is greater than zero.
    1493              :  */
    1494              : Datum
    1495           32 : numeric_sign(PG_FUNCTION_ARGS)
    1496              : {
    1497           32 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1498              : 
    1499              :     /*
    1500              :      * Handle NaN (infinities can be handled normally)
    1501              :      */
    1502           32 :     if (NUMERIC_IS_NAN(num))
    1503            4 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    1504              : 
    1505           28 :     switch (numeric_sign_internal(num))
    1506              :     {
    1507            4 :         case 0:
    1508            4 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    1509           12 :         case 1:
    1510           12 :             PG_RETURN_NUMERIC(make_result(&const_one));
    1511           12 :         case -1:
    1512           12 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
    1513              :     }
    1514              : 
    1515              :     Assert(false);
    1516            0 :     return (Datum) 0;
    1517              : }
    1518              : 
    1519              : 
    1520              : /*
    1521              :  * numeric_round() -
    1522              :  *
    1523              :  *  Round a value to have 'scale' digits after the decimal point.
    1524              :  *  We allow negative 'scale', implying rounding before the decimal
    1525              :  *  point --- Oracle interprets rounding that way.
    1526              :  */
    1527              : Datum
    1528         5217 : numeric_round(PG_FUNCTION_ARGS)
    1529              : {
    1530         5217 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1531         5217 :     int32       scale = PG_GETARG_INT32(1);
    1532              :     Numeric     res;
    1533              :     NumericVar  arg;
    1534              : 
    1535              :     /*
    1536              :      * Handle NaN and infinities
    1537              :      */
    1538         5217 :     if (NUMERIC_IS_SPECIAL(num))
    1539           64 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1540              : 
    1541              :     /*
    1542              :      * Limit the scale value to avoid possible overflow in calculations.
    1543              :      *
    1544              :      * These limits are based on the maximum number of digits a Numeric value
    1545              :      * can have before and after the decimal point, but we must allow for one
    1546              :      * extra digit before the decimal point, in case the most significant
    1547              :      * digit rounds up; we must check if that causes Numeric overflow.
    1548              :      */
    1549         5153 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS - 1);
    1550         5153 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1551              : 
    1552              :     /*
    1553              :      * Unpack the argument and round it at the proper digit position
    1554              :      */
    1555         5153 :     init_var(&arg);
    1556         5153 :     set_var_from_num(num, &arg);
    1557              : 
    1558         5153 :     round_var(&arg, scale);
    1559              : 
    1560              :     /* We don't allow negative output dscale */
    1561         5153 :     if (scale < 0)
    1562          149 :         arg.dscale = 0;
    1563              : 
    1564              :     /*
    1565              :      * Return the rounded result
    1566              :      */
    1567         5153 :     res = make_result(&arg);
    1568              : 
    1569         5149 :     free_var(&arg);
    1570         5149 :     PG_RETURN_NUMERIC(res);
    1571              : }
    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          442 : numeric_trunc(PG_FUNCTION_ARGS)
    1583              : {
    1584          442 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1585          442 :     int32       scale = PG_GETARG_INT32(1);
    1586              :     Numeric     res;
    1587              :     NumericVar  arg;
    1588              : 
    1589              :     /*
    1590              :      * Handle NaN and infinities
    1591              :      */
    1592          442 :     if (NUMERIC_IS_SPECIAL(num))
    1593           24 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1594              : 
    1595              :     /*
    1596              :      * Limit the scale value to avoid possible overflow in calculations.
    1597              :      *
    1598              :      * These limits are based on the maximum number of digits a Numeric value
    1599              :      * can have before and after the decimal point.
    1600              :      */
    1601          418 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS);
    1602          418 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1603              : 
    1604              :     /*
    1605              :      * Unpack the argument and truncate it at the proper digit position
    1606              :      */
    1607          418 :     init_var(&arg);
    1608          418 :     set_var_from_num(num, &arg);
    1609              : 
    1610          418 :     trunc_var(&arg, scale);
    1611              : 
    1612              :     /* We don't allow negative output dscale */
    1613          418 :     if (scale < 0)
    1614           20 :         arg.dscale = 0;
    1615              : 
    1616              :     /*
    1617              :      * Return the truncated result
    1618              :      */
    1619          418 :     res = make_result(&arg);
    1620              : 
    1621          418 :     free_var(&arg);
    1622          418 :     PG_RETURN_NUMERIC(res);
    1623              : }
    1624              : 
    1625              : 
    1626              : /*
    1627              :  * numeric_ceil() -
    1628              :  *
    1629              :  *  Return the smallest integer greater than or equal to the argument
    1630              :  */
    1631              : Datum
    1632          148 : numeric_ceil(PG_FUNCTION_ARGS)
    1633              : {
    1634          148 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1635              :     Numeric     res;
    1636              :     NumericVar  result;
    1637              : 
    1638              :     /*
    1639              :      * Handle NaN and infinities
    1640              :      */
    1641          148 :     if (NUMERIC_IS_SPECIAL(num))
    1642           12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1643              : 
    1644          136 :     init_var_from_num(num, &result);
    1645          136 :     ceil_var(&result, &result);
    1646              : 
    1647          136 :     res = make_result(&result);
    1648          136 :     free_var(&result);
    1649              : 
    1650          136 :     PG_RETURN_NUMERIC(res);
    1651              : }
    1652              : 
    1653              : 
    1654              : /*
    1655              :  * numeric_floor() -
    1656              :  *
    1657              :  *  Return the largest integer equal to or less than the argument
    1658              :  */
    1659              : Datum
    1660           84 : numeric_floor(PG_FUNCTION_ARGS)
    1661              : {
    1662           84 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1663              :     Numeric     res;
    1664              :     NumericVar  result;
    1665              : 
    1666              :     /*
    1667              :      * Handle NaN and infinities
    1668              :      */
    1669           84 :     if (NUMERIC_IS_SPECIAL(num))
    1670           12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1671              : 
    1672           72 :     init_var_from_num(num, &result);
    1673           72 :     floor_var(&result, &result);
    1674              : 
    1675           72 :     res = make_result(&result);
    1676           72 :     free_var(&result);
    1677              : 
    1678           72 :     PG_RETURN_NUMERIC(res);
    1679              : }
    1680              : 
    1681              : 
    1682              : /*
    1683              :  * generate_series_numeric() -
    1684              :  *
    1685              :  *  Generate series of numeric.
    1686              :  */
    1687              : Datum
    1688        80256 : generate_series_numeric(PG_FUNCTION_ARGS)
    1689              : {
    1690        80256 :     return generate_series_step_numeric(fcinfo);
    1691              : }
    1692              : 
    1693              : Datum
    1694        80556 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1695              : {
    1696              :     generate_series_numeric_fctx *fctx;
    1697              :     FuncCallContext *funcctx;
    1698              :     MemoryContext oldcontext;
    1699              : 
    1700        80556 :     if (SRF_IS_FIRSTCALL())
    1701              :     {
    1702          116 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1703          116 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1704          116 :         NumericVar  steploc = const_one;
    1705              : 
    1706              :         /* Reject NaN and infinities in start and stop values */
    1707          116 :         if (NUMERIC_IS_SPECIAL(start_num))
    1708              :         {
    1709            8 :             if (NUMERIC_IS_NAN(start_num))
    1710            4 :                 ereport(ERROR,
    1711              :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1712              :                          errmsg("start value cannot be NaN")));
    1713              :             else
    1714            4 :                 ereport(ERROR,
    1715              :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1716              :                          errmsg("start value cannot be infinity")));
    1717              :         }
    1718          108 :         if (NUMERIC_IS_SPECIAL(stop_num))
    1719              :         {
    1720            8 :             if (NUMERIC_IS_NAN(stop_num))
    1721            4 :                 ereport(ERROR,
    1722              :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1723              :                          errmsg("stop value cannot be NaN")));
    1724              :             else
    1725            4 :                 ereport(ERROR,
    1726              :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1727              :                          errmsg("stop value cannot be infinity")));
    1728              :         }
    1729              : 
    1730              :         /* see if we were given an explicit step size */
    1731          100 :         if (PG_NARGS() == 3)
    1732              :         {
    1733           48 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
    1734              : 
    1735           48 :             if (NUMERIC_IS_SPECIAL(step_num))
    1736              :             {
    1737            8 :                 if (NUMERIC_IS_NAN(step_num))
    1738            4 :                     ereport(ERROR,
    1739              :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1740              :                              errmsg("step size cannot be NaN")));
    1741              :                 else
    1742            4 :                     ereport(ERROR,
    1743              :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1744              :                              errmsg("step size cannot be infinity")));
    1745              :             }
    1746              : 
    1747           40 :             init_var_from_num(step_num, &steploc);
    1748              : 
    1749           40 :             if (cmp_var(&steploc, &const_zero) == 0)
    1750            4 :                 ereport(ERROR,
    1751              :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1752              :                          errmsg("step size cannot equal zero")));
    1753              :         }
    1754              : 
    1755              :         /* create a function context for cross-call persistence */
    1756           88 :         funcctx = SRF_FIRSTCALL_INIT();
    1757              : 
    1758              :         /*
    1759              :          * Switch to memory context appropriate for multiple function calls.
    1760              :          */
    1761           88 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1762              : 
    1763              :         /* allocate memory for user context */
    1764           88 :         fctx = palloc_object(generate_series_numeric_fctx);
    1765              : 
    1766              :         /*
    1767              :          * Use fctx to keep state from call to call. Seed current with the
    1768              :          * original start value. We must copy the start_num and stop_num
    1769              :          * values rather than pointing to them, since we may have detoasted
    1770              :          * them in the per-call context.
    1771              :          */
    1772           88 :         init_var(&fctx->current);
    1773           88 :         init_var(&fctx->stop);
    1774           88 :         init_var(&fctx->step);
    1775              : 
    1776           88 :         set_var_from_num(start_num, &fctx->current);
    1777           88 :         set_var_from_num(stop_num, &fctx->stop);
    1778           88 :         set_var_from_var(&steploc, &fctx->step);
    1779              : 
    1780           88 :         funcctx->user_fctx = fctx;
    1781           88 :         MemoryContextSwitchTo(oldcontext);
    1782              :     }
    1783              : 
    1784              :     /* stuff done on every call of the function */
    1785        80528 :     funcctx = SRF_PERCALL_SETUP();
    1786              : 
    1787              :     /*
    1788              :      * Get the saved state and use current state as the result of this
    1789              :      * iteration.
    1790              :      */
    1791        80528 :     fctx = funcctx->user_fctx;
    1792              : 
    1793       160936 :     if ((fctx->step.sign == NUMERIC_POS &&
    1794        80408 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1795          320 :         (fctx->step.sign == NUMERIC_NEG &&
    1796          120 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1797              :     {
    1798        80440 :         Numeric     result = make_result(&fctx->current);
    1799              : 
    1800              :         /* switch to memory context appropriate for iteration calculation */
    1801        80440 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1802              : 
    1803              :         /* increment current in preparation for next iteration */
    1804        80440 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1805        80440 :         MemoryContextSwitchTo(oldcontext);
    1806              : 
    1807              :         /* do when there is more left to send */
    1808        80440 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1809              :     }
    1810              :     else
    1811              :         /* do when there is no more left */
    1812           88 :         SRF_RETURN_DONE(funcctx);
    1813              : }
    1814              : 
    1815              : /*
    1816              :  * Planner support function for generate_series(numeric, numeric [, numeric])
    1817              :  */
    1818              : Datum
    1819          535 : generate_series_numeric_support(PG_FUNCTION_ARGS)
    1820              : {
    1821          535 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1822          535 :     Node       *ret = NULL;
    1823              : 
    1824          535 :     if (IsA(rawreq, SupportRequestRows))
    1825              :     {
    1826              :         /* Try to estimate the number of rows returned */
    1827          130 :         SupportRequestRows *req = (SupportRequestRows *) rawreq;
    1828              : 
    1829          130 :         if (is_funcclause(req->node))    /* be paranoid */
    1830              :         {
    1831          130 :             List       *args = ((FuncExpr *) req->node)->args;
    1832              :             Node       *arg1,
    1833              :                        *arg2,
    1834              :                        *arg3;
    1835              : 
    1836              :             /* We can use estimated argument values here */
    1837          130 :             arg1 = estimate_expression_value(req->root, linitial(args));
    1838          130 :             arg2 = estimate_expression_value(req->root, lsecond(args));
    1839          130 :             if (list_length(args) >= 3)
    1840           85 :                 arg3 = estimate_expression_value(req->root, lthird(args));
    1841              :             else
    1842           45 :                 arg3 = NULL;
    1843              : 
    1844              :             /*
    1845              :              * If any argument is constant NULL, we can safely assume that
    1846              :              * zero rows are returned.  Otherwise, if they're all non-NULL
    1847              :              * constants, we can calculate the number of rows that will be
    1848              :              * returned.
    1849              :              */
    1850          130 :             if ((IsA(arg1, Const) &&
    1851          125 :                  ((Const *) arg1)->constisnull) ||
    1852          130 :                 (IsA(arg2, Const) &&
    1853          130 :                  ((Const *) arg2)->constisnull) ||
    1854           85 :                 (arg3 != NULL && IsA(arg3, Const) &&
    1855           80 :                  ((Const *) arg3)->constisnull))
    1856              :             {
    1857            0 :                 req->rows = 0;
    1858            0 :                 ret = (Node *) req;
    1859              :             }
    1860          130 :             else if (IsA(arg1, Const) &&
    1861          125 :                      IsA(arg2, Const) &&
    1862           85 :                      (arg3 == NULL || IsA(arg3, Const)))
    1863              :             {
    1864              :                 Numeric     start_num;
    1865              :                 Numeric     stop_num;
    1866          115 :                 NumericVar  step = const_one;
    1867              : 
    1868              :                 /*
    1869              :                  * If any argument is NaN or infinity, generate_series() will
    1870              :                  * error out, so we needn't produce an estimate.
    1871              :                  */
    1872          115 :                 start_num = DatumGetNumeric(((Const *) arg1)->constvalue);
    1873          115 :                 stop_num = DatumGetNumeric(((Const *) arg2)->constvalue);
    1874              : 
    1875          115 :                 if (NUMERIC_IS_SPECIAL(start_num) ||
    1876          100 :                     NUMERIC_IS_SPECIAL(stop_num))
    1877           40 :                     PG_RETURN_POINTER(NULL);
    1878              : 
    1879           90 :                 if (arg3)
    1880              :                 {
    1881              :                     Numeric     step_num;
    1882              : 
    1883           55 :                     step_num = DatumGetNumeric(((Const *) arg3)->constvalue);
    1884              : 
    1885           55 :                     if (NUMERIC_IS_SPECIAL(step_num))
    1886           15 :                         PG_RETURN_POINTER(NULL);
    1887              : 
    1888           40 :                     init_var_from_num(step_num, &step);
    1889              :                 }
    1890              : 
    1891              :                 /*
    1892              :                  * The number of rows that will be returned is given by
    1893              :                  * floor((stop - start) / step) + 1, if the sign of step
    1894              :                  * matches the sign of stop - start.  Otherwise, no rows will
    1895              :                  * be returned.
    1896              :                  */
    1897           75 :                 if (cmp_var(&step, &const_zero) != 0)
    1898              :                 {
    1899              :                     NumericVar  start;
    1900              :                     NumericVar  stop;
    1901              :                     NumericVar  res;
    1902              : 
    1903           65 :                     init_var_from_num(start_num, &start);
    1904           65 :                     init_var_from_num(stop_num, &stop);
    1905              : 
    1906           65 :                     init_var(&res);
    1907           65 :                     sub_var(&stop, &start, &res);
    1908              : 
    1909           65 :                     if (step.sign != res.sign)
    1910              :                     {
    1911              :                         /* no rows will be returned */
    1912            5 :                         req->rows = 0;
    1913            5 :                         ret = (Node *) req;
    1914              :                     }
    1915              :                     else
    1916              :                     {
    1917           60 :                         if (arg3)
    1918           25 :                             div_var(&res, &step, &res, 0, false, false);
    1919              :                         else
    1920           35 :                             trunc_var(&res, 0); /* step = 1 */
    1921              : 
    1922           60 :                         req->rows = numericvar_to_double_no_overflow(&res) + 1;
    1923           60 :                         ret = (Node *) req;
    1924              :                     }
    1925              : 
    1926           65 :                     free_var(&res);
    1927              :                 }
    1928              :             }
    1929              :         }
    1930              :     }
    1931              : 
    1932          495 :     PG_RETURN_POINTER(ret);
    1933              : }
    1934              : 
    1935              : 
    1936              : /*
    1937              :  * Implements the numeric version of the width_bucket() function
    1938              :  * defined by SQL2003. See also width_bucket_float8().
    1939              :  *
    1940              :  * 'bound1' and 'bound2' are the lower and upper bounds of the
    1941              :  * histogram's range, respectively. 'count' is the number of buckets
    1942              :  * in the histogram. width_bucket() returns an integer indicating the
    1943              :  * bucket number that 'operand' belongs to in an equiwidth histogram
    1944              :  * with the specified characteristics. An operand smaller than the
    1945              :  * lower bound is assigned to bucket 0. An operand greater than or equal
    1946              :  * to the upper bound is assigned to an additional bucket (with number
    1947              :  * count+1). We don't allow the histogram bounds to be NaN or +/- infinity,
    1948              :  * but we do allow those values for the operand (taking NaN to be larger
    1949              :  * than any other value, as we do in comparisons).
    1950              :  */
    1951              : Datum
    1952          529 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1953              : {
    1954          529 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1955          529 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1956          529 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1957          529 :     int32       count = PG_GETARG_INT32(3);
    1958              :     NumericVar  count_var;
    1959              :     NumericVar  result_var;
    1960              :     int32       result;
    1961              : 
    1962          529 :     if (count <= 0)
    1963            8 :         ereport(ERROR,
    1964              :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1965              :                  errmsg("count must be greater than zero")));
    1966              : 
    1967          521 :     if (NUMERIC_IS_SPECIAL(bound1) || NUMERIC_IS_SPECIAL(bound2))
    1968              :     {
    1969           16 :         if (NUMERIC_IS_NAN(bound1) || NUMERIC_IS_NAN(bound2))
    1970            4 :             ereport(ERROR,
    1971              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1972              :                      errmsg("lower and upper bounds cannot be NaN")));
    1973              : 
    1974           12 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1975           12 :             ereport(ERROR,
    1976              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1977              :                      errmsg("lower and upper bounds must be finite")));
    1978              :     }
    1979              : 
    1980          505 :     init_var(&result_var);
    1981          505 :     init_var(&count_var);
    1982              : 
    1983              :     /* Convert 'count' to a numeric, for ease of use later */
    1984          505 :     int64_to_numericvar((int64) count, &count_var);
    1985              : 
    1986          505 :     switch (cmp_numerics(bound1, bound2))
    1987              :     {
    1988            4 :         case 0:
    1989            4 :             ereport(ERROR,
    1990              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1991              :                      errmsg("lower bound cannot equal upper bound")));
    1992              :             break;
    1993              : 
    1994              :             /* bound1 < bound2 */
    1995          372 :         case -1:
    1996          372 :             if (cmp_numerics(operand, bound1) < 0)
    1997           77 :                 set_var_from_var(&const_zero, &result_var);
    1998          295 :             else if (cmp_numerics(operand, bound2) >= 0)
    1999           78 :                 add_var(&count_var, &const_one, &result_var);
    2000              :             else
    2001          217 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2002              :                                &result_var);
    2003          372 :             break;
    2004              : 
    2005              :             /* bound1 > bound2 */
    2006          129 :         case 1:
    2007          129 :             if (cmp_numerics(operand, bound1) > 0)
    2008            8 :                 set_var_from_var(&const_zero, &result_var);
    2009          121 :             else if (cmp_numerics(operand, bound2) <= 0)
    2010           16 :                 add_var(&count_var, &const_one, &result_var);
    2011              :             else
    2012          105 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2013              :                                &result_var);
    2014          129 :             break;
    2015              :     }
    2016              : 
    2017              :     /* if result exceeds the range of a legal int4, we ereport here */
    2018          501 :     if (!numericvar_to_int32(&result_var, &result))
    2019            0 :         ereport(ERROR,
    2020              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    2021              :                  errmsg("integer out of range")));
    2022              : 
    2023          501 :     free_var(&count_var);
    2024          501 :     free_var(&result_var);
    2025              : 
    2026          501 :     PG_RETURN_INT32(result);
    2027              : }
    2028              : 
    2029              : /*
    2030              :  * 'operand' is inside the bucket range, so determine the correct
    2031              :  * bucket for it to go in. The calculations performed by this function
    2032              :  * are derived directly from the SQL2003 spec. Note however that we
    2033              :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    2034              :  */
    2035              : static void
    2036          322 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    2037              :                const NumericVar *count_var, NumericVar *result_var)
    2038              : {
    2039              :     NumericVar  bound1_var;
    2040              :     NumericVar  bound2_var;
    2041              :     NumericVar  operand_var;
    2042              : 
    2043          322 :     init_var_from_num(bound1, &bound1_var);
    2044          322 :     init_var_from_num(bound2, &bound2_var);
    2045          322 :     init_var_from_num(operand, &operand_var);
    2046              : 
    2047              :     /*
    2048              :      * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
    2049              :      * bound1 <= operand < bound2 or bound1 >= operand > bound2.  Either way,
    2050              :      * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
    2051              :      * where the quotient is computed using floor division (i.e., division to
    2052              :      * zero decimal places with truncation), which guarantees that the result
    2053              :      * is in the range [1, count].  Reversing the bounds doesn't affect the
    2054              :      * computation, because the signs cancel out when dividing.
    2055              :      */
    2056          322 :     sub_var(&operand_var, &bound1_var, &operand_var);
    2057          322 :     sub_var(&bound2_var, &bound1_var, &bound2_var);
    2058              : 
    2059          322 :     mul_var(&operand_var, count_var, &operand_var,
    2060          322 :             operand_var.dscale + count_var->dscale);
    2061          322 :     div_var(&operand_var, &bound2_var, result_var, 0, false, true);
    2062          322 :     add_var(result_var, &const_one, result_var);
    2063              : 
    2064          322 :     free_var(&bound1_var);
    2065          322 :     free_var(&bound2_var);
    2066          322 :     free_var(&operand_var);
    2067          322 : }
    2068              : 
    2069              : /* ----------------------------------------------------------------------
    2070              :  *
    2071              :  * Comparison functions
    2072              :  *
    2073              :  * Note: btree indexes need these routines not to leak memory; therefore,
    2074              :  * be careful to free working copies of toasted datums.  Most places don't
    2075              :  * need to be so careful.
    2076              :  *
    2077              :  * Sort support:
    2078              :  *
    2079              :  * We implement the sortsupport strategy routine in order to get the benefit of
    2080              :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    2081              :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    2082              :  * while this could be worked on itself, the abbreviation strategy gives more
    2083              :  * speedup in many common cases.
    2084              :  *
    2085              :  * The abbreviated format is an int64. The representation is negated relative
    2086              :  * to the original value, because we use the largest negative value for NaN,
    2087              :  * which sorts higher than other values. We convert the absolute value of the
    2088              :  * numeric to a 63-bit positive value, and then negate it if the original
    2089              :  * number was positive.
    2090              :  *
    2091              :  * We abort the abbreviation process if the abbreviation cardinality is below
    2092              :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    2093              :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    2094              :  * very small penalty), but we don't want to build up too many abbreviated
    2095              :  * values before first testing for abort, so we take the slightly pessimistic
    2096              :  * number.  We make no attempt to estimate the cardinality of the real values,
    2097              :  * since it plays no part in the cost model here (if the abbreviation is equal,
    2098              :  * the cost of comparing equal and unequal underlying values is comparable).
    2099              :  * We discontinue even checking for abort (saving us the hashing overhead) if
    2100              :  * the estimated cardinality gets to 100k; that would be enough to support many
    2101              :  * billions of rows while doing no worse than breaking even.
    2102              :  *
    2103              :  * ----------------------------------------------------------------------
    2104              :  */
    2105              : 
    2106              : /*
    2107              :  * Sort support strategy routine.
    2108              :  */
    2109              : Datum
    2110          791 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2111              : {
    2112          791 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2113              : 
    2114          791 :     ssup->comparator = numeric_fast_cmp;
    2115              : 
    2116          791 :     if (ssup->abbreviate)
    2117              :     {
    2118              :         NumericSortSupport *nss;
    2119          171 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2120              : 
    2121          171 :         nss = palloc_object(NumericSortSupport);
    2122              : 
    2123              :         /*
    2124              :          * palloc a buffer for handling unaligned packed values in addition to
    2125              :          * the support struct
    2126              :          */
    2127          171 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2128              : 
    2129          171 :         nss->input_count = 0;
    2130          171 :         nss->estimating = true;
    2131          171 :         initHyperLogLog(&nss->abbr_card, 10);
    2132              : 
    2133          171 :         ssup->ssup_extra = nss;
    2134              : 
    2135          171 :         ssup->abbrev_full_comparator = ssup->comparator;
    2136          171 :         ssup->comparator = numeric_cmp_abbrev;
    2137          171 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2138          171 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2139              : 
    2140          171 :         MemoryContextSwitchTo(oldcontext);
    2141              :     }
    2142              : 
    2143          791 :     PG_RETURN_VOID();
    2144              : }
    2145              : 
    2146              : /*
    2147              :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2148              :  * (must not leak memory!)
    2149              :  */
    2150              : static Datum
    2151        12779 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2152              : {
    2153        12779 :     NumericSortSupport *nss = ssup->ssup_extra;
    2154        12779 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2155              :     Numeric     value;
    2156              :     Datum       result;
    2157              : 
    2158        12779 :     nss->input_count += 1;
    2159              : 
    2160              :     /*
    2161              :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2162              :      * we keep and reuse a buffer large enough to handle any short datum.
    2163              :      */
    2164        12779 :     if (VARATT_IS_SHORT(original_varatt))
    2165              :     {
    2166          679 :         void       *buf = nss->buf;
    2167          679 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2168              : 
    2169              :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2170              : 
    2171          679 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2172          679 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2173              : 
    2174          679 :         value = (Numeric) buf;
    2175              :     }
    2176              :     else
    2177        12100 :         value = (Numeric) original_varatt;
    2178              : 
    2179        12779 :     if (NUMERIC_IS_SPECIAL(value))
    2180              :     {
    2181          100 :         if (NUMERIC_IS_PINF(value))
    2182           32 :             result = NUMERIC_ABBREV_PINF;
    2183           68 :         else if (NUMERIC_IS_NINF(value))
    2184           32 :             result = NUMERIC_ABBREV_NINF;
    2185              :         else
    2186           36 :             result = NUMERIC_ABBREV_NAN;
    2187              :     }
    2188              :     else
    2189              :     {
    2190              :         NumericVar  var;
    2191              : 
    2192        12679 :         init_var_from_num(value, &var);
    2193              : 
    2194        12679 :         result = numeric_abbrev_convert_var(&var, nss);
    2195              :     }
    2196              : 
    2197              :     /* should happen only for external/compressed toasts */
    2198        12779 :     if (original_varatt != DatumGetPointer(original_datum))
    2199            0 :         pfree(original_varatt);
    2200              : 
    2201        12779 :     return result;
    2202              : }
    2203              : 
    2204              : /*
    2205              :  * Consider whether to abort abbreviation.
    2206              :  *
    2207              :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2208              :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2209              :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2210              :  * whether the underlying values are also equal.
    2211              :  */
    2212              : static bool
    2213           96 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2214              : {
    2215           96 :     NumericSortSupport *nss = ssup->ssup_extra;
    2216              :     double      abbr_card;
    2217              : 
    2218           96 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2219           96 :         return false;
    2220              : 
    2221            0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2222              : 
    2223              :     /*
    2224              :      * If we have >100k distinct values, then even if we were sorting many
    2225              :      * billion rows we'd likely still break even, and the penalty of undoing
    2226              :      * that many rows of abbrevs would probably not be worth it. Stop even
    2227              :      * counting at that point.
    2228              :      */
    2229            0 :     if (abbr_card > 100000.0)
    2230              :     {
    2231            0 :         if (trace_sort)
    2232            0 :             elog(LOG,
    2233              :                  "numeric_abbrev: estimation ends at cardinality %f"
    2234              :                  " after " INT64_FORMAT " values (%d rows)",
    2235              :                  abbr_card, nss->input_count, memtupcount);
    2236            0 :         nss->estimating = false;
    2237            0 :         return false;
    2238              :     }
    2239              : 
    2240              :     /*
    2241              :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2242              :      * break even point is somewhere between one per 100k rows, where
    2243              :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2244              :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2245              :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2246              :      * abort earlier on genuinely pathological data where we've had exactly
    2247              :      * one abbreviated value in the first 10k (non-null) rows.
    2248              :      */
    2249            0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2250              :     {
    2251            0 :         if (trace_sort)
    2252            0 :             elog(LOG,
    2253              :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2254              :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2255              :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2256              :                  nss->input_count, memtupcount);
    2257            0 :         return true;
    2258              :     }
    2259              : 
    2260            0 :     if (trace_sort)
    2261            0 :         elog(LOG,
    2262              :              "numeric_abbrev: cardinality %f"
    2263              :              " after " INT64_FORMAT " values (%d rows)",
    2264              :              abbr_card, nss->input_count, memtupcount);
    2265              : 
    2266            0 :     return false;
    2267              : }
    2268              : 
    2269              : /*
    2270              :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2271              :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2272              :  * are, but it is a required part of the sort support API when abbreviations
    2273              :  * are performed.
    2274              :  *
    2275              :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2276              :  * aligning short-varlena inputs, but this has not so far been considered to
    2277              :  * be worth the effort.
    2278              :  */
    2279              : static int
    2280     17208108 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2281              : {
    2282     17208108 :     Numeric     nx = DatumGetNumeric(x);
    2283     17208108 :     Numeric     ny = DatumGetNumeric(y);
    2284              :     int         result;
    2285              : 
    2286     17208108 :     result = cmp_numerics(nx, ny);
    2287              : 
    2288     17208108 :     if (nx != DatumGetPointer(x))
    2289      7409856 :         pfree(nx);
    2290     17208108 :     if (ny != DatumGetPointer(y))
    2291      7409852 :         pfree(ny);
    2292              : 
    2293     17208108 :     return result;
    2294              : }
    2295              : 
    2296              : /*
    2297              :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2298              :  * values differ, but if the abbreviations differ, they must reflect the
    2299              :  * ordering of the true values.)
    2300              :  */
    2301              : static int
    2302       126967 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2303              : {
    2304              :     /*
    2305              :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2306              :      * negated relative to the original value, to handle NaN/infinity cases.
    2307              :      */
    2308       126967 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2309        66757 :         return 1;
    2310        60210 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2311        60061 :         return -1;
    2312          149 :     return 0;
    2313              : }
    2314              : 
    2315              : /*
    2316              :  * Abbreviate a NumericVar into the 64-bit sortsupport size.
    2317              :  *
    2318              :  * The 31-bit value is constructed as:
    2319              :  *
    2320              :  *  0 + 7bits digit weight + 24 bits digit value
    2321              :  *
    2322              :  * where the digit weight is in single decimal digits, not digit words, and
    2323              :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2324              :  * significant decimal digits of the value converted to binary. Values whose
    2325              :  * weights would fall outside the representable range are rounded off to zero
    2326              :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2327              :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2328              :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2329              :  * to be a serious limitation, or when values are of the same magnitude and
    2330              :  * equal in the first 7 decimal digits, which is considered to be an
    2331              :  * unavoidable limitation given the available bits. (Stealing three more bits
    2332              :  * to compare another digit would narrow the range of representable weights by
    2333              :  * a factor of 8, which starts to look like a real limiting factor.)
    2334              :  *
    2335              :  * (The value 44 for the excess is essentially arbitrary)
    2336              :  *
    2337              :  * The 63-bit value is constructed as:
    2338              :  *
    2339              :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2340              :  *
    2341              :  * The weight in this case is again stored in excess-44, but this time it is
    2342              :  * the original weight in digit words (i.e. powers of 10000). The first four
    2343              :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2344              :  * are packed into 14 bits each to form the rest of the value. Again,
    2345              :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2346              :  * representable range in this case is 10^-176 to 10^332, which is considered
    2347              :  * to be good enough for all practical purposes, and comparison of 4 words
    2348              :  * means that at least 13 decimal digits are compared, which is considered to
    2349              :  * be a reasonable compromise between effectiveness and efficiency in computing
    2350              :  * the abbreviation.
    2351              :  *
    2352              :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2353              :  * to match the value used in the 31-bit case)
    2354              :  *
    2355              :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2356              :  * and then treated as unsigned, so the smallest representable value is stored
    2357              :  * with all bits zero. This allows simple comparisons to work on the composite
    2358              :  * value.
    2359              :  */
    2360              : static Datum
    2361        12679 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2362              : {
    2363        12679 :     int         ndigits = var->ndigits;
    2364        12679 :     int         weight = var->weight;
    2365              :     int64       result;
    2366              : 
    2367        12679 :     if (ndigits == 0 || weight < -44)
    2368              :     {
    2369           34 :         result = 0;
    2370              :     }
    2371        12645 :     else if (weight > 83)
    2372              :     {
    2373            8 :         result = PG_INT64_MAX;
    2374              :     }
    2375              :     else
    2376              :     {
    2377        12637 :         result = ((int64) (weight + 44) << 56);
    2378              : 
    2379        12637 :         switch (ndigits)
    2380              :         {
    2381            0 :             default:
    2382            0 :                 result |= ((int64) var->digits[3]);
    2383              :                 pg_fallthrough;
    2384         4138 :             case 3:
    2385         4138 :                 result |= ((int64) var->digits[2]) << 14;
    2386              :                 pg_fallthrough;
    2387        12198 :             case 2:
    2388        12198 :                 result |= ((int64) var->digits[1]) << 28;
    2389              :                 pg_fallthrough;
    2390        12637 :             case 1:
    2391        12637 :                 result |= ((int64) var->digits[0]) << 42;
    2392        12637 :                 break;
    2393              :         }
    2394              :     }
    2395              : 
    2396              :     /* the abbrev is negated relative to the original */
    2397        12679 :     if (var->sign == NUMERIC_POS)
    2398        12615 :         result = -result;
    2399              : 
    2400        12679 :     if (nss->estimating)
    2401              :     {
    2402        12679 :         uint32      tmp = ((uint32) result
    2403        12679 :                            ^ (uint32) ((uint64) result >> 32));
    2404              : 
    2405        12679 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2406              :     }
    2407              : 
    2408        12679 :     return NumericAbbrevGetDatum(result);
    2409              : }
    2410              : 
    2411              : 
    2412              : /*
    2413              :  * Ordinary (non-sortsupport) comparisons follow.
    2414              :  */
    2415              : 
    2416              : Datum
    2417       485645 : numeric_cmp(PG_FUNCTION_ARGS)
    2418              : {
    2419       485645 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2420       485645 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2421              :     int         result;
    2422              : 
    2423       485645 :     result = cmp_numerics(num1, num2);
    2424              : 
    2425       485645 :     PG_FREE_IF_COPY(num1, 0);
    2426       485645 :     PG_FREE_IF_COPY(num2, 1);
    2427              : 
    2428       485645 :     PG_RETURN_INT32(result);
    2429              : }
    2430              : 
    2431              : 
    2432              : Datum
    2433       428457 : numeric_eq(PG_FUNCTION_ARGS)
    2434              : {
    2435       428457 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2436       428457 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2437              :     bool        result;
    2438              : 
    2439       428457 :     result = cmp_numerics(num1, num2) == 0;
    2440              : 
    2441       428457 :     PG_FREE_IF_COPY(num1, 0);
    2442       428457 :     PG_FREE_IF_COPY(num2, 1);
    2443              : 
    2444       428457 :     PG_RETURN_BOOL(result);
    2445              : }
    2446              : 
    2447              : Datum
    2448         3584 : numeric_ne(PG_FUNCTION_ARGS)
    2449              : {
    2450         3584 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2451         3584 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2452              :     bool        result;
    2453              : 
    2454         3584 :     result = cmp_numerics(num1, num2) != 0;
    2455              : 
    2456         3584 :     PG_FREE_IF_COPY(num1, 0);
    2457         3584 :     PG_FREE_IF_COPY(num2, 1);
    2458              : 
    2459         3584 :     PG_RETURN_BOOL(result);
    2460              : }
    2461              : 
    2462              : Datum
    2463        34063 : numeric_gt(PG_FUNCTION_ARGS)
    2464              : {
    2465        34063 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2466        34063 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2467              :     bool        result;
    2468              : 
    2469        34063 :     result = cmp_numerics(num1, num2) > 0;
    2470              : 
    2471        34063 :     PG_FREE_IF_COPY(num1, 0);
    2472        34063 :     PG_FREE_IF_COPY(num2, 1);
    2473              : 
    2474        34063 :     PG_RETURN_BOOL(result);
    2475              : }
    2476              : 
    2477              : Datum
    2478         8164 : numeric_ge(PG_FUNCTION_ARGS)
    2479              : {
    2480         8164 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2481         8164 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2482              :     bool        result;
    2483              : 
    2484         8164 :     result = cmp_numerics(num1, num2) >= 0;
    2485              : 
    2486         8164 :     PG_FREE_IF_COPY(num1, 0);
    2487         8164 :     PG_FREE_IF_COPY(num2, 1);
    2488              : 
    2489         8164 :     PG_RETURN_BOOL(result);
    2490              : }
    2491              : 
    2492              : Datum
    2493       198390 : numeric_lt(PG_FUNCTION_ARGS)
    2494              : {
    2495       198390 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2496       198390 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2497              :     bool        result;
    2498              : 
    2499       198390 :     result = cmp_numerics(num1, num2) < 0;
    2500              : 
    2501       198390 :     PG_FREE_IF_COPY(num1, 0);
    2502       198390 :     PG_FREE_IF_COPY(num2, 1);
    2503              : 
    2504       198390 :     PG_RETURN_BOOL(result);
    2505              : }
    2506              : 
    2507              : Datum
    2508         9690 : numeric_le(PG_FUNCTION_ARGS)
    2509              : {
    2510         9690 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2511         9690 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2512              :     bool        result;
    2513              : 
    2514         9690 :     result = cmp_numerics(num1, num2) <= 0;
    2515              : 
    2516         9690 :     PG_FREE_IF_COPY(num1, 0);
    2517         9690 :     PG_FREE_IF_COPY(num2, 1);
    2518              : 
    2519         9690 :     PG_RETURN_BOOL(result);
    2520              : }
    2521              : 
    2522              : static int
    2523     18390486 : cmp_numerics(Numeric num1, Numeric num2)
    2524              : {
    2525              :     int         result;
    2526              : 
    2527              :     /*
    2528              :      * We consider all NANs to be equal and larger than any non-NAN (including
    2529              :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2530              :      * a consistent sort order.
    2531              :      */
    2532     18390486 :     if (NUMERIC_IS_SPECIAL(num1))
    2533              :     {
    2534         3327 :         if (NUMERIC_IS_NAN(num1))
    2535              :         {
    2536         3264 :             if (NUMERIC_IS_NAN(num2))
    2537          463 :                 result = 0;     /* NAN = NAN */
    2538              :             else
    2539         2801 :                 result = 1;     /* NAN > non-NAN */
    2540              :         }
    2541           63 :         else if (NUMERIC_IS_PINF(num1))
    2542              :         {
    2543           50 :             if (NUMERIC_IS_NAN(num2))
    2544            0 :                 result = -1;    /* PINF < NAN */
    2545           50 :             else if (NUMERIC_IS_PINF(num2))
    2546            4 :                 result = 0;     /* PINF = PINF */
    2547              :             else
    2548           46 :                 result = 1;     /* PINF > anything else */
    2549              :         }
    2550              :         else                    /* num1 must be NINF */
    2551              :         {
    2552           13 :             if (NUMERIC_IS_NINF(num2))
    2553            4 :                 result = 0;     /* NINF = NINF */
    2554              :             else
    2555            9 :                 result = -1;    /* NINF < anything else */
    2556              :         }
    2557              :     }
    2558     18387159 :     else if (NUMERIC_IS_SPECIAL(num2))
    2559              :     {
    2560         5594 :         if (NUMERIC_IS_NINF(num2))
    2561            8 :             result = 1;         /* normal > NINF */
    2562              :         else
    2563         5586 :             result = -1;        /* normal < NAN or PINF */
    2564              :     }
    2565              :     else
    2566              :     {
    2567     36763774 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2568     18381745 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2569     18381565 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2570     18382029 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2571              :     }
    2572              : 
    2573     18390486 :     return result;
    2574              : }
    2575              : 
    2576              : /*
    2577              :  * in_range support function for numeric.
    2578              :  */
    2579              : Datum
    2580          768 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2581              : {
    2582          768 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2583          768 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2584          768 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2585          768 :     bool        sub = PG_GETARG_BOOL(3);
    2586          768 :     bool        less = PG_GETARG_BOOL(4);
    2587              :     bool        result;
    2588              : 
    2589              :     /*
    2590              :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2591              :      * and NaN is because appropriate semantics for that seem non-obvious.
    2592              :      */
    2593          768 :     if (NUMERIC_IS_NAN(offset) ||
    2594          764 :         NUMERIC_IS_NINF(offset) ||
    2595          764 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2596            4 :         ereport(ERROR,
    2597              :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2598              :                  errmsg("invalid preceding or following size in window function")));
    2599              : 
    2600              :     /*
    2601              :      * Deal with cases where val and/or base is NaN, following the rule that
    2602              :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2603              :      * the conclusion.
    2604              :      */
    2605          764 :     if (NUMERIC_IS_NAN(val))
    2606              :     {
    2607          124 :         if (NUMERIC_IS_NAN(base))
    2608           40 :             result = true;      /* NAN = NAN */
    2609              :         else
    2610           84 :             result = !less;     /* NAN > non-NAN */
    2611              :     }
    2612          640 :     else if (NUMERIC_IS_NAN(base))
    2613              :     {
    2614           84 :         result = less;          /* non-NAN < NAN */
    2615              :     }
    2616              : 
    2617              :     /*
    2618              :      * Deal with infinite offset (necessarily +Inf, at this point).
    2619              :      */
    2620          556 :     else if (NUMERIC_IS_SPECIAL(offset))
    2621              :     {
    2622              :         Assert(NUMERIC_IS_PINF(offset));
    2623          280 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2624              :         {
    2625              :             /*
    2626              :              * base +/- offset would produce NaN, so return true for any val
    2627              :              * (see in_range_float8_float8() for reasoning).
    2628              :              */
    2629          116 :             result = true;
    2630              :         }
    2631          164 :         else if (sub)
    2632              :         {
    2633              :             /* base - offset must be -inf */
    2634          100 :             if (less)
    2635           36 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2636              :             else
    2637           64 :                 result = true;  /* any val is >= sum */
    2638              :         }
    2639              :         else
    2640              :         {
    2641              :             /* base + offset must be +inf */
    2642           64 :             if (less)
    2643            0 :                 result = true;  /* any val is <= sum */
    2644              :             else
    2645           64 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2646              :         }
    2647              :     }
    2648              : 
    2649              :     /*
    2650              :      * Deal with cases where val and/or base is infinite.  The offset, being
    2651              :      * now known finite, cannot affect the conclusion.
    2652              :      */
    2653          276 :     else if (NUMERIC_IS_SPECIAL(val))
    2654              :     {
    2655           52 :         if (NUMERIC_IS_PINF(val))
    2656              :         {
    2657           24 :             if (NUMERIC_IS_PINF(base))
    2658           16 :                 result = true;  /* PINF = PINF */
    2659              :             else
    2660            8 :                 result = !less; /* PINF > any other non-NAN */
    2661              :         }
    2662              :         else                    /* val must be NINF */
    2663              :         {
    2664           28 :             if (NUMERIC_IS_NINF(base))
    2665           20 :                 result = true;  /* NINF = NINF */
    2666              :             else
    2667            8 :                 result = less;  /* NINF < anything else */
    2668              :         }
    2669              :     }
    2670          224 :     else if (NUMERIC_IS_SPECIAL(base))
    2671              :     {
    2672           16 :         if (NUMERIC_IS_NINF(base))
    2673            8 :             result = !less;     /* normal > NINF */
    2674              :         else
    2675            8 :             result = less;      /* normal < PINF */
    2676              :     }
    2677              :     else
    2678              :     {
    2679              :         /*
    2680              :          * Otherwise go ahead and compute base +/- offset.  While it's
    2681              :          * possible for this to overflow the numeric format, it's unlikely
    2682              :          * enough that we don't take measures to prevent it.
    2683              :          */
    2684              :         NumericVar  valv;
    2685              :         NumericVar  basev;
    2686              :         NumericVar  offsetv;
    2687              :         NumericVar  sum;
    2688              : 
    2689          208 :         init_var_from_num(val, &valv);
    2690          208 :         init_var_from_num(base, &basev);
    2691          208 :         init_var_from_num(offset, &offsetv);
    2692          208 :         init_var(&sum);
    2693              : 
    2694          208 :         if (sub)
    2695          104 :             sub_var(&basev, &offsetv, &sum);
    2696              :         else
    2697          104 :             add_var(&basev, &offsetv, &sum);
    2698              : 
    2699          208 :         if (less)
    2700          104 :             result = (cmp_var(&valv, &sum) <= 0);
    2701              :         else
    2702          104 :             result = (cmp_var(&valv, &sum) >= 0);
    2703              : 
    2704          208 :         free_var(&sum);
    2705              :     }
    2706              : 
    2707          764 :     PG_FREE_IF_COPY(val, 0);
    2708          764 :     PG_FREE_IF_COPY(base, 1);
    2709          764 :     PG_FREE_IF_COPY(offset, 2);
    2710              : 
    2711          764 :     PG_RETURN_BOOL(result);
    2712              : }
    2713              : 
    2714              : Datum
    2715       405032 : hash_numeric(PG_FUNCTION_ARGS)
    2716              : {
    2717       405032 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2718              :     Datum       digit_hash;
    2719              :     Datum       result;
    2720              :     int         weight;
    2721              :     int         start_offset;
    2722              :     int         end_offset;
    2723              :     int         i;
    2724              :     int         hash_len;
    2725              :     NumericDigit *digits;
    2726              : 
    2727              :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2728       405032 :     if (NUMERIC_IS_SPECIAL(key))
    2729            0 :         PG_RETURN_UINT32(0);
    2730              : 
    2731       405032 :     weight = NUMERIC_WEIGHT(key);
    2732       405032 :     start_offset = 0;
    2733       405032 :     end_offset = 0;
    2734              : 
    2735              :     /*
    2736              :      * Omit any leading or trailing zeros from the input to the hash. The
    2737              :      * numeric implementation *should* guarantee that leading and trailing
    2738              :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2739              :      * starting and ending offsets in units of NumericDigits, not bytes.
    2740              :      */
    2741       405032 :     digits = NUMERIC_DIGITS(key);
    2742       405032 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2743              :     {
    2744       403945 :         if (digits[i] != (NumericDigit) 0)
    2745       403945 :             break;
    2746              : 
    2747            0 :         start_offset++;
    2748              : 
    2749              :         /*
    2750              :          * The weight is effectively the # of digits before the decimal point,
    2751              :          * so decrement it for each leading zero we skip.
    2752              :          */
    2753            0 :         weight--;
    2754              :     }
    2755              : 
    2756              :     /*
    2757              :      * If there are no non-zero digits, then the value of the number is zero,
    2758              :      * regardless of any other fields.
    2759              :      */
    2760       405032 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2761         1087 :         PG_RETURN_UINT32(-1);
    2762              : 
    2763       403945 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2764              :     {
    2765       403945 :         if (digits[i] != (NumericDigit) 0)
    2766       403945 :             break;
    2767              : 
    2768            0 :         end_offset++;
    2769              :     }
    2770              : 
    2771              :     /* If we get here, there should be at least one non-zero digit */
    2772              :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2773              : 
    2774              :     /*
    2775              :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2776              :      * compare equal but have different scales. We also don't hash on the
    2777              :      * sign, although we could: since a sign difference implies inequality,
    2778              :      * this shouldn't affect correctness.
    2779              :      */
    2780       403945 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2781       403945 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2782              :                           hash_len * sizeof(NumericDigit));
    2783              : 
    2784              :     /* Mix in the weight, via XOR */
    2785       403945 :     result = digit_hash ^ weight;
    2786              : 
    2787       403945 :     PG_RETURN_DATUM(result);
    2788              : }
    2789              : 
    2790              : /*
    2791              :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2792              :  * Otherwise, similar to hash_numeric.
    2793              :  */
    2794              : Datum
    2795           56 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2796              : {
    2797           56 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2798           56 :     uint64      seed = PG_GETARG_INT64(1);
    2799              :     Datum       digit_hash;
    2800              :     Datum       result;
    2801              :     int         weight;
    2802              :     int         start_offset;
    2803              :     int         end_offset;
    2804              :     int         i;
    2805              :     int         hash_len;
    2806              :     NumericDigit *digits;
    2807              : 
    2808              :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2809           56 :     if (NUMERIC_IS_SPECIAL(key))
    2810            0 :         PG_RETURN_UINT64(seed);
    2811              : 
    2812           56 :     weight = NUMERIC_WEIGHT(key);
    2813           56 :     start_offset = 0;
    2814           56 :     end_offset = 0;
    2815              : 
    2816           56 :     digits = NUMERIC_DIGITS(key);
    2817           56 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2818              :     {
    2819           48 :         if (digits[i] != (NumericDigit) 0)
    2820           48 :             break;
    2821              : 
    2822            0 :         start_offset++;
    2823              : 
    2824            0 :         weight--;
    2825              :     }
    2826              : 
    2827           56 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2828            8 :         PG_RETURN_UINT64(seed - 1);
    2829              : 
    2830           48 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2831              :     {
    2832           48 :         if (digits[i] != (NumericDigit) 0)
    2833           48 :             break;
    2834              : 
    2835            0 :         end_offset++;
    2836              :     }
    2837              : 
    2838              :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2839              : 
    2840           48 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2841           48 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2842           48 :                                                       + start_offset),
    2843              :                                    hash_len * sizeof(NumericDigit),
    2844              :                                    seed);
    2845              : 
    2846           48 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2847              : 
    2848           48 :     PG_RETURN_DATUM(result);
    2849              : }
    2850              : 
    2851              : 
    2852              : /* ----------------------------------------------------------------------
    2853              :  *
    2854              :  * Basic arithmetic functions
    2855              :  *
    2856              :  * ----------------------------------------------------------------------
    2857              :  */
    2858              : 
    2859              : 
    2860              : /*
    2861              :  * numeric_add() -
    2862              :  *
    2863              :  *  Add two numerics
    2864              :  */
    2865              : Datum
    2866       168428 : numeric_add(PG_FUNCTION_ARGS)
    2867              : {
    2868       168428 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2869       168428 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2870              :     Numeric     res;
    2871              : 
    2872       168428 :     res = numeric_add_safe(num1, num2, NULL);
    2873              : 
    2874       168428 :     PG_RETURN_NUMERIC(res);
    2875              : }
    2876              : 
    2877              : /*
    2878              :  * numeric_add_safe() -
    2879              :  *
    2880              :  *  Internal version of numeric_add() with support for soft error reporting.
    2881              :  */
    2882              : Numeric
    2883       169122 : numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)
    2884              : {
    2885              :     NumericVar  arg1;
    2886              :     NumericVar  arg2;
    2887              :     NumericVar  result;
    2888              :     Numeric     res;
    2889              : 
    2890              :     /*
    2891              :      * Handle NaN and infinities
    2892              :      */
    2893       169122 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2894              :     {
    2895          132 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2896           52 :             return make_result(&const_nan);
    2897           80 :         if (NUMERIC_IS_PINF(num1))
    2898              :         {
    2899           24 :             if (NUMERIC_IS_NINF(num2))
    2900            4 :                 return make_result(&const_nan); /* Inf + -Inf */
    2901              :             else
    2902           20 :                 return make_result(&const_pinf);
    2903              :         }
    2904           56 :         if (NUMERIC_IS_NINF(num1))
    2905              :         {
    2906           24 :             if (NUMERIC_IS_PINF(num2))
    2907            4 :                 return make_result(&const_nan); /* -Inf + Inf */
    2908              :             else
    2909           20 :                 return make_result(&const_ninf);
    2910              :         }
    2911              :         /* by here, num1 must be finite, so num2 is not */
    2912           32 :         if (NUMERIC_IS_PINF(num2))
    2913           16 :             return make_result(&const_pinf);
    2914              :         Assert(NUMERIC_IS_NINF(num2));
    2915           16 :         return make_result(&const_ninf);
    2916              :     }
    2917              : 
    2918              :     /*
    2919              :      * Unpack the values, let add_var() compute the result and return it.
    2920              :      */
    2921       168990 :     init_var_from_num(num1, &arg1);
    2922       168990 :     init_var_from_num(num2, &arg2);
    2923              : 
    2924       168990 :     init_var(&result);
    2925       168990 :     add_var(&arg1, &arg2, &result);
    2926              : 
    2927       168990 :     res = make_result_safe(&result, escontext);
    2928              : 
    2929       168990 :     free_var(&result);
    2930              : 
    2931       168990 :     return res;
    2932              : }
    2933              : 
    2934              : 
    2935              : /*
    2936              :  * numeric_sub() -
    2937              :  *
    2938              :  *  Subtract one numeric from another
    2939              :  */
    2940              : Datum
    2941        46198 : numeric_sub(PG_FUNCTION_ARGS)
    2942              : {
    2943        46198 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2944        46198 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2945              :     Numeric     res;
    2946              : 
    2947        46198 :     res = numeric_sub_safe(num1, num2, NULL);
    2948              : 
    2949        46198 :     PG_RETURN_NUMERIC(res);
    2950              : }
    2951              : 
    2952              : 
    2953              : /*
    2954              :  * numeric_sub_safe() -
    2955              :  *
    2956              :  *  Internal version of numeric_sub() with support for soft error reporting.
    2957              :  */
    2958              : Numeric
    2959        46302 : numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)
    2960              : {
    2961              :     NumericVar  arg1;
    2962              :     NumericVar  arg2;
    2963              :     NumericVar  result;
    2964              :     Numeric     res;
    2965              : 
    2966              :     /*
    2967              :      * Handle NaN and infinities
    2968              :      */
    2969        46302 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2970              :     {
    2971          132 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2972           52 :             return make_result(&const_nan);
    2973           80 :         if (NUMERIC_IS_PINF(num1))
    2974              :         {
    2975           24 :             if (NUMERIC_IS_PINF(num2))
    2976            4 :                 return make_result(&const_nan); /* Inf - Inf */
    2977              :             else
    2978           20 :                 return make_result(&const_pinf);
    2979              :         }
    2980           56 :         if (NUMERIC_IS_NINF(num1))
    2981              :         {
    2982           24 :             if (NUMERIC_IS_NINF(num2))
    2983            4 :                 return make_result(&const_nan); /* -Inf - -Inf */
    2984              :             else
    2985           20 :                 return make_result(&const_ninf);
    2986              :         }
    2987              :         /* by here, num1 must be finite, so num2 is not */
    2988           32 :         if (NUMERIC_IS_PINF(num2))
    2989           16 :             return make_result(&const_ninf);
    2990              :         Assert(NUMERIC_IS_NINF(num2));
    2991           16 :         return make_result(&const_pinf);
    2992              :     }
    2993              : 
    2994              :     /*
    2995              :      * Unpack the values, let sub_var() compute the result and return it.
    2996              :      */
    2997        46170 :     init_var_from_num(num1, &arg1);
    2998        46170 :     init_var_from_num(num2, &arg2);
    2999              : 
    3000        46170 :     init_var(&result);
    3001        46170 :     sub_var(&arg1, &arg2, &result);
    3002              : 
    3003        46170 :     res = make_result_safe(&result, escontext);
    3004              : 
    3005        46170 :     free_var(&result);
    3006              : 
    3007        46170 :     return res;
    3008              : }
    3009              : 
    3010              : 
    3011              : /*
    3012              :  * numeric_mul() -
    3013              :  *
    3014              :  *  Calculate the product of two numerics
    3015              :  */
    3016              : Datum
    3017       326743 : numeric_mul(PG_FUNCTION_ARGS)
    3018              : {
    3019       326743 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3020       326743 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3021              :     Numeric     res;
    3022              : 
    3023       326743 :     res = numeric_mul_safe(num1, num2, fcinfo->context);
    3024              : 
    3025       326743 :     if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
    3026            0 :         PG_RETURN_NULL();
    3027              : 
    3028       326743 :     PG_RETURN_NUMERIC(res);
    3029              : }
    3030              : 
    3031              : 
    3032              : /*
    3033              :  * numeric_mul_safe() -
    3034              :  *
    3035              :  *  Internal version of numeric_mul() with support for soft error reporting.
    3036              :  */
    3037              : Numeric
    3038       326775 : numeric_mul_safe(Numeric num1, Numeric num2, Node *escontext)
    3039              : {
    3040              :     NumericVar  arg1;
    3041              :     NumericVar  arg2;
    3042              :     NumericVar  result;
    3043              :     Numeric     res;
    3044              : 
    3045              :     /*
    3046              :      * Handle NaN and infinities
    3047              :      */
    3048       326775 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3049              :     {
    3050          132 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3051           52 :             return make_result(&const_nan);
    3052           80 :         if (NUMERIC_IS_PINF(num1))
    3053              :         {
    3054           24 :             switch (numeric_sign_internal(num2))
    3055              :             {
    3056            4 :                 case 0:
    3057            4 :                     return make_result(&const_nan); /* Inf * 0 */
    3058           12 :                 case 1:
    3059           12 :                     return make_result(&const_pinf);
    3060            8 :                 case -1:
    3061            8 :                     return make_result(&const_ninf);
    3062              :             }
    3063              :             Assert(false);
    3064              :         }
    3065           56 :         if (NUMERIC_IS_NINF(num1))
    3066              :         {
    3067           24 :             switch (numeric_sign_internal(num2))
    3068              :             {
    3069            4 :                 case 0:
    3070            4 :                     return make_result(&const_nan); /* -Inf * 0 */
    3071           12 :                 case 1:
    3072           12 :                     return make_result(&const_ninf);
    3073            8 :                 case -1:
    3074            8 :                     return make_result(&const_pinf);
    3075              :             }
    3076              :             Assert(false);
    3077              :         }
    3078              :         /* by here, num1 must be finite, so num2 is not */
    3079           32 :         if (NUMERIC_IS_PINF(num2))
    3080              :         {
    3081           16 :             switch (numeric_sign_internal(num1))
    3082              :             {
    3083            4 :                 case 0:
    3084            4 :                     return make_result(&const_nan); /* 0 * Inf */
    3085            8 :                 case 1:
    3086            8 :                     return make_result(&const_pinf);
    3087            4 :                 case -1:
    3088            4 :                     return make_result(&const_ninf);
    3089              :             }
    3090              :             Assert(false);
    3091              :         }
    3092              :         Assert(NUMERIC_IS_NINF(num2));
    3093           16 :         switch (numeric_sign_internal(num1))
    3094              :         {
    3095            4 :             case 0:
    3096            4 :                 return make_result(&const_nan); /* 0 * -Inf */
    3097            8 :             case 1:
    3098            8 :                 return make_result(&const_ninf);
    3099            4 :             case -1:
    3100            4 :                 return make_result(&const_pinf);
    3101              :         }
    3102              :         Assert(false);
    3103              :     }
    3104              : 
    3105              :     /*
    3106              :      * Unpack the values, let mul_var() compute the result and return it.
    3107              :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3108              :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3109              :      * we request exact representation for the product (rscale = sum(dscale of
    3110              :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3111              :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3112              :      * after computing the exact result ensures that the final result is
    3113              :      * correctly rounded (rounding in mul_var() using a truncated product
    3114              :      * would not guarantee this).
    3115              :      */
    3116       326643 :     init_var_from_num(num1, &arg1);
    3117       326643 :     init_var_from_num(num2, &arg2);
    3118              : 
    3119       326643 :     init_var(&result);
    3120       326643 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3121              : 
    3122       326643 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3123            5 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3124              : 
    3125       326643 :     res = make_result_safe(&result, escontext);
    3126              : 
    3127       326643 :     free_var(&result);
    3128              : 
    3129       326643 :     return res;
    3130              : }
    3131              : 
    3132              : 
    3133              : /*
    3134              :  * numeric_div() -
    3135              :  *
    3136              :  *  Divide one numeric into another
    3137              :  */
    3138              : Datum
    3139        98464 : numeric_div(PG_FUNCTION_ARGS)
    3140              : {
    3141        98464 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3142        98464 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3143              :     Numeric     res;
    3144              : 
    3145        98464 :     res = numeric_div_safe(num1, num2, NULL);
    3146              : 
    3147        98443 :     PG_RETURN_NUMERIC(res);
    3148              : }
    3149              : 
    3150              : 
    3151              : /*
    3152              :  * numeric_div_safe() -
    3153              :  *
    3154              :  *  Internal version of numeric_div() with support for soft error reporting.
    3155              :  */
    3156              : Numeric
    3157        99025 : numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)
    3158              : {
    3159              :     NumericVar  arg1;
    3160              :     NumericVar  arg2;
    3161              :     NumericVar  result;
    3162              :     Numeric     res;
    3163              :     int         rscale;
    3164              : 
    3165              :     /*
    3166              :      * Handle NaN and infinities
    3167              :      */
    3168        99025 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3169              :     {
    3170          133 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3171           53 :             return make_result(&const_nan);
    3172           80 :         if (NUMERIC_IS_PINF(num1))
    3173              :         {
    3174           24 :             if (NUMERIC_IS_SPECIAL(num2))
    3175            8 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3176           16 :             switch (numeric_sign_internal(num2))
    3177              :             {
    3178            4 :                 case 0:
    3179            4 :                     goto division_by_zero;
    3180            8 :                 case 1:
    3181            8 :                     return make_result(&const_pinf);
    3182            4 :                 case -1:
    3183            4 :                     return make_result(&const_ninf);
    3184              :             }
    3185              :             Assert(false);
    3186              :         }
    3187           56 :         if (NUMERIC_IS_NINF(num1))
    3188              :         {
    3189           24 :             if (NUMERIC_IS_SPECIAL(num2))
    3190            8 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
    3191           16 :             switch (numeric_sign_internal(num2))
    3192              :             {
    3193            4 :                 case 0:
    3194            4 :                     goto division_by_zero;
    3195            8 :                 case 1:
    3196            8 :                     return make_result(&const_ninf);
    3197            4 :                 case -1:
    3198            4 :                     return make_result(&const_pinf);
    3199              :             }
    3200              :             Assert(false);
    3201              :         }
    3202              :         /* by here, num1 must be finite, so num2 is not */
    3203              : 
    3204              :         /*
    3205              :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3206              :          * otherwise throw an underflow error.  But the numeric type doesn't
    3207              :          * really do underflow, so let's just return zero.
    3208              :          */
    3209           32 :         return make_result(&const_zero);
    3210              :     }
    3211              : 
    3212              :     /*
    3213              :      * Unpack the arguments
    3214              :      */
    3215        98892 :     init_var_from_num(num1, &arg1);
    3216        98892 :     init_var_from_num(num2, &arg2);
    3217              : 
    3218        98892 :     init_var(&result);
    3219              : 
    3220              :     /*
    3221              :      * Select scale for division result
    3222              :      */
    3223        98892 :     rscale = select_div_scale(&arg1, &arg2);
    3224              : 
    3225              :     /* Check for division by zero */
    3226        98892 :     if (arg2.ndigits == 0 || arg2.digits[0] == 0)
    3227           33 :         goto division_by_zero;
    3228              : 
    3229              :     /*
    3230              :      * Do the divide and return the result
    3231              :      */
    3232        98859 :     div_var(&arg1, &arg2, &result, rscale, true, true);
    3233              : 
    3234        98859 :     res = make_result_safe(&result, escontext);
    3235              : 
    3236        98859 :     free_var(&result);
    3237              : 
    3238        98859 :     return res;
    3239              : 
    3240           41 : division_by_zero:
    3241           41 :     ereturn(escontext, NULL,
    3242              :             errcode(ERRCODE_DIVISION_BY_ZERO),
    3243              :             errmsg("division by zero"));
    3244              : }
    3245              : 
    3246              : 
    3247              : /*
    3248              :  * numeric_div_trunc() -
    3249              :  *
    3250              :  *  Divide one numeric into another, truncating the result to an integer
    3251              :  */
    3252              : Datum
    3253          822 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3254              : {
    3255          822 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3256          822 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3257              :     NumericVar  arg1;
    3258              :     NumericVar  arg2;
    3259              :     NumericVar  result;
    3260              :     Numeric     res;
    3261              : 
    3262              :     /*
    3263              :      * Handle NaN and infinities
    3264              :      */
    3265          822 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3266              :     {
    3267          133 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3268           53 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3269           80 :         if (NUMERIC_IS_PINF(num1))
    3270              :         {
    3271           24 :             if (NUMERIC_IS_SPECIAL(num2))
    3272            8 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3273           16 :             switch (numeric_sign_internal(num2))
    3274              :             {
    3275            4 :                 case 0:
    3276            4 :                     ereport(ERROR,
    3277              :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3278              :                              errmsg("division by zero")));
    3279              :                     break;
    3280            8 :                 case 1:
    3281            8 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3282            4 :                 case -1:
    3283            4 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3284              :             }
    3285              :             Assert(false);
    3286              :         }
    3287           56 :         if (NUMERIC_IS_NINF(num1))
    3288              :         {
    3289           24 :             if (NUMERIC_IS_SPECIAL(num2))
    3290            8 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3291           16 :             switch (numeric_sign_internal(num2))
    3292              :             {
    3293            4 :                 case 0:
    3294            4 :                     ereport(ERROR,
    3295              :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3296              :                              errmsg("division by zero")));
    3297              :                     break;
    3298            8 :                 case 1:
    3299            8 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3300            4 :                 case -1:
    3301            4 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3302              :             }
    3303              :             Assert(false);
    3304              :         }
    3305              :         /* by here, num1 must be finite, so num2 is not */
    3306              : 
    3307              :         /*
    3308              :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3309              :          * otherwise throw an underflow error.  But the numeric type doesn't
    3310              :          * really do underflow, so let's just return zero.
    3311              :          */
    3312           32 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3313              :     }
    3314              : 
    3315              :     /*
    3316              :      * Unpack the arguments
    3317              :      */
    3318          689 :     init_var_from_num(num1, &arg1);
    3319          689 :     init_var_from_num(num2, &arg2);
    3320              : 
    3321          689 :     init_var(&result);
    3322              : 
    3323              :     /*
    3324              :      * Do the divide and return the result
    3325              :      */
    3326          689 :     div_var(&arg1, &arg2, &result, 0, false, true);
    3327              : 
    3328          685 :     res = make_result(&result);
    3329              : 
    3330          685 :     free_var(&result);
    3331              : 
    3332          685 :     PG_RETURN_NUMERIC(res);
    3333              : }
    3334              : 
    3335              : 
    3336              : /*
    3337              :  * numeric_mod() -
    3338              :  *
    3339              :  *  Calculate the modulo of two numerics
    3340              :  */
    3341              : Datum
    3342       275181 : numeric_mod(PG_FUNCTION_ARGS)
    3343              : {
    3344       275181 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3345       275181 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3346              :     Numeric     res;
    3347              : 
    3348       275181 :     res = numeric_mod_safe(num1, num2, NULL);
    3349              : 
    3350       275169 :     PG_RETURN_NUMERIC(res);
    3351              : }
    3352              : 
    3353              : 
    3354              : /*
    3355              :  * numeric_mod_safe() -
    3356              :  *
    3357              :  *  Internal version of numeric_mod() with support for soft error reporting.
    3358              :  */
    3359              : Numeric
    3360       275189 : numeric_mod_safe(Numeric num1, Numeric num2, Node *escontext)
    3361              : {
    3362              :     Numeric     res;
    3363              :     NumericVar  arg1;
    3364              :     NumericVar  arg2;
    3365              :     NumericVar  result;
    3366              : 
    3367              :     /*
    3368              :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3369              :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3370              :      * returning NaN.  We choose to throw error only for y-is-zero.
    3371              :      */
    3372       275189 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3373              :     {
    3374          133 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3375           53 :             return make_result(&const_nan);
    3376           80 :         if (NUMERIC_IS_INF(num1))
    3377              :         {
    3378           48 :             if (numeric_sign_internal(num2) == 0)
    3379            8 :                 goto division_by_zero;
    3380              : 
    3381              :             /* Inf % any nonzero = NaN */
    3382           40 :             return make_result(&const_nan);
    3383              :         }
    3384              :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3385           32 :         return duplicate_numeric(num1);
    3386              :     }
    3387              : 
    3388       275056 :     init_var_from_num(num1, &arg1);
    3389       275056 :     init_var_from_num(num2, &arg2);
    3390              : 
    3391       275056 :     init_var(&result);
    3392              : 
    3393              :     /* Check for division by zero */
    3394       275056 :     if (arg2.ndigits == 0 || arg2.digits[0] == 0)
    3395            8 :         goto division_by_zero;
    3396              : 
    3397       275048 :     mod_var(&arg1, &arg2, &result);
    3398              : 
    3399       275048 :     res = make_result_safe(&result, escontext);
    3400              : 
    3401       275048 :     free_var(&result);
    3402              : 
    3403       275048 :     return res;
    3404              : 
    3405           16 : division_by_zero:
    3406           16 :     ereturn(escontext, NULL,
    3407              :             errcode(ERRCODE_DIVISION_BY_ZERO),
    3408              :             errmsg("division by zero"));
    3409              : }
    3410              : 
    3411              : 
    3412              : /*
    3413              :  * numeric_inc() -
    3414              :  *
    3415              :  *  Increment a number by one
    3416              :  */
    3417              : Datum
    3418           32 : numeric_inc(PG_FUNCTION_ARGS)
    3419              : {
    3420           32 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3421              :     NumericVar  arg;
    3422              :     Numeric     res;
    3423              : 
    3424              :     /*
    3425              :      * Handle NaN and infinities
    3426              :      */
    3427           32 :     if (NUMERIC_IS_SPECIAL(num))
    3428           12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3429              : 
    3430              :     /*
    3431              :      * Compute the result and return it
    3432              :      */
    3433           20 :     init_var_from_num(num, &arg);
    3434              : 
    3435           20 :     add_var(&arg, &const_one, &arg);
    3436              : 
    3437           20 :     res = make_result(&arg);
    3438              : 
    3439           20 :     free_var(&arg);
    3440              : 
    3441           20 :     PG_RETURN_NUMERIC(res);
    3442              : }
    3443              : 
    3444              : 
    3445              : /*
    3446              :  * numeric_smaller() -
    3447              :  *
    3448              :  *  Return the smaller of two numbers
    3449              :  */
    3450              : Datum
    3451          543 : numeric_smaller(PG_FUNCTION_ARGS)
    3452              : {
    3453          543 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3454          543 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3455              : 
    3456              :     /*
    3457              :      * Use cmp_numerics so that this will agree with the comparison operators,
    3458              :      * particularly as regards comparisons involving NaN.
    3459              :      */
    3460          543 :     if (cmp_numerics(num1, num2) < 0)
    3461          437 :         PG_RETURN_NUMERIC(num1);
    3462              :     else
    3463          106 :         PG_RETURN_NUMERIC(num2);
    3464              : }
    3465              : 
    3466              : 
    3467              : /*
    3468              :  * numeric_larger() -
    3469              :  *
    3470              :  *  Return the larger of two numbers
    3471              :  */
    3472              : Datum
    3473        12420 : numeric_larger(PG_FUNCTION_ARGS)
    3474              : {
    3475        12420 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3476        12420 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3477              : 
    3478              :     /*
    3479              :      * Use cmp_numerics so that this will agree with the comparison operators,
    3480              :      * particularly as regards comparisons involving NaN.
    3481              :      */
    3482        12420 :     if (cmp_numerics(num1, num2) > 0)
    3483        11952 :         PG_RETURN_NUMERIC(num1);
    3484              :     else
    3485          468 :         PG_RETURN_NUMERIC(num2);
    3486              : }
    3487              : 
    3488              : 
    3489              : /* ----------------------------------------------------------------------
    3490              :  *
    3491              :  * Advanced math functions
    3492              :  *
    3493              :  * ----------------------------------------------------------------------
    3494              :  */
    3495              : 
    3496              : /*
    3497              :  * numeric_gcd() -
    3498              :  *
    3499              :  *  Calculate the greatest common divisor of two numerics
    3500              :  */
    3501              : Datum
    3502          144 : numeric_gcd(PG_FUNCTION_ARGS)
    3503              : {
    3504          144 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3505          144 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3506              :     NumericVar  arg1;
    3507              :     NumericVar  arg2;
    3508              :     NumericVar  result;
    3509              :     Numeric     res;
    3510              : 
    3511              :     /*
    3512              :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3513              :      * cases.
    3514              :      */
    3515          144 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3516           64 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3517              : 
    3518              :     /*
    3519              :      * Unpack the arguments
    3520              :      */
    3521           80 :     init_var_from_num(num1, &arg1);
    3522           80 :     init_var_from_num(num2, &arg2);
    3523              : 
    3524           80 :     init_var(&result);
    3525              : 
    3526              :     /*
    3527              :      * Find the GCD and return the result
    3528              :      */
    3529           80 :     gcd_var(&arg1, &arg2, &result);
    3530              : 
    3531           80 :     res = make_result(&result);
    3532              : 
    3533           80 :     free_var(&result);
    3534              : 
    3535           80 :     PG_RETURN_NUMERIC(res);
    3536              : }
    3537              : 
    3538              : 
    3539              : /*
    3540              :  * numeric_lcm() -
    3541              :  *
    3542              :  *  Calculate the least common multiple of two numerics
    3543              :  */
    3544              : Datum
    3545          164 : numeric_lcm(PG_FUNCTION_ARGS)
    3546              : {
    3547          164 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3548          164 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3549              :     NumericVar  arg1;
    3550              :     NumericVar  arg2;
    3551              :     NumericVar  result;
    3552              :     Numeric     res;
    3553              : 
    3554              :     /*
    3555              :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3556              :      * cases.
    3557              :      */
    3558          164 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3559           64 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3560              : 
    3561              :     /*
    3562              :      * Unpack the arguments
    3563              :      */
    3564          100 :     init_var_from_num(num1, &arg1);
    3565          100 :     init_var_from_num(num2, &arg2);
    3566              : 
    3567          100 :     init_var(&result);
    3568              : 
    3569              :     /*
    3570              :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3571              :      * zero if either input is zero.
    3572              :      *
    3573              :      * Note that the division is guaranteed to be exact, returning an integer
    3574              :      * result, so the LCM is an integral multiple of both x and y.  A display
    3575              :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3576              :      * but as with other numeric functions, we choose to return a result whose
    3577              :      * display scale is no smaller than either input.
    3578              :      */
    3579          100 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3580           32 :         set_var_from_var(&const_zero, &result);
    3581              :     else
    3582              :     {
    3583           68 :         gcd_var(&arg1, &arg2, &result);
    3584           68 :         div_var(&arg1, &result, &result, 0, false, true);
    3585           68 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3586           68 :         result.sign = NUMERIC_POS;
    3587              :     }
    3588              : 
    3589          100 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3590              : 
    3591          100 :     res = make_result(&result);
    3592              : 
    3593           96 :     free_var(&result);
    3594              : 
    3595           96 :     PG_RETURN_NUMERIC(res);
    3596              : }
    3597              : 
    3598              : 
    3599              : /*
    3600              :  * numeric_fac()
    3601              :  *
    3602              :  * Compute factorial
    3603              :  */
    3604              : Datum
    3605           33 : numeric_fac(PG_FUNCTION_ARGS)
    3606              : {
    3607           33 :     int64       num = PG_GETARG_INT64(0);
    3608              :     Numeric     res;
    3609              :     NumericVar  fact;
    3610              :     NumericVar  result;
    3611              : 
    3612           33 :     if (num < 0)
    3613            4 :         ereport(ERROR,
    3614              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3615              :                  errmsg("factorial of a negative number is undefined")));
    3616           29 :     if (num <= 1)
    3617              :     {
    3618            5 :         res = make_result(&const_one);
    3619            5 :         PG_RETURN_NUMERIC(res);
    3620              :     }
    3621              :     /* Fail immediately if the result would overflow */
    3622           24 :     if (num > 32177)
    3623            4 :         ereport(ERROR,
    3624              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3625              :                  errmsg("value overflows numeric format")));
    3626              : 
    3627           20 :     init_var(&fact);
    3628           20 :     init_var(&result);
    3629              : 
    3630           20 :     int64_to_numericvar(num, &result);
    3631              : 
    3632          245 :     for (num = num - 1; num > 1; num--)
    3633              :     {
    3634              :         /* this loop can take awhile, so allow it to be interrupted */
    3635          225 :         CHECK_FOR_INTERRUPTS();
    3636              : 
    3637          225 :         int64_to_numericvar(num, &fact);
    3638              : 
    3639          225 :         mul_var(&result, &fact, &result, 0);
    3640              :     }
    3641              : 
    3642           20 :     res = make_result(&result);
    3643              : 
    3644           20 :     free_var(&fact);
    3645           20 :     free_var(&result);
    3646              : 
    3647           20 :     PG_RETURN_NUMERIC(res);
    3648              : }
    3649              : 
    3650              : 
    3651              : /*
    3652              :  * numeric_sqrt() -
    3653              :  *
    3654              :  *  Compute the square root of a numeric.
    3655              :  */
    3656              : Datum
    3657          108 : numeric_sqrt(PG_FUNCTION_ARGS)
    3658              : {
    3659          108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3660              :     Numeric     res;
    3661              :     NumericVar  arg;
    3662              :     NumericVar  result;
    3663              :     int         sweight;
    3664              :     int         rscale;
    3665              : 
    3666              :     /*
    3667              :      * Handle NaN and infinities
    3668              :      */
    3669          108 :     if (NUMERIC_IS_SPECIAL(num))
    3670              :     {
    3671              :         /* error should match that in sqrt_var() */
    3672           12 :         if (NUMERIC_IS_NINF(num))
    3673            4 :             ereport(ERROR,
    3674              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3675              :                      errmsg("cannot take square root of a negative number")));
    3676              :         /* For NAN or PINF, just duplicate the input */
    3677            8 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3678              :     }
    3679              : 
    3680              :     /*
    3681              :      * Unpack the argument and determine the result scale.  We choose a scale
    3682              :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3683              :      * case not less than the input's dscale.
    3684              :      */
    3685           96 :     init_var_from_num(num, &arg);
    3686              : 
    3687           96 :     init_var(&result);
    3688              : 
    3689              :     /*
    3690              :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3691              :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3692              :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3693              :      * a few cycles, since the division is exact and there is no need to round
    3694              :      * towards negative infinity.
    3695              :      */
    3696              : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3697           96 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3698              : #else
    3699              :     if (arg.weight >= 0)
    3700              :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3701              :     else
    3702              :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3703              : #endif
    3704              : 
    3705           96 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3706           96 :     rscale = Max(rscale, arg.dscale);
    3707           96 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3708           96 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3709              : 
    3710              :     /*
    3711              :      * Let sqrt_var() do the calculation and return the result.
    3712              :      */
    3713           96 :     sqrt_var(&arg, &result, rscale);
    3714              : 
    3715           92 :     res = make_result(&result);
    3716              : 
    3717           92 :     free_var(&result);
    3718              : 
    3719           92 :     PG_RETURN_NUMERIC(res);
    3720              : }
    3721              : 
    3722              : 
    3723              : /*
    3724              :  * numeric_exp() -
    3725              :  *
    3726              :  *  Raise e to the power of x
    3727              :  */
    3728              : Datum
    3729           65 : numeric_exp(PG_FUNCTION_ARGS)
    3730              : {
    3731           65 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3732              :     Numeric     res;
    3733              :     NumericVar  arg;
    3734              :     NumericVar  result;
    3735              :     int         rscale;
    3736              :     double      val;
    3737              : 
    3738              :     /*
    3739              :      * Handle NaN and infinities
    3740              :      */
    3741           65 :     if (NUMERIC_IS_SPECIAL(num))
    3742              :     {
    3743              :         /* Per POSIX, exp(-Inf) is zero */
    3744           15 :         if (NUMERIC_IS_NINF(num))
    3745            5 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3746              :         /* For NAN or PINF, just duplicate the input */
    3747           10 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3748              :     }
    3749              : 
    3750              :     /*
    3751              :      * Unpack the argument and determine the result scale.  We choose a scale
    3752              :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3753              :      * case not less than the input's dscale.
    3754              :      */
    3755           50 :     init_var_from_num(num, &arg);
    3756              : 
    3757           50 :     init_var(&result);
    3758              : 
    3759              :     /* convert input to float8, ignoring overflow */
    3760           50 :     val = numericvar_to_double_no_overflow(&arg);
    3761              : 
    3762              :     /*
    3763              :      * log10(result) = num * log10(e), so this is approximately the decimal
    3764              :      * weight of the result:
    3765              :      */
    3766           50 :     val *= 0.434294481903252;
    3767              : 
    3768              :     /* limit to something that won't cause integer overflow */
    3769           50 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3770           50 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3771              : 
    3772           50 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3773           50 :     rscale = Max(rscale, arg.dscale);
    3774           50 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3775           50 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3776              : 
    3777              :     /*
    3778              :      * Let exp_var() do the calculation and return the result.
    3779              :      */
    3780           50 :     exp_var(&arg, &result, rscale);
    3781              : 
    3782           50 :     res = make_result(&result);
    3783              : 
    3784           50 :     free_var(&result);
    3785              : 
    3786           50 :     PG_RETURN_NUMERIC(res);
    3787              : }
    3788              : 
    3789              : 
    3790              : /*
    3791              :  * numeric_ln() -
    3792              :  *
    3793              :  *  Compute the natural logarithm of x
    3794              :  */
    3795              : Datum
    3796          140 : numeric_ln(PG_FUNCTION_ARGS)
    3797              : {
    3798          140 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3799              :     Numeric     res;
    3800              :     NumericVar  arg;
    3801              :     NumericVar  result;
    3802              :     int         ln_dweight;
    3803              :     int         rscale;
    3804              : 
    3805              :     /*
    3806              :      * Handle NaN and infinities
    3807              :      */
    3808          140 :     if (NUMERIC_IS_SPECIAL(num))
    3809              :     {
    3810           12 :         if (NUMERIC_IS_NINF(num))
    3811            4 :             ereport(ERROR,
    3812              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3813              :                      errmsg("cannot take logarithm of a negative number")));
    3814              :         /* For NAN or PINF, just duplicate the input */
    3815            8 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3816              :     }
    3817              : 
    3818          128 :     init_var_from_num(num, &arg);
    3819          128 :     init_var(&result);
    3820              : 
    3821              :     /* Estimated dweight of logarithm */
    3822          128 :     ln_dweight = estimate_ln_dweight(&arg);
    3823              : 
    3824          128 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3825          128 :     rscale = Max(rscale, arg.dscale);
    3826          128 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3827          128 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3828              : 
    3829          128 :     ln_var(&arg, &result, rscale);
    3830              : 
    3831          112 :     res = make_result(&result);
    3832              : 
    3833          112 :     free_var(&result);
    3834              : 
    3835          112 :     PG_RETURN_NUMERIC(res);
    3836              : }
    3837              : 
    3838              : 
    3839              : /*
    3840              :  * numeric_log() -
    3841              :  *
    3842              :  *  Compute the logarithm of x in a given base
    3843              :  */
    3844              : Datum
    3845          240 : numeric_log(PG_FUNCTION_ARGS)
    3846              : {
    3847          240 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3848          240 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3849              :     Numeric     res;
    3850              :     NumericVar  arg1;
    3851              :     NumericVar  arg2;
    3852              :     NumericVar  result;
    3853              : 
    3854              :     /*
    3855              :      * Handle NaN and infinities
    3856              :      */
    3857          240 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3858              :     {
    3859              :         int         sign1,
    3860              :                     sign2;
    3861              : 
    3862           84 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3863           36 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3864              :         /* fail on negative inputs including -Inf, as log_var would */
    3865           48 :         sign1 = numeric_sign_internal(num1);
    3866           48 :         sign2 = numeric_sign_internal(num2);
    3867           48 :         if (sign1 < 0 || sign2 < 0)
    3868           16 :             ereport(ERROR,
    3869              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3870              :                      errmsg("cannot take logarithm of a negative number")));
    3871              :         /* fail on zero inputs, as log_var would */
    3872           32 :         if (sign1 == 0 || sign2 == 0)
    3873            4 :             ereport(ERROR,
    3874              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3875              :                      errmsg("cannot take logarithm of zero")));
    3876           28 :         if (NUMERIC_IS_PINF(num1))
    3877              :         {
    3878              :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    3879           12 :             if (NUMERIC_IS_PINF(num2))
    3880            4 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    3881              :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    3882            8 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3883              :         }
    3884              :         Assert(NUMERIC_IS_PINF(num2));
    3885              :         /* log(finite-positive, Inf) is Inf */
    3886           16 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    3887              :     }
    3888              : 
    3889              :     /*
    3890              :      * Initialize things
    3891              :      */
    3892          156 :     init_var_from_num(num1, &arg1);
    3893          156 :     init_var_from_num(num2, &arg2);
    3894          156 :     init_var(&result);
    3895              : 
    3896              :     /*
    3897              :      * Call log_var() to compute and return the result; note it handles scale
    3898              :      * selection itself.
    3899              :      */
    3900          156 :     log_var(&arg1, &arg2, &result);
    3901              : 
    3902          116 :     res = make_result(&result);
    3903              : 
    3904          116 :     free_var(&result);
    3905              : 
    3906          116 :     PG_RETURN_NUMERIC(res);
    3907              : }
    3908              : 
    3909              : 
    3910              : /*
    3911              :  * numeric_power() -
    3912              :  *
    3913              :  *  Raise x to the power of y
    3914              :  */
    3915              : Datum
    3916         1149 : numeric_power(PG_FUNCTION_ARGS)
    3917              : {
    3918         1149 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3919         1149 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3920              :     Numeric     res;
    3921              :     NumericVar  arg1;
    3922              :     NumericVar  arg2;
    3923              :     NumericVar  result;
    3924              :     int         sign1,
    3925              :                 sign2;
    3926              : 
    3927              :     /*
    3928              :      * Handle NaN and infinities
    3929              :      */
    3930         1149 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3931              :     {
    3932              :         /*
    3933              :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    3934              :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    3935              :          * (with no error).
    3936              :          */
    3937          173 :         if (NUMERIC_IS_NAN(num1))
    3938              :         {
    3939           39 :             if (!NUMERIC_IS_SPECIAL(num2))
    3940              :             {
    3941           26 :                 init_var_from_num(num2, &arg2);
    3942           26 :                 if (cmp_var(&arg2, &const_zero) == 0)
    3943            9 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3944              :             }
    3945           30 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3946              :         }
    3947          134 :         if (NUMERIC_IS_NAN(num2))
    3948              :         {
    3949           30 :             if (!NUMERIC_IS_SPECIAL(num1))
    3950              :             {
    3951           26 :                 init_var_from_num(num1, &arg1);
    3952           26 :                 if (cmp_var(&arg1, &const_one) == 0)
    3953            9 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3954              :             }
    3955           21 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3956              :         }
    3957              :         /* At least one input is infinite, but error rules still apply */
    3958          104 :         sign1 = numeric_sign_internal(num1);
    3959          104 :         sign2 = numeric_sign_internal(num2);
    3960          104 :         if (sign1 == 0 && sign2 < 0)
    3961            4 :             ereport(ERROR,
    3962              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3963              :                      errmsg("zero raised to a negative power is undefined")));
    3964          100 :         if (sign1 < 0 && !numeric_is_integral(num2))
    3965            4 :             ereport(ERROR,
    3966              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3967              :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    3968              : 
    3969              :         /*
    3970              :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    3971              :          *
    3972              :          * For any value of y, if x is +1, 1.0 shall be returned.
    3973              :          */
    3974           96 :         if (!NUMERIC_IS_SPECIAL(num1))
    3975              :         {
    3976           31 :             init_var_from_num(num1, &arg1);
    3977           31 :             if (cmp_var(&arg1, &const_one) == 0)
    3978            4 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    3979              :         }
    3980              : 
    3981              :         /*
    3982              :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    3983              :          */
    3984           92 :         if (sign2 == 0)
    3985            9 :             PG_RETURN_NUMERIC(make_result(&const_one));
    3986              : 
    3987              :         /*
    3988              :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    3989              :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    3990              :          * be returned.  (Since we don't deal in minus zero, we need not
    3991              :          * distinguish these two cases.)
    3992              :          */
    3993           83 :         if (sign1 == 0 && sign2 > 0)
    3994            4 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3995              : 
    3996              :         /*
    3997              :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    3998              :          *
    3999              :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4000              :          *
    4001              :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4002              :          *
    4003              :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4004              :          *
    4005              :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4006              :          */
    4007           79 :         if (NUMERIC_IS_INF(num2))
    4008              :         {
    4009              :             bool        abs_x_gt_one;
    4010              : 
    4011           42 :             if (NUMERIC_IS_SPECIAL(num1))
    4012           19 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4013              :             else
    4014              :             {
    4015           23 :                 init_var_from_num(num1, &arg1);
    4016           23 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4017            5 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4018           18 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4019           18 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4020              :             }
    4021           37 :             if (abs_x_gt_one == (sign2 > 0))
    4022           22 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4023              :             else
    4024           15 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4025              :         }
    4026              : 
    4027              :         /*
    4028              :          * For y < 0, if x is +Inf, +0 shall be returned.
    4029              :          *
    4030              :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4031              :          */
    4032           37 :         if (NUMERIC_IS_PINF(num1))
    4033              :         {
    4034           17 :             if (sign2 > 0)
    4035           12 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4036              :             else
    4037            5 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4038              :         }
    4039              : 
    4040              :         Assert(NUMERIC_IS_NINF(num1));
    4041              : 
    4042              :         /*
    4043              :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4044              :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4045              :          * (Again, we need not distinguish these two cases.)
    4046              :          */
    4047           20 :         if (sign2 < 0)
    4048           10 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4049              : 
    4050              :         /*
    4051              :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4052              :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4053              :          */
    4054           10 :         init_var_from_num(num2, &arg2);
    4055           10 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4056           10 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4057            5 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4058              :         else
    4059            5 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4060              :     }
    4061              : 
    4062              :     /*
    4063              :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4064              :      * certain error conditions.  Specifically, we don't return a
    4065              :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4066              :      * non-integer power must produce the same error code, but that case is
    4067              :      * handled in power_var().
    4068              :      */
    4069          976 :     sign1 = numeric_sign_internal(num1);
    4070          976 :     sign2 = numeric_sign_internal(num2);
    4071              : 
    4072          976 :     if (sign1 == 0 && sign2 < 0)
    4073            8 :         ereport(ERROR,
    4074              :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4075              :                  errmsg("zero raised to a negative power is undefined")));
    4076              : 
    4077              :     /*
    4078              :      * Initialize things
    4079              :      */
    4080          968 :     init_var(&result);
    4081          968 :     init_var_from_num(num1, &arg1);
    4082          968 :     init_var_from_num(num2, &arg2);
    4083              : 
    4084              :     /*
    4085              :      * Call power_var() to compute and return the result; note it handles
    4086              :      * scale selection itself.
    4087              :      */
    4088          968 :     power_var(&arg1, &arg2, &result);
    4089              : 
    4090          948 :     res = make_result(&result);
    4091              : 
    4092          948 :     free_var(&result);
    4093              : 
    4094          948 :     PG_RETURN_NUMERIC(res);
    4095              : }
    4096              : 
    4097              : /*
    4098              :  * numeric_scale() -
    4099              :  *
    4100              :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4101              :  */
    4102              : Datum
    4103           81 : numeric_scale(PG_FUNCTION_ARGS)
    4104              : {
    4105           81 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4106              : 
    4107           81 :     if (NUMERIC_IS_SPECIAL(num))
    4108           14 :         PG_RETURN_NULL();
    4109              : 
    4110           67 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4111              : }
    4112              : 
    4113              : /*
    4114              :  * Calculate minimum scale for value.
    4115              :  */
    4116              : static int
    4117          267 : get_min_scale(NumericVar *var)
    4118              : {
    4119              :     int         min_scale;
    4120              :     int         last_digit_pos;
    4121              : 
    4122              :     /*
    4123              :      * Ordinarily, the input value will be "stripped" so that the last
    4124              :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4125              :      * loop if it isn't, so explicitly find the last nonzero digit.
    4126              :      */
    4127          267 :     last_digit_pos = var->ndigits - 1;
    4128          267 :     while (last_digit_pos >= 0 &&
    4129          243 :            var->digits[last_digit_pos] == 0)
    4130            0 :         last_digit_pos--;
    4131              : 
    4132          267 :     if (last_digit_pos >= 0)
    4133              :     {
    4134              :         /* compute min_scale assuming that last ndigit has no zeroes */
    4135          243 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4136              : 
    4137              :         /*
    4138              :          * We could get a negative result if there are no digits after the
    4139              :          * decimal point.  In this case the min_scale must be zero.
    4140              :          */
    4141          243 :         if (min_scale > 0)
    4142              :         {
    4143              :             /*
    4144              :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4145              :              * zero.
    4146              :              */
    4147          135 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4148              : 
    4149          365 :             while (last_digit % 10 == 0)
    4150              :             {
    4151          230 :                 min_scale--;
    4152          230 :                 last_digit /= 10;
    4153              :             }
    4154              :         }
    4155              :         else
    4156          108 :             min_scale = 0;
    4157              :     }
    4158              :     else
    4159           24 :         min_scale = 0;          /* result if input is zero */
    4160              : 
    4161          267 :     return min_scale;
    4162              : }
    4163              : 
    4164              : /*
    4165              :  * Returns minimum scale required to represent supplied value without loss.
    4166              :  */
    4167              : Datum
    4168           60 : numeric_min_scale(PG_FUNCTION_ARGS)
    4169              : {
    4170           60 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4171              :     NumericVar  arg;
    4172              :     int         min_scale;
    4173              : 
    4174           60 :     if (NUMERIC_IS_SPECIAL(num))
    4175           10 :         PG_RETURN_NULL();
    4176              : 
    4177           50 :     init_var_from_num(num, &arg);
    4178           50 :     min_scale = get_min_scale(&arg);
    4179           50 :     free_var(&arg);
    4180              : 
    4181           50 :     PG_RETURN_INT32(min_scale);
    4182              : }
    4183              : 
    4184              : /*
    4185              :  * Reduce scale of numeric value to represent supplied value without loss.
    4186              :  */
    4187              : Datum
    4188          227 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4189              : {
    4190          227 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4191              :     Numeric     res;
    4192              :     NumericVar  result;
    4193              : 
    4194          227 :     if (NUMERIC_IS_SPECIAL(num))
    4195           10 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4196              : 
    4197          217 :     init_var_from_num(num, &result);
    4198          217 :     result.dscale = get_min_scale(&result);
    4199          217 :     res = make_result(&result);
    4200          217 :     free_var(&result);
    4201              : 
    4202          217 :     PG_RETURN_NUMERIC(res);
    4203              : }
    4204              : 
    4205              : /*
    4206              :  * Return a random numeric value in the range [rmin, rmax].
    4207              :  */
    4208              : Numeric
    4209        22308 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
    4210              : {
    4211              :     NumericVar  rmin_var;
    4212              :     NumericVar  rmax_var;
    4213              :     NumericVar  result;
    4214              :     Numeric     res;
    4215              : 
    4216              :     /* Range bounds must not be NaN/infinity */
    4217        22308 :     if (NUMERIC_IS_SPECIAL(rmin))
    4218              :     {
    4219            8 :         if (NUMERIC_IS_NAN(rmin))
    4220            4 :             ereport(ERROR,
    4221              :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4222              :                     errmsg("lower bound cannot be NaN"));
    4223              :         else
    4224            4 :             ereport(ERROR,
    4225              :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4226              :                     errmsg("lower bound cannot be infinity"));
    4227              :     }
    4228        22300 :     if (NUMERIC_IS_SPECIAL(rmax))
    4229              :     {
    4230            8 :         if (NUMERIC_IS_NAN(rmax))
    4231            4 :             ereport(ERROR,
    4232              :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4233              :                     errmsg("upper bound cannot be NaN"));
    4234              :         else
    4235            4 :             ereport(ERROR,
    4236              :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4237              :                     errmsg("upper bound cannot be infinity"));
    4238              :     }
    4239              : 
    4240              :     /* Return a random value in the range [rmin, rmax] */
    4241        22292 :     init_var_from_num(rmin, &rmin_var);
    4242        22292 :     init_var_from_num(rmax, &rmax_var);
    4243              : 
    4244        22292 :     init_var(&result);
    4245              : 
    4246        22292 :     random_var(state, &rmin_var, &rmax_var, &result);
    4247              : 
    4248        22288 :     res = make_result(&result);
    4249              : 
    4250        22288 :     free_var(&result);
    4251              : 
    4252        22288 :     return res;
    4253              : }
    4254              : 
    4255              : 
    4256              : /* ----------------------------------------------------------------------
    4257              :  *
    4258              :  * Type conversion functions
    4259              :  *
    4260              :  * ----------------------------------------------------------------------
    4261              :  */
    4262              : 
    4263              : Numeric
    4264      1245493 : int64_to_numeric(int64 val)
    4265              : {
    4266              :     Numeric     res;
    4267              :     NumericVar  result;
    4268              : 
    4269      1245493 :     init_var(&result);
    4270              : 
    4271      1245493 :     int64_to_numericvar(val, &result);
    4272              : 
    4273      1245493 :     res = make_result(&result);
    4274              : 
    4275      1245493 :     free_var(&result);
    4276              : 
    4277      1245493 :     return res;
    4278              : }
    4279              : 
    4280              : /*
    4281              :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4282              :  * numeric division.
    4283              :  */
    4284              : Numeric
    4285        15155 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4286              : {
    4287              :     Numeric     res;
    4288              :     NumericVar  result;
    4289              :     int         rscale;
    4290              :     int         w;
    4291              :     int         m;
    4292              : 
    4293        15155 :     init_var(&result);
    4294              : 
    4295              :     /* result scale */
    4296        15155 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4297              : 
    4298              :     /* how much to decrease the weight by */
    4299        15155 :     w = log10val2 / DEC_DIGITS;
    4300              :     /* how much is left to divide by */
    4301        15155 :     m = log10val2 % DEC_DIGITS;
    4302        15155 :     if (m < 0)
    4303              :     {
    4304            0 :         m += DEC_DIGITS;
    4305            0 :         w--;
    4306              :     }
    4307              : 
    4308              :     /*
    4309              :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4310              :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4311              :      * one more.
    4312              :      */
    4313        15155 :     if (m > 0)
    4314              :     {
    4315              : #if DEC_DIGITS == 4
    4316              :         static const int pow10[] = {1, 10, 100, 1000};
    4317              : #elif DEC_DIGITS == 2
    4318              :         static const int pow10[] = {1, 10};
    4319              : #elif DEC_DIGITS == 1
    4320              :         static const int pow10[] = {1};
    4321              : #else
    4322              : #error unsupported NBASE
    4323              : #endif
    4324        15155 :         int64       factor = pow10[DEC_DIGITS - m];
    4325              :         int64       new_val1;
    4326              : 
    4327              :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4328              : 
    4329        15155 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4330              :         {
    4331              :             /* do the multiplication using 128-bit integers */
    4332              :             INT128      tmp;
    4333              : 
    4334            9 :             tmp = int64_to_int128(0);
    4335            9 :             int128_add_int64_mul_int64(&tmp, val1, factor);
    4336              : 
    4337            9 :             int128_to_numericvar(tmp, &result);
    4338              :         }
    4339              :         else
    4340        15146 :             int64_to_numericvar(new_val1, &result);
    4341              : 
    4342        15155 :         w++;
    4343              :     }
    4344              :     else
    4345            0 :         int64_to_numericvar(val1, &result);
    4346              : 
    4347        15155 :     result.weight -= w;
    4348        15155 :     result.dscale = rscale;
    4349              : 
    4350        15155 :     res = make_result(&result);
    4351              : 
    4352        15155 :     free_var(&result);
    4353              : 
    4354        15155 :     return res;
    4355              : }
    4356              : 
    4357              : Datum
    4358      1037830 : int4_numeric(PG_FUNCTION_ARGS)
    4359              : {
    4360      1037830 :     int32       val = PG_GETARG_INT32(0);
    4361              : 
    4362      1037830 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4363              : }
    4364              : 
    4365              : /*
    4366              :  * Internal version of numeric_int4() with support for soft error reporting.
    4367              :  */
    4368              : int32
    4369         4800 : numeric_int4_safe(Numeric num, Node *escontext)
    4370              : {
    4371              :     NumericVar  x;
    4372              :     int32       result;
    4373              : 
    4374         4800 :     if (NUMERIC_IS_SPECIAL(num))
    4375              :     {
    4376           12 :         if (NUMERIC_IS_NAN(num))
    4377            4 :             ereturn(escontext, 0,
    4378              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4379              :                      errmsg("cannot convert NaN to %s", "integer")));
    4380              :         else
    4381            8 :             ereturn(escontext, 0,
    4382              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4383              :                      errmsg("cannot convert infinity to %s", "integer")));
    4384              :     }
    4385              : 
    4386              :     /* Convert to variable format, then convert to int4 */
    4387         4788 :     init_var_from_num(num, &x);
    4388              : 
    4389         4788 :     if (!numericvar_to_int32(&x, &result))
    4390           62 :         ereturn(escontext, 0,
    4391              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4392              :                  errmsg("integer out of range")));
    4393              : 
    4394         4726 :     return result;
    4395              : }
    4396              : 
    4397              : Datum
    4398         3726 : numeric_int4(PG_FUNCTION_ARGS)
    4399              : {
    4400         3726 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4401              :     int32       result;
    4402              : 
    4403         3726 :     result = numeric_int4_safe(num, fcinfo->context);
    4404              : 
    4405         3706 :     if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
    4406            0 :         PG_RETURN_NULL();
    4407              : 
    4408         3706 :     PG_RETURN_INT32(result);
    4409              : }
    4410              : 
    4411              : /*
    4412              :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4413              :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4414              :  * The input NumericVar is *not* free'd.
    4415              :  */
    4416              : static bool
    4417         5289 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4418              : {
    4419              :     int64       val;
    4420              : 
    4421         5289 :     if (!numericvar_to_int64(var, &val))
    4422            4 :         return false;
    4423              : 
    4424         5285 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4425           58 :         return false;
    4426              : 
    4427              :     /* Down-convert to int4 */
    4428         5227 :     *result = (int32) val;
    4429              : 
    4430         5227 :     return true;
    4431              : }
    4432              : 
    4433              : Datum
    4434        24587 : int8_numeric(PG_FUNCTION_ARGS)
    4435              : {
    4436        24587 :     int64       val = PG_GETARG_INT64(0);
    4437              : 
    4438        24587 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4439              : }
    4440              : 
    4441              : /*
    4442              :  * Internal version of numeric_int8() with support for soft error reporting.
    4443              :  */
    4444              : int64
    4445          387 : numeric_int8_safe(Numeric num, Node *escontext)
    4446              : {
    4447              :     NumericVar  x;
    4448              :     int64       result;
    4449              : 
    4450          387 :     if (NUMERIC_IS_SPECIAL(num))
    4451              :     {
    4452           12 :         if (NUMERIC_IS_NAN(num))
    4453            4 :             ereturn(escontext, 0,
    4454              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4455              :                      errmsg("cannot convert NaN to %s", "bigint")));
    4456              :         else
    4457            8 :             ereturn(escontext, 0,
    4458              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4459              :                      errmsg("cannot convert infinity to %s", "bigint")));
    4460              :     }
    4461              : 
    4462              :     /* Convert to variable format, then convert to int8 */
    4463          375 :     init_var_from_num(num, &x);
    4464              : 
    4465          375 :     if (!numericvar_to_int64(&x, &result))
    4466           40 :         ereturn(escontext, 0,
    4467              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4468              :                  errmsg("bigint out of range")));
    4469              : 
    4470          335 :     return result;
    4471              : }
    4472              : 
    4473              : Datum
    4474          347 : numeric_int8(PG_FUNCTION_ARGS)
    4475              : {
    4476          347 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4477              :     int64       result;
    4478              : 
    4479          347 :     result = numeric_int8_safe(num, fcinfo->context);
    4480              : 
    4481          303 :     if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
    4482            0 :         PG_RETURN_NULL();
    4483              : 
    4484          303 :     PG_RETURN_INT64(result);
    4485              : }
    4486              : 
    4487              : 
    4488              : Datum
    4489            5 : int2_numeric(PG_FUNCTION_ARGS)
    4490              : {
    4491            5 :     int16       val = PG_GETARG_INT16(0);
    4492              : 
    4493            5 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4494              : }
    4495              : 
    4496              : 
    4497              : Datum
    4498           73 : numeric_int2(PG_FUNCTION_ARGS)
    4499              : {
    4500           73 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4501              :     NumericVar  x;
    4502              :     int64       val;
    4503              :     int16       result;
    4504              : 
    4505           73 :     if (NUMERIC_IS_SPECIAL(num))
    4506              :     {
    4507           12 :         if (NUMERIC_IS_NAN(num))
    4508            4 :             ereturn(fcinfo->context, (Datum) 0,
    4509              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4510              :                      errmsg("cannot convert NaN to %s", "smallint")));
    4511              :         else
    4512            8 :             ereturn(fcinfo->context, (Datum) 0,
    4513              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4514              :                      errmsg("cannot convert infinity to %s", "smallint")));
    4515              :     }
    4516              : 
    4517              :     /* Convert to variable format and thence to int8 */
    4518           61 :     init_var_from_num(num, &x);
    4519              : 
    4520           61 :     if (!numericvar_to_int64(&x, &val))
    4521            0 :         ereturn(fcinfo->context, (Datum) 0,
    4522              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4523              :                  errmsg("smallint out of range")));
    4524              : 
    4525           61 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4526            8 :         ereturn(fcinfo->context, (Datum) 0,
    4527              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4528              :                  errmsg("smallint out of range")));
    4529              : 
    4530              :     /* Down-convert to int2 */
    4531           53 :     result = (int16) val;
    4532              : 
    4533           53 :     PG_RETURN_INT16(result);
    4534              : }
    4535              : 
    4536              : 
    4537              : Datum
    4538          654 : float8_numeric(PG_FUNCTION_ARGS)
    4539              : {
    4540          654 :     float8      val = PG_GETARG_FLOAT8(0);
    4541              :     Numeric     res;
    4542              :     NumericVar  result;
    4543              :     char        buf[DBL_DIG + 100];
    4544              :     const char *endptr;
    4545              : 
    4546          654 :     if (isnan(val))
    4547            5 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4548              : 
    4549          649 :     if (isinf(val))
    4550              :     {
    4551           10 :         if (val < 0)
    4552            5 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4553              :         else
    4554            5 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4555              :     }
    4556              : 
    4557          639 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4558              : 
    4559          639 :     init_var(&result);
    4560              : 
    4561              :     /* Assume we need not worry about leading/trailing spaces */
    4562          639 :     if (!set_var_from_str(buf, buf, &result, &endptr, fcinfo->context))
    4563            0 :         PG_RETURN_NULL();
    4564              : 
    4565          639 :     res = make_result(&result);
    4566              : 
    4567          639 :     free_var(&result);
    4568              : 
    4569          639 :     PG_RETURN_NUMERIC(res);
    4570              : }
    4571              : 
    4572              : 
    4573              : Datum
    4574       347599 : numeric_float8(PG_FUNCTION_ARGS)
    4575              : {
    4576       347599 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4577              :     char       *tmp;
    4578              :     Datum       result;
    4579              : 
    4580       347599 :     if (NUMERIC_IS_SPECIAL(num))
    4581              :     {
    4582           56 :         if (NUMERIC_IS_PINF(num))
    4583           17 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4584           39 :         else if (NUMERIC_IS_NINF(num))
    4585           17 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4586              :         else
    4587           22 :             PG_RETURN_FLOAT8(get_float8_nan());
    4588              :     }
    4589              : 
    4590       347543 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4591              :                                               NumericGetDatum(num)));
    4592       347543 :     if (!DirectInputFunctionCallSafe(float8in, tmp,
    4593              :                                      InvalidOid, -1,
    4594              :                                      (Node *) fcinfo->context,
    4595              :                                      &result))
    4596              :     {
    4597            0 :         pfree(tmp);
    4598            0 :         PG_RETURN_NULL();
    4599              :     }
    4600              : 
    4601       347543 :     PG_RETURN_DATUM(result);
    4602              : }
    4603              : 
    4604              : 
    4605              : /*
    4606              :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4607              :  *
    4608              :  * (internal helper function, not directly callable from SQL)
    4609              :  */
    4610              : Datum
    4611           16 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4612              : {
    4613           16 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4614              :     double      val;
    4615              : 
    4616           16 :     if (NUMERIC_IS_SPECIAL(num))
    4617              :     {
    4618            0 :         if (NUMERIC_IS_PINF(num))
    4619            0 :             val = HUGE_VAL;
    4620            0 :         else if (NUMERIC_IS_NINF(num))
    4621            0 :             val = -HUGE_VAL;
    4622              :         else
    4623            0 :             val = get_float8_nan();
    4624              :     }
    4625              :     else
    4626              :     {
    4627              :         NumericVar  x;
    4628              : 
    4629           16 :         init_var_from_num(num, &x);
    4630           16 :         val = numericvar_to_double_no_overflow(&x);
    4631              :     }
    4632              : 
    4633           16 :     PG_RETURN_FLOAT8(val);
    4634              : }
    4635              : 
    4636              : Datum
    4637        15170 : float4_numeric(PG_FUNCTION_ARGS)
    4638              : {
    4639        15170 :     float4      val = PG_GETARG_FLOAT4(0);
    4640              :     Numeric     res;
    4641              :     NumericVar  result;
    4642              :     char        buf[FLT_DIG + 100];
    4643              :     const char *endptr;
    4644              : 
    4645        15170 :     if (isnan(val))
    4646            5 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4647              : 
    4648        15165 :     if (isinf(val))
    4649              :     {
    4650           10 :         if (val < 0)
    4651            5 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4652              :         else
    4653            5 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4654              :     }
    4655              : 
    4656        15155 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4657              : 
    4658        15155 :     init_var(&result);
    4659              : 
    4660              :     /* Assume we need not worry about leading/trailing spaces */
    4661        15155 :     if (!set_var_from_str(buf, buf, &result, &endptr, fcinfo->context))
    4662            0 :         PG_RETURN_NULL();
    4663              : 
    4664        15155 :     res = make_result(&result);
    4665              : 
    4666        15155 :     free_var(&result);
    4667              : 
    4668        15155 :     PG_RETURN_NUMERIC(res);
    4669              : }
    4670              : 
    4671              : 
    4672              : Datum
    4673         1701 : numeric_float4(PG_FUNCTION_ARGS)
    4674              : {
    4675         1701 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4676              :     char       *tmp;
    4677              :     Datum       result;
    4678              : 
    4679         1701 :     if (NUMERIC_IS_SPECIAL(num))
    4680              :     {
    4681           56 :         if (NUMERIC_IS_PINF(num))
    4682           17 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4683           39 :         else if (NUMERIC_IS_NINF(num))
    4684           17 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4685              :         else
    4686           22 :             PG_RETURN_FLOAT4(get_float4_nan());
    4687              :     }
    4688              : 
    4689         1645 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4690              :                                               NumericGetDatum(num)));
    4691              : 
    4692         1645 :     if (!DirectInputFunctionCallSafe(float4in, tmp,
    4693              :                                      InvalidOid, -1,
    4694              :                                      (Node *) fcinfo->context,
    4695              :                                      &result))
    4696              :     {
    4697            0 :         pfree(tmp);
    4698            0 :         PG_RETURN_NULL();
    4699              :     }
    4700              : 
    4701         1645 :     pfree(tmp);
    4702              : 
    4703         1645 :     PG_RETURN_DATUM(result);
    4704              : }
    4705              : 
    4706              : 
    4707              : Datum
    4708           98 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4709              : {
    4710           98 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4711              :     NumericVar  x;
    4712              :     XLogRecPtr  result;
    4713              : 
    4714           98 :     if (NUMERIC_IS_SPECIAL(num))
    4715              :     {
    4716            4 :         if (NUMERIC_IS_NAN(num))
    4717            4 :             ereport(ERROR,
    4718              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4719              :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4720              :         else
    4721            0 :             ereport(ERROR,
    4722              :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4723              :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4724              :     }
    4725              : 
    4726              :     /* Convert to variable format and thence to pg_lsn */
    4727           94 :     init_var_from_num(num, &x);
    4728              : 
    4729           94 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4730           16 :         ereport(ERROR,
    4731              :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4732              :                  errmsg("pg_lsn out of range")));
    4733              : 
    4734           78 :     PG_RETURN_LSN(result);
    4735              : }
    4736              : 
    4737              : 
    4738              : /* ----------------------------------------------------------------------
    4739              :  *
    4740              :  * Aggregate functions
    4741              :  *
    4742              :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4743              :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4744              :  * context.  The digit buffers for the NumericVars will be there too.
    4745              :  *
    4746              :  * For integer inputs, some aggregates use special-purpose 64-bit or 128-bit
    4747              :  * integer based transition datatypes to speed up calculations.
    4748              :  *
    4749              :  * ----------------------------------------------------------------------
    4750              :  */
    4751              : 
    4752              : typedef struct NumericAggState
    4753              : {
    4754              :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4755              :     MemoryContext agg_context;  /* context we're calculating in */
    4756              :     int64       N;              /* count of processed numbers */
    4757              :     NumericSumAccum sumX;       /* sum of processed numbers */
    4758              :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4759              :     int         maxScale;       /* maximum scale seen so far */
    4760              :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4761              :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4762              :     int64       NaNcount;       /* count of NaN values */
    4763              :     int64       pInfcount;      /* count of +Inf values */
    4764              :     int64       nInfcount;      /* count of -Inf values */
    4765              : } NumericAggState;
    4766              : 
    4767              : #define NA_TOTAL_COUNT(na) \
    4768              :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4769              : 
    4770              : /*
    4771              :  * Prepare state data for a numeric aggregate function that needs to compute
    4772              :  * sum, count and optionally sum of squares of the input.
    4773              :  */
    4774              : static NumericAggState *
    4775       114080 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4776              : {
    4777              :     NumericAggState *state;
    4778              :     MemoryContext agg_context;
    4779              :     MemoryContext old_context;
    4780              : 
    4781       114080 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4782            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4783              : 
    4784       114080 :     old_context = MemoryContextSwitchTo(agg_context);
    4785              : 
    4786       114080 :     state = palloc0_object(NumericAggState);
    4787       114080 :     state->calcSumX2 = calcSumX2;
    4788       114080 :     state->agg_context = agg_context;
    4789              : 
    4790       114080 :     MemoryContextSwitchTo(old_context);
    4791              : 
    4792       114080 :     return state;
    4793              : }
    4794              : 
    4795              : /*
    4796              :  * Like makeNumericAggState(), but allocate the state in the current memory
    4797              :  * context.
    4798              :  */
    4799              : static NumericAggState *
    4800           54 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4801              : {
    4802              :     NumericAggState *state;
    4803              : 
    4804           54 :     state = palloc0_object(NumericAggState);
    4805           54 :     state->calcSumX2 = calcSumX2;
    4806           54 :     state->agg_context = CurrentMemoryContext;
    4807              : 
    4808           54 :     return state;
    4809              : }
    4810              : 
    4811              : /*
    4812              :  * Accumulate a new input value for numeric aggregate functions.
    4813              :  */
    4814              : static void
    4815      1409012 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4816              : {
    4817              :     NumericVar  X;
    4818              :     NumericVar  X2;
    4819              :     MemoryContext old_context;
    4820              : 
    4821              :     /* Count NaN/infinity inputs separately from all else */
    4822      1409012 :     if (NUMERIC_IS_SPECIAL(newval))
    4823              :     {
    4824          108 :         if (NUMERIC_IS_PINF(newval))
    4825           48 :             state->pInfcount++;
    4826           60 :         else if (NUMERIC_IS_NINF(newval))
    4827           24 :             state->nInfcount++;
    4828              :         else
    4829           36 :             state->NaNcount++;
    4830          108 :         return;
    4831              :     }
    4832              : 
    4833              :     /* load processed number in short-lived context */
    4834      1408904 :     init_var_from_num(newval, &X);
    4835              : 
    4836              :     /*
    4837              :      * Track the highest input dscale that we've seen, to support inverse
    4838              :      * transitions (see do_numeric_discard).
    4839              :      */
    4840      1408904 :     if (X.dscale > state->maxScale)
    4841              :     {
    4842          104 :         state->maxScale = X.dscale;
    4843          104 :         state->maxScaleCount = 1;
    4844              :     }
    4845      1408800 :     else if (X.dscale == state->maxScale)
    4846      1408776 :         state->maxScaleCount++;
    4847              : 
    4848              :     /* if we need X^2, calculate that in short-lived context */
    4849      1408904 :     if (state->calcSumX2)
    4850              :     {
    4851       160488 :         init_var(&X2);
    4852       160488 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4853              :     }
    4854              : 
    4855              :     /* The rest of this needs to work in the aggregate context */
    4856      1408904 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4857              : 
    4858      1408904 :     state->N++;
    4859              : 
    4860              :     /* Accumulate sums */
    4861      1408904 :     accum_sum_add(&(state->sumX), &X);
    4862              : 
    4863      1408904 :     if (state->calcSumX2)
    4864       160488 :         accum_sum_add(&(state->sumX2), &X2);
    4865              : 
    4866      1408904 :     MemoryContextSwitchTo(old_context);
    4867              : }
    4868              : 
    4869              : /*
    4870              :  * Attempt to remove an input value from the aggregated state.
    4871              :  *
    4872              :  * If the value cannot be removed then the function will return false; the
    4873              :  * possible reasons for failing are described below.
    4874              :  *
    4875              :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    4876              :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    4877              :  * won't be able to tell what the new aggregated value's dscale should be.
    4878              :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    4879              :  * have been zero if we'd really aggregated only 2.
    4880              :  *
    4881              :  * Note: alternatively, we could count the number of inputs with each possible
    4882              :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    4883              :  */
    4884              : static bool
    4885          228 : do_numeric_discard(NumericAggState *state, Numeric newval)
    4886              : {
    4887              :     NumericVar  X;
    4888              :     NumericVar  X2;
    4889              :     MemoryContext old_context;
    4890              : 
    4891              :     /* Count NaN/infinity inputs separately from all else */
    4892          228 :     if (NUMERIC_IS_SPECIAL(newval))
    4893              :     {
    4894            4 :         if (NUMERIC_IS_PINF(newval))
    4895            0 :             state->pInfcount--;
    4896            4 :         else if (NUMERIC_IS_NINF(newval))
    4897            0 :             state->nInfcount--;
    4898              :         else
    4899            4 :             state->NaNcount--;
    4900            4 :         return true;
    4901              :     }
    4902              : 
    4903              :     /* load processed number in short-lived context */
    4904          224 :     init_var_from_num(newval, &X);
    4905              : 
    4906              :     /*
    4907              :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    4908              :      * Removing the last input with that dscale would require us to recompute
    4909              :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    4910              :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    4911              :      * and force the aggregation to be redone from scratch.
    4912              :      */
    4913          224 :     if (X.dscale == state->maxScale)
    4914              :     {
    4915          224 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    4916              :         {
    4917              :             /*
    4918              :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    4919              :              * above zero anyway
    4920              :              */
    4921          212 :             state->maxScaleCount--;
    4922              :         }
    4923           12 :         else if (state->N == 1)
    4924              :         {
    4925              :             /* No remaining non-NaN inputs at all, so reset maxScale */
    4926            8 :             state->maxScale = 0;
    4927            8 :             state->maxScaleCount = 0;
    4928              :         }
    4929              :         else
    4930              :         {
    4931              :             /* Correct new maxScale is uncertain, must fail */
    4932            4 :             return false;
    4933              :         }
    4934              :     }
    4935              : 
    4936              :     /* if we need X^2, calculate that in short-lived context */
    4937          220 :     if (state->calcSumX2)
    4938              :     {
    4939          192 :         init_var(&X2);
    4940          192 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4941              :     }
    4942              : 
    4943              :     /* The rest of this needs to work in the aggregate context */
    4944          220 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4945              : 
    4946          220 :     if (state->N-- > 1)
    4947              :     {
    4948              :         /* Negate X, to subtract it from the sum */
    4949          208 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    4950          208 :         accum_sum_add(&(state->sumX), &X);
    4951              : 
    4952          208 :         if (state->calcSumX2)
    4953              :         {
    4954              :             /* Negate X^2. X^2 is always positive */
    4955          192 :             X2.sign = NUMERIC_NEG;
    4956          192 :             accum_sum_add(&(state->sumX2), &X2);
    4957              :         }
    4958              :     }
    4959              :     else
    4960              :     {
    4961              :         /* Zero the sums */
    4962              :         Assert(state->N == 0);
    4963              : 
    4964           12 :         accum_sum_reset(&state->sumX);
    4965           12 :         if (state->calcSumX2)
    4966            0 :             accum_sum_reset(&state->sumX2);
    4967              :     }
    4968              : 
    4969          220 :     MemoryContextSwitchTo(old_context);
    4970              : 
    4971          220 :     return true;
    4972              : }
    4973              : 
    4974              : /*
    4975              :  * Generic transition function for numeric aggregates that require sumX2.
    4976              :  */
    4977              : Datum
    4978          428 : numeric_accum(PG_FUNCTION_ARGS)
    4979              : {
    4980              :     NumericAggState *state;
    4981              : 
    4982          428 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    4983              : 
    4984              :     /* Create the state data on the first call */
    4985          428 :     if (state == NULL)
    4986          116 :         state = makeNumericAggState(fcinfo, true);
    4987              : 
    4988          428 :     if (!PG_ARGISNULL(1))
    4989          416 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    4990              : 
    4991          428 :     PG_RETURN_POINTER(state);
    4992              : }
    4993              : 
    4994              : /*
    4995              :  * Generic combine function for numeric aggregates which require sumX2
    4996              :  */
    4997              : Datum
    4998           23 : numeric_combine(PG_FUNCTION_ARGS)
    4999              : {
    5000              :     NumericAggState *state1;
    5001              :     NumericAggState *state2;
    5002              :     MemoryContext agg_context;
    5003              :     MemoryContext old_context;
    5004              : 
    5005           23 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5006            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5007              : 
    5008           23 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5009           23 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5010              : 
    5011           23 :     if (state2 == NULL)
    5012            0 :         PG_RETURN_POINTER(state1);
    5013              : 
    5014              :     /* manually copy all fields from state2 to state1 */
    5015           23 :     if (state1 == NULL)
    5016              :     {
    5017           12 :         old_context = MemoryContextSwitchTo(agg_context);
    5018              : 
    5019           12 :         state1 = makeNumericAggStateCurrentContext(true);
    5020           12 :         state1->N = state2->N;
    5021           12 :         state1->NaNcount = state2->NaNcount;
    5022           12 :         state1->pInfcount = state2->pInfcount;
    5023           12 :         state1->nInfcount = state2->nInfcount;
    5024           12 :         state1->maxScale = state2->maxScale;
    5025           12 :         state1->maxScaleCount = state2->maxScaleCount;
    5026              : 
    5027           12 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5028           12 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5029              : 
    5030           12 :         MemoryContextSwitchTo(old_context);
    5031              : 
    5032           12 :         PG_RETURN_POINTER(state1);
    5033              :     }
    5034              : 
    5035           11 :     state1->N += state2->N;
    5036           11 :     state1->NaNcount += state2->NaNcount;
    5037           11 :     state1->pInfcount += state2->pInfcount;
    5038           11 :     state1->nInfcount += state2->nInfcount;
    5039              : 
    5040           11 :     if (state2->N > 0)
    5041              :     {
    5042              :         /*
    5043              :          * These are currently only needed for moving aggregates, but let's do
    5044              :          * the right thing anyway...
    5045              :          */
    5046           11 :         if (state2->maxScale > state1->maxScale)
    5047              :         {
    5048            0 :             state1->maxScale = state2->maxScale;
    5049            0 :             state1->maxScaleCount = state2->maxScaleCount;
    5050              :         }
    5051           11 :         else if (state2->maxScale == state1->maxScale)
    5052           11 :             state1->maxScaleCount += state2->maxScaleCount;
    5053              : 
    5054              :         /* The rest of this needs to work in the aggregate context */
    5055           11 :         old_context = MemoryContextSwitchTo(agg_context);
    5056              : 
    5057              :         /* Accumulate sums */
    5058           11 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5059           11 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5060              : 
    5061           11 :         MemoryContextSwitchTo(old_context);
    5062              :     }
    5063           11 :     PG_RETURN_POINTER(state1);
    5064              : }
    5065              : 
    5066              : /*
    5067              :  * Generic transition function for numeric aggregates that don't require sumX2.
    5068              :  */
    5069              : Datum
    5070      1248516 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5071              : {
    5072              :     NumericAggState *state;
    5073              : 
    5074      1248516 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5075              : 
    5076              :     /* Create the state data on the first call */
    5077      1248516 :     if (state == NULL)
    5078       113925 :         state = makeNumericAggState(fcinfo, false);
    5079              : 
    5080      1248516 :     if (!PG_ARGISNULL(1))
    5081      1248476 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5082              : 
    5083      1248516 :     PG_RETURN_POINTER(state);
    5084              : }
    5085              : 
    5086              : /*
    5087              :  * Combine function for numeric aggregates which don't require sumX2
    5088              :  */
    5089              : Datum
    5090           15 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5091              : {
    5092              :     NumericAggState *state1;
    5093              :     NumericAggState *state2;
    5094              :     MemoryContext agg_context;
    5095              :     MemoryContext old_context;
    5096              : 
    5097           15 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5098            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5099              : 
    5100           15 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5101           15 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5102              : 
    5103           15 :     if (state2 == NULL)
    5104            0 :         PG_RETURN_POINTER(state1);
    5105              : 
    5106              :     /* manually copy all fields from state2 to state1 */
    5107           15 :     if (state1 == NULL)
    5108              :     {
    5109            4 :         old_context = MemoryContextSwitchTo(agg_context);
    5110              : 
    5111            4 :         state1 = makeNumericAggStateCurrentContext(false);
    5112            4 :         state1->N = state2->N;
    5113            4 :         state1->NaNcount = state2->NaNcount;
    5114            4 :         state1->pInfcount = state2->pInfcount;
    5115            4 :         state1->nInfcount = state2->nInfcount;
    5116            4 :         state1->maxScale = state2->maxScale;
    5117            4 :         state1->maxScaleCount = state2->maxScaleCount;
    5118              : 
    5119            4 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5120              : 
    5121            4 :         MemoryContextSwitchTo(old_context);
    5122              : 
    5123            4 :         PG_RETURN_POINTER(state1);
    5124              :     }
    5125              : 
    5126           11 :     state1->N += state2->N;
    5127           11 :     state1->NaNcount += state2->NaNcount;
    5128           11 :     state1->pInfcount += state2->pInfcount;
    5129           11 :     state1->nInfcount += state2->nInfcount;
    5130              : 
    5131           11 :     if (state2->N > 0)
    5132              :     {
    5133              :         /*
    5134              :          * These are currently only needed for moving aggregates, but let's do
    5135              :          * the right thing anyway...
    5136              :          */
    5137           11 :         if (state2->maxScale > state1->maxScale)
    5138              :         {
    5139            0 :             state1->maxScale = state2->maxScale;
    5140            0 :             state1->maxScaleCount = state2->maxScaleCount;
    5141              :         }
    5142           11 :         else if (state2->maxScale == state1->maxScale)
    5143           11 :             state1->maxScaleCount += state2->maxScaleCount;
    5144              : 
    5145              :         /* The rest of this needs to work in the aggregate context */
    5146           11 :         old_context = MemoryContextSwitchTo(agg_context);
    5147              : 
    5148              :         /* Accumulate sums */
    5149           11 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5150              : 
    5151           11 :         MemoryContextSwitchTo(old_context);
    5152              :     }
    5153           11 :     PG_RETURN_POINTER(state1);
    5154              : }
    5155              : 
    5156              : /*
    5157              :  * numeric_avg_serialize
    5158              :  *      Serialize NumericAggState for numeric aggregates that don't require
    5159              :  *      sumX2.
    5160              :  */
    5161              : Datum
    5162           15 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5163              : {
    5164              :     NumericAggState *state;
    5165              :     StringInfoData buf;
    5166              :     bytea      *result;
    5167              :     NumericVar  tmp_var;
    5168              : 
    5169              :     /* Ensure we disallow calling when not in aggregate context */
    5170           15 :     if (!AggCheckCallContext(fcinfo, NULL))
    5171            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5172              : 
    5173           15 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5174              : 
    5175           15 :     init_var(&tmp_var);
    5176              : 
    5177           15 :     pq_begintypsend(&buf);
    5178              : 
    5179              :     /* N */
    5180           15 :     pq_sendint64(&buf, state->N);
    5181              : 
    5182              :     /* sumX */
    5183           15 :     accum_sum_final(&state->sumX, &tmp_var);
    5184           15 :     numericvar_serialize(&buf, &tmp_var);
    5185              : 
    5186              :     /* maxScale */
    5187           15 :     pq_sendint32(&buf, state->maxScale);
    5188              : 
    5189              :     /* maxScaleCount */
    5190           15 :     pq_sendint64(&buf, state->maxScaleCount);
    5191              : 
    5192              :     /* NaNcount */
    5193           15 :     pq_sendint64(&buf, state->NaNcount);
    5194              : 
    5195              :     /* pInfcount */
    5196           15 :     pq_sendint64(&buf, state->pInfcount);
    5197              : 
    5198              :     /* nInfcount */
    5199           15 :     pq_sendint64(&buf, state->nInfcount);
    5200              : 
    5201           15 :     result = pq_endtypsend(&buf);
    5202              : 
    5203           15 :     free_var(&tmp_var);
    5204              : 
    5205           15 :     PG_RETURN_BYTEA_P(result);
    5206              : }
    5207              : 
    5208              : /*
    5209              :  * numeric_avg_deserialize
    5210              :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5211              :  *      don't require sumX2.
    5212              :  */
    5213              : Datum
    5214           15 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5215              : {
    5216              :     bytea      *sstate;
    5217              :     NumericAggState *result;
    5218              :     StringInfoData buf;
    5219              :     NumericVar  tmp_var;
    5220              : 
    5221           15 :     if (!AggCheckCallContext(fcinfo, NULL))
    5222            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5223              : 
    5224           15 :     sstate = PG_GETARG_BYTEA_PP(0);
    5225              : 
    5226           15 :     init_var(&tmp_var);
    5227              : 
    5228              :     /*
    5229              :      * Initialize a StringInfo so that we can "receive" it using the standard
    5230              :      * recv-function infrastructure.
    5231              :      */
    5232           15 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5233           15 :                            VARSIZE_ANY_EXHDR(sstate));
    5234              : 
    5235           15 :     result = makeNumericAggStateCurrentContext(false);
    5236              : 
    5237              :     /* N */
    5238           15 :     result->N = pq_getmsgint64(&buf);
    5239              : 
    5240              :     /* sumX */
    5241           15 :     numericvar_deserialize(&buf, &tmp_var);
    5242           15 :     accum_sum_add(&(result->sumX), &tmp_var);
    5243              : 
    5244              :     /* maxScale */
    5245           15 :     result->maxScale = pq_getmsgint(&buf, 4);
    5246              : 
    5247              :     /* maxScaleCount */
    5248           15 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5249              : 
    5250              :     /* NaNcount */
    5251           15 :     result->NaNcount = pq_getmsgint64(&buf);
    5252              : 
    5253              :     /* pInfcount */
    5254           15 :     result->pInfcount = pq_getmsgint64(&buf);
    5255              : 
    5256              :     /* nInfcount */
    5257           15 :     result->nInfcount = pq_getmsgint64(&buf);
    5258              : 
    5259           15 :     pq_getmsgend(&buf);
    5260              : 
    5261           15 :     free_var(&tmp_var);
    5262              : 
    5263           15 :     PG_RETURN_POINTER(result);
    5264              : }
    5265              : 
    5266              : /*
    5267              :  * numeric_serialize
    5268              :  *      Serialization function for NumericAggState for numeric aggregates that
    5269              :  *      require sumX2.
    5270              :  */
    5271              : Datum
    5272           23 : numeric_serialize(PG_FUNCTION_ARGS)
    5273              : {
    5274              :     NumericAggState *state;
    5275              :     StringInfoData buf;
    5276              :     bytea      *result;
    5277              :     NumericVar  tmp_var;
    5278              : 
    5279              :     /* Ensure we disallow calling when not in aggregate context */
    5280           23 :     if (!AggCheckCallContext(fcinfo, NULL))
    5281            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5282              : 
    5283           23 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5284              : 
    5285           23 :     init_var(&tmp_var);
    5286              : 
    5287           23 :     pq_begintypsend(&buf);
    5288              : 
    5289              :     /* N */
    5290           23 :     pq_sendint64(&buf, state->N);
    5291              : 
    5292              :     /* sumX */
    5293           23 :     accum_sum_final(&state->sumX, &tmp_var);
    5294           23 :     numericvar_serialize(&buf, &tmp_var);
    5295              : 
    5296              :     /* sumX2 */
    5297           23 :     accum_sum_final(&state->sumX2, &tmp_var);
    5298           23 :     numericvar_serialize(&buf, &tmp_var);
    5299              : 
    5300              :     /* maxScale */
    5301           23 :     pq_sendint32(&buf, state->maxScale);
    5302              : 
    5303              :     /* maxScaleCount */
    5304           23 :     pq_sendint64(&buf, state->maxScaleCount);
    5305              : 
    5306              :     /* NaNcount */
    5307           23 :     pq_sendint64(&buf, state->NaNcount);
    5308              : 
    5309              :     /* pInfcount */
    5310           23 :     pq_sendint64(&buf, state->pInfcount);
    5311              : 
    5312              :     /* nInfcount */
    5313           23 :     pq_sendint64(&buf, state->nInfcount);
    5314              : 
    5315           23 :     result = pq_endtypsend(&buf);
    5316              : 
    5317           23 :     free_var(&tmp_var);
    5318              : 
    5319           23 :     PG_RETURN_BYTEA_P(result);
    5320              : }
    5321              : 
    5322              : /*
    5323              :  * numeric_deserialize
    5324              :  *      Deserialization function for NumericAggState for numeric aggregates that
    5325              :  *      require sumX2.
    5326              :  */
    5327              : Datum
    5328           23 : numeric_deserialize(PG_FUNCTION_ARGS)
    5329              : {
    5330              :     bytea      *sstate;
    5331              :     NumericAggState *result;
    5332              :     StringInfoData buf;
    5333              :     NumericVar  tmp_var;
    5334              : 
    5335           23 :     if (!AggCheckCallContext(fcinfo, NULL))
    5336            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5337              : 
    5338           23 :     sstate = PG_GETARG_BYTEA_PP(0);
    5339              : 
    5340           23 :     init_var(&tmp_var);
    5341              : 
    5342              :     /*
    5343              :      * Initialize a StringInfo so that we can "receive" it using the standard
    5344              :      * recv-function infrastructure.
    5345              :      */
    5346           23 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5347           23 :                            VARSIZE_ANY_EXHDR(sstate));
    5348              : 
    5349           23 :     result = makeNumericAggStateCurrentContext(false);
    5350              : 
    5351              :     /* N */
    5352           23 :     result->N = pq_getmsgint64(&buf);
    5353              : 
    5354              :     /* sumX */
    5355           23 :     numericvar_deserialize(&buf, &tmp_var);
    5356           23 :     accum_sum_add(&(result->sumX), &tmp_var);
    5357              : 
    5358              :     /* sumX2 */
    5359           23 :     numericvar_deserialize(&buf, &tmp_var);
    5360           23 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5361              : 
    5362              :     /* maxScale */
    5363           23 :     result->maxScale = pq_getmsgint(&buf, 4);
    5364              : 
    5365              :     /* maxScaleCount */
    5366           23 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5367              : 
    5368              :     /* NaNcount */
    5369           23 :     result->NaNcount = pq_getmsgint64(&buf);
    5370              : 
    5371              :     /* pInfcount */
    5372           23 :     result->pInfcount = pq_getmsgint64(&buf);
    5373              : 
    5374              :     /* nInfcount */
    5375           23 :     result->nInfcount = pq_getmsgint64(&buf);
    5376              : 
    5377           23 :     pq_getmsgend(&buf);
    5378              : 
    5379           23 :     free_var(&tmp_var);
    5380              : 
    5381           23 :     PG_RETURN_POINTER(result);
    5382              : }
    5383              : 
    5384              : /*
    5385              :  * Generic inverse transition function for numeric aggregates
    5386              :  * (with or without requirement for X^2).
    5387              :  */
    5388              : Datum
    5389          152 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5390              : {
    5391              :     NumericAggState *state;
    5392              : 
    5393          152 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5394              : 
    5395              :     /* Should not get here with no state */
    5396          152 :     if (state == NULL)
    5397            0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5398              : 
    5399          152 :     if (!PG_ARGISNULL(1))
    5400              :     {
    5401              :         /* If we fail to perform the inverse transition, return NULL */
    5402          132 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5403            4 :             PG_RETURN_NULL();
    5404              :     }
    5405              : 
    5406          148 :     PG_RETURN_POINTER(state);
    5407              : }
    5408              : 
    5409              : 
    5410              : /*
    5411              :  * Integer data types in general use Numeric accumulators to share code and
    5412              :  * avoid risk of overflow.  However for performance reasons optimized
    5413              :  * special-purpose accumulator routines are used when possible:
    5414              :  *
    5415              :  * For 16-bit and 32-bit inputs, N and sum(X) fit into 64-bit, so 64-bit
    5416              :  * accumulators are used for SUM and AVG of these data types.
    5417              :  *
    5418              :  * For 16-bit and 32-bit inputs, sum(X^2) fits into 128-bit, so 128-bit
    5419              :  * accumulators are used for STDDEV_POP, STDDEV_SAMP, VAR_POP, and VAR_SAMP of
    5420              :  * these data types.
    5421              :  *
    5422              :  * For 64-bit inputs, sum(X) fits into 128-bit, so a 128-bit accumulator is
    5423              :  * used for SUM(int8) and AVG(int8).
    5424              :  */
    5425              : 
    5426              : typedef struct Int128AggState
    5427              : {
    5428              :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5429              :     int64       N;              /* count of processed numbers */
    5430              :     INT128      sumX;           /* sum of processed numbers */
    5431              :     INT128      sumX2;          /* sum of squares of processed numbers */
    5432              : } Int128AggState;
    5433              : 
    5434              : /*
    5435              :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5436              :  * sum, count and optionally sum of squares of the input.
    5437              :  */
    5438              : static Int128AggState *
    5439          634 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5440              : {
    5441              :     Int128AggState *state;
    5442              :     MemoryContext agg_context;
    5443              :     MemoryContext old_context;
    5444              : 
    5445          634 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5446            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5447              : 
    5448          634 :     old_context = MemoryContextSwitchTo(agg_context);
    5449              : 
    5450          634 :     state = palloc0_object(Int128AggState);
    5451          634 :     state->calcSumX2 = calcSumX2;
    5452              : 
    5453          634 :     MemoryContextSwitchTo(old_context);
    5454              : 
    5455          634 :     return state;
    5456              : }
    5457              : 
    5458              : /*
    5459              :  * Like makeInt128AggState(), but allocate the state in the current memory
    5460              :  * context.
    5461              :  */
    5462              : static Int128AggState *
    5463           36 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5464              : {
    5465              :     Int128AggState *state;
    5466              : 
    5467           36 :     state = palloc0_object(Int128AggState);
    5468           36 :     state->calcSumX2 = calcSumX2;
    5469              : 
    5470           36 :     return state;
    5471              : }
    5472              : 
    5473              : /*
    5474              :  * Accumulate a new input value for 128-bit aggregate functions.
    5475              :  */
    5476              : static void
    5477       371598 : do_int128_accum(Int128AggState *state, int64 newval)
    5478              : {
    5479       371598 :     if (state->calcSumX2)
    5480       161240 :         int128_add_int64_mul_int64(&state->sumX2, newval, newval);
    5481              : 
    5482       371598 :     int128_add_int64(&state->sumX, newval);
    5483       371598 :     state->N++;
    5484       371598 : }
    5485              : 
    5486              : /*
    5487              :  * Remove an input value from the aggregated state.
    5488              :  */
    5489              : static void
    5490          208 : do_int128_discard(Int128AggState *state, int64 newval)
    5491              : {
    5492          208 :     if (state->calcSumX2)
    5493          192 :         int128_sub_int64_mul_int64(&state->sumX2, newval, newval);
    5494              : 
    5495          208 :     int128_sub_int64(&state->sumX, newval);
    5496          208 :     state->N--;
    5497          208 : }
    5498              : 
    5499              : Datum
    5500          132 : int2_accum(PG_FUNCTION_ARGS)
    5501              : {
    5502              :     Int128AggState *state;
    5503              : 
    5504          132 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5505              : 
    5506              :     /* Create the state data on the first call */
    5507          132 :     if (state == NULL)
    5508           24 :         state = makeInt128AggState(fcinfo, true);
    5509              : 
    5510          132 :     if (!PG_ARGISNULL(1))
    5511          120 :         do_int128_accum(state, PG_GETARG_INT16(1));
    5512              : 
    5513          132 :     PG_RETURN_POINTER(state);
    5514              : }
    5515              : 
    5516              : Datum
    5517       161132 : int4_accum(PG_FUNCTION_ARGS)
    5518              : {
    5519              :     Int128AggState *state;
    5520              : 
    5521       161132 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5522              : 
    5523              :     /* Create the state data on the first call */
    5524       161132 :     if (state == NULL)
    5525           50 :         state = makeInt128AggState(fcinfo, true);
    5526              : 
    5527       161132 :     if (!PG_ARGISNULL(1))
    5528       161120 :         do_int128_accum(state, PG_GETARG_INT32(1));
    5529              : 
    5530       161132 :     PG_RETURN_POINTER(state);
    5531              : }
    5532              : 
    5533              : Datum
    5534       160132 : int8_accum(PG_FUNCTION_ARGS)
    5535              : {
    5536              :     NumericAggState *state;
    5537              : 
    5538       160132 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5539              : 
    5540              :     /* Create the state data on the first call */
    5541       160132 :     if (state == NULL)
    5542           39 :         state = makeNumericAggState(fcinfo, true);
    5543              : 
    5544       160132 :     if (!PG_ARGISNULL(1))
    5545       160120 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5546              : 
    5547       160132 :     PG_RETURN_POINTER(state);
    5548              : }
    5549              : 
    5550              : /*
    5551              :  * Combine function for Int128AggState for aggregates which require sumX2
    5552              :  */
    5553              : Datum
    5554           16 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5555              : {
    5556              :     Int128AggState *state1;
    5557              :     Int128AggState *state2;
    5558              :     MemoryContext agg_context;
    5559              :     MemoryContext old_context;
    5560              : 
    5561           16 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5562            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5563              : 
    5564           16 :     state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5565           16 :     state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
    5566              : 
    5567           16 :     if (state2 == NULL)
    5568            0 :         PG_RETURN_POINTER(state1);
    5569              : 
    5570              :     /* manually copy all fields from state2 to state1 */
    5571           16 :     if (state1 == NULL)
    5572              :     {
    5573            4 :         old_context = MemoryContextSwitchTo(agg_context);
    5574              : 
    5575            4 :         state1 = makeInt128AggState(fcinfo, true);
    5576            4 :         state1->N = state2->N;
    5577            4 :         state1->sumX = state2->sumX;
    5578            4 :         state1->sumX2 = state2->sumX2;
    5579              : 
    5580            4 :         MemoryContextSwitchTo(old_context);
    5581              : 
    5582            4 :         PG_RETURN_POINTER(state1);
    5583              :     }
    5584              : 
    5585           12 :     if (state2->N > 0)
    5586              :     {
    5587           12 :         state1->N += state2->N;
    5588           12 :         int128_add_int128(&state1->sumX, state2->sumX);
    5589           12 :         int128_add_int128(&state1->sumX2, state2->sumX2);
    5590              :     }
    5591           12 :     PG_RETURN_POINTER(state1);
    5592              : }
    5593              : 
    5594              : /*
    5595              :  * int128_serialize - serialize a 128-bit integer to binary format
    5596              :  */
    5597              : static inline void
    5598           52 : int128_serialize(StringInfo buf, INT128 val)
    5599              : {
    5600           52 :     pq_sendint64(buf, PG_INT128_HI_INT64(val));
    5601           52 :     pq_sendint64(buf, PG_INT128_LO_UINT64(val));
    5602           52 : }
    5603              : 
    5604              : /*
    5605              :  * int128_deserialize - deserialize binary format to a 128-bit integer.
    5606              :  */
    5607              : static inline INT128
    5608           52 : int128_deserialize(StringInfo buf)
    5609              : {
    5610           52 :     int64       hi = pq_getmsgint64(buf);
    5611           52 :     uint64      lo = pq_getmsgint64(buf);
    5612              : 
    5613           52 :     return make_int128(hi, lo);
    5614              : }
    5615              : 
    5616              : /*
    5617              :  * numeric_poly_serialize
    5618              :  *      Serialize Int128AggState into bytea for aggregate functions which
    5619              :  *      require sumX2.
    5620              :  */
    5621              : Datum
    5622           16 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5623              : {
    5624              :     Int128AggState *state;
    5625              :     StringInfoData buf;
    5626              :     bytea      *result;
    5627              : 
    5628              :     /* Ensure we disallow calling when not in aggregate context */
    5629           16 :     if (!AggCheckCallContext(fcinfo, NULL))
    5630            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5631              : 
    5632           16 :     state = (Int128AggState *) PG_GETARG_POINTER(0);
    5633              : 
    5634           16 :     pq_begintypsend(&buf);
    5635              : 
    5636              :     /* N */
    5637           16 :     pq_sendint64(&buf, state->N);
    5638              : 
    5639              :     /* sumX */
    5640           16 :     int128_serialize(&buf, state->sumX);
    5641              : 
    5642              :     /* sumX2 */
    5643           16 :     int128_serialize(&buf, state->sumX2);
    5644              : 
    5645           16 :     result = pq_endtypsend(&buf);
    5646              : 
    5647           16 :     PG_RETURN_BYTEA_P(result);
    5648              : }
    5649              : 
    5650              : /*
    5651              :  * numeric_poly_deserialize
    5652              :  *      Deserialize Int128AggState from bytea for aggregate functions which
    5653              :  *      require sumX2.
    5654              :  */
    5655              : Datum
    5656           16 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5657              : {
    5658              :     bytea      *sstate;
    5659              :     Int128AggState *result;
    5660              :     StringInfoData buf;
    5661              : 
    5662           16 :     if (!AggCheckCallContext(fcinfo, NULL))
    5663            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5664              : 
    5665           16 :     sstate = PG_GETARG_BYTEA_PP(0);
    5666              : 
    5667              :     /*
    5668              :      * Initialize a StringInfo so that we can "receive" it using the standard
    5669              :      * recv-function infrastructure.
    5670              :      */
    5671           16 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5672           16 :                            VARSIZE_ANY_EXHDR(sstate));
    5673              : 
    5674           16 :     result = makeInt128AggStateCurrentContext(false);
    5675              : 
    5676              :     /* N */
    5677           16 :     result->N = pq_getmsgint64(&buf);
    5678              : 
    5679              :     /* sumX */
    5680           16 :     result->sumX = int128_deserialize(&buf);
    5681              : 
    5682              :     /* sumX2 */
    5683           16 :     result->sumX2 = int128_deserialize(&buf);
    5684              : 
    5685           16 :     pq_getmsgend(&buf);
    5686              : 
    5687           16 :     PG_RETURN_POINTER(result);
    5688              : }
    5689              : 
    5690              : /*
    5691              :  * Transition function for int8 input when we don't need sumX2.
    5692              :  */
    5693              : Datum
    5694       213257 : int8_avg_accum(PG_FUNCTION_ARGS)
    5695              : {
    5696              :     Int128AggState *state;
    5697              : 
    5698       213257 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5699              : 
    5700              :     /* Create the state data on the first call */
    5701       213257 :     if (state == NULL)
    5702          548 :         state = makeInt128AggState(fcinfo, false);
    5703              : 
    5704       213257 :     if (!PG_ARGISNULL(1))
    5705       210358 :         do_int128_accum(state, PG_GETARG_INT64(1));
    5706              : 
    5707       213257 :     PG_RETURN_POINTER(state);
    5708              : }
    5709              : 
    5710              : /*
    5711              :  * Combine function for Int128AggState for aggregates which don't require
    5712              :  * sumX2
    5713              :  */
    5714              : Datum
    5715           20 : int8_avg_combine(PG_FUNCTION_ARGS)
    5716              : {
    5717              :     Int128AggState *state1;
    5718              :     Int128AggState *state2;
    5719              :     MemoryContext agg_context;
    5720              :     MemoryContext old_context;
    5721              : 
    5722           20 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5723            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5724              : 
    5725           20 :     state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5726           20 :     state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
    5727              : 
    5728           20 :     if (state2 == NULL)
    5729            0 :         PG_RETURN_POINTER(state1);
    5730              : 
    5731              :     /* manually copy all fields from state2 to state1 */
    5732           20 :     if (state1 == NULL)
    5733              :     {
    5734            8 :         old_context = MemoryContextSwitchTo(agg_context);
    5735              : 
    5736            8 :         state1 = makeInt128AggState(fcinfo, false);
    5737            8 :         state1->N = state2->N;
    5738            8 :         state1->sumX = state2->sumX;
    5739              : 
    5740            8 :         MemoryContextSwitchTo(old_context);
    5741              : 
    5742            8 :         PG_RETURN_POINTER(state1);
    5743              :     }
    5744              : 
    5745           12 :     if (state2->N > 0)
    5746              :     {
    5747           12 :         state1->N += state2->N;
    5748           12 :         int128_add_int128(&state1->sumX, state2->sumX);
    5749              :     }
    5750           12 :     PG_RETURN_POINTER(state1);
    5751              : }
    5752              : 
    5753              : /*
    5754              :  * int8_avg_serialize
    5755              :  *      Serialize Int128AggState into bytea for aggregate functions which
    5756              :  *      don't require sumX2.
    5757              :  */
    5758              : Datum
    5759           20 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5760              : {
    5761              :     Int128AggState *state;
    5762              :     StringInfoData buf;
    5763              :     bytea      *result;
    5764              : 
    5765              :     /* Ensure we disallow calling when not in aggregate context */
    5766           20 :     if (!AggCheckCallContext(fcinfo, NULL))
    5767            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5768              : 
    5769           20 :     state = (Int128AggState *) PG_GETARG_POINTER(0);
    5770              : 
    5771           20 :     pq_begintypsend(&buf);
    5772              : 
    5773              :     /* N */
    5774           20 :     pq_sendint64(&buf, state->N);
    5775              : 
    5776              :     /* sumX */
    5777           20 :     int128_serialize(&buf, state->sumX);
    5778              : 
    5779           20 :     result = pq_endtypsend(&buf);
    5780              : 
    5781           20 :     PG_RETURN_BYTEA_P(result);
    5782              : }
    5783              : 
    5784              : /*
    5785              :  * int8_avg_deserialize
    5786              :  *      Deserialize Int128AggState from bytea for aggregate functions which
    5787              :  *      don't require sumX2.
    5788              :  */
    5789              : Datum
    5790           20 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    5791              : {
    5792              :     bytea      *sstate;
    5793              :     Int128AggState *result;
    5794              :     StringInfoData buf;
    5795              : 
    5796           20 :     if (!AggCheckCallContext(fcinfo, NULL))
    5797            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5798              : 
    5799           20 :     sstate = PG_GETARG_BYTEA_PP(0);
    5800              : 
    5801              :     /*
    5802              :      * Initialize a StringInfo so that we can "receive" it using the standard
    5803              :      * recv-function infrastructure.
    5804              :      */
    5805           20 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5806           20 :                            VARSIZE_ANY_EXHDR(sstate));
    5807              : 
    5808           20 :     result = makeInt128AggStateCurrentContext(false);
    5809              : 
    5810              :     /* N */
    5811           20 :     result->N = pq_getmsgint64(&buf);
    5812              : 
    5813              :     /* sumX */
    5814           20 :     result->sumX = int128_deserialize(&buf);
    5815              : 
    5816           20 :     pq_getmsgend(&buf);
    5817              : 
    5818           20 :     PG_RETURN_POINTER(result);
    5819              : }
    5820              : 
    5821              : /*
    5822              :  * Inverse transition functions to go with the above.
    5823              :  */
    5824              : 
    5825              : Datum
    5826          108 : int2_accum_inv(PG_FUNCTION_ARGS)
    5827              : {
    5828              :     Int128AggState *state;
    5829              : 
    5830          108 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5831              : 
    5832              :     /* Should not get here with no state */
    5833          108 :     if (state == NULL)
    5834            0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    5835              : 
    5836          108 :     if (!PG_ARGISNULL(1))
    5837           96 :         do_int128_discard(state, PG_GETARG_INT16(1));
    5838              : 
    5839          108 :     PG_RETURN_POINTER(state);
    5840              : }
    5841              : 
    5842              : Datum
    5843          108 : int4_accum_inv(PG_FUNCTION_ARGS)
    5844              : {
    5845              :     Int128AggState *state;
    5846              : 
    5847          108 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5848              : 
    5849              :     /* Should not get here with no state */
    5850          108 :     if (state == NULL)
    5851            0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    5852              : 
    5853          108 :     if (!PG_ARGISNULL(1))
    5854           96 :         do_int128_discard(state, PG_GETARG_INT32(1));
    5855              : 
    5856          108 :     PG_RETURN_POINTER(state);
    5857              : }
    5858              : 
    5859              : Datum
    5860          108 : int8_accum_inv(PG_FUNCTION_ARGS)
    5861              : {
    5862              :     NumericAggState *state;
    5863              : 
    5864          108 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5865              : 
    5866              :     /* Should not get here with no state */
    5867          108 :     if (state == NULL)
    5868            0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    5869              : 
    5870          108 :     if (!PG_ARGISNULL(1))
    5871              :     {
    5872              :         /* Should never fail, all inputs have dscale 0 */
    5873           96 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    5874            0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5875              :     }
    5876              : 
    5877          108 :     PG_RETURN_POINTER(state);
    5878              : }
    5879              : 
    5880              : Datum
    5881           24 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    5882              : {
    5883              :     Int128AggState *state;
    5884              : 
    5885           24 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5886              : 
    5887              :     /* Should not get here with no state */
    5888           24 :     if (state == NULL)
    5889            0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    5890              : 
    5891           24 :     if (!PG_ARGISNULL(1))
    5892           16 :         do_int128_discard(state, PG_GETARG_INT64(1));
    5893              : 
    5894           24 :     PG_RETURN_POINTER(state);
    5895              : }
    5896              : 
    5897              : Datum
    5898          692 : numeric_poly_sum(PG_FUNCTION_ARGS)
    5899              : {
    5900              :     Int128AggState *state;
    5901              :     Numeric     res;
    5902              :     NumericVar  result;
    5903              : 
    5904          692 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5905              : 
    5906              :     /* If there were no non-null inputs, return NULL */
    5907          692 :     if (state == NULL || state->N == 0)
    5908           16 :         PG_RETURN_NULL();
    5909              : 
    5910          676 :     init_var(&result);
    5911              : 
    5912          676 :     int128_to_numericvar(state->sumX, &result);
    5913              : 
    5914          676 :     res = make_result(&result);
    5915              : 
    5916          676 :     free_var(&result);
    5917              : 
    5918          676 :     PG_RETURN_NUMERIC(res);
    5919              : }
    5920              : 
    5921              : Datum
    5922           24 : numeric_poly_avg(PG_FUNCTION_ARGS)
    5923              : {
    5924              :     Int128AggState *state;
    5925              :     NumericVar  result;
    5926              :     Datum       countd,
    5927              :                 sumd;
    5928              : 
    5929           24 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5930              : 
    5931              :     /* If there were no non-null inputs, return NULL */
    5932           24 :     if (state == NULL || state->N == 0)
    5933           12 :         PG_RETURN_NULL();
    5934              : 
    5935           12 :     init_var(&result);
    5936              : 
    5937           12 :     int128_to_numericvar(state->sumX, &result);
    5938              : 
    5939           12 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    5940           12 :     sumd = NumericGetDatum(make_result(&result));
    5941              : 
    5942           12 :     free_var(&result);
    5943              : 
    5944           12 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    5945              : }
    5946              : 
    5947              : Datum
    5948           52 : numeric_avg(PG_FUNCTION_ARGS)
    5949              : {
    5950              :     NumericAggState *state;
    5951              :     Datum       N_datum;
    5952              :     Datum       sumX_datum;
    5953              :     NumericVar  sumX_var;
    5954              : 
    5955           52 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5956              : 
    5957              :     /* If there were no non-null inputs, return NULL */
    5958           52 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    5959           12 :         PG_RETURN_NULL();
    5960              : 
    5961           40 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    5962            4 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    5963              : 
    5964              :     /* adding plus and minus infinities gives NaN */
    5965           36 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    5966            4 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    5967           32 :     if (state->pInfcount > 0)
    5968           12 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    5969           20 :     if (state->nInfcount > 0)
    5970            4 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    5971              : 
    5972           16 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    5973              : 
    5974           16 :     init_var(&sumX_var);
    5975           16 :     accum_sum_final(&state->sumX, &sumX_var);
    5976           16 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    5977           16 :     free_var(&sumX_var);
    5978              : 
    5979           16 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    5980              : }
    5981              : 
    5982              : Datum
    5983       113926 : numeric_sum(PG_FUNCTION_ARGS)
    5984              : {
    5985              :     NumericAggState *state;
    5986              :     NumericVar  sumX_var;
    5987              :     Numeric     result;
    5988              : 
    5989       113926 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5990              : 
    5991              :     /* If there were no non-null inputs, return NULL */
    5992       113926 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    5993           12 :         PG_RETURN_NULL();
    5994              : 
    5995       113914 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    5996           12 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    5997              : 
    5998              :     /* adding plus and minus infinities gives NaN */
    5999       113902 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6000            4 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6001       113898 :     if (state->pInfcount > 0)
    6002           12 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6003       113886 :     if (state->nInfcount > 0)
    6004            4 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6005              : 
    6006       113882 :     init_var(&sumX_var);
    6007       113882 :     accum_sum_final(&state->sumX, &sumX_var);
    6008       113882 :     result = make_result(&sumX_var);
    6009       113882 :     free_var(&sumX_var);
    6010              : 
    6011       113882 :     PG_RETURN_NUMERIC(result);
    6012              : }
    6013              : 
    6014              : /*
    6015              :  * Workhorse routine for the standard deviance and variance
    6016              :  * aggregates. 'state' is aggregate's transition state.
    6017              :  * 'variance' specifies whether we should calculate the
    6018              :  * variance or the standard deviation. 'sample' indicates whether the
    6019              :  * caller is interested in the sample or the population
    6020              :  * variance/stddev.
    6021              :  *
    6022              :  * If appropriate variance statistic is undefined for the input,
    6023              :  * *is_null is set to true and NULL is returned.
    6024              :  */
    6025              : static Numeric
    6026          654 : numeric_stddev_internal(NumericAggState *state,
    6027              :                         bool variance, bool sample,
    6028              :                         bool *is_null)
    6029              : {
    6030              :     Numeric     res;
    6031              :     NumericVar  vN,
    6032              :                 vsumX,
    6033              :                 vsumX2,
    6034              :                 vNminus1;
    6035              :     int64       totCount;
    6036              :     int         rscale;
    6037              : 
    6038              :     /*
    6039              :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6040              :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6041              :      * and infinities count as normal inputs for this purpose).
    6042              :      */
    6043          654 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6044              :     {
    6045            0 :         *is_null = true;
    6046            0 :         return NULL;
    6047              :     }
    6048              : 
    6049          654 :     if (sample && totCount <= 1)
    6050              :     {
    6051           88 :         *is_null = true;
    6052           88 :         return NULL;
    6053              :     }
    6054              : 
    6055          566 :     *is_null = false;
    6056              : 
    6057              :     /*
    6058              :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6059              :      * float8 functions, any infinity input produces NaN output.
    6060              :      */
    6061          566 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6062           36 :         return make_result(&const_nan);
    6063              : 
    6064              :     /* OK, normal calculation applies */
    6065          530 :     init_var(&vN);
    6066          530 :     init_var(&vsumX);
    6067          530 :     init_var(&vsumX2);
    6068              : 
    6069          530 :     int64_to_numericvar(state->N, &vN);
    6070          530 :     accum_sum_final(&(state->sumX), &vsumX);
    6071          530 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6072              : 
    6073          530 :     init_var(&vNminus1);
    6074          530 :     sub_var(&vN, &const_one, &vNminus1);
    6075              : 
    6076              :     /* compute rscale for mul_var calls */
    6077          530 :     rscale = vsumX.dscale * 2;
    6078              : 
    6079          530 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6080          530 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6081          530 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6082              : 
    6083          530 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6084              :     {
    6085              :         /* Watch out for roundoff error producing a negative numerator */
    6086           50 :         res = make_result(&const_zero);
    6087              :     }
    6088              :     else
    6089              :     {
    6090          480 :         if (sample)
    6091          328 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6092              :         else
    6093          152 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6094          480 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6095          480 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true);    /* variance */
    6096          480 :         if (!variance)
    6097          252 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6098              : 
    6099          480 :         res = make_result(&vsumX);
    6100              :     }
    6101              : 
    6102          530 :     free_var(&vNminus1);
    6103          530 :     free_var(&vsumX);
    6104          530 :     free_var(&vsumX2);
    6105              : 
    6106          530 :     return res;
    6107              : }
    6108              : 
    6109              : Datum
    6110          120 : numeric_var_samp(PG_FUNCTION_ARGS)
    6111              : {
    6112              :     NumericAggState *state;
    6113              :     Numeric     res;
    6114              :     bool        is_null;
    6115              : 
    6116          120 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6117              : 
    6118          120 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6119              : 
    6120          120 :     if (is_null)
    6121           28 :         PG_RETURN_NULL();
    6122              :     else
    6123           92 :         PG_RETURN_NUMERIC(res);
    6124              : }
    6125              : 
    6126              : Datum
    6127          116 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6128              : {
    6129              :     NumericAggState *state;
    6130              :     Numeric     res;
    6131              :     bool        is_null;
    6132              : 
    6133          116 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6134              : 
    6135          116 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6136              : 
    6137          116 :     if (is_null)
    6138           28 :         PG_RETURN_NULL();
    6139              :     else
    6140           88 :         PG_RETURN_NUMERIC(res);
    6141              : }
    6142              : 
    6143              : Datum
    6144           76 : numeric_var_pop(PG_FUNCTION_ARGS)
    6145              : {
    6146              :     NumericAggState *state;
    6147              :     Numeric     res;
    6148              :     bool        is_null;
    6149              : 
    6150           76 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6151              : 
    6152           76 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6153              : 
    6154           76 :     if (is_null)
    6155            0 :         PG_RETURN_NULL();
    6156              :     else
    6157           76 :         PG_RETURN_NUMERIC(res);
    6158              : }
    6159              : 
    6160              : Datum
    6161           64 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6162              : {
    6163              :     NumericAggState *state;
    6164              :     Numeric     res;
    6165              :     bool        is_null;
    6166              : 
    6167           64 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6168              : 
    6169           64 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6170              : 
    6171           64 :     if (is_null)
    6172            0 :         PG_RETURN_NULL();
    6173              :     else
    6174           64 :         PG_RETURN_NUMERIC(res);
    6175              : }
    6176              : 
    6177              : static Numeric
    6178          278 : numeric_poly_stddev_internal(Int128AggState *state,
    6179              :                              bool variance, bool sample,
    6180              :                              bool *is_null)
    6181              : {
    6182              :     NumericAggState numstate;
    6183              :     Numeric     res;
    6184              : 
    6185              :     /* Initialize an empty agg state */
    6186          278 :     memset(&numstate, 0, sizeof(NumericAggState));
    6187              : 
    6188          278 :     if (state)
    6189              :     {
    6190              :         NumericVar  tmp_var;
    6191              : 
    6192          278 :         numstate.N = state->N;
    6193              : 
    6194          278 :         init_var(&tmp_var);
    6195              : 
    6196          278 :         int128_to_numericvar(state->sumX, &tmp_var);
    6197          278 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6198              : 
    6199          278 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6200          278 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6201              : 
    6202          278 :         free_var(&tmp_var);
    6203              :     }
    6204              : 
    6205          278 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6206              : 
    6207          278 :     if (numstate.sumX.ndigits > 0)
    6208              :     {
    6209          278 :         pfree(numstate.sumX.pos_digits);
    6210          278 :         pfree(numstate.sumX.neg_digits);
    6211              :     }
    6212          278 :     if (numstate.sumX2.ndigits > 0)
    6213              :     {
    6214          278 :         pfree(numstate.sumX2.pos_digits);
    6215          278 :         pfree(numstate.sumX2.neg_digits);
    6216              :     }
    6217              : 
    6218          278 :     return res;
    6219              : }
    6220              : 
    6221              : Datum
    6222           84 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6223              : {
    6224              :     Int128AggState *state;
    6225              :     Numeric     res;
    6226              :     bool        is_null;
    6227              : 
    6228           84 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6229              : 
    6230           84 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6231              : 
    6232           84 :     if (is_null)
    6233           16 :         PG_RETURN_NULL();
    6234              :     else
    6235           68 :         PG_RETURN_NUMERIC(res);
    6236              : }
    6237              : 
    6238              : Datum
    6239          106 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6240              : {
    6241              :     Int128AggState *state;
    6242              :     Numeric     res;
    6243              :     bool        is_null;
    6244              : 
    6245          106 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6246              : 
    6247          106 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6248              : 
    6249          106 :     if (is_null)
    6250           16 :         PG_RETURN_NULL();
    6251              :     else
    6252           90 :         PG_RETURN_NUMERIC(res);
    6253              : }
    6254              : 
    6255              : Datum
    6256           40 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6257              : {
    6258              :     Int128AggState *state;
    6259              :     Numeric     res;
    6260              :     bool        is_null;
    6261              : 
    6262           40 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6263              : 
    6264           40 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6265              : 
    6266           40 :     if (is_null)
    6267            0 :         PG_RETURN_NULL();
    6268              :     else
    6269           40 :         PG_RETURN_NUMERIC(res);
    6270              : }
    6271              : 
    6272              : Datum
    6273           48 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6274              : {
    6275              :     Int128AggState *state;
    6276              :     Numeric     res;
    6277              :     bool        is_null;
    6278              : 
    6279           48 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6280              : 
    6281           48 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6282              : 
    6283           48 :     if (is_null)
    6284            0 :         PG_RETURN_NULL();
    6285              :     else
    6286           48 :         PG_RETURN_NUMERIC(res);
    6287              : }
    6288              : 
    6289              : /*
    6290              :  * SUM transition functions for integer datatypes.
    6291              :  *
    6292              :  * To avoid overflow, we use accumulators wider than the input datatype.
    6293              :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6294              :  * inputs, we use int8 accumulators which should be sufficient for practical
    6295              :  * purposes.  (The latter two therefore don't really belong in this file,
    6296              :  * but we keep them here anyway.)
    6297              :  *
    6298              :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6299              :  * the initial condition of the transition data value needs to be NULL. This
    6300              :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6301              :  * data value into the transition data: it doesn't know how to do the type
    6302              :  * conversion.  The upshot is that these routines have to be marked non-strict
    6303              :  * and handle substitution of the first non-null input themselves.
    6304              :  *
    6305              :  * Note: these functions are used only in plain aggregation mode.
    6306              :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6307              :  */
    6308              : 
    6309              : Datum
    6310           16 : int2_sum(PG_FUNCTION_ARGS)
    6311              : {
    6312              :     int64       oldsum;
    6313              :     int64       newval;
    6314              : 
    6315           16 :     if (PG_ARGISNULL(0))
    6316              :     {
    6317              :         /* No non-null input seen so far... */
    6318            4 :         if (PG_ARGISNULL(1))
    6319            0 :             PG_RETURN_NULL();   /* still no non-null */
    6320              :         /* This is the first non-null input. */
    6321            4 :         newval = (int64) PG_GETARG_INT16(1);
    6322            4 :         PG_RETURN_INT64(newval);
    6323              :     }
    6324              : 
    6325           12 :     oldsum = PG_GETARG_INT64(0);
    6326              : 
    6327              :     /* Leave sum unchanged if new input is null. */
    6328           12 :     if (PG_ARGISNULL(1))
    6329            0 :         PG_RETURN_INT64(oldsum);
    6330              : 
    6331              :     /* OK to do the addition. */
    6332           12 :     newval = oldsum + (int64) PG_GETARG_INT16(1);
    6333              : 
    6334           12 :     PG_RETURN_INT64(newval);
    6335              : }
    6336              : 
    6337              : Datum
    6338      3267520 : int4_sum(PG_FUNCTION_ARGS)
    6339              : {
    6340              :     int64       oldsum;
    6341              :     int64       newval;
    6342              : 
    6343      3267520 :     if (PG_ARGISNULL(0))
    6344              :     {
    6345              :         /* No non-null input seen so far... */
    6346       129046 :         if (PG_ARGISNULL(1))
    6347          654 :             PG_RETURN_NULL();   /* still no non-null */
    6348              :         /* This is the first non-null input. */
    6349       128392 :         newval = (int64) PG_GETARG_INT32(1);
    6350       128392 :         PG_RETURN_INT64(newval);
    6351              :     }
    6352              : 
    6353      3138474 :     oldsum = PG_GETARG_INT64(0);
    6354              : 
    6355              :     /* Leave sum unchanged if new input is null. */
    6356      3138474 :     if (PG_ARGISNULL(1))
    6357        20606 :         PG_RETURN_INT64(oldsum);
    6358              : 
    6359              :     /* OK to do the addition. */
    6360      3117868 :     newval = oldsum + (int64) PG_GETARG_INT32(1);
    6361              : 
    6362      3117868 :     PG_RETURN_INT64(newval);
    6363              : }
    6364              : 
    6365              : /*
    6366              :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6367              :  */
    6368              : Datum
    6369            0 : int8_sum(PG_FUNCTION_ARGS)
    6370              : {
    6371              :     Numeric     oldsum;
    6372              : 
    6373            0 :     if (PG_ARGISNULL(0))
    6374              :     {
    6375              :         /* No non-null input seen so far... */
    6376            0 :         if (PG_ARGISNULL(1))
    6377            0 :             PG_RETURN_NULL();   /* still no non-null */
    6378              :         /* This is the first non-null input. */
    6379            0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6380              :     }
    6381              : 
    6382              :     /*
    6383              :      * Note that we cannot special-case the aggregate case here, as we do for
    6384              :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6385              :      * our first parameter in-place.
    6386              :      */
    6387              : 
    6388            0 :     oldsum = PG_GETARG_NUMERIC(0);
    6389              : 
    6390              :     /* Leave sum unchanged if new input is null. */
    6391            0 :     if (PG_ARGISNULL(1))
    6392            0 :         PG_RETURN_NUMERIC(oldsum);
    6393              : 
    6394              :     /* OK to do the addition. */
    6395            0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6396              :                                         NumericGetDatum(oldsum),
    6397              :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6398              : }
    6399              : 
    6400              : 
    6401              : /*
    6402              :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6403              :  * is a two-element int8 array, holding count and sum.
    6404              :  *
    6405              :  * These functions are also used for sum(int2) and sum(int4) when
    6406              :  * operating in moving-aggregate mode, since for correct inverse transitions
    6407              :  * we need to count the inputs.
    6408              :  */
    6409              : 
    6410              : typedef struct Int8TransTypeData
    6411              : {
    6412              :     int64       count;
    6413              :     int64       sum;
    6414              : } Int8TransTypeData;
    6415              : 
    6416              : Datum
    6417           28 : int2_avg_accum(PG_FUNCTION_ARGS)
    6418              : {
    6419              :     ArrayType  *transarray;
    6420           28 :     int16       newval = PG_GETARG_INT16(1);
    6421              :     Int8TransTypeData *transdata;
    6422              : 
    6423              :     /*
    6424              :      * If we're invoked as an aggregate, we can cheat and modify our first
    6425              :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6426              :      * a copy of it before scribbling on it.
    6427              :      */
    6428           28 :     if (AggCheckCallContext(fcinfo, NULL))
    6429           28 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6430              :     else
    6431            0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6432              : 
    6433           56 :     if (ARR_HASNULL(transarray) ||
    6434           28 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6435            0 :         elog(ERROR, "expected 2-element int8 array");
    6436              : 
    6437           28 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6438           28 :     transdata->count++;
    6439           28 :     transdata->sum += newval;
    6440              : 
    6441           28 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6442              : }
    6443              : 
    6444              : Datum
    6445      1743850 : int4_avg_accum(PG_FUNCTION_ARGS)
    6446              : {
    6447              :     ArrayType  *transarray;
    6448      1743850 :     int32       newval = PG_GETARG_INT32(1);
    6449              :     Int8TransTypeData *transdata;
    6450              : 
    6451              :     /*
    6452              :      * If we're invoked as an aggregate, we can cheat and modify our first
    6453              :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6454              :      * a copy of it before scribbling on it.
    6455              :      */
    6456      1743850 :     if (AggCheckCallContext(fcinfo, NULL))
    6457      1743850 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6458              :     else
    6459            0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6460              : 
    6461      3487700 :     if (ARR_HASNULL(transarray) ||
    6462      1743850 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6463            0 :         elog(ERROR, "expected 2-element int8 array");
    6464              : 
    6465      1743850 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6466      1743850 :     transdata->count++;
    6467      1743850 :     transdata->sum += newval;
    6468              : 
    6469      1743850 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6470              : }
    6471              : 
    6472              : Datum
    6473         6660 : int4_avg_combine(PG_FUNCTION_ARGS)
    6474              : {
    6475              :     ArrayType  *transarray1;
    6476              :     ArrayType  *transarray2;
    6477              :     Int8TransTypeData *state1;
    6478              :     Int8TransTypeData *state2;
    6479              : 
    6480         6660 :     if (!AggCheckCallContext(fcinfo, NULL))
    6481            0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6482              : 
    6483         6660 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6484         6660 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6485              : 
    6486        13320 :     if (ARR_HASNULL(transarray1) ||
    6487         6660 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6488            0 :         elog(ERROR, "expected 2-element int8 array");
    6489              : 
    6490        13320 :     if (ARR_HASNULL(transarray2) ||
    6491         6660 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6492            0 :         elog(ERROR, "expected 2-element int8 array");
    6493              : 
    6494         6660 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6495         6660 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6496              : 
    6497         6660 :     state1->count += state2->count;
    6498         6660 :     state1->sum += state2->sum;
    6499              : 
    6500         6660 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6501              : }
    6502              : 
    6503              : Datum
    6504            8 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6505              : {
    6506              :     ArrayType  *transarray;
    6507            8 :     int16       newval = PG_GETARG_INT16(1);
    6508              :     Int8TransTypeData *transdata;
    6509              : 
    6510              :     /*
    6511              :      * If we're invoked as an aggregate, we can cheat and modify our first
    6512              :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6513              :      * a copy of it before scribbling on it.
    6514              :      */
    6515            8 :     if (AggCheckCallContext(fcinfo, NULL))
    6516            8 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6517              :     else
    6518            0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6519              : 
    6520           16 :     if (ARR_HASNULL(transarray) ||
    6521            8 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6522            0 :         elog(ERROR, "expected 2-element int8 array");
    6523              : 
    6524            8 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6525            8 :     transdata->count--;
    6526            8 :     transdata->sum -= newval;
    6527              : 
    6528            8 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6529              : }
    6530              : 
    6531              : Datum
    6532          968 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6533              : {
    6534              :     ArrayType  *transarray;
    6535          968 :     int32       newval = PG_GETARG_INT32(1);
    6536              :     Int8TransTypeData *transdata;
    6537              : 
    6538              :     /*
    6539              :      * If we're invoked as an aggregate, we can cheat and modify our first
    6540              :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6541              :      * a copy of it before scribbling on it.
    6542              :      */
    6543          968 :     if (AggCheckCallContext(fcinfo, NULL))
    6544          968 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6545              :     else
    6546            0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6547              : 
    6548         1936 :     if (ARR_HASNULL(transarray) ||
    6549          968 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6550            0 :         elog(ERROR, "expected 2-element int8 array");
    6551              : 
    6552          968 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6553          968 :     transdata->count--;
    6554          968 :     transdata->sum -= newval;
    6555              : 
    6556          968 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6557              : }
    6558              : 
    6559              : Datum
    6560         6817 : int8_avg(PG_FUNCTION_ARGS)
    6561              : {
    6562         6817 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6563              :     Int8TransTypeData *transdata;
    6564              :     Datum       countd,
    6565              :                 sumd;
    6566              : 
    6567        13634 :     if (ARR_HASNULL(transarray) ||
    6568         6817 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6569            0 :         elog(ERROR, "expected 2-element int8 array");
    6570         6817 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6571              : 
    6572              :     /* SQL defines AVG of no values to be NULL */
    6573         6817 :     if (transdata->count == 0)
    6574           73 :         PG_RETURN_NULL();
    6575              : 
    6576         6744 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6577         6744 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6578              : 
    6579         6744 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6580              : }
    6581              : 
    6582              : /*
    6583              :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6584              :  * final function for both.
    6585              :  */
    6586              : Datum
    6587         2556 : int2int4_sum(PG_FUNCTION_ARGS)
    6588              : {
    6589         2556 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6590              :     Int8TransTypeData *transdata;
    6591              : 
    6592         5112 :     if (ARR_HASNULL(transarray) ||
    6593         2556 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6594            0 :         elog(ERROR, "expected 2-element int8 array");
    6595         2556 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6596              : 
    6597              :     /* SQL defines SUM of no values to be NULL */
    6598         2556 :     if (transdata->count == 0)
    6599          320 :         PG_RETURN_NULL();
    6600              : 
    6601         2236 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6602              : }
    6603              : 
    6604              : 
    6605              : /* ----------------------------------------------------------------------
    6606              :  *
    6607              :  * Debug support
    6608              :  *
    6609              :  * ----------------------------------------------------------------------
    6610              :  */
    6611              : 
    6612              : #ifdef NUMERIC_DEBUG
    6613              : 
    6614              : /*
    6615              :  * dump_numeric() - Dump a value in the db storage format for debugging
    6616              :  */
    6617              : static void
    6618              : dump_numeric(const char *str, Numeric num)
    6619              : {
    6620              :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6621              :     int         ndigits;
    6622              :     int         i;
    6623              : 
    6624              :     ndigits = NUMERIC_NDIGITS(num);
    6625              : 
    6626              :     printf("%s: NUMERIC w=%d d=%d ", str,
    6627              :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6628              :     switch (NUMERIC_SIGN(num))
    6629              :     {
    6630              :         case NUMERIC_POS:
    6631              :             printf("POS");
    6632              :             break;
    6633              :         case NUMERIC_NEG:
    6634              :             printf("NEG");
    6635              :             break;
    6636              :         case NUMERIC_NAN:
    6637              :             printf("NaN");
    6638              :             break;
    6639              :         case NUMERIC_PINF:
    6640              :             printf("Infinity");
    6641              :             break;
    6642              :         case NUMERIC_NINF:
    6643              :             printf("-Infinity");
    6644              :             break;
    6645              :         default:
    6646              :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    6647              :             break;
    6648              :     }
    6649              : 
    6650              :     for (i = 0; i < ndigits; i++)
    6651              :         printf(" %0*d", DEC_DIGITS, digits[i]);
    6652              :     printf("\n");
    6653              : }
    6654              : 
    6655              : 
    6656              : /*
    6657              :  * dump_var() - Dump a value in the variable format for debugging
    6658              :  */
    6659              : static void
    6660              : dump_var(const char *str, NumericVar *var)
    6661              : {
    6662              :     int         i;
    6663              : 
    6664              :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    6665              :     switch (var->sign)
    6666              :     {
    6667              :         case NUMERIC_POS:
    6668              :             printf("POS");
    6669              :             break;
    6670              :         case NUMERIC_NEG:
    6671              :             printf("NEG");
    6672              :             break;
    6673              :         case NUMERIC_NAN:
    6674              :             printf("NaN");
    6675              :             break;
    6676              :         case NUMERIC_PINF:
    6677              :             printf("Infinity");
    6678              :             break;
    6679              :         case NUMERIC_NINF:
    6680              :             printf("-Infinity");
    6681              :             break;
    6682              :         default:
    6683              :             printf("SIGN=0x%x", var->sign);
    6684              :             break;
    6685              :     }
    6686              : 
    6687              :     for (i = 0; i < var->ndigits; i++)
    6688              :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    6689              : 
    6690              :     printf("\n");
    6691              : }
    6692              : #endif                          /* NUMERIC_DEBUG */
    6693              : 
    6694              : 
    6695              : /* ----------------------------------------------------------------------
    6696              :  *
    6697              :  * Local functions follow
    6698              :  *
    6699              :  * In general, these do not support "special" (NaN or infinity) inputs;
    6700              :  * callers should handle those possibilities first.
    6701              :  * (There are one or two exceptions, noted in their header comments.)
    6702              :  *
    6703              :  * ----------------------------------------------------------------------
    6704              :  */
    6705              : 
    6706              : 
    6707              : /*
    6708              :  * alloc_var() -
    6709              :  *
    6710              :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    6711              :  */
    6712              : static void
    6713      1444700 : alloc_var(NumericVar *var, int ndigits)
    6714              : {
    6715      1444700 :     digitbuf_free(var->buf);
    6716      1444700 :     var->buf = digitbuf_alloc(ndigits + 1);
    6717      1444700 :     var->buf[0] = 0;         /* spare digit for rounding */
    6718      1444700 :     var->digits = var->buf + 1;
    6719      1444700 :     var->ndigits = ndigits;
    6720      1444700 : }
    6721              : 
    6722              : 
    6723              : /*
    6724              :  * free_var() -
    6725              :  *
    6726              :  *  Return the digit buffer of a variable to the free pool
    6727              :  */
    6728              : static void
    6729      2780649 : free_var(NumericVar *var)
    6730              : {
    6731      2780649 :     digitbuf_free(var->buf);
    6732      2780649 :     var->buf = NULL;
    6733      2780649 :     var->digits = NULL;
    6734      2780649 :     var->sign = NUMERIC_NAN;
    6735      2780649 : }
    6736              : 
    6737              : 
    6738              : /*
    6739              :  * zero_var() -
    6740              :  *
    6741              :  *  Set a variable to ZERO.
    6742              :  *  Note: its dscale is not touched.
    6743              :  */
    6744              : static void
    6745        37986 : zero_var(NumericVar *var)
    6746              : {
    6747        37986 :     digitbuf_free(var->buf);
    6748        37986 :     var->buf = NULL;
    6749        37986 :     var->digits = NULL;
    6750        37986 :     var->ndigits = 0;
    6751        37986 :     var->weight = 0;         /* by convention; doesn't really matter */
    6752        37986 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    6753        37986 : }
    6754              : 
    6755              : 
    6756              : /*
    6757              :  * set_var_from_str()
    6758              :  *
    6759              :  *  Parse a string and put the number into a variable
    6760              :  *
    6761              :  * This function does not handle leading or trailing spaces.  It returns
    6762              :  * the end+1 position parsed into *endptr, so that caller can check for
    6763              :  * trailing spaces/garbage if deemed necessary.
    6764              :  *
    6765              :  * cp is the place to actually start parsing; str is what to use in error
    6766              :  * reports.  (Typically cp would be the same except advanced over spaces.)
    6767              :  *
    6768              :  * Returns true on success, false on failure (if escontext points to an
    6769              :  * ErrorSaveContext; otherwise errors are thrown).
    6770              :  */
    6771              : static bool
    6772       118233 : set_var_from_str(const char *str, const char *cp,
    6773              :                  NumericVar *dest, const char **endptr,
    6774              :                  Node *escontext)
    6775              : {
    6776       118233 :     bool        have_dp = false;
    6777              :     int         i;
    6778              :     unsigned char *decdigits;
    6779       118233 :     int         sign = NUMERIC_POS;
    6780       118233 :     int         dweight = -1;
    6781              :     int         ddigits;
    6782       118233 :     int         dscale = 0;
    6783              :     int         weight;
    6784              :     int         ndigits;
    6785              :     int         offset;
    6786              :     NumericDigit *digits;
    6787              : 
    6788              :     /*
    6789              :      * We first parse the string to extract decimal digits and determine the
    6790              :      * correct decimal weight.  Then convert to NBASE representation.
    6791              :      */
    6792       118233 :     switch (*cp)
    6793              :     {
    6794            0 :         case '+':
    6795            0 :             sign = NUMERIC_POS;
    6796            0 :             cp++;
    6797            0 :             break;
    6798              : 
    6799          183 :         case '-':
    6800          183 :             sign = NUMERIC_NEG;
    6801          183 :             cp++;
    6802          183 :             break;
    6803              :     }
    6804              : 
    6805       118233 :     if (*cp == '.')
    6806              :     {
    6807          252 :         have_dp = true;
    6808          252 :         cp++;
    6809              :     }
    6810              : 
    6811       118233 :     if (!isdigit((unsigned char) *cp))
    6812            0 :         goto invalid_syntax;
    6813              : 
    6814       118233 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    6815              : 
    6816              :     /* leading padding for digit alignment later */
    6817       118233 :     memset(decdigits, 0, DEC_DIGITS);
    6818       118233 :     i = DEC_DIGITS;
    6819              : 
    6820       497694 :     while (*cp)
    6821              :     {
    6822       380443 :         if (isdigit((unsigned char) *cp))
    6823              :         {
    6824       367591 :             decdigits[i++] = *cp++ - '0';
    6825       367591 :             if (!have_dp)
    6826       311702 :                 dweight++;
    6827              :             else
    6828        55889 :                 dscale++;
    6829              :         }
    6830        12852 :         else if (*cp == '.')
    6831              :         {
    6832        11762 :             if (have_dp)
    6833            0 :                 goto invalid_syntax;
    6834        11762 :             have_dp = true;
    6835        11762 :             cp++;
    6836              :             /* decimal point must not be followed by underscore */
    6837        11762 :             if (*cp == '_')
    6838            4 :                 goto invalid_syntax;
    6839              :         }
    6840         1090 :         else if (*cp == '_')
    6841              :         {
    6842              :             /* underscore must be followed by more digits */
    6843          124 :             cp++;
    6844          124 :             if (!isdigit((unsigned char) *cp))
    6845           12 :                 goto invalid_syntax;
    6846              :         }
    6847              :         else
    6848          966 :             break;
    6849              :     }
    6850              : 
    6851       118217 :     ddigits = i - DEC_DIGITS;
    6852              :     /* trailing padding for digit alignment later */
    6853       118217 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    6854              : 
    6855              :     /* Handle exponent, if any */
    6856       118217 :     if (*cp == 'e' || *cp == 'E')
    6857              :     {
    6858          934 :         int64       exponent = 0;
    6859          934 :         bool        neg = false;
    6860              : 
    6861              :         /*
    6862              :          * At this point, dweight and dscale can't be more than about
    6863              :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    6864              :          * constraining the exponent similarly should be enough to prevent
    6865              :          * integer overflow in this function.  If the value is too large to
    6866              :          * fit in storage format, make_result() will complain about it later;
    6867              :          * for consistency use the same ereport errcode/text as make_result().
    6868              :          */
    6869              : 
    6870              :         /* exponent sign */
    6871          934 :         cp++;
    6872          934 :         if (*cp == '+')
    6873          102 :             cp++;
    6874          832 :         else if (*cp == '-')
    6875              :         {
    6876          400 :             neg = true;
    6877          400 :             cp++;
    6878              :         }
    6879              : 
    6880              :         /* exponent digits */
    6881          934 :         if (!isdigit((unsigned char) *cp))
    6882            4 :             goto invalid_syntax;
    6883              : 
    6884         3233 :         while (*cp)
    6885              :         {
    6886         2315 :             if (isdigit((unsigned char) *cp))
    6887              :             {
    6888         2287 :                 exponent = exponent * 10 + (*cp++ - '0');
    6889         2287 :                 if (exponent > PG_INT32_MAX / 2)
    6890            4 :                     goto out_of_range;
    6891              :             }
    6892           28 :             else if (*cp == '_')
    6893              :             {
    6894              :                 /* underscore must be followed by more digits */
    6895           28 :                 cp++;
    6896           28 :                 if (!isdigit((unsigned char) *cp))
    6897            8 :                     goto invalid_syntax;
    6898              :             }
    6899              :             else
    6900            0 :                 break;
    6901              :         }
    6902              : 
    6903          918 :         if (neg)
    6904          400 :             exponent = -exponent;
    6905              : 
    6906          918 :         dweight += (int) exponent;
    6907          918 :         dscale -= (int) exponent;
    6908          918 :         if (dscale < 0)
    6909          382 :             dscale = 0;
    6910              :     }
    6911              : 
    6912              :     /*
    6913              :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    6914              :      * to determine the converted weight and ndigits.  offset is the number of
    6915              :      * decimal zeroes to insert before the first given digit to have a
    6916              :      * correctly aligned first NBASE digit.
    6917              :      */
    6918       118201 :     if (dweight >= 0)
    6919       117617 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    6920              :     else
    6921          584 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    6922       118201 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    6923       118201 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    6924              : 
    6925       118201 :     alloc_var(dest, ndigits);
    6926       118201 :     dest->sign = sign;
    6927       118201 :     dest->weight = weight;
    6928       118201 :     dest->dscale = dscale;
    6929              : 
    6930       118201 :     i = DEC_DIGITS - offset;
    6931       118201 :     digits = dest->digits;
    6932              : 
    6933       281399 :     while (ndigits-- > 0)
    6934              :     {
    6935              : #if DEC_DIGITS == 4
    6936       163198 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    6937       163198 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    6938              : #elif DEC_DIGITS == 2
    6939              :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    6940              : #elif DEC_DIGITS == 1
    6941              :         *digits++ = decdigits[i];
    6942              : #else
    6943              : #error unsupported NBASE
    6944              : #endif
    6945       163198 :         i += DEC_DIGITS;
    6946              :     }
    6947              : 
    6948       118201 :     pfree(decdigits);
    6949              : 
    6950              :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    6951       118201 :     strip_var(dest);
    6952              : 
    6953              :     /* Return end+1 position for caller */
    6954       118201 :     *endptr = cp;
    6955              : 
    6956       118201 :     return true;
    6957              : 
    6958            4 : out_of_range:
    6959            4 :     ereturn(escontext, false,
    6960              :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    6961              :              errmsg("value overflows numeric format")));
    6962              : 
    6963           28 : invalid_syntax:
    6964           28 :     ereturn(escontext, false,
    6965              :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    6966              :              errmsg("invalid input syntax for type %s: \"%s\"",
    6967              :                     "numeric", str)));
    6968              : }
    6969              : 
    6970              : 
    6971              : /*
    6972              :  * Return the numeric value of a single hex digit.
    6973              :  */
    6974              : static inline int
    6975          472 : xdigit_value(char dig)
    6976              : {
    6977          596 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    6978          196 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    6979           72 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    6980              : }
    6981              : 
    6982              : /*
    6983              :  * set_var_from_non_decimal_integer_str()
    6984              :  *
    6985              :  *  Parse a string containing a non-decimal integer
    6986              :  *
    6987              :  * This function does not handle leading or trailing spaces.  It returns
    6988              :  * the end+1 position parsed into *endptr, so that caller can check for
    6989              :  * trailing spaces/garbage if deemed necessary.
    6990              :  *
    6991              :  * cp is the place to actually start parsing; str is what to use in error
    6992              :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    6993              :  * assumed to have already been parsed, so cp should point to the number's
    6994              :  * first digit in the base specified.
    6995              :  *
    6996              :  * base is expected to be 2, 8 or 16.
    6997              :  *
    6998              :  * Returns true on success, false on failure (if escontext points to an
    6999              :  * ErrorSaveContext; otherwise errors are thrown).
    7000              :  */
    7001              : static bool
    7002          104 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7003              :                                      int base, NumericVar *dest,
    7004              :                                      const char **endptr, Node *escontext)
    7005              : {
    7006          104 :     const char *firstdigit = cp;
    7007              :     int64       tmp;
    7008              :     int64       mul;
    7009              :     NumericVar  tmp_var;
    7010              : 
    7011          104 :     init_var(&tmp_var);
    7012              : 
    7013          104 :     zero_var(dest);
    7014              : 
    7015              :     /*
    7016              :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7017              :      * value of the digits in the group, and "mul" is base^n, where n is the
    7018              :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7019              :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7020              :      */
    7021          104 :     tmp = 0;
    7022          104 :     mul = 1;
    7023              : 
    7024          104 :     if (base == 16)
    7025              :     {
    7026          552 :         while (*cp)
    7027              :         {
    7028          532 :             if (isxdigit((unsigned char) *cp))
    7029              :             {
    7030          472 :                 if (mul > PG_INT64_MAX / 16)
    7031              :                 {
    7032              :                     /* Add the contribution from this group of digits */
    7033           20 :                     int64_to_numericvar(mul, &tmp_var);
    7034           20 :                     mul_var(dest, &tmp_var, dest, 0);
    7035           20 :                     int64_to_numericvar(tmp, &tmp_var);
    7036           20 :                     add_var(dest, &tmp_var, dest);
    7037              : 
    7038              :                     /* Result will overflow if weight overflows int16 */
    7039           20 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7040            0 :                         goto out_of_range;
    7041              : 
    7042              :                     /* Begin a new group */
    7043           20 :                     tmp = 0;
    7044           20 :                     mul = 1;
    7045              :                 }
    7046              : 
    7047          472 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7048          472 :                 mul = mul * 16;
    7049              :             }
    7050           60 :             else if (*cp == '_')
    7051              :             {
    7052              :                 /* Underscore must be followed by more digits */
    7053           44 :                 cp++;
    7054           44 :                 if (!isxdigit((unsigned char) *cp))
    7055           12 :                     goto invalid_syntax;
    7056              :             }
    7057              :             else
    7058           16 :                 break;
    7059              :         }
    7060              :     }
    7061           56 :     else if (base == 8)
    7062              :     {
    7063          424 :         while (*cp)
    7064              :         {
    7065          404 :             if (*cp >= '0' && *cp <= '7')
    7066              :             {
    7067          372 :                 if (mul > PG_INT64_MAX / 8)
    7068              :                 {
    7069              :                     /* Add the contribution from this group of digits */
    7070           12 :                     int64_to_numericvar(mul, &tmp_var);
    7071           12 :                     mul_var(dest, &tmp_var, dest, 0);
    7072           12 :                     int64_to_numericvar(tmp, &tmp_var);
    7073           12 :                     add_var(dest, &tmp_var, dest);
    7074              : 
    7075              :                     /* Result will overflow if weight overflows int16 */
    7076           12 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7077            0 :                         goto out_of_range;
    7078              : 
    7079              :                     /* Begin a new group */
    7080           12 :                     tmp = 0;
    7081           12 :                     mul = 1;
    7082              :                 }
    7083              : 
    7084          372 :                 tmp = tmp * 8 + (*cp++ - '0');
    7085          372 :                 mul = mul * 8;
    7086              :             }
    7087           32 :             else if (*cp == '_')
    7088              :             {
    7089              :                 /* Underscore must be followed by more digits */
    7090           24 :                 cp++;
    7091           24 :                 if (*cp < '0' || *cp > '7')
    7092            0 :                     goto invalid_syntax;
    7093              :             }
    7094              :             else
    7095            8 :                 break;
    7096              :         }
    7097              :     }
    7098           28 :     else if (base == 2)
    7099              :     {
    7100         1040 :         while (*cp)
    7101              :         {
    7102         1020 :             if (*cp >= '0' && *cp <= '1')
    7103              :             {
    7104          944 :                 if (mul > PG_INT64_MAX / 2)
    7105              :                 {
    7106              :                     /* Add the contribution from this group of digits */
    7107           12 :                     int64_to_numericvar(mul, &tmp_var);
    7108           12 :                     mul_var(dest, &tmp_var, dest, 0);
    7109           12 :                     int64_to_numericvar(tmp, &tmp_var);
    7110           12 :                     add_var(dest, &tmp_var, dest);
    7111              : 
    7112              :                     /* Result will overflow if weight overflows int16 */
    7113           12 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7114            0 :                         goto out_of_range;
    7115              : 
    7116              :                     /* Begin a new group */
    7117           12 :                     tmp = 0;
    7118           12 :                     mul = 1;
    7119              :                 }
    7120              : 
    7121          944 :                 tmp = tmp * 2 + (*cp++ - '0');
    7122          944 :                 mul = mul * 2;
    7123              :             }
    7124           76 :             else if (*cp == '_')
    7125              :             {
    7126              :                 /* Underscore must be followed by more digits */
    7127           68 :                 cp++;
    7128           68 :                 if (*cp < '0' || *cp > '1')
    7129            0 :                     goto invalid_syntax;
    7130              :             }
    7131              :             else
    7132            8 :                 break;
    7133              :         }
    7134              :     }
    7135              :     else
    7136              :         /* Should never happen; treat as invalid input */
    7137            0 :         goto invalid_syntax;
    7138              : 
    7139              :     /* Check that we got at least one digit */
    7140           92 :     if (unlikely(cp == firstdigit))
    7141            0 :         goto invalid_syntax;
    7142              : 
    7143              :     /* Add the contribution from the final group of digits */
    7144           92 :     int64_to_numericvar(mul, &tmp_var);
    7145           92 :     mul_var(dest, &tmp_var, dest, 0);
    7146           92 :     int64_to_numericvar(tmp, &tmp_var);
    7147           92 :     add_var(dest, &tmp_var, dest);
    7148              : 
    7149           92 :     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7150            0 :         goto out_of_range;
    7151              : 
    7152           92 :     dest->sign = sign;
    7153              : 
    7154           92 :     free_var(&tmp_var);
    7155              : 
    7156              :     /* Return end+1 position for caller */
    7157           92 :     *endptr = cp;
    7158              : 
    7159           92 :     return true;
    7160              : 
    7161            0 : out_of_range:
    7162            0 :     ereturn(escontext, false,
    7163              :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7164              :              errmsg("value overflows numeric format")));
    7165              : 
    7166           12 : invalid_syntax:
    7167           12 :     ereturn(escontext, false,
    7168              :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7169              :              errmsg("invalid input syntax for type %s: \"%s\"",
    7170              :                     "numeric", str)));
    7171              : }
    7172              : 
    7173              : 
    7174              : /*
    7175              :  * set_var_from_num() -
    7176              :  *
    7177              :  *  Convert the packed db format into a variable
    7178              :  */
    7179              : static void
    7180         8820 : set_var_from_num(Numeric num, NumericVar *dest)
    7181              : {
    7182              :     int         ndigits;
    7183              : 
    7184         8820 :     ndigits = NUMERIC_NDIGITS(num);
    7185              : 
    7186         8820 :     alloc_var(dest, ndigits);
    7187              : 
    7188         8820 :     dest->weight = NUMERIC_WEIGHT(num);
    7189         8820 :     dest->sign = NUMERIC_SIGN(num);
    7190         8820 :     dest->dscale = NUMERIC_DSCALE(num);
    7191              : 
    7192         8820 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7193         8820 : }
    7194              : 
    7195              : 
    7196              : /*
    7197              :  * init_var_from_num() -
    7198              :  *
    7199              :  *  Initialize a variable from packed db format. The digits array is not
    7200              :  *  copied, which saves some cycles when the resulting var is not modified.
    7201              :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7202              :  *  other value to it (with set_var_* functions, or by using the var as the
    7203              :  *  destination of a function like add_var())
    7204              :  *
    7205              :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7206              :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7207              :  *  propagate to the original Numeric! It's OK to use it as the destination
    7208              :  *  argument of one of the calculational functions, though.
    7209              :  */
    7210              : static void
    7211      3865801 : init_var_from_num(Numeric num, NumericVar *dest)
    7212              : {
    7213      3865801 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7214      3865801 :     dest->weight = NUMERIC_WEIGHT(num);
    7215      3865801 :     dest->sign = NUMERIC_SIGN(num);
    7216      3865801 :     dest->dscale = NUMERIC_DSCALE(num);
    7217      3865801 :     dest->digits = NUMERIC_DIGITS(num);
    7218      3865801 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7219      3865801 : }
    7220              : 
    7221              : 
    7222              : /*
    7223              :  * set_var_from_var() -
    7224              :  *
    7225              :  *  Copy one variable into another
    7226              :  */
    7227              : static void
    7228        24522 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7229              : {
    7230              :     NumericDigit *newbuf;
    7231              : 
    7232        24522 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7233        24522 :     newbuf[0] = 0;              /* spare digit for rounding */
    7234        24522 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7235        23862 :         memcpy(newbuf + 1, value->digits,
    7236        23862 :                value->ndigits * sizeof(NumericDigit));
    7237              : 
    7238        24522 :     digitbuf_free(dest->buf);
    7239              : 
    7240        24522 :     memmove(dest, value, sizeof(NumericVar));
    7241        24522 :     dest->buf = newbuf;
    7242        24522 :     dest->digits = newbuf + 1;
    7243        24522 : }
    7244              : 
    7245              : 
    7246              : /*
    7247              :  * get_str_from_var() -
    7248              :  *
    7249              :  *  Convert a var to text representation (guts of numeric_out).
    7250              :  *  The var is displayed to the number of digits indicated by its dscale.
    7251              :  *  Returns a palloc'd string.
    7252              :  */
    7253              : static char *
    7254       556198 : get_str_from_var(const NumericVar *var)
    7255              : {
    7256              :     int         dscale;
    7257              :     char       *str;
    7258              :     char       *cp;
    7259              :     char       *endcp;
    7260              :     int         i;
    7261              :     int         d;
    7262              :     NumericDigit dig;
    7263              : 
    7264              : #if DEC_DIGITS > 1
    7265              :     NumericDigit d1;
    7266              : #endif
    7267              : 
    7268       556198 :     dscale = var->dscale;
    7269              : 
    7270              :     /*
    7271              :      * Allocate space for the result.
    7272              :      *
    7273              :      * i is set to the # of decimal digits before decimal point. dscale is the
    7274              :      * # of decimal digits we will print after decimal point. We may generate
    7275              :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7276              :      * need room for sign, decimal point, null terminator.
    7277              :      */
    7278       556198 :     i = (var->weight + 1) * DEC_DIGITS;
    7279       556198 :     if (i <= 0)
    7280        72415 :         i = 1;
    7281              : 
    7282       556198 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7283       556198 :     cp = str;
    7284              : 
    7285              :     /*
    7286              :      * Output a dash for negative values
    7287              :      */
    7288       556198 :     if (var->sign == NUMERIC_NEG)
    7289         4120 :         *cp++ = '-';
    7290              : 
    7291              :     /*
    7292              :      * Output all digits before the decimal point
    7293              :      */
    7294       556198 :     if (var->weight < 0)
    7295              :     {
    7296        72415 :         d = var->weight + 1;
    7297        72415 :         *cp++ = '0';
    7298              :     }
    7299              :     else
    7300              :     {
    7301      1028306 :         for (d = 0; d <= var->weight; d++)
    7302              :         {
    7303       544523 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7304              :             /* In the first digit, suppress extra leading decimal zeroes */
    7305              : #if DEC_DIGITS == 4
    7306              :             {
    7307       544523 :                 bool        putit = (d > 0);
    7308              : 
    7309       544523 :                 d1 = dig / 1000;
    7310       544523 :                 dig -= d1 * 1000;
    7311       544523 :                 putit |= (d1 > 0);
    7312       544523 :                 if (putit)
    7313       101132 :                     *cp++ = d1 + '0';
    7314       544523 :                 d1 = dig / 100;
    7315       544523 :                 dig -= d1 * 100;
    7316       544523 :                 putit |= (d1 > 0);
    7317       544523 :                 if (putit)
    7318       373774 :                     *cp++ = d1 + '0';
    7319       544523 :                 d1 = dig / 10;
    7320       544523 :                 dig -= d1 * 10;
    7321       544523 :                 putit |= (d1 > 0);
    7322       544523 :                 if (putit)
    7323       456878 :                     *cp++ = d1 + '0';
    7324       544523 :                 *cp++ = dig + '0';
    7325              :             }
    7326              : #elif DEC_DIGITS == 2
    7327              :             d1 = dig / 10;
    7328              :             dig -= d1 * 10;
    7329              :             if (d1 > 0 || d > 0)
    7330              :                 *cp++ = d1 + '0';
    7331              :             *cp++ = dig + '0';
    7332              : #elif DEC_DIGITS == 1
    7333              :             *cp++ = dig + '0';
    7334              : #else
    7335              : #error unsupported NBASE
    7336              : #endif
    7337              :         }
    7338              :     }
    7339              : 
    7340              :     /*
    7341              :      * If requested, output a decimal point and all the digits that follow it.
    7342              :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7343              :      * needed.
    7344              :      */
    7345       556198 :     if (dscale > 0)
    7346              :     {
    7347       409296 :         *cp++ = '.';
    7348       409296 :         endcp = cp + dscale;
    7349      1148221 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7350              :         {
    7351       738925 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7352              : #if DEC_DIGITS == 4
    7353       738925 :             d1 = dig / 1000;
    7354       738925 :             dig -= d1 * 1000;
    7355       738925 :             *cp++ = d1 + '0';
    7356       738925 :             d1 = dig / 100;
    7357       738925 :             dig -= d1 * 100;
    7358       738925 :             *cp++ = d1 + '0';
    7359       738925 :             d1 = dig / 10;
    7360       738925 :             dig -= d1 * 10;
    7361       738925 :             *cp++ = d1 + '0';
    7362       738925 :             *cp++ = dig + '0';
    7363              : #elif DEC_DIGITS == 2
    7364              :             d1 = dig / 10;
    7365              :             dig -= d1 * 10;
    7366              :             *cp++ = d1 + '0';
    7367              :             *cp++ = dig + '0';
    7368              : #elif DEC_DIGITS == 1
    7369              :             *cp++ = dig + '0';
    7370              : #else
    7371              : #error unsupported NBASE
    7372              : #endif
    7373              :         }
    7374       409296 :         cp = endcp;
    7375              :     }
    7376              : 
    7377              :     /*
    7378              :      * terminate the string and return it
    7379              :      */
    7380       556198 :     *cp = '\0';
    7381       556198 :     return str;
    7382              : }
    7383              : 
    7384              : /*
    7385              :  * get_str_from_var_sci() -
    7386              :  *
    7387              :  *  Convert a var to a normalised scientific notation text representation.
    7388              :  *  This function does the heavy lifting for numeric_out_sci().
    7389              :  *
    7390              :  *  This notation has the general form a * 10^b, where a is known as the
    7391              :  *  "significand" and b is known as the "exponent".
    7392              :  *
    7393              :  *  Because we can't do superscript in ASCII (and because we want to copy
    7394              :  *  printf's behaviour) we display the exponent using E notation, with a
    7395              :  *  minimum of two exponent digits.
    7396              :  *
    7397              :  *  For example, the value 1234 could be output as 1.2e+03.
    7398              :  *
    7399              :  *  We assume that the exponent can fit into an int32.
    7400              :  *
    7401              :  *  rscale is the number of decimal digits desired after the decimal point in
    7402              :  *  the output, negative values will be treated as meaning zero.
    7403              :  *
    7404              :  *  Returns a palloc'd string.
    7405              :  */
    7406              : static char *
    7407          152 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7408              : {
    7409              :     int32       exponent;
    7410              :     NumericVar  tmp_var;
    7411              :     size_t      len;
    7412              :     char       *str;
    7413              :     char       *sig_out;
    7414              : 
    7415          152 :     if (rscale < 0)
    7416            0 :         rscale = 0;
    7417              : 
    7418              :     /*
    7419              :      * Determine the exponent of this number in normalised form.
    7420              :      *
    7421              :      * This is the exponent required to represent the number with only one
    7422              :      * significant digit before the decimal place.
    7423              :      */
    7424          152 :     if (var->ndigits > 0)
    7425              :     {
    7426          140 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7427              : 
    7428              :         /*
    7429              :          * Compensate for leading decimal zeroes in the first numeric digit by
    7430              :          * decrementing the exponent.
    7431              :          */
    7432          140 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7433              :     }
    7434              :     else
    7435              :     {
    7436              :         /*
    7437              :          * If var has no digits, then it must be zero.
    7438              :          *
    7439              :          * Zero doesn't technically have a meaningful exponent in normalised
    7440              :          * notation, but we just display the exponent as zero for consistency
    7441              :          * of output.
    7442              :          */
    7443           12 :         exponent = 0;
    7444              :     }
    7445              : 
    7446              :     /*
    7447              :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7448              :      * decimal digits in the process.
    7449              :      */
    7450          152 :     init_var(&tmp_var);
    7451              : 
    7452          152 :     power_ten_int(exponent, &tmp_var);
    7453          152 :     div_var(var, &tmp_var, &tmp_var, rscale, true, true);
    7454          152 :     sig_out = get_str_from_var(&tmp_var);
    7455              : 
    7456          152 :     free_var(&tmp_var);
    7457              : 
    7458              :     /*
    7459              :      * Allocate space for the result.
    7460              :      *
    7461              :      * In addition to the significand, we need room for the exponent
    7462              :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7463              :      * exponent itself, and of course the null terminator.
    7464              :      */
    7465          152 :     len = strlen(sig_out) + 13;
    7466          152 :     str = palloc(len);
    7467          152 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7468              : 
    7469          152 :     pfree(sig_out);
    7470              : 
    7471          152 :     return str;
    7472              : }
    7473              : 
    7474              : 
    7475              : /*
    7476              :  * numericvar_serialize - serialize NumericVar to binary format
    7477              :  *
    7478              :  * At variable level, no checks are performed on the weight or dscale, allowing
    7479              :  * us to pass around intermediate values with higher precision than supported
    7480              :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7481              :  * which use 16-bit integers for these fields.
    7482              :  */
    7483              : static void
    7484           61 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7485              : {
    7486              :     int         i;
    7487              : 
    7488           61 :     pq_sendint32(buf, var->ndigits);
    7489           61 :     pq_sendint32(buf, var->weight);
    7490           61 :     pq_sendint32(buf, var->sign);
    7491           61 :     pq_sendint32(buf, var->dscale);
    7492       425165 :     for (i = 0; i < var->ndigits; i++)
    7493       425104 :         pq_sendint16(buf, var->digits[i]);
    7494           61 : }
    7495              : 
    7496              : /*
    7497              :  * numericvar_deserialize - deserialize binary format to NumericVar
    7498              :  */
    7499              : static void
    7500           61 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7501              : {
    7502              :     int         len,
    7503              :                 i;
    7504              : 
    7505           61 :     len = pq_getmsgint(buf, sizeof(int32));
    7506              : 
    7507           61 :     alloc_var(var, len);        /* sets var->ndigits */
    7508              : 
    7509           61 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7510           61 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7511           61 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7512       425165 :     for (i = 0; i < len; i++)
    7513       425104 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7514           61 : }
    7515              : 
    7516              : 
    7517              : /*
    7518              :  * duplicate_numeric() - copy a packed-format Numeric
    7519              :  *
    7520              :  * This will handle NaN and Infinity cases.
    7521              :  */
    7522              : static Numeric
    7523        18817 : duplicate_numeric(Numeric num)
    7524              : {
    7525              :     Numeric     res;
    7526              : 
    7527        18817 :     res = (Numeric) palloc(VARSIZE(num));
    7528        18817 :     memcpy(res, num, VARSIZE(num));
    7529        18817 :     return res;
    7530              : }
    7531              : 
    7532              : /*
    7533              :  * make_result_safe() -
    7534              :  *
    7535              :  *  Create the packed db numeric format in palloc()'d memory from
    7536              :  *  a variable.  This will handle NaN and Infinity cases.
    7537              :  */
    7538              : static Numeric
    7539      2526119 : make_result_safe(const NumericVar *var, Node *escontext)
    7540              : {
    7541              :     Numeric     result;
    7542      2526119 :     NumericDigit *digits = var->digits;
    7543      2526119 :     int         weight = var->weight;
    7544      2526119 :     int         sign = var->sign;
    7545              :     int         n;
    7546              :     Size        len;
    7547              : 
    7548      2526119 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7549              :     {
    7550              :         /*
    7551              :          * Verify valid special value.  This could be just an Assert, perhaps,
    7552              :          * but it seems worthwhile to expend a few cycles to ensure that we
    7553              :          * never write any nonzero reserved bits to disk.
    7554              :          */
    7555         2205 :         if (!(sign == NUMERIC_NAN ||
    7556              :               sign == NUMERIC_PINF ||
    7557              :               sign == NUMERIC_NINF))
    7558            0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7559              : 
    7560         2205 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7561              : 
    7562         2205 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7563         2205 :         result->choice.n_header = sign;
    7564              :         /* the header word is all we need */
    7565              : 
    7566              :         dump_numeric("make_result()", result);
    7567         2205 :         return result;
    7568              :     }
    7569              : 
    7570      2523914 :     n = var->ndigits;
    7571              : 
    7572              :     /* truncate leading zeroes */
    7573      2523944 :     while (n > 0 && *digits == 0)
    7574              :     {
    7575           30 :         digits++;
    7576           30 :         weight--;
    7577           30 :         n--;
    7578              :     }
    7579              :     /* truncate trailing zeroes */
    7580      2576040 :     while (n > 0 && digits[n - 1] == 0)
    7581        52126 :         n--;
    7582              : 
    7583              :     /* If zero result, force to weight=0 and positive sign */
    7584      2523914 :     if (n == 0)
    7585              :     {
    7586        83969 :         weight = 0;
    7587        83969 :         sign = NUMERIC_POS;
    7588              :     }
    7589              : 
    7590              :     /* Build the result */
    7591      2523914 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7592              :     {
    7593      2522024 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7594      2522024 :         result = (Numeric) palloc(len);
    7595      2522024 :         SET_VARSIZE(result, len);
    7596      2522024 :         result->choice.n_short.n_header =
    7597              :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7598              :              : NUMERIC_SHORT)
    7599      2522024 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7600      2522024 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7601      2522024 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7602              :     }
    7603              :     else
    7604              :     {
    7605         1890 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7606         1890 :         result = (Numeric) palloc(len);
    7607         1890 :         SET_VARSIZE(result, len);
    7608         1890 :         result->choice.n_long.n_sign_dscale =
    7609         1890 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7610         1890 :         result->choice.n_long.n_weight = weight;
    7611              :     }
    7612              : 
    7613              :     Assert(NUMERIC_NDIGITS(result) == n);
    7614      2523914 :     if (n > 0)
    7615      2439945 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7616              : 
    7617              :     /* Check for overflow of int16 fields */
    7618      2523914 :     if (NUMERIC_WEIGHT(result) != weight ||
    7619      2523894 :         NUMERIC_DSCALE(result) != var->dscale)
    7620           20 :         ereturn(escontext, NULL,
    7621              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7622              :                  errmsg("value overflows numeric format")));
    7623              : 
    7624              :     dump_numeric("make_result()", result);
    7625      2523894 :     return result;
    7626              : }
    7627              : 
    7628              : 
    7629              : /*
    7630              :  * make_result() -
    7631              :  *
    7632              :  *  An interface to make_result_safe() without "escontext" argument.
    7633              :  */
    7634              : static Numeric
    7635      1504941 : make_result(const NumericVar *var)
    7636              : {
    7637      1504941 :     return make_result_safe(var, NULL);
    7638              : }
    7639              : 
    7640              : 
    7641              : /*
    7642              :  * apply_typmod() -
    7643              :  *
    7644              :  *  Do bounds checking and rounding according to the specified typmod.
    7645              :  *  Note that this is only applied to normal finite values.
    7646              :  *
    7647              :  * Returns true on success, false on failure (if escontext points to an
    7648              :  * ErrorSaveContext; otherwise errors are thrown).
    7649              :  */
    7650              : static bool
    7651       105575 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    7652              : {
    7653              :     int         precision;
    7654              :     int         scale;
    7655              :     int         maxdigits;
    7656              :     int         ddigits;
    7657              :     int         i;
    7658              : 
    7659              :     /* Do nothing if we have an invalid typmod */
    7660       105575 :     if (!is_valid_numeric_typmod(typmod))
    7661        86074 :         return true;
    7662              : 
    7663        19501 :     precision = numeric_typmod_precision(typmod);
    7664        19501 :     scale = numeric_typmod_scale(typmod);
    7665        19501 :     maxdigits = precision - scale;
    7666              : 
    7667              :     /* Round to target scale (and set var->dscale) */
    7668        19501 :     round_var(var, scale);
    7669              : 
    7670              :     /* but don't allow var->dscale to be negative */
    7671        19501 :     if (var->dscale < 0)
    7672          100 :         var->dscale = 0;
    7673              : 
    7674              :     /*
    7675              :      * Check for overflow - note we can't do this before rounding, because
    7676              :      * rounding could raise the weight.  Also note that the var's weight could
    7677              :      * be inflated by leading zeroes, which will be stripped before storage
    7678              :      * but perhaps might not have been yet. In any case, we must recognize a
    7679              :      * true zero, whose weight doesn't mean anything.
    7680              :      */
    7681        19501 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    7682        19501 :     if (ddigits > maxdigits)
    7683              :     {
    7684              :         /* Determine true weight; and check for all-zero result */
    7685         4289 :         for (i = 0; i < var->ndigits; i++)
    7686              :         {
    7687         4278 :             NumericDigit dig = var->digits[i];
    7688              : 
    7689         4278 :             if (dig)
    7690              :             {
    7691              :                 /* Adjust for any high-order decimal zero digits */
    7692              : #if DEC_DIGITS == 4
    7693         4278 :                 if (dig < 10)
    7694          206 :                     ddigits -= 3;
    7695         4072 :                 else if (dig < 100)
    7696          420 :                     ddigits -= 2;
    7697         3652 :                 else if (dig < 1000)
    7698         3640 :                     ddigits -= 1;
    7699              : #elif DEC_DIGITS == 2
    7700              :                 if (dig < 10)
    7701              :                     ddigits -= 1;
    7702              : #elif DEC_DIGITS == 1
    7703              :                 /* no adjustment */
    7704              : #else
    7705              : #error unsupported NBASE
    7706              : #endif
    7707         4278 :                 if (ddigits > maxdigits)
    7708           56 :                     ereturn(escontext, false,
    7709              :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7710              :                              errmsg("numeric field overflow"),
    7711              :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    7712              :                                        precision, scale,
    7713              :                     /* Display 10^0 as 1 */
    7714              :                                        maxdigits ? "10^" : "",
    7715              :                                        maxdigits ? maxdigits : 1
    7716              :                                        )));
    7717         4222 :                 break;
    7718              :             }
    7719            0 :             ddigits -= DEC_DIGITS;
    7720              :         }
    7721              :     }
    7722              : 
    7723        19445 :     return true;
    7724              : }
    7725              : 
    7726              : /*
    7727              :  * apply_typmod_special() -
    7728              :  *
    7729              :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    7730              :  *  For convenience of most callers, the value is presented in packed form.
    7731              :  *
    7732              :  * Returns true on success, false on failure (if escontext points to an
    7733              :  * ErrorSaveContext; otherwise errors are thrown).
    7734              :  */
    7735              : static bool
    7736         1297 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    7737              : {
    7738              :     int         precision;
    7739              :     int         scale;
    7740              : 
    7741              :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    7742              : 
    7743              :     /*
    7744              :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    7745              :      * but it's a longstanding behavior.  Inf is rejected if we have any
    7746              :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    7747              :      * any finite number of digits.
    7748              :      */
    7749         1297 :     if (NUMERIC_IS_NAN(num))
    7750          556 :         return true;
    7751              : 
    7752              :     /* Do nothing if we have a default typmod (-1) */
    7753          741 :     if (!is_valid_numeric_typmod(typmod))
    7754          729 :         return true;
    7755              : 
    7756           12 :     precision = numeric_typmod_precision(typmod);
    7757           12 :     scale = numeric_typmod_scale(typmod);
    7758              : 
    7759           12 :     ereturn(escontext, false,
    7760              :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7761              :              errmsg("numeric field overflow"),
    7762              :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    7763              :                        precision, scale)));
    7764              : }
    7765              : 
    7766              : 
    7767              : /*
    7768              :  * Convert numeric to int8, rounding if needed.
    7769              :  *
    7770              :  * If overflow, return false (no error is raised).  Return true if okay.
    7771              :  */
    7772              : static bool
    7773         6603 : numericvar_to_int64(const NumericVar *var, int64 *result)
    7774              : {
    7775              :     NumericDigit *digits;
    7776              :     int         ndigits;
    7777              :     int         weight;
    7778              :     int         i;
    7779              :     int64       val;
    7780              :     bool        neg;
    7781              :     NumericVar  rounded;
    7782              : 
    7783              :     /* Round to nearest integer */
    7784         6603 :     init_var(&rounded);
    7785         6603 :     set_var_from_var(var, &rounded);
    7786         6603 :     round_var(&rounded, 0);
    7787              : 
    7788              :     /* Check for zero input */
    7789         6603 :     strip_var(&rounded);
    7790         6603 :     ndigits = rounded.ndigits;
    7791         6603 :     if (ndigits == 0)
    7792              :     {
    7793          332 :         *result = 0;
    7794          332 :         free_var(&rounded);
    7795          332 :         return true;
    7796              :     }
    7797              : 
    7798              :     /*
    7799              :      * For input like 10000000000, we must treat stripped digits as real. So
    7800              :      * the loop assumes there are weight+1 digits before the decimal point.
    7801              :      */
    7802         6271 :     weight = rounded.weight;
    7803              :     Assert(weight >= 0 && ndigits <= weight + 1);
    7804              : 
    7805              :     /*
    7806              :      * Construct the result. To avoid issues with converting a value
    7807              :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    7808              :      * bit two's complement integer), accumulate value as a negative number.
    7809              :      */
    7810         6271 :     digits = rounded.digits;
    7811         6271 :     neg = (rounded.sign == NUMERIC_NEG);
    7812         6271 :     val = -digits[0];
    7813         8732 :     for (i = 1; i <= weight; i++)
    7814              :     {
    7815         2494 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    7816              :         {
    7817           21 :             free_var(&rounded);
    7818           21 :             return false;
    7819              :         }
    7820              : 
    7821         2473 :         if (i < ndigits)
    7822              :         {
    7823         2268 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    7824              :             {
    7825           12 :                 free_var(&rounded);
    7826           12 :                 return false;
    7827              :             }
    7828              :         }
    7829              :     }
    7830              : 
    7831         6238 :     free_var(&rounded);
    7832              : 
    7833         6238 :     if (!neg)
    7834              :     {
    7835         5696 :         if (unlikely(val == PG_INT64_MIN))
    7836           16 :             return false;
    7837         5680 :         val = -val;
    7838              :     }
    7839         6222 :     *result = val;
    7840              : 
    7841         6222 :     return true;
    7842              : }
    7843              : 
    7844              : /*
    7845              :  * Convert int8 value to numeric.
    7846              :  */
    7847              : static void
    7848      1262191 : int64_to_numericvar(int64 val, NumericVar *var)
    7849              : {
    7850              :     uint64      uval,
    7851              :                 newuval;
    7852              :     NumericDigit *ptr;
    7853              :     int         ndigits;
    7854              : 
    7855              :     /* int64 can require at most 19 decimal digits; add one for safety */
    7856      1262191 :     alloc_var(var, 20 / DEC_DIGITS);
    7857      1262191 :     if (val < 0)
    7858              :     {
    7859         1263 :         var->sign = NUMERIC_NEG;
    7860         1263 :         uval = pg_abs_s64(val);
    7861              :     }
    7862              :     else
    7863              :     {
    7864      1260928 :         var->sign = NUMERIC_POS;
    7865      1260928 :         uval = val;
    7866              :     }
    7867      1262191 :     var->dscale = 0;
    7868      1262191 :     if (val == 0)
    7869              :     {
    7870        19316 :         var->ndigits = 0;
    7871        19316 :         var->weight = 0;
    7872        19316 :         return;
    7873              :     }
    7874      1242875 :     ptr = var->digits + var->ndigits;
    7875      1242875 :     ndigits = 0;
    7876              :     do
    7877              :     {
    7878      1440325 :         ptr--;
    7879      1440325 :         ndigits++;
    7880      1440325 :         newuval = uval / NBASE;
    7881      1440325 :         *ptr = uval - newuval * NBASE;
    7882      1440325 :         uval = newuval;
    7883      1440325 :     } while (uval);
    7884      1242875 :     var->digits = ptr;
    7885      1242875 :     var->ndigits = ndigits;
    7886      1242875 :     var->weight = ndigits - 1;
    7887              : }
    7888              : 
    7889              : /*
    7890              :  * Convert numeric to uint64, rounding if needed.
    7891              :  *
    7892              :  * If overflow, return false (no error is raised).  Return true if okay.
    7893              :  */
    7894              : static bool
    7895           94 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    7896              : {
    7897              :     NumericDigit *digits;
    7898              :     int         ndigits;
    7899              :     int         weight;
    7900              :     int         i;
    7901              :     uint64      val;
    7902              :     NumericVar  rounded;
    7903              : 
    7904              :     /* Round to nearest integer */
    7905           94 :     init_var(&rounded);
    7906           94 :     set_var_from_var(var, &rounded);
    7907           94 :     round_var(&rounded, 0);
    7908              : 
    7909              :     /* Check for zero input */
    7910           94 :     strip_var(&rounded);
    7911           94 :     ndigits = rounded.ndigits;
    7912           94 :     if (ndigits == 0)
    7913              :     {
    7914           15 :         *result = 0;
    7915           15 :         free_var(&rounded);
    7916           15 :         return true;
    7917              :     }
    7918              : 
    7919              :     /* Check for negative input */
    7920           79 :     if (rounded.sign == NUMERIC_NEG)
    7921              :     {
    7922            8 :         free_var(&rounded);
    7923            8 :         return false;
    7924              :     }
    7925              : 
    7926              :     /*
    7927              :      * For input like 10000000000, we must treat stripped digits as real. So
    7928              :      * the loop assumes there are weight+1 digits before the decimal point.
    7929              :      */
    7930           71 :     weight = rounded.weight;
    7931              :     Assert(weight >= 0 && ndigits <= weight + 1);
    7932              : 
    7933              :     /* Construct the result */
    7934           71 :     digits = rounded.digits;
    7935           71 :     val = digits[0];
    7936          205 :     for (i = 1; i <= weight; i++)
    7937              :     {
    7938          142 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    7939              :         {
    7940            0 :             free_var(&rounded);
    7941            0 :             return false;
    7942              :         }
    7943              : 
    7944          142 :         if (i < ndigits)
    7945              :         {
    7946          142 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    7947              :             {
    7948            8 :                 free_var(&rounded);
    7949            8 :                 return false;
    7950              :             }
    7951              :         }
    7952              :     }
    7953              : 
    7954           63 :     free_var(&rounded);
    7955              : 
    7956           63 :     *result = val;
    7957              : 
    7958           63 :     return true;
    7959              : }
    7960              : 
    7961              : /*
    7962              :  * Convert 128 bit integer to numeric.
    7963              :  */
    7964              : static void
    7965         6293 : int128_to_numericvar(INT128 val, NumericVar *var)
    7966              : {
    7967              :     int         sign;
    7968              :     NumericDigit *ptr;
    7969              :     int         ndigits;
    7970              :     int32       dig;
    7971              : 
    7972              :     /* int128 can require at most 39 decimal digits; add one for safety */
    7973         6293 :     alloc_var(var, 40 / DEC_DIGITS);
    7974         6293 :     sign = int128_sign(val);
    7975         6293 :     var->sign = sign < 0 ? NUMERIC_NEG : NUMERIC_POS;
    7976         6293 :     var->dscale = 0;
    7977         6293 :     if (sign == 0)
    7978              :     {
    7979          143 :         var->ndigits = 0;
    7980          143 :         var->weight = 0;
    7981          143 :         return;
    7982              :     }
    7983         6150 :     ptr = var->digits + var->ndigits;
    7984         6150 :     ndigits = 0;
    7985              :     do
    7986              :     {
    7987        33056 :         ptr--;
    7988        33056 :         ndigits++;
    7989        33056 :         int128_div_mod_int32(&val, NBASE, &dig);
    7990        33056 :         *ptr = (NumericDigit) abs(dig);
    7991        33056 :     } while (!int128_is_zero(val));
    7992         6150 :     var->digits = ptr;
    7993         6150 :     var->ndigits = ndigits;
    7994         6150 :     var->weight = ndigits - 1;
    7995              : }
    7996              : 
    7997              : /*
    7998              :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    7999              :  */
    8000              : static double
    8001          359 : numericvar_to_double_no_overflow(const NumericVar *var)
    8002              : {
    8003              :     char       *tmp;
    8004              :     double      val;
    8005              :     char       *endptr;
    8006              : 
    8007          359 :     tmp = get_str_from_var(var);
    8008              : 
    8009              :     /* unlike float8in, we ignore ERANGE from strtod */
    8010          359 :     val = strtod(tmp, &endptr);
    8011          359 :     if (*endptr != '\0')
    8012              :     {
    8013              :         /* shouldn't happen ... */
    8014            0 :         ereport(ERROR,
    8015              :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8016              :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8017              :                         "double precision", tmp)));
    8018              :     }
    8019              : 
    8020          359 :     pfree(tmp);
    8021              : 
    8022          359 :     return val;
    8023              : }
    8024              : 
    8025              : 
    8026              : /*
    8027              :  * cmp_var() -
    8028              :  *
    8029              :  *  Compare two values on variable level.  We assume zeroes have been
    8030              :  *  truncated to no digits.
    8031              :  */
    8032              : static int
    8033       114439 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8034              : {
    8035       228878 :     return cmp_var_common(var1->digits, var1->ndigits,
    8036       114439 :                           var1->weight, var1->sign,
    8037       114439 :                           var2->digits, var2->ndigits,
    8038       114439 :                           var2->weight, var2->sign);
    8039              : }
    8040              : 
    8041              : /*
    8042              :  * cmp_var_common() -
    8043              :  *
    8044              :  *  Main routine of cmp_var(). This function can be used by both
    8045              :  *  NumericVar and Numeric.
    8046              :  */
    8047              : static int
    8048     18496004 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8049              :                int var1weight, int var1sign,
    8050              :                const NumericDigit *var2digits, int var2ndigits,
    8051              :                int var2weight, int var2sign)
    8052              : {
    8053     18496004 :     if (var1ndigits == 0)
    8054              :     {
    8055       425935 :         if (var2ndigits == 0)
    8056       333902 :             return 0;
    8057        92033 :         if (var2sign == NUMERIC_NEG)
    8058         2178 :             return 1;
    8059        89855 :         return -1;
    8060              :     }
    8061     18070069 :     if (var2ndigits == 0)
    8062              :     {
    8063        66397 :         if (var1sign == NUMERIC_POS)
    8064        62662 :             return 1;
    8065         3735 :         return -1;
    8066              :     }
    8067              : 
    8068     18003672 :     if (var1sign == NUMERIC_POS)
    8069              :     {
    8070     17954501 :         if (var2sign == NUMERIC_NEG)
    8071        14477 :             return 1;
    8072     17940024 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8073              :                               var2digits, var2ndigits, var2weight);
    8074              :     }
    8075              : 
    8076        49171 :     if (var2sign == NUMERIC_POS)
    8077        14754 :         return -1;
    8078              : 
    8079        34417 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8080              :                           var1digits, var1ndigits, var1weight);
    8081              : }
    8082              : 
    8083              : 
    8084              : /*
    8085              :  * add_var() -
    8086              :  *
    8087              :  *  Full version of add functionality on variable level (handling signs).
    8088              :  *  result might point to one of the operands too without danger.
    8089              :  */
    8090              : static void
    8091       414476 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8092              : {
    8093              :     /*
    8094              :      * Decide on the signs of the two variables what to do
    8095              :      */
    8096       414476 :     if (var1->sign == NUMERIC_POS)
    8097              :     {
    8098       413221 :         if (var2->sign == NUMERIC_POS)
    8099              :         {
    8100              :             /*
    8101              :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8102              :              */
    8103       279626 :             add_abs(var1, var2, result);
    8104       279626 :             result->sign = NUMERIC_POS;
    8105              :         }
    8106              :         else
    8107              :         {
    8108              :             /*
    8109              :              * var1 is positive, var2 is negative Must compare absolute values
    8110              :              */
    8111       133595 :             switch (cmp_abs(var1, var2))
    8112              :             {
    8113          123 :                 case 0:
    8114              :                     /* ----------
    8115              :                      * ABS(var1) == ABS(var2)
    8116              :                      * result = ZERO
    8117              :                      * ----------
    8118              :                      */
    8119          123 :                     zero_var(result);
    8120          123 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8121          123 :                     break;
    8122              : 
    8123       124291 :                 case 1:
    8124              :                     /* ----------
    8125              :                      * ABS(var1) > ABS(var2)
    8126              :                      * result = +(ABS(var1) - ABS(var2))
    8127              :                      * ----------
    8128              :                      */
    8129       124291 :                     sub_abs(var1, var2, result);
    8130       124291 :                     result->sign = NUMERIC_POS;
    8131       124291 :                     break;
    8132              : 
    8133         9181 :                 case -1:
    8134              :                     /* ----------
    8135              :                      * ABS(var1) < ABS(var2)
    8136              :                      * result = -(ABS(var2) - ABS(var1))
    8137              :                      * ----------
    8138              :                      */
    8139         9181 :                     sub_abs(var2, var1, result);
    8140         9181 :                     result->sign = NUMERIC_NEG;
    8141         9181 :                     break;
    8142              :             }
    8143              :         }
    8144              :     }
    8145              :     else
    8146              :     {
    8147         1255 :         if (var2->sign == NUMERIC_POS)
    8148              :         {
    8149              :             /* ----------
    8150              :              * var1 is negative, var2 is positive
    8151              :              * Must compare absolute values
    8152              :              * ----------
    8153              :              */
    8154          318 :             switch (cmp_abs(var1, var2))
    8155              :             {
    8156           20 :                 case 0:
    8157              :                     /* ----------
    8158              :                      * ABS(var1) == ABS(var2)
    8159              :                      * result = ZERO
    8160              :                      * ----------
    8161              :                      */
    8162           20 :                     zero_var(result);
    8163           20 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8164           20 :                     break;
    8165              : 
    8166          197 :                 case 1:
    8167              :                     /* ----------
    8168              :                      * ABS(var1) > ABS(var2)
    8169              :                      * result = -(ABS(var1) - ABS(var2))
    8170              :                      * ----------
    8171              :                      */
    8172          197 :                     sub_abs(var1, var2, result);
    8173          197 :                     result->sign = NUMERIC_NEG;
    8174          197 :                     break;
    8175              : 
    8176          101 :                 case -1:
    8177              :                     /* ----------
    8178              :                      * ABS(var1) < ABS(var2)
    8179              :                      * result = +(ABS(var2) - ABS(var1))
    8180              :                      * ----------
    8181              :                      */
    8182          101 :                     sub_abs(var2, var1, result);
    8183          101 :                     result->sign = NUMERIC_POS;
    8184          101 :                     break;
    8185              :             }
    8186              :         }
    8187              :         else
    8188              :         {
    8189              :             /* ----------
    8190              :              * Both are negative
    8191              :              * result = -(ABS(var1) + ABS(var2))
    8192              :              * ----------
    8193              :              */
    8194          937 :             add_abs(var1, var2, result);
    8195          937 :             result->sign = NUMERIC_NEG;
    8196              :         }
    8197              :     }
    8198       414476 : }
    8199              : 
    8200              : 
    8201              : /*
    8202              :  * sub_var() -
    8203              :  *
    8204              :  *  Full version of sub functionality on variable level (handling signs).
    8205              :  *  result might point to one of the operands too without danger.
    8206              :  */
    8207              : static void
    8208       351114 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8209              : {
    8210              :     /*
    8211              :      * Decide on the signs of the two variables what to do
    8212              :      */
    8213       351114 :     if (var1->sign == NUMERIC_POS)
    8214              :     {
    8215       350505 :         if (var2->sign == NUMERIC_NEG)
    8216              :         {
    8217              :             /* ----------
    8218              :              * var1 is positive, var2 is negative
    8219              :              * result = +(ABS(var1) + ABS(var2))
    8220              :              * ----------
    8221              :              */
    8222        18797 :             add_abs(var1, var2, result);
    8223        18797 :             result->sign = NUMERIC_POS;
    8224              :         }
    8225              :         else
    8226              :         {
    8227              :             /* ----------
    8228              :              * Both are positive
    8229              :              * Must compare absolute values
    8230              :              * ----------
    8231              :              */
    8232       331708 :             switch (cmp_abs(var1, var2))
    8233              :             {
    8234        29543 :                 case 0:
    8235              :                     /* ----------
    8236              :                      * ABS(var1) == ABS(var2)
    8237              :                      * result = ZERO
    8238              :                      * ----------
    8239              :                      */
    8240        29543 :                     zero_var(result);
    8241        29543 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8242        29543 :                     break;
    8243              : 
    8244       294372 :                 case 1:
    8245              :                     /* ----------
    8246              :                      * ABS(var1) > ABS(var2)
    8247              :                      * result = +(ABS(var1) - ABS(var2))
    8248              :                      * ----------
    8249              :                      */
    8250       294372 :                     sub_abs(var1, var2, result);
    8251       294372 :                     result->sign = NUMERIC_POS;
    8252       294372 :                     break;
    8253              : 
    8254         7793 :                 case -1:
    8255              :                     /* ----------
    8256              :                      * ABS(var1) < ABS(var2)
    8257              :                      * result = -(ABS(var2) - ABS(var1))
    8258              :                      * ----------
    8259              :                      */
    8260         7793 :                     sub_abs(var2, var1, result);
    8261         7793 :                     result->sign = NUMERIC_NEG;
    8262         7793 :                     break;
    8263              :             }
    8264              :         }
    8265              :     }
    8266              :     else
    8267              :     {
    8268          609 :         if (var2->sign == NUMERIC_NEG)
    8269              :         {
    8270              :             /* ----------
    8271              :              * Both are negative
    8272              :              * Must compare absolute values
    8273              :              * ----------
    8274              :              */
    8275          304 :             switch (cmp_abs(var1, var2))
    8276              :             {
    8277          110 :                 case 0:
    8278              :                     /* ----------
    8279              :                      * ABS(var1) == ABS(var2)
    8280              :                      * result = ZERO
    8281              :                      * ----------
    8282              :                      */
    8283          110 :                     zero_var(result);
    8284          110 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8285          110 :                     break;
    8286              : 
    8287          162 :                 case 1:
    8288              :                     /* ----------
    8289              :                      * ABS(var1) > ABS(var2)
    8290              :                      * result = -(ABS(var1) - ABS(var2))
    8291              :                      * ----------
    8292              :                      */
    8293          162 :                     sub_abs(var1, var2, result);
    8294          162 :                     result->sign = NUMERIC_NEG;
    8295          162 :                     break;
    8296              : 
    8297           32 :                 case -1:
    8298              :                     /* ----------
    8299              :                      * ABS(var1) < ABS(var2)
    8300              :                      * result = +(ABS(var2) - ABS(var1))
    8301              :                      * ----------
    8302              :                      */
    8303           32 :                     sub_abs(var2, var1, result);
    8304           32 :                     result->sign = NUMERIC_POS;
    8305           32 :                     break;
    8306              :             }
    8307              :         }
    8308              :         else
    8309              :         {
    8310              :             /* ----------
    8311              :              * var1 is negative, var2 is positive
    8312              :              * result = -(ABS(var1) + ABS(var2))
    8313              :              * ----------
    8314              :              */
    8315          305 :             add_abs(var1, var2, result);
    8316          305 :             result->sign = NUMERIC_NEG;
    8317              :         }
    8318              :     }
    8319       351114 : }
    8320              : 
    8321              : 
    8322              : /*
    8323              :  * mul_var() -
    8324              :  *
    8325              :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8326              :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8327              :  */
    8328              : static void
    8329       795584 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8330              :         int rscale)
    8331              : {
    8332              :     int         res_ndigits;
    8333              :     int         res_ndigitpairs;
    8334              :     int         res_sign;
    8335              :     int         res_weight;
    8336              :     int         pair_offset;
    8337              :     int         maxdigits;
    8338              :     int         maxdigitpairs;
    8339              :     uint64     *dig,
    8340              :                *dig_i1_off;
    8341              :     uint64      maxdig;
    8342              :     uint64      carry;
    8343              :     uint64      newdig;
    8344              :     int         var1ndigits;
    8345              :     int         var2ndigits;
    8346              :     int         var1ndigitpairs;
    8347              :     int         var2ndigitpairs;
    8348              :     NumericDigit *var1digits;
    8349              :     NumericDigit *var2digits;
    8350              :     uint32      var1digitpair;
    8351              :     uint32     *var2digitpairs;
    8352              :     NumericDigit *res_digits;
    8353              :     int         i,
    8354              :                 i1,
    8355              :                 i2,
    8356              :                 i2limit;
    8357              : 
    8358              :     /*
    8359              :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8360              :      * performance because the inner multiplication loop is much simpler than
    8361              :      * the outer loop, so it's better to have a smaller number of iterations
    8362              :      * of the outer loop.  This also reduces the number of times that the
    8363              :      * accumulator array needs to be normalized.
    8364              :      */
    8365       795584 :     if (var1->ndigits > var2->ndigits)
    8366              :     {
    8367        10365 :         const NumericVar *tmp = var1;
    8368              : 
    8369        10365 :         var1 = var2;
    8370        10365 :         var2 = tmp;
    8371              :     }
    8372              : 
    8373              :     /* copy these values into local vars for speed in inner loop */
    8374       795584 :     var1ndigits = var1->ndigits;
    8375       795584 :     var2ndigits = var2->ndigits;
    8376       795584 :     var1digits = var1->digits;
    8377       795584 :     var2digits = var2->digits;
    8378              : 
    8379       795584 :     if (var1ndigits == 0)
    8380              :     {
    8381              :         /* one or both inputs is zero; so is result */
    8382         1959 :         zero_var(result);
    8383         1959 :         result->dscale = rscale;
    8384         1959 :         return;
    8385              :     }
    8386              : 
    8387              :     /*
    8388              :      * If var1 has 1-6 digits and the exact result was requested, delegate to
    8389              :      * mul_var_short() which uses a faster direct multiplication algorithm.
    8390              :      */
    8391       793625 :     if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
    8392              :     {
    8393       772956 :         mul_var_short(var1, var2, result);
    8394       772956 :         return;
    8395              :     }
    8396              : 
    8397              :     /* Determine result sign */
    8398        20669 :     if (var1->sign == var2->sign)
    8399        19390 :         res_sign = NUMERIC_POS;
    8400              :     else
    8401         1279 :         res_sign = NUMERIC_NEG;
    8402              : 
    8403              :     /*
    8404              :      * Determine the number of result digits to compute and the (maximum
    8405              :      * possible) result weight.  If the exact result would have more than
    8406              :      * rscale fractional digits, truncate the computation with
    8407              :      * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
    8408              :      * only contribute to the right of that.  (This will give the exact
    8409              :      * rounded-to-rscale answer unless carries out of the ignored positions
    8410              :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8411              :      *
    8412              :      * Note: an exact computation could not produce more than var1ndigits +
    8413              :      * var2ndigits digits, but we allocate at least one extra output digit in
    8414              :      * case rscale-driven rounding produces a carry out of the highest exact
    8415              :      * digit.
    8416              :      *
    8417              :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    8418              :      * actually process the input digits in pairs, producing a base-NBASE^2
    8419              :      * intermediate result.  This significantly improves performance, since
    8420              :      * schoolbook multiplication is O(N^2) in the number of input digits, and
    8421              :      * working in base NBASE^2 effectively halves "N".
    8422              :      *
    8423              :      * Note: in a truncated computation, we must compute at least one extra
    8424              :      * output digit to ensure that all the guard digits are fully computed.
    8425              :      */
    8426              :     /* digit pairs in each input */
    8427        20669 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    8428        20669 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    8429              : 
    8430              :     /* digits in exact result */
    8431        20669 :     res_ndigits = var1ndigits + var2ndigits;
    8432              : 
    8433              :     /* digit pairs in exact result with at least one extra output digit */
    8434        20669 :     res_ndigitpairs = res_ndigits / 2 + 1;
    8435              : 
    8436              :     /* pair offset to align result to end of dig[] */
    8437        20669 :     pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
    8438              : 
    8439              :     /* maximum possible result weight (odd-length inputs shifted up below) */
    8440        20669 :     res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
    8441        20669 :         res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
    8442              : 
    8443              :     /* rscale-based truncation with at least one extra output digit */
    8444        20669 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8445              :         MUL_GUARD_DIGITS;
    8446        20669 :     maxdigitpairs = maxdigits / 2 + 1;
    8447              : 
    8448        20669 :     res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
    8449        20669 :     res_ndigits = 2 * res_ndigitpairs;
    8450              : 
    8451              :     /*
    8452              :      * In the computation below, digit pair i1 of var1 and digit pair i2 of
    8453              :      * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
    8454              :      * input digit pairs with index >= res_ndigitpairs - pair_offset don't
    8455              :      * contribute to the result, and can be ignored.
    8456              :      */
    8457        20669 :     if (res_ndigitpairs <= pair_offset)
    8458              :     {
    8459              :         /* All input digits will be ignored; so result is zero */
    8460           10 :         zero_var(result);
    8461           10 :         result->dscale = rscale;
    8462           10 :         return;
    8463              :     }
    8464        20659 :     var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
    8465        20659 :     var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
    8466              : 
    8467              :     /*
    8468              :      * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
    8469              :      * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
    8470              :      * headroom to avoid normalizing carries immediately.
    8471              :      *
    8472              :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8473              :      * threatens to exceed PG_UINT64_MAX, we take the time to propagate
    8474              :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    8475              :      * during the carry propagation passes either.  The carry values could be
    8476              :      * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
    8477              :      * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
    8478              :      *
    8479              :      * To avoid overflow in maxdig itself, it actually represents the maximum
    8480              :      * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
    8481              :      * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
    8482              :      *
    8483              :      * The conversion of var1 to base NBASE^2 is done on the fly, as each new
    8484              :      * digit is required.  The digits of var2 are converted upfront, and
    8485              :      * stored at the end of dig[].  To avoid loss of precision, the input
    8486              :      * digits are aligned with the start of digit pair array, effectively
    8487              :      * shifting them up (multiplying by NBASE) if the inputs have an odd
    8488              :      * number of NBASE digits.
    8489              :      */
    8490        20659 :     dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
    8491              :                             var2ndigitpairs * sizeof(uint32));
    8492              : 
    8493              :     /* convert var2 to base NBASE^2, shifting up if its length is odd */
    8494        20659 :     var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
    8495              : 
    8496      1048389 :     for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
    8497      1027730 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8498              : 
    8499        20659 :     if (2 * i2 + 1 < var2ndigits)
    8500        14659 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8501              :     else
    8502         6000 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
    8503              : 
    8504              :     /*
    8505              :      * Start by multiplying var2 by the least significant contributing digit
    8506              :      * pair from var1, storing the results at the end of dig[], and filling
    8507              :      * the leading digits with zeros.
    8508              :      *
    8509              :      * The loop here is the same as the inner loop below, except that we set
    8510              :      * the results in dig[], rather than adding to them.  This is the
    8511              :      * performance bottleneck for multiplication, so we want to keep it simple
    8512              :      * enough so that it can be auto-vectorized.  Accordingly, process the
    8513              :      * digits left-to-right even though schoolbook multiplication would
    8514              :      * suggest right-to-left.  Since we aren't propagating carries in this
    8515              :      * loop, the order does not matter.
    8516              :      */
    8517        20659 :     i1 = var1ndigitpairs - 1;
    8518        20659 :     if (2 * i1 + 1 < var1ndigits)
    8519         9183 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8520              :     else
    8521        11476 :         var1digitpair = var1digits[2 * i1] * NBASE;
    8522        20659 :     maxdig = var1digitpair;
    8523              : 
    8524        20659 :     i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8525        20659 :     dig_i1_off = &dig[i1 + pair_offset];
    8526              : 
    8527        20659 :     memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
    8528       930539 :     for (i2 = 0; i2 < i2limit; i2++)
    8529       909880 :         dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
    8530              : 
    8531              :     /*
    8532              :      * Next, multiply var2 by the remaining digit pairs from var1, adding the
    8533              :      * results to dig[] at the appropriate offsets, and normalizing whenever
    8534              :      * there is a risk of any dig[] entry overflowing.
    8535              :      */
    8536      1012436 :     for (i1 = i1 - 1; i1 >= 0; i1--)
    8537              :     {
    8538       991777 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8539       991777 :         if (var1digitpair == 0)
    8540       786344 :             continue;
    8541              : 
    8542              :         /* Time to normalize? */
    8543       205433 :         maxdig += var1digitpair;
    8544       205433 :         if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
    8545              :         {
    8546              :             /* Yes, do it (to base NBASE^2) */
    8547           21 :             carry = 0;
    8548        84074 :             for (i = res_ndigitpairs - 1; i >= 0; i--)
    8549              :             {
    8550        84053 :                 newdig = dig[i] + carry;
    8551        84053 :                 if (newdig >= NBASE_SQR)
    8552              :                 {
    8553        80719 :                     carry = newdig / NBASE_SQR;
    8554        80719 :                     newdig -= carry * NBASE_SQR;
    8555              :                 }
    8556              :                 else
    8557         3334 :                     carry = 0;
    8558        84053 :                 dig[i] = newdig;
    8559              :             }
    8560              :             Assert(carry == 0);
    8561              :             /* Reset maxdig to indicate new worst-case */
    8562           21 :             maxdig = 1 + var1digitpair;
    8563              :         }
    8564              : 
    8565              :         /* Multiply and add */
    8566       205433 :         i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8567       205433 :         dig_i1_off = &dig[i1 + pair_offset];
    8568              : 
    8569     87005259 :         for (i2 = 0; i2 < i2limit; i2++)
    8570     86799826 :             dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
    8571              :     }
    8572              : 
    8573              :     /*
    8574              :      * Now we do a final carry propagation pass to normalize back to base
    8575              :      * NBASE^2, and construct the base-NBASE result digits.  Note that this is
    8576              :      * still done at full precision w/guard digits.
    8577              :      */
    8578        20659 :     alloc_var(result, res_ndigits);
    8579        20659 :     res_digits = result->digits;
    8580        20659 :     carry = 0;
    8581      1946324 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    8582              :     {
    8583      1925665 :         newdig = dig[i] + carry;
    8584      1925665 :         if (newdig >= NBASE_SQR)
    8585              :         {
    8586       290140 :             carry = newdig / NBASE_SQR;
    8587       290140 :             newdig -= carry * NBASE_SQR;
    8588              :         }
    8589              :         else
    8590      1635525 :             carry = 0;
    8591      1925665 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    8592      1925665 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    8593              :     }
    8594              :     Assert(carry == 0);
    8595              : 
    8596        20659 :     pfree(dig);
    8597              : 
    8598              :     /*
    8599              :      * Finally, round the result to the requested precision.
    8600              :      */
    8601        20659 :     result->weight = res_weight;
    8602        20659 :     result->sign = res_sign;
    8603              : 
    8604              :     /* Round to target rscale (and set result->dscale) */
    8605        20659 :     round_var(result, rscale);
    8606              : 
    8607              :     /* Strip leading and trailing zeroes */
    8608        20659 :     strip_var(result);
    8609              : }
    8610              : 
    8611              : 
    8612              : /*
    8613              :  * mul_var_short() -
    8614              :  *
    8615              :  *  Special-case multiplication function used when var1 has 1-6 digits, var2
    8616              :  *  has at least as many digits as var1, and the exact product var1 * var2 is
    8617              :  *  requested.
    8618              :  */
    8619              : static void
    8620       772956 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
    8621              :               NumericVar *result)
    8622              : {
    8623       772956 :     int         var1ndigits = var1->ndigits;
    8624       772956 :     int         var2ndigits = var2->ndigits;
    8625       772956 :     NumericDigit *var1digits = var1->digits;
    8626       772956 :     NumericDigit *var2digits = var2->digits;
    8627              :     int         res_sign;
    8628              :     int         res_weight;
    8629              :     int         res_ndigits;
    8630              :     NumericDigit *res_buf;
    8631              :     NumericDigit *res_digits;
    8632       772956 :     uint32      carry = 0;
    8633              :     uint32      term;
    8634              : 
    8635              :     /* Check preconditions */
    8636              :     Assert(var1ndigits >= 1);
    8637              :     Assert(var1ndigits <= 6);
    8638              :     Assert(var2ndigits >= var1ndigits);
    8639              : 
    8640              :     /*
    8641              :      * Determine the result sign, weight, and number of digits to calculate.
    8642              :      * The weight figured here is correct if the product has no leading zero
    8643              :      * digits; otherwise strip_var() will fix things up.  Note that, unlike
    8644              :      * mul_var(), we do not need to allocate an extra output digit, because we
    8645              :      * are not rounding here.
    8646              :      */
    8647       772956 :     if (var1->sign == var2->sign)
    8648       772149 :         res_sign = NUMERIC_POS;
    8649              :     else
    8650          807 :         res_sign = NUMERIC_NEG;
    8651       772956 :     res_weight = var1->weight + var2->weight + 1;
    8652       772956 :     res_ndigits = var1ndigits + var2ndigits;
    8653              : 
    8654              :     /* Allocate result digit array */
    8655       772956 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    8656       772956 :     res_buf[0] = 0;             /* spare digit for later rounding */
    8657       772956 :     res_digits = res_buf + 1;
    8658              : 
    8659              :     /*
    8660              :      * Compute the result digits in reverse, in one pass, propagating the
    8661              :      * carry up as we go.  The i'th result digit consists of the sum of the
    8662              :      * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
    8663              :      */
    8664              : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
    8665              : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
    8666              : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
    8667              : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
    8668              : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
    8669              : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
    8670              : 
    8671       772956 :     switch (var1ndigits)
    8672              :     {
    8673       768811 :         case 1:
    8674              :             /* ---------
    8675              :              * 1-digit case:
    8676              :              *      var1ndigits = 1
    8677              :              *      var2ndigits >= 1
    8678              :              *      res_ndigits = var2ndigits + 1
    8679              :              * ----------
    8680              :              */
    8681      2406163 :             for (int i = var2ndigits - 1; i >= 0; i--)
    8682              :             {
    8683      1637352 :                 term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
    8684      1637352 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8685      1637352 :                 carry = term / NBASE;
    8686              :             }
    8687       768811 :             res_digits[0] = (NumericDigit) carry;
    8688       768811 :             break;
    8689              : 
    8690          519 :         case 2:
    8691              :             /* ---------
    8692              :              * 2-digit case:
    8693              :              *      var1ndigits = 2
    8694              :              *      var2ndigits >= 2
    8695              :              *      res_ndigits = var2ndigits + 2
    8696              :              * ----------
    8697              :              */
    8698              :             /* last result digit and carry */
    8699          519 :             term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
    8700          519 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8701          519 :             carry = term / NBASE;
    8702              : 
    8703              :             /* remaining digits, except for the first two */
    8704         1573 :             for (int i = var2ndigits - 1; i >= 1; i--)
    8705              :             {
    8706         1054 :                 term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
    8707         1054 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8708         1054 :                 carry = term / NBASE;
    8709              :             }
    8710          519 :             break;
    8711              : 
    8712          146 :         case 3:
    8713              :             /* ---------
    8714              :              * 3-digit case:
    8715              :              *      var1ndigits = 3
    8716              :              *      var2ndigits >= 3
    8717              :              *      res_ndigits = var2ndigits + 3
    8718              :              * ----------
    8719              :              */
    8720              :             /* last two result digits */
    8721          146 :             term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
    8722          146 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8723          146 :             carry = term / NBASE;
    8724              : 
    8725          146 :             term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8726          146 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8727          146 :             carry = term / NBASE;
    8728              : 
    8729              :             /* remaining digits, except for the first three */
    8730          387 :             for (int i = var2ndigits - 1; i >= 2; i--)
    8731              :             {
    8732          241 :                 term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
    8733          241 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8734          241 :                 carry = term / NBASE;
    8735              :             }
    8736          146 :             break;
    8737              : 
    8738         2888 :         case 4:
    8739              :             /* ---------
    8740              :              * 4-digit case:
    8741              :              *      var1ndigits = 4
    8742              :              *      var2ndigits >= 4
    8743              :              *      res_ndigits = var2ndigits + 4
    8744              :              * ----------
    8745              :              */
    8746              :             /* last three result digits */
    8747         2888 :             term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
    8748         2888 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8749         2888 :             carry = term / NBASE;
    8750              : 
    8751         2888 :             term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    8752         2888 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8753         2888 :             carry = term / NBASE;
    8754              : 
    8755         2888 :             term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8756         2888 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    8757         2888 :             carry = term / NBASE;
    8758              : 
    8759              :             /* remaining digits, except for the first four */
    8760         8058 :             for (int i = var2ndigits - 1; i >= 3; i--)
    8761              :             {
    8762         5170 :                 term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
    8763         5170 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8764         5170 :                 carry = term / NBASE;
    8765              :             }
    8766         2888 :             break;
    8767              : 
    8768           91 :         case 5:
    8769              :             /* ---------
    8770              :              * 5-digit case:
    8771              :              *      var1ndigits = 5
    8772              :              *      var2ndigits >= 5
    8773              :              *      res_ndigits = var2ndigits + 5
    8774              :              * ----------
    8775              :              */
    8776              :             /* last four result digits */
    8777           91 :             term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
    8778           91 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8779           91 :             carry = term / NBASE;
    8780              : 
    8781           91 :             term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    8782           91 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8783           91 :             carry = term / NBASE;
    8784              : 
    8785           91 :             term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    8786           91 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    8787           91 :             carry = term / NBASE;
    8788              : 
    8789           91 :             term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8790           91 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    8791           91 :             carry = term / NBASE;
    8792              : 
    8793              :             /* remaining digits, except for the first five */
    8794          242 :             for (int i = var2ndigits - 1; i >= 4; i--)
    8795              :             {
    8796          151 :                 term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
    8797          151 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8798          151 :                 carry = term / NBASE;
    8799              :             }
    8800           91 :             break;
    8801              : 
    8802          501 :         case 6:
    8803              :             /* ---------
    8804              :              * 6-digit case:
    8805              :              *      var1ndigits = 6
    8806              :              *      var2ndigits >= 6
    8807              :              *      res_ndigits = var2ndigits + 6
    8808              :              * ----------
    8809              :              */
    8810              :             /* last five result digits */
    8811          501 :             term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
    8812          501 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8813          501 :             carry = term / NBASE;
    8814              : 
    8815          501 :             term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
    8816          501 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8817          501 :             carry = term / NBASE;
    8818              : 
    8819          501 :             term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    8820          501 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    8821          501 :             carry = term / NBASE;
    8822              : 
    8823          501 :             term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    8824          501 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    8825          501 :             carry = term / NBASE;
    8826              : 
    8827          501 :             term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8828          501 :             res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
    8829          501 :             carry = term / NBASE;
    8830              : 
    8831              :             /* remaining digits, except for the first six */
    8832         1400 :             for (int i = var2ndigits - 1; i >= 5; i--)
    8833              :             {
    8834          899 :                 term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
    8835          899 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8836          899 :                 carry = term / NBASE;
    8837              :             }
    8838          501 :             break;
    8839              :     }
    8840              : 
    8841              :     /*
    8842              :      * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
    8843              :      * significant result digits.
    8844              :      */
    8845       772956 :     switch (var1ndigits)
    8846              :     {
    8847          501 :         case 6:
    8848          501 :             term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
    8849          501 :             res_digits[5] = (NumericDigit) (term % NBASE);
    8850          501 :             carry = term / NBASE;
    8851              :             pg_fallthrough;
    8852          592 :         case 5:
    8853          592 :             term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
    8854          592 :             res_digits[4] = (NumericDigit) (term % NBASE);
    8855          592 :             carry = term / NBASE;
    8856              :             pg_fallthrough;
    8857         3480 :         case 4:
    8858         3480 :             term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
    8859         3480 :             res_digits[3] = (NumericDigit) (term % NBASE);
    8860         3480 :             carry = term / NBASE;
    8861              :             pg_fallthrough;
    8862         3626 :         case 3:
    8863         3626 :             term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
    8864         3626 :             res_digits[2] = (NumericDigit) (term % NBASE);
    8865         3626 :             carry = term / NBASE;
    8866              :             pg_fallthrough;
    8867         4145 :         case 2:
    8868         4145 :             term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
    8869         4145 :             res_digits[1] = (NumericDigit) (term % NBASE);
    8870         4145 :             res_digits[0] = (NumericDigit) (term / NBASE);
    8871         4145 :             break;
    8872              :     }
    8873              : 
    8874              :     /* Store the product in result */
    8875       772956 :     digitbuf_free(result->buf);
    8876       772956 :     result->ndigits = res_ndigits;
    8877       772956 :     result->buf = res_buf;
    8878       772956 :     result->digits = res_digits;
    8879       772956 :     result->weight = res_weight;
    8880       772956 :     result->sign = res_sign;
    8881       772956 :     result->dscale = var1->dscale + var2->dscale;
    8882              : 
    8883              :     /* Strip leading and trailing zeroes */
    8884       772956 :     strip_var(result);
    8885       772956 : }
    8886              : 
    8887              : 
    8888              : /*
    8889              :  * div_var() -
    8890              :  *
    8891              :  *  Compute the quotient var1 / var2 to rscale fractional digits.
    8892              :  *
    8893              :  *  If "round" is true, the result is rounded at the rscale'th digit; if
    8894              :  *  false, it is truncated (towards zero) at that digit.
    8895              :  *
    8896              :  *  If "exact" is true, the exact result is computed to the specified rscale;
    8897              :  *  if false, successive quotient digits are approximated up to rscale plus
    8898              :  *  DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
    8899              :  *  the right of that, before rounding or truncating to the specified rscale.
    8900              :  *  This can be significantly faster, and usually gives the same result as the
    8901              :  *  exact computation, but it may occasionally be off by one in the final
    8902              :  *  digit, if contributions from the ignored digits would have propagated
    8903              :  *  through the guard digits.  This is good enough for the transcendental
    8904              :  *  functions, where small errors are acceptable.
    8905              :  */
    8906              : static void
    8907       380354 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8908              :         int rscale, bool round, bool exact)
    8909              : {
    8910       380354 :     int         var1ndigits = var1->ndigits;
    8911       380354 :     int         var2ndigits = var2->ndigits;
    8912              :     int         res_sign;
    8913              :     int         res_weight;
    8914              :     int         res_ndigits;
    8915              :     int         var1ndigitpairs;
    8916              :     int         var2ndigitpairs;
    8917              :     int         res_ndigitpairs;
    8918              :     int         div_ndigitpairs;
    8919              :     int64      *dividend;
    8920              :     int32      *divisor;
    8921              :     double      fdivisor,
    8922              :                 fdivisorinverse,
    8923              :                 fdividend,
    8924              :                 fquotient;
    8925              :     int64       maxdiv;
    8926              :     int         qi;
    8927              :     int32       qdigit;
    8928              :     int64       carry;
    8929              :     int64       newdig;
    8930              :     int64      *remainder;
    8931              :     NumericDigit *res_digits;
    8932              :     int         i;
    8933              : 
    8934              :     /*
    8935              :      * First of all division by zero check; we must not be handed an
    8936              :      * unnormalized divisor.
    8937              :      */
    8938       380354 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    8939            8 :         ereport(ERROR,
    8940              :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    8941              :                  errmsg("division by zero")));
    8942              : 
    8943              :     /*
    8944              :      * If the divisor has just one or two digits, delegate to div_var_int(),
    8945              :      * which uses fast short division.
    8946              :      *
    8947              :      * Similarly, on platforms with 128-bit integer support, delegate to
    8948              :      * div_var_int64() for divisors with three or four digits.
    8949              :      */
    8950       380346 :     if (var2ndigits <= 2)
    8951              :     {
    8952              :         int         idivisor;
    8953              :         int         idivisor_weight;
    8954              : 
    8955       375994 :         idivisor = var2->digits[0];
    8956       375994 :         idivisor_weight = var2->weight;
    8957       375994 :         if (var2ndigits == 2)
    8958              :         {
    8959         2200 :             idivisor = idivisor * NBASE + var2->digits[1];
    8960         2200 :             idivisor_weight--;
    8961              :         }
    8962       375994 :         if (var2->sign == NUMERIC_NEG)
    8963          440 :             idivisor = -idivisor;
    8964              : 
    8965       375994 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    8966       375994 :         return;
    8967              :     }
    8968              : #ifdef HAVE_INT128
    8969         4352 :     if (var2ndigits <= 4)
    8970              :     {
    8971              :         int64       idivisor;
    8972              :         int         idivisor_weight;
    8973              : 
    8974          360 :         idivisor = var2->digits[0];
    8975          360 :         idivisor_weight = var2->weight;
    8976         1340 :         for (i = 1; i < var2ndigits; i++)
    8977              :         {
    8978          980 :             idivisor = idivisor * NBASE + var2->digits[i];
    8979          980 :             idivisor_weight--;
    8980              :         }
    8981          360 :         if (var2->sign == NUMERIC_NEG)
    8982           80 :             idivisor = -idivisor;
    8983              : 
    8984          360 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    8985          360 :         return;
    8986              :     }
    8987              : #endif
    8988              : 
    8989              :     /*
    8990              :      * Otherwise, perform full long division.
    8991              :      */
    8992              : 
    8993              :     /* Result zero check */
    8994         3992 :     if (var1ndigits == 0)
    8995              :     {
    8996           24 :         zero_var(result);
    8997           24 :         result->dscale = rscale;
    8998           24 :         return;
    8999              :     }
    9000              : 
    9001              :     /*
    9002              :      * The approximate computation can be significantly faster than the exact
    9003              :      * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
    9004              :      * shorter below.  However, that comes with the tradeoff of computing
    9005              :      * DIV_GUARD_DIGITS extra base-NBASE result digits.  Ignoring all other
    9006              :      * overheads, that suggests that, in theory, the approximate computation
    9007              :      * will only be faster than the exact one when var2ndigits is greater than
    9008              :      * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
    9009              :      *
    9010              :      * Thus, we're better off doing an exact computation when var2 is shorter
    9011              :      * than this.  Empirically, it has been found that the exact threshold is
    9012              :      * a little higher, due to other overheads in the outer division loop.
    9013              :      */
    9014         3968 :     if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
    9015         2712 :         exact = true;
    9016              : 
    9017              :     /*
    9018              :      * Determine the result sign, weight and number of digits to calculate.
    9019              :      * The weight figured here is correct if the emitted quotient has no
    9020              :      * leading zero digits; otherwise strip_var() will fix things up.
    9021              :      */
    9022         3968 :     if (var1->sign == var2->sign)
    9023         3866 :         res_sign = NUMERIC_POS;
    9024              :     else
    9025          102 :         res_sign = NUMERIC_NEG;
    9026         3968 :     res_weight = var1->weight - var2->weight + 1;
    9027              :     /* The number of accurate result digits we need to produce: */
    9028         3968 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9029              :     /* ... but always at least 1 */
    9030         3968 :     res_ndigits = Max(res_ndigits, 1);
    9031              :     /* If rounding needed, figure one more digit to ensure correct result */
    9032         3968 :     if (round)
    9033          658 :         res_ndigits++;
    9034              :     /* Add guard digits for roundoff error when producing approx result */
    9035         3968 :     if (!exact)
    9036         1246 :         res_ndigits += DIV_GUARD_DIGITS;
    9037              : 
    9038              :     /*
    9039              :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    9040              :      * actually process the input digits in pairs, producing a base-NBASE^2
    9041              :      * intermediate result.  This significantly improves performance, since
    9042              :      * the computation is O(N^2) in the number of input digits, and working in
    9043              :      * base NBASE^2 effectively halves "N".
    9044              :      */
    9045         3968 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    9046         3968 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    9047         3968 :     res_ndigitpairs = (res_ndigits + 1) / 2;
    9048         3968 :     res_ndigits = 2 * res_ndigitpairs;
    9049              : 
    9050              :     /*
    9051              :      * We do the arithmetic in an array "dividend[]" of signed 64-bit
    9052              :      * integers.  Since PG_INT64_MAX is much larger than NBASE^4, this gives
    9053              :      * us a lot of headroom to avoid normalizing carries immediately.
    9054              :      *
    9055              :      * When performing an exact computation, the working dividend requires
    9056              :      * res_ndigitpairs + var2ndigitpairs digits.  If var1 is larger than that,
    9057              :      * the extra digits do not contribute to the result, and are ignored.
    9058              :      *
    9059              :      * When performing an approximate computation, the working dividend only
    9060              :      * requires res_ndigitpairs digits (which includes the extra guard
    9061              :      * digits).  All input digits beyond that are ignored.
    9062              :      */
    9063         3968 :     if (exact)
    9064              :     {
    9065         2722 :         div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
    9066         2722 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9067              :     }
    9068              :     else
    9069              :     {
    9070         1246 :         div_ndigitpairs = res_ndigitpairs;
    9071         1246 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9072         1246 :         var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
    9073              :     }
    9074              : 
    9075              :     /*
    9076              :      * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
    9077              :      * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
    9078              :      *
    9079              :      * For convenience, we allocate one extra dividend digit, which is set to
    9080              :      * zero and not counted in div_ndigitpairs, so that the main loop below
    9081              :      * can safely read and write the (qi+1)'th digit in the approximate case.
    9082              :      */
    9083         3968 :     dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
    9084              :                                 var2ndigitpairs * sizeof(int32));
    9085         3968 :     divisor = (int32 *) (dividend + div_ndigitpairs + 1);
    9086              : 
    9087              :     /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
    9088        37128 :     for (i = 0; i < var1ndigitpairs - 1; i++)
    9089        33160 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9090              : 
    9091         3968 :     if (2 * i + 1 < var1ndigits)
    9092         2341 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9093              :     else
    9094         1627 :         dividend[i] = var1->digits[2 * i] * NBASE;
    9095              : 
    9096         3968 :     memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
    9097              : 
    9098              :     /* load var2 into divisor[0 .. var2ndigitpairs-1] */
    9099        29424 :     for (i = 0; i < var2ndigitpairs - 1; i++)
    9100        25456 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9101              : 
    9102         3968 :     if (2 * i + 1 < var2ndigits)
    9103         2138 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9104              :     else
    9105         1830 :         divisor[i] = var2->digits[2 * i] * NBASE;
    9106              : 
    9107              :     /*
    9108              :      * We estimate each quotient digit using floating-point arithmetic, taking
    9109              :      * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
    9110              :      * This must be float to avoid overflow.
    9111              :      *
    9112              :      * Since the floating-point dividend and divisor use 4 base-NBASE input
    9113              :      * digits, they include roughly 40-53 bits of information from their
    9114              :      * respective inputs (assuming NBASE is 10000), which fits well in IEEE
    9115              :      * double-precision variables.  The relative error in the floating-point
    9116              :      * quotient digit will then be less than around 2/NBASE^3, so the
    9117              :      * estimated base-NBASE^2 quotient digit will typically be correct, and
    9118              :      * should not be off by more than one from the correct value.
    9119              :      */
    9120         3968 :     fdivisor = (double) divisor[0] * NBASE_SQR;
    9121         3968 :     if (var2ndigitpairs > 1)
    9122         3968 :         fdivisor += (double) divisor[1];
    9123         3968 :     fdivisorinverse = 1.0 / fdivisor;
    9124              : 
    9125              :     /*
    9126              :      * maxdiv tracks the maximum possible absolute value of any dividend[]
    9127              :      * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
    9128              :      * propagate carries.  Furthermore, we need to ensure that overflow
    9129              :      * doesn't occur during the carry propagation passes either.  The carry
    9130              :      * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
    9131              :      * so really we must normalize when digits threaten to exceed PG_INT64_MAX
    9132              :      * - PG_INT64_MAX/NBASE^2 - 1.
    9133              :      *
    9134              :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9135              :      * value divided by NBASE^2-1, i.e., at the top of the loop it is known
    9136              :      * that no dividend[] entry has an absolute value exceeding maxdiv *
    9137              :      * (NBASE^2-1).
    9138              :      *
    9139              :      * Actually, though, that holds good only for dividend[] entries after
    9140              :      * dividend[qi]; the adjustment done at the bottom of the loop may cause
    9141              :      * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
    9142              :      * the next iteration is beyond the limit.  This does not cause problems,
    9143              :      * as explained below.
    9144              :      */
    9145         3968 :     maxdiv = 1;
    9146              : 
    9147              :     /*
    9148              :      * Outer loop computes next quotient digit, which goes in dividend[qi].
    9149              :      */
    9150        36464 :     for (qi = 0; qi < res_ndigitpairs; qi++)
    9151              :     {
    9152              :         /* Approximate the current dividend value */
    9153        32496 :         fdividend = (double) dividend[qi] * NBASE_SQR;
    9154        32496 :         fdividend += (double) dividend[qi + 1];
    9155              : 
    9156              :         /* Compute the (approximate) quotient digit */
    9157        32496 :         fquotient = fdividend * fdivisorinverse;
    9158        32496 :         qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9159            5 :             (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9160              : 
    9161        32496 :         if (qdigit != 0)
    9162              :         {
    9163              :             /* Do we need to normalize now? */
    9164        29863 :             maxdiv += i64abs(qdigit);
    9165        29863 :             if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
    9166              :             {
    9167              :                 /*
    9168              :                  * Yes, do it.  Note that if var2ndigitpairs is much smaller
    9169              :                  * than div_ndigitpairs, we can save a significant amount of
    9170              :                  * effort here by noting that we only need to normalise those
    9171              :                  * dividend[] entries touched where prior iterations
    9172              :                  * subtracted multiples of the divisor.
    9173              :                  */
    9174            5 :                 carry = 0;
    9175         5625 :                 for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
    9176              :                 {
    9177         5620 :                     newdig = dividend[i] + carry;
    9178         5620 :                     if (newdig < 0)
    9179              :                     {
    9180         5620 :                         carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9181         5620 :                         newdig -= carry * NBASE_SQR;
    9182              :                     }
    9183            0 :                     else if (newdig >= NBASE_SQR)
    9184              :                     {
    9185            0 :                         carry = newdig / NBASE_SQR;
    9186            0 :                         newdig -= carry * NBASE_SQR;
    9187              :                     }
    9188              :                     else
    9189            0 :                         carry = 0;
    9190         5620 :                     dividend[i] = newdig;
    9191              :                 }
    9192            5 :                 dividend[qi] += carry;
    9193              : 
    9194              :                 /*
    9195              :                  * All the dividend[] digits except possibly dividend[qi] are
    9196              :                  * now in the range 0..NBASE^2-1.  We do not need to consider
    9197              :                  * dividend[qi] in the maxdiv value anymore, so we can reset
    9198              :                  * maxdiv to 1.
    9199              :                  */
    9200            5 :                 maxdiv = 1;
    9201              : 
    9202              :                 /*
    9203              :                  * Recompute the quotient digit since new info may have
    9204              :                  * propagated into the top two dividend digits.
    9205              :                  */
    9206            5 :                 fdividend = (double) dividend[qi] * NBASE_SQR;
    9207            5 :                 fdividend += (double) dividend[qi + 1];
    9208            5 :                 fquotient = fdividend * fdivisorinverse;
    9209            5 :                 qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9210            0 :                     (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9211              : 
    9212            5 :                 maxdiv += i64abs(qdigit);
    9213              :             }
    9214              : 
    9215              :             /*
    9216              :              * Subtract off the appropriate multiple of the divisor.
    9217              :              *
    9218              :              * The digits beyond dividend[qi] cannot overflow, because we know
    9219              :              * they will fall within the maxdiv limit.  As for dividend[qi]
    9220              :              * itself, note that qdigit is approximately trunc(dividend[qi] /
    9221              :              * divisor[0]), which would make the new value simply dividend[qi]
    9222              :              * mod divisor[0].  The lower-order terms in qdigit can change
    9223              :              * this result by not more than about twice PG_INT64_MAX/NBASE^2,
    9224              :              * so overflow is impossible.
    9225              :              *
    9226              :              * This inner loop is the performance bottleneck for division, so
    9227              :              * code it in the same way as the inner loop of mul_var() so that
    9228              :              * it can be auto-vectorized.
    9229              :              */
    9230        29863 :             if (qdigit != 0)
    9231              :             {
    9232        29863 :                 int         istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
    9233        29863 :                 int64      *dividend_qi = &dividend[qi];
    9234              : 
    9235      6518873 :                 for (i = 0; i < istop; i++)
    9236      6489010 :                     dividend_qi[i] -= (int64) qdigit * divisor[i];
    9237              :             }
    9238              :         }
    9239              : 
    9240              :         /*
    9241              :          * The dividend digit we are about to replace might still be nonzero.
    9242              :          * Fold it into the next digit position.
    9243              :          *
    9244              :          * There is no risk of overflow here, although proving that requires
    9245              :          * some care.  Much as with the argument for dividend[qi] not
    9246              :          * overflowing, if we consider the first two terms in the numerator
    9247              :          * and denominator of qdigit, we can see that the final value of
    9248              :          * dividend[qi + 1] will be approximately a remainder mod
    9249              :          * (divisor[0]*NBASE^2 + divisor[1]).  Accounting for the lower-order
    9250              :          * terms is a bit complicated but ends up adding not much more than
    9251              :          * PG_INT64_MAX/NBASE^2 to the possible range.  Thus, dividend[qi + 1]
    9252              :          * cannot overflow here, and in its role as dividend[qi] in the next
    9253              :          * loop iteration, it can't be large enough to cause overflow in the
    9254              :          * carry propagation step (if any), either.
    9255              :          *
    9256              :          * But having said that: dividend[qi] can be more than
    9257              :          * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
    9258              :          * dividend[qi] * NBASE^2 *can* overflow.  When that happens, adding
    9259              :          * it to dividend[qi + 1] will always cause a canceling overflow so
    9260              :          * that the end result is correct.  We could avoid the intermediate
    9261              :          * overflow by doing the multiplication and addition using unsigned
    9262              :          * int64 arithmetic, which is modulo 2^64, but so far there appears no
    9263              :          * need.
    9264              :          */
    9265        32496 :         dividend[qi + 1] += dividend[qi] * NBASE_SQR;
    9266              : 
    9267        32496 :         dividend[qi] = qdigit;
    9268              :     }
    9269              : 
    9270              :     /*
    9271              :      * If an exact result was requested, use the remainder to correct the
    9272              :      * approximate quotient.  The remainder is in dividend[], immediately
    9273              :      * after the quotient digits.  Note, however, that although the remainder
    9274              :      * starts at dividend[qi = res_ndigitpairs], the first digit is the result
    9275              :      * of folding two remainder digits into one above, and the remainder
    9276              :      * currently only occupies var2ndigitpairs - 1 digits (the last digit of
    9277              :      * the working dividend was untouched by the computation above).  Thus we
    9278              :      * expand the remainder down by one base-NBASE^2 digit when we normalize
    9279              :      * it, so that it completely fills the last var2ndigitpairs digits of the
    9280              :      * dividend array.
    9281              :      */
    9282         3968 :     if (exact)
    9283              :     {
    9284              :         /* Normalize the remainder, expanding it down by one digit */
    9285         2722 :         remainder = &dividend[qi];
    9286         2722 :         carry = 0;
    9287        15518 :         for (i = var2ndigitpairs - 2; i >= 0; i--)
    9288              :         {
    9289        12796 :             newdig = remainder[i] + carry;
    9290        12796 :             if (newdig < 0)
    9291              :             {
    9292        10044 :                 carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9293        10044 :                 newdig -= carry * NBASE_SQR;
    9294              :             }
    9295         2752 :             else if (newdig >= NBASE_SQR)
    9296              :             {
    9297         2696 :                 carry = newdig / NBASE_SQR;
    9298         2696 :                 newdig -= carry * NBASE_SQR;
    9299              :             }
    9300              :             else
    9301           56 :                 carry = 0;
    9302        12796 :             remainder[i + 1] = newdig;
    9303              :         }
    9304         2722 :         remainder[0] = carry;
    9305              : 
    9306         2722 :         if (remainder[0] < 0)
    9307              :         {
    9308              :             /*
    9309              :              * The remainder is negative, so the approximate quotient is too
    9310              :              * large.  Correct by reducing the quotient by one and adding the
    9311              :              * divisor to the remainder until the remainder is positive.  We
    9312              :              * expect the quotient to be off by at most one, which has been
    9313              :              * borne out in all testing, but not conclusively proven, so we
    9314              :              * allow for larger corrections, just in case.
    9315              :              */
    9316              :             do
    9317              :             {
    9318              :                 /* Add the divisor to the remainder */
    9319            5 :                 carry = 0;
    9320           65 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9321              :                 {
    9322           60 :                     newdig = remainder[i] + divisor[i] + carry;
    9323           60 :                     if (newdig >= NBASE_SQR)
    9324              :                     {
    9325            0 :                         remainder[i] = newdig - NBASE_SQR;
    9326            0 :                         carry = 1;
    9327              :                     }
    9328              :                     else
    9329              :                     {
    9330           60 :                         remainder[i] = newdig;
    9331           60 :                         carry = 0;
    9332              :                     }
    9333              :                 }
    9334            5 :                 remainder[0] += divisor[0] + carry;
    9335              : 
    9336              :                 /* Subtract 1 from the quotient (propagating carries later) */
    9337            5 :                 dividend[qi - 1]--;
    9338              : 
    9339            5 :             } while (remainder[0] < 0);
    9340              :         }
    9341              :         else
    9342              :         {
    9343              :             /*
    9344              :              * The remainder is nonnegative.  If it's greater than or equal to
    9345              :              * the divisor, then the approximate quotient is too small and
    9346              :              * must be corrected.  As above, we don't expect to have to apply
    9347              :              * more than one correction, but allow for it just in case.
    9348              :              */
    9349              :             while (true)
    9350            5 :             {
    9351         2722 :                 bool        less = false;
    9352              : 
    9353              :                 /* Is remainder < divisor? */
    9354         2737 :                 for (i = 0; i < var2ndigitpairs; i++)
    9355              :                 {
    9356         2732 :                     if (remainder[i] < divisor[i])
    9357              :                     {
    9358         2717 :                         less = true;
    9359         2717 :                         break;
    9360              :                     }
    9361           15 :                     if (remainder[i] > divisor[i])
    9362            0 :                         break;  /* remainder > divisor */
    9363              :                 }
    9364         2722 :                 if (less)
    9365         2717 :                     break;      /* quotient is correct */
    9366              : 
    9367              :                 /* Subtract the divisor from the remainder */
    9368            5 :                 carry = 0;
    9369           15 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9370              :                 {
    9371           10 :                     newdig = remainder[i] - divisor[i] + carry;
    9372           10 :                     if (newdig < 0)
    9373              :                     {
    9374            0 :                         remainder[i] = newdig + NBASE_SQR;
    9375            0 :                         carry = -1;
    9376              :                     }
    9377              :                     else
    9378              :                     {
    9379           10 :                         remainder[i] = newdig;
    9380           10 :                         carry = 0;
    9381              :                     }
    9382              :                 }
    9383            5 :                 remainder[0] = remainder[0] - divisor[0] + carry;
    9384              : 
    9385              :                 /* Add 1 to the quotient (propagating carries later) */
    9386            5 :                 dividend[qi - 1]++;
    9387              :             }
    9388              :         }
    9389              :     }
    9390              : 
    9391              :     /*
    9392              :      * Because the quotient digits were estimates that might have been off by
    9393              :      * one (and we didn't bother propagating carries when adjusting the
    9394              :      * quotient above), some quotient digits might be out of range, so do a
    9395              :      * final carry propagation pass to normalize back to base NBASE^2, and
    9396              :      * construct the base-NBASE result digits.  Note that this is still done
    9397              :      * at full precision w/guard digits.
    9398              :      */
    9399         3968 :     alloc_var(result, res_ndigits);
    9400         3968 :     res_digits = result->digits;
    9401         3968 :     carry = 0;
    9402        36464 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9403              :     {
    9404        32496 :         newdig = dividend[i] + carry;
    9405        32496 :         if (newdig < 0)
    9406              :         {
    9407            5 :             carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9408            5 :             newdig -= carry * NBASE_SQR;
    9409              :         }
    9410        32491 :         else if (newdig >= NBASE_SQR)
    9411              :         {
    9412            0 :             carry = newdig / NBASE_SQR;
    9413            0 :             newdig -= carry * NBASE_SQR;
    9414              :         }
    9415              :         else
    9416        32491 :             carry = 0;
    9417        32496 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9418        32496 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9419              :     }
    9420              :     Assert(carry == 0);
    9421              : 
    9422         3968 :     pfree(dividend);
    9423              : 
    9424              :     /*
    9425              :      * Finally, round or truncate the result to the requested precision.
    9426              :      */
    9427         3968 :     result->weight = res_weight;
    9428         3968 :     result->sign = res_sign;
    9429              : 
    9430              :     /* Round or truncate to target rscale (and set result->dscale) */
    9431         3968 :     if (round)
    9432          658 :         round_var(result, rscale);
    9433              :     else
    9434         3310 :         trunc_var(result, rscale);
    9435              : 
    9436              :     /* Strip leading and trailing zeroes */
    9437         3968 :     strip_var(result);
    9438              : }
    9439              : 
    9440              : 
    9441              : /*
    9442              :  * div_var_int() -
    9443              :  *
    9444              :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9445              :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9446              :  */
    9447              : static void
    9448       389752 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9449              :             NumericVar *result, int rscale, bool round)
    9450              : {
    9451       389752 :     NumericDigit *var_digits = var->digits;
    9452       389752 :     int         var_ndigits = var->ndigits;
    9453              :     int         res_sign;
    9454              :     int         res_weight;
    9455              :     int         res_ndigits;
    9456              :     NumericDigit *res_buf;
    9457              :     NumericDigit *res_digits;
    9458              :     uint32      divisor;
    9459              :     int         i;
    9460              : 
    9461              :     /* Guard against division by zero */
    9462       389752 :     if (ival == 0)
    9463            0 :         ereport(ERROR,
    9464              :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9465              :                 errmsg("division by zero"));
    9466              : 
    9467              :     /* Result zero check */
    9468       389752 :     if (var_ndigits == 0)
    9469              :     {
    9470         1583 :         zero_var(result);
    9471         1583 :         result->dscale = rscale;
    9472         1583 :         return;
    9473              :     }
    9474              : 
    9475              :     /*
    9476              :      * Determine the result sign, weight and number of digits to calculate.
    9477              :      * The weight figured here is correct if the emitted quotient has no
    9478              :      * leading zero digits; otherwise strip_var() will fix things up.
    9479              :      */
    9480       388169 :     if (var->sign == NUMERIC_POS)
    9481       385925 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9482              :     else
    9483         2244 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9484       388169 :     res_weight = var->weight - ival_weight;
    9485              :     /* The number of accurate result digits we need to produce: */
    9486       388169 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9487              :     /* ... but always at least 1 */
    9488       388169 :     res_ndigits = Max(res_ndigits, 1);
    9489              :     /* If rounding needed, figure one more digit to ensure correct result */
    9490       388169 :     if (round)
    9491       111693 :         res_ndigits++;
    9492              : 
    9493       388169 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9494       388169 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9495       388169 :     res_digits = res_buf + 1;
    9496              : 
    9497              :     /*
    9498              :      * Now compute the quotient digits.  This is the short division algorithm
    9499              :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9500              :      * allow the divisor to exceed the internal base.
    9501              :      *
    9502              :      * In this algorithm, the carry from one digit to the next is at most
    9503              :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9504              :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9505              :      * integer if this exceeds UINT_MAX.
    9506              :      */
    9507       388169 :     divisor = abs(ival);
    9508              : 
    9509       388169 :     if (divisor <= UINT_MAX / NBASE)
    9510              :     {
    9511              :         /* carry cannot overflow 32 bits */
    9512       386370 :         uint32      carry = 0;
    9513              : 
    9514      1914216 :         for (i = 0; i < res_ndigits; i++)
    9515              :         {
    9516      1527846 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9517      1527846 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9518      1527846 :             carry = carry % divisor;
    9519              :         }
    9520              :     }
    9521              :     else
    9522              :     {
    9523              :         /* carry may exceed 32 bits */
    9524         1799 :         uint64      carry = 0;
    9525              : 
    9526         5846 :         for (i = 0; i < res_ndigits; i++)
    9527              :         {
    9528         4047 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9529         4047 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9530         4047 :             carry = carry % divisor;
    9531              :         }
    9532              :     }
    9533              : 
    9534              :     /* Store the quotient in result */
    9535       388169 :     digitbuf_free(result->buf);
    9536       388169 :     result->ndigits = res_ndigits;
    9537       388169 :     result->buf = res_buf;
    9538       388169 :     result->digits = res_digits;
    9539       388169 :     result->weight = res_weight;
    9540       388169 :     result->sign = res_sign;
    9541              : 
    9542              :     /* Round or truncate to target rscale (and set result->dscale) */
    9543       388169 :     if (round)
    9544       111693 :         round_var(result, rscale);
    9545              :     else
    9546       276476 :         trunc_var(result, rscale);
    9547              : 
    9548              :     /* Strip leading/trailing zeroes */
    9549       388169 :     strip_var(result);
    9550              : }
    9551              : 
    9552              : 
    9553              : #ifdef HAVE_INT128
    9554              : /*
    9555              :  * div_var_int64() -
    9556              :  *
    9557              :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
    9558              :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9559              :  *
    9560              :  *  This duplicates the logic in div_var_int(), so any changes made there
    9561              :  *  should be made here too.
    9562              :  */
    9563              : static void
    9564          360 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
    9565              :               NumericVar *result, int rscale, bool round)
    9566              : {
    9567          360 :     NumericDigit *var_digits = var->digits;
    9568          360 :     int         var_ndigits = var->ndigits;
    9569              :     int         res_sign;
    9570              :     int         res_weight;
    9571              :     int         res_ndigits;
    9572              :     NumericDigit *res_buf;
    9573              :     NumericDigit *res_digits;
    9574              :     uint64      divisor;
    9575              :     int         i;
    9576              : 
    9577              :     /* Guard against division by zero */
    9578          360 :     if (ival == 0)
    9579            0 :         ereport(ERROR,
    9580              :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9581              :                 errmsg("division by zero"));
    9582              : 
    9583              :     /* Result zero check */
    9584          360 :     if (var_ndigits == 0)
    9585              :     {
    9586           64 :         zero_var(result);
    9587           64 :         result->dscale = rscale;
    9588           64 :         return;
    9589              :     }
    9590              : 
    9591              :     /*
    9592              :      * Determine the result sign, weight and number of digits to calculate.
    9593              :      * The weight figured here is correct if the emitted quotient has no
    9594              :      * leading zero digits; otherwise strip_var() will fix things up.
    9595              :      */
    9596          296 :     if (var->sign == NUMERIC_POS)
    9597          175 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9598              :     else
    9599          121 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9600          296 :     res_weight = var->weight - ival_weight;
    9601              :     /* The number of accurate result digits we need to produce: */
    9602          296 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9603              :     /* ... but always at least 1 */
    9604          296 :     res_ndigits = Max(res_ndigits, 1);
    9605              :     /* If rounding needed, figure one more digit to ensure correct result */
    9606          296 :     if (round)
    9607          291 :         res_ndigits++;
    9608              : 
    9609          296 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9610          296 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9611          296 :     res_digits = res_buf + 1;
    9612              : 
    9613              :     /*
    9614              :      * Now compute the quotient digits.  This is the short division algorithm
    9615              :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9616              :      * allow the divisor to exceed the internal base.
    9617              :      *
    9618              :      * In this algorithm, the carry from one digit to the next is at most
    9619              :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9620              :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
    9621              :      * integer if this exceeds PG_UINT64_MAX.
    9622              :      */
    9623          296 :     divisor = i64abs(ival);
    9624              : 
    9625          296 :     if (divisor <= PG_UINT64_MAX / NBASE)
    9626              :     {
    9627              :         /* carry cannot overflow 64 bits */
    9628          232 :         uint64      carry = 0;
    9629              : 
    9630         2361 :         for (i = 0; i < res_ndigits; i++)
    9631              :         {
    9632         2129 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9633         2129 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9634         2129 :             carry = carry % divisor;
    9635              :         }
    9636              :     }
    9637              :     else
    9638              :     {
    9639              :         /* carry may exceed 64 bits */
    9640           64 :         uint128     carry = 0;
    9641              : 
    9642          688 :         for (i = 0; i < res_ndigits; i++)
    9643              :         {
    9644          624 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9645          624 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9646          624 :             carry = carry % divisor;
    9647              :         }
    9648              :     }
    9649              : 
    9650              :     /* Store the quotient in result */
    9651          296 :     digitbuf_free(result->buf);
    9652          296 :     result->ndigits = res_ndigits;
    9653          296 :     result->buf = res_buf;
    9654          296 :     result->digits = res_digits;
    9655          296 :     result->weight = res_weight;
    9656          296 :     result->sign = res_sign;
    9657              : 
    9658              :     /* Round or truncate to target rscale (and set result->dscale) */
    9659          296 :     if (round)
    9660          291 :         round_var(result, rscale);
    9661              :     else
    9662            5 :         trunc_var(result, rscale);
    9663              : 
    9664              :     /* Strip leading/trailing zeroes */
    9665          296 :     strip_var(result);
    9666              : }
    9667              : #endif
    9668              : 
    9669              : 
    9670              : /*
    9671              :  * Default scale selection for division
    9672              :  *
    9673              :  * Returns the appropriate result scale for the division result.
    9674              :  */
    9675              : static int
    9676        99372 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
    9677              : {
    9678              :     int         weight1,
    9679              :                 weight2,
    9680              :                 qweight,
    9681              :                 i;
    9682              :     NumericDigit firstdigit1,
    9683              :                 firstdigit2;
    9684              :     int         rscale;
    9685              : 
    9686              :     /*
    9687              :      * The result scale of a division isn't specified in any SQL standard. For
    9688              :      * PostgreSQL we select a result scale that will give at least
    9689              :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
    9690              :      * result no less accurate than float8; but use a scale not less than
    9691              :      * either input's display scale.
    9692              :      */
    9693              : 
    9694              :     /* Get the actual (normalized) weight and first digit of each input */
    9695              : 
    9696        99372 :     weight1 = 0;                /* values to use if var1 is zero */
    9697        99372 :     firstdigit1 = 0;
    9698        99372 :     for (i = 0; i < var1->ndigits; i++)
    9699              :     {
    9700        98239 :         firstdigit1 = var1->digits[i];
    9701        98239 :         if (firstdigit1 != 0)
    9702              :         {
    9703        98239 :             weight1 = var1->weight - i;
    9704        98239 :             break;
    9705              :         }
    9706              :     }
    9707              : 
    9708        99372 :     weight2 = 0;                /* values to use if var2 is zero */
    9709        99372 :     firstdigit2 = 0;
    9710        99372 :     for (i = 0; i < var2->ndigits; i++)
    9711              :     {
    9712        99339 :         firstdigit2 = var2->digits[i];
    9713        99339 :         if (firstdigit2 != 0)
    9714              :         {
    9715        99339 :             weight2 = var2->weight - i;
    9716        99339 :             break;
    9717              :         }
    9718              :     }
    9719              : 
    9720              :     /*
    9721              :      * Estimate weight of quotient.  If the two first digits are equal, we
    9722              :      * can't be sure, but assume that var1 is less than var2.
    9723              :      */
    9724        99372 :     qweight = weight1 - weight2;
    9725        99372 :     if (firstdigit1 <= firstdigit2)
    9726        88541 :         qweight--;
    9727              : 
    9728              :     /* Select result scale */
    9729        99372 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
    9730        99372 :     rscale = Max(rscale, var1->dscale);
    9731        99372 :     rscale = Max(rscale, var2->dscale);
    9732        99372 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    9733        99372 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    9734              : 
    9735        99372 :     return rscale;
    9736              : }
    9737              : 
    9738              : 
    9739              : /*
    9740              :  * mod_var() -
    9741              :  *
    9742              :  *  Calculate the modulo of two numerics at variable level
    9743              :  */
    9744              : static void
    9745       275440 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9746              : {
    9747              :     NumericVar  tmp;
    9748              : 
    9749       275440 :     init_var(&tmp);
    9750              : 
    9751              :     /* ---------
    9752              :      * We do this using the equation
    9753              :      *      mod(x,y) = x - trunc(x/y)*y
    9754              :      * div_var can be persuaded to give us trunc(x/y) directly.
    9755              :      * ----------
    9756              :      */
    9757       275440 :     div_var(var1, var2, &tmp, 0, false, true);
    9758              : 
    9759       275440 :     mul_var(var2, &tmp, &tmp, var2->dscale);
    9760              : 
    9761       275440 :     sub_var(var1, &tmp, result);
    9762              : 
    9763       275440 :     free_var(&tmp);
    9764       275440 : }
    9765              : 
    9766              : 
    9767              : /*
    9768              :  * div_mod_var() -
    9769              :  *
    9770              :  *  Calculate the truncated integer quotient and numeric remainder of two
    9771              :  *  numeric variables.  The remainder is precise to var2's dscale.
    9772              :  */
    9773              : static void
    9774         3295 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
    9775              :             NumericVar *quot, NumericVar *rem)
    9776              : {
    9777              :     NumericVar  q;
    9778              :     NumericVar  r;
    9779              : 
    9780         3295 :     init_var(&q);
    9781         3295 :     init_var(&r);
    9782              : 
    9783              :     /*
    9784              :      * Use div_var() with exact = false to get an initial estimate for the
    9785              :      * integer quotient (truncated towards zero).  This might be slightly
    9786              :      * inaccurate, but we correct it below.
    9787              :      */
    9788         3295 :     div_var(var1, var2, &q, 0, false, false);
    9789              : 
    9790              :     /* Compute initial estimate of remainder using the quotient estimate. */
    9791         3295 :     mul_var(var2, &q, &r, var2->dscale);
    9792         3295 :     sub_var(var1, &r, &r);
    9793              : 
    9794              :     /*
    9795              :      * Adjust the results if necessary --- the remainder should have the same
    9796              :      * sign as var1, and its absolute value should be less than the absolute
    9797              :      * value of var2.
    9798              :      */
    9799         3295 :     while (r.ndigits != 0 && r.sign != var1->sign)
    9800              :     {
    9801              :         /* The absolute value of the quotient is too large */
    9802            0 :         if (var1->sign == var2->sign)
    9803              :         {
    9804            0 :             sub_var(&q, &const_one, &q);
    9805            0 :             add_var(&r, var2, &r);
    9806              :         }
    9807              :         else
    9808              :         {
    9809            0 :             add_var(&q, &const_one, &q);
    9810            0 :             sub_var(&r, var2, &r);
    9811              :         }
    9812              :     }
    9813              : 
    9814         3295 :     while (cmp_abs(&r, var2) >= 0)
    9815              :     {
    9816              :         /* The absolute value of the quotient is too small */
    9817            0 :         if (var1->sign == var2->sign)
    9818              :         {
    9819            0 :             add_var(&q, &const_one, &q);
    9820            0 :             sub_var(&r, var2, &r);
    9821              :         }
    9822              :         else
    9823              :         {
    9824            0 :             sub_var(&q, &const_one, &q);
    9825            0 :             add_var(&r, var2, &r);
    9826              :         }
    9827              :     }
    9828              : 
    9829         3295 :     set_var_from_var(&q, quot);
    9830         3295 :     set_var_from_var(&r, rem);
    9831              : 
    9832         3295 :     free_var(&q);
    9833         3295 :     free_var(&r);
    9834         3295 : }
    9835              : 
    9836              : 
    9837              : /*
    9838              :  * ceil_var() -
    9839              :  *
    9840              :  *  Return the smallest integer greater than or equal to the argument
    9841              :  *  on variable level
    9842              :  */
    9843              : static void
    9844          136 : ceil_var(const NumericVar *var, NumericVar *result)
    9845              : {
    9846              :     NumericVar  tmp;
    9847              : 
    9848          136 :     init_var(&tmp);
    9849          136 :     set_var_from_var(var, &tmp);
    9850              : 
    9851          136 :     trunc_var(&tmp, 0);
    9852              : 
    9853          136 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
    9854           40 :         add_var(&tmp, &const_one, &tmp);
    9855              : 
    9856          136 :     set_var_from_var(&tmp, result);
    9857          136 :     free_var(&tmp);
    9858          136 : }
    9859              : 
    9860              : 
    9861              : /*
    9862              :  * floor_var() -
    9863              :  *
    9864              :  *  Return the largest integer equal to or less than the argument
    9865              :  *  on variable level
    9866              :  */
    9867              : static void
    9868           72 : floor_var(const NumericVar *var, NumericVar *result)
    9869              : {
    9870              :     NumericVar  tmp;
    9871              : 
    9872           72 :     init_var(&tmp);
    9873           72 :     set_var_from_var(var, &tmp);
    9874              : 
    9875           72 :     trunc_var(&tmp, 0);
    9876              : 
    9877           72 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
    9878           20 :         sub_var(&tmp, &const_one, &tmp);
    9879              : 
    9880           72 :     set_var_from_var(&tmp, result);
    9881           72 :     free_var(&tmp);
    9882           72 : }
    9883              : 
    9884              : 
    9885              : /*
    9886              :  * gcd_var() -
    9887              :  *
    9888              :  *  Calculate the greatest common divisor of two numerics at variable level
    9889              :  */
    9890              : static void
    9891          148 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9892              : {
    9893              :     int         res_dscale;
    9894              :     int         cmp;
    9895              :     NumericVar  tmp_arg;
    9896              :     NumericVar  mod;
    9897              : 
    9898          148 :     res_dscale = Max(var1->dscale, var2->dscale);
    9899              : 
    9900              :     /*
    9901              :      * Arrange for var1 to be the number with the greater absolute value.
    9902              :      *
    9903              :      * This would happen automatically in the loop below, but avoids an
    9904              :      * expensive modulo operation.
    9905              :      */
    9906          148 :     cmp = cmp_abs(var1, var2);
    9907          148 :     if (cmp < 0)
    9908              :     {
    9909           56 :         const NumericVar *tmp = var1;
    9910              : 
    9911           56 :         var1 = var2;
    9912           56 :         var2 = tmp;
    9913              :     }
    9914              : 
    9915              :     /*
    9916              :      * Also avoid the taking the modulo if the inputs have the same absolute
    9917              :      * value, or if the smaller input is zero.
    9918              :      */
    9919          148 :     if (cmp == 0 || var2->ndigits == 0)
    9920              :     {
    9921           48 :         set_var_from_var(var1, result);
    9922           48 :         result->sign = NUMERIC_POS;
    9923           48 :         result->dscale = res_dscale;
    9924           48 :         return;
    9925              :     }
    9926              : 
    9927          100 :     init_var(&tmp_arg);
    9928          100 :     init_var(&mod);
    9929              : 
    9930              :     /* Use the Euclidean algorithm to find the GCD */
    9931          100 :     set_var_from_var(var1, &tmp_arg);
    9932          100 :     set_var_from_var(var2, result);
    9933              : 
    9934              :     for (;;)
    9935              :     {
    9936              :         /* this loop can take a while, so allow it to be interrupted */
    9937          392 :         CHECK_FOR_INTERRUPTS();
    9938              : 
    9939          392 :         mod_var(&tmp_arg, result, &mod);
    9940          392 :         if (mod.ndigits == 0)
    9941          100 :             break;
    9942          292 :         set_var_from_var(result, &tmp_arg);
    9943          292 :         set_var_from_var(&mod, result);
    9944              :     }
    9945          100 :     result->sign = NUMERIC_POS;
    9946          100 :     result->dscale = res_dscale;
    9947              : 
    9948          100 :     free_var(&tmp_arg);
    9949          100 :     free_var(&mod);
    9950              : }
    9951              : 
    9952              : 
    9953              : /*
    9954              :  * sqrt_var() -
    9955              :  *
    9956              :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
    9957              :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
    9958              :  *  point.
    9959              :  */
    9960              : static void
    9961         3048 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
    9962              : {
    9963              :     int         stat;
    9964              :     int         res_weight;
    9965              :     int         res_ndigits;
    9966              :     int         src_ndigits;
    9967              :     int         step;
    9968              :     int         ndigits[32];
    9969              :     int         blen;
    9970              :     int64       arg_int64;
    9971              :     int         src_idx;
    9972              :     int64       s_int64;
    9973              :     int64       r_int64;
    9974              :     NumericVar  s_var;
    9975              :     NumericVar  r_var;
    9976              :     NumericVar  a0_var;
    9977              :     NumericVar  a1_var;
    9978              :     NumericVar  q_var;
    9979              :     NumericVar  u_var;
    9980              : 
    9981         3048 :     stat = cmp_var(arg, &const_zero);
    9982         3048 :     if (stat == 0)
    9983              :     {
    9984           12 :         zero_var(result);
    9985           12 :         result->dscale = rscale;
    9986           12 :         return;
    9987              :     }
    9988              : 
    9989              :     /*
    9990              :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
    9991              :      * SQLSTATE error code if the operand is negative.
    9992              :      */
    9993         3036 :     if (stat < 0)
    9994            4 :         ereport(ERROR,
    9995              :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    9996              :                  errmsg("cannot take square root of a negative number")));
    9997              : 
    9998         3032 :     init_var(&s_var);
    9999         3032 :     init_var(&r_var);
   10000         3032 :     init_var(&a0_var);
   10001         3032 :     init_var(&a1_var);
   10002         3032 :     init_var(&q_var);
   10003         3032 :     init_var(&u_var);
   10004              : 
   10005              :     /*
   10006              :      * The result weight is half the input weight, rounded towards minus
   10007              :      * infinity --- res_weight = floor(arg->weight / 2).
   10008              :      */
   10009         3032 :     if (arg->weight >= 0)
   10010         2761 :         res_weight = arg->weight / 2;
   10011              :     else
   10012          271 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10013              : 
   10014              :     /*
   10015              :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10016              :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10017              :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10018              :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10019              :      */
   10020         3032 :     if (rscale + 1 >= 0)
   10021         3032 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10022              :     else
   10023            0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10024         3032 :     res_ndigits = Max(res_ndigits, 1);
   10025              : 
   10026              :     /*
   10027              :      * Number of source NBASE digits logically required to produce a result
   10028              :      * with this precision --- every digit before the decimal point, plus 2
   10029              :      * for each result digit after the decimal point (or minus 2 for each
   10030              :      * result digit we round before the decimal point).
   10031              :      */
   10032         3032 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10033         3032 :     src_ndigits = Max(src_ndigits, 1);
   10034              : 
   10035              :     /* ----------
   10036              :      * From this point on, we treat the input and the result as integers and
   10037              :      * compute the integer square root and remainder using the Karatsuba
   10038              :      * Square Root algorithm, which may be written recursively as follows:
   10039              :      *
   10040              :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10041              :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10042              :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10043              :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10044              :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10045              :      *      Let s = s*b + q
   10046              :      *      Let r = u*b + a0 - q^2
   10047              :      *      If r < 0 Then
   10048              :      *          Let r = r + s
   10049              :      *          Let s = s - 1
   10050              :      *          Let r = r + s
   10051              :      *      Return (s,r)
   10052              :      *
   10053              :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10054              :      * RR-3805, November 1999.  At the time of writing this was available
   10055              :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10056              :      *
   10057              :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10058              :      * "choose a base b such that n requires at least four base-b digits to
   10059              :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10060              :      * than b".  For optimal performance, b should have approximately a
   10061              :      * quarter the number of digits in the input, so that the outer square
   10062              :      * root computes roughly twice as many digits as the inner one.  For
   10063              :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10064              :      *
   10065              :      * We implement the algorithm iteratively rather than recursively, to
   10066              :      * allow the working variables to be reused.  With this approach, each
   10067              :      * digit of the input is read precisely once --- src_idx tracks the number
   10068              :      * of input digits used so far.
   10069              :      *
   10070              :      * The array ndigits[] holds the number of NBASE digits of the input that
   10071              :      * will have been used at the end of each iteration, which roughly doubles
   10072              :      * each time.  Note that the array elements are stored in reverse order,
   10073              :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10074              :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10075              :      * the square root of the 3 most significant NBASE digits.
   10076              :      *
   10077              :      * In each iteration, we choose blen to be the largest integer for which
   10078              :      * the input number has a3 >= b/4, when written in the form above.  In
   10079              :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10080              :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10081              :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10082              :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10083              :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10084              :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10085              :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10086              :      * the first input digit.
   10087              :      *
   10088              :      * Additionally, we can put an upper bound on the number of steps required
   10089              :      * as follows --- suppose that the number of source digits is an n-bit
   10090              :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10091              :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10092              :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10093              :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10094              :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10095              :      * This pattern repeats, and in the worst case the array ndigits[] will
   10096              :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10097              :      * will require n steps.  Therefore, since all digit array sizes are
   10098              :      * signed 32-bit integers, the number of steps required is guaranteed to
   10099              :      * be less than 32.
   10100              :      * ----------
   10101              :      */
   10102         3032 :     step = 0;
   10103        14531 :     while ((ndigits[step] = src_ndigits) > 4)
   10104              :     {
   10105              :         /* Choose b so that a3 >= b/4, as described above */
   10106        11499 :         blen = src_ndigits / 4;
   10107        11499 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10108          259 :             blen--;
   10109              : 
   10110              :         /* Number of digits in the next step (inner square root) */
   10111        11499 :         src_ndigits -= 2 * blen;
   10112        11499 :         step++;
   10113              :     }
   10114              : 
   10115              :     /*
   10116              :      * First iteration (innermost square root and remainder):
   10117              :      *
   10118              :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10119              :      * has at most 9 decimal digits, so estimate it using double precision
   10120              :      * arithmetic, which will in fact almost certainly return the correct
   10121              :      * result with no further correction required.
   10122              :      */
   10123         3032 :     arg_int64 = arg->digits[0];
   10124         9695 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10125              :     {
   10126         6663 :         arg_int64 *= NBASE;
   10127         6663 :         if (src_idx < arg->ndigits)
   10128         5647 :             arg_int64 += arg->digits[src_idx];
   10129              :     }
   10130              : 
   10131         3032 :     s_int64 = (int64) sqrt((double) arg_int64);
   10132         3032 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10133              : 
   10134              :     /*
   10135              :      * Use Newton's method to correct the result, if necessary.
   10136              :      *
   10137              :      * This uses integer division with truncation to compute the truncated
   10138              :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10139              :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10140              :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10141              :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10142              :      * checking the remainder.
   10143              :      */
   10144         3032 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10145              :     {
   10146            0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10147            0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10148              :     }
   10149              : 
   10150              :     /*
   10151              :      * Iterations with src_ndigits <= 8:
   10152              :      *
   10153              :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10154              :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10155              :      * input no longer does) and we can continue to compute using int64
   10156              :      * variables to avoid more expensive numeric computations.
   10157              :      *
   10158              :      * It is fairly easy to see that there is no risk of the intermediate
   10159              :      * values below overflowing 64-bit integers.  In the worst case, the
   10160              :      * previous iteration will have computed a 3-digit square root (of a
   10161              :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10162              :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10163              :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10164              :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10165              :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10166              :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10167              :      * in 64-bit integers.
   10168              :      */
   10169         3032 :     step--;
   10170         7672 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10171              :     {
   10172              :         int         b;
   10173              :         int         a0;
   10174              :         int         a1;
   10175              :         int         i;
   10176              :         int64       numer;
   10177              :         int64       denom;
   10178              :         int64       q;
   10179              :         int64       u;
   10180              : 
   10181         4640 :         blen = (src_ndigits - src_idx) / 2;
   10182              : 
   10183              :         /* Extract a1 and a0, and compute b */
   10184         4640 :         a0 = 0;
   10185         4640 :         a1 = 0;
   10186         4640 :         b = 1;
   10187              : 
   10188         9399 :         for (i = 0; i < blen; i++, src_idx++)
   10189              :         {
   10190         4759 :             b *= NBASE;
   10191         4759 :             a1 *= NBASE;
   10192         4759 :             if (src_idx < arg->ndigits)
   10193         3532 :                 a1 += arg->digits[src_idx];
   10194              :         }
   10195              : 
   10196         9399 :         for (i = 0; i < blen; i++, src_idx++)
   10197              :         {
   10198         4759 :             a0 *= NBASE;
   10199         4759 :             if (src_idx < arg->ndigits)
   10200         3420 :                 a0 += arg->digits[src_idx];
   10201              :         }
   10202              : 
   10203              :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10204         4640 :         numer = r_int64 * b + a1;
   10205         4640 :         denom = 2 * s_int64;
   10206         4640 :         q = numer / denom;
   10207         4640 :         u = numer - q * denom;
   10208              : 
   10209              :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10210         4640 :         s_int64 = s_int64 * b + q;
   10211         4640 :         r_int64 = u * b + a0 - q * q;
   10212              : 
   10213         4640 :         if (r_int64 < 0)
   10214              :         {
   10215              :             /* s is too large by 1; set r += s, s--, r += s */
   10216          161 :             r_int64 += s_int64;
   10217          161 :             s_int64--;
   10218          161 :             r_int64 += s_int64;
   10219              :         }
   10220              : 
   10221              :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10222         4640 :         step--;
   10223              :     }
   10224              : 
   10225              :     /*
   10226              :      * On platforms with 128-bit integer support, we can further delay the
   10227              :      * need to use numeric variables.
   10228              :      */
   10229              : #ifdef HAVE_INT128
   10230         3032 :     if (step >= 0)
   10231              :     {
   10232              :         int128      s_int128;
   10233              :         int128      r_int128;
   10234              : 
   10235         3032 :         s_int128 = s_int64;
   10236         3032 :         r_int128 = r_int64;
   10237              : 
   10238              :         /*
   10239              :          * Iterations with src_ndigits <= 16:
   10240              :          *
   10241              :          * The result fits in an int128 (even though the input doesn't) so we
   10242              :          * use int128 variables to avoid more expensive numeric computations.
   10243              :          */
   10244         6596 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10245              :         {
   10246              :             int64       b;
   10247              :             int64       a0;
   10248              :             int64       a1;
   10249              :             int64       i;
   10250              :             int128      numer;
   10251              :             int128      denom;
   10252              :             int128      q;
   10253              :             int128      u;
   10254              : 
   10255         3564 :             blen = (src_ndigits - src_idx) / 2;
   10256              : 
   10257              :             /* Extract a1 and a0, and compute b */
   10258         3564 :             a0 = 0;
   10259         3564 :             a1 = 0;
   10260         3564 :             b = 1;
   10261              : 
   10262        11796 :             for (i = 0; i < blen; i++, src_idx++)
   10263              :             {
   10264         8232 :                 b *= NBASE;
   10265         8232 :                 a1 *= NBASE;
   10266         8232 :                 if (src_idx < arg->ndigits)
   10267         4947 :                     a1 += arg->digits[src_idx];
   10268              :             }
   10269              : 
   10270        11796 :             for (i = 0; i < blen; i++, src_idx++)
   10271              :             {
   10272         8232 :                 a0 *= NBASE;
   10273         8232 :                 if (src_idx < arg->ndigits)
   10274         3407 :                     a0 += arg->digits[src_idx];
   10275              :             }
   10276              : 
   10277              :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10278         3564 :             numer = r_int128 * b + a1;
   10279         3564 :             denom = 2 * s_int128;
   10280         3564 :             q = numer / denom;
   10281         3564 :             u = numer - q * denom;
   10282              : 
   10283              :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10284         3564 :             s_int128 = s_int128 * b + q;
   10285         3564 :             r_int128 = u * b + a0 - q * q;
   10286              : 
   10287         3564 :             if (r_int128 < 0)
   10288              :             {
   10289              :                 /* s is too large by 1; set r += s, s--, r += s */
   10290          146 :                 r_int128 += s_int128;
   10291          146 :                 s_int128--;
   10292          146 :                 r_int128 += s_int128;
   10293              :             }
   10294              : 
   10295              :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10296         3564 :             step--;
   10297              :         }
   10298              : 
   10299              :         /*
   10300              :          * All remaining iterations require numeric variables.  Convert the
   10301              :          * integer values to NumericVar and continue.  Note that in the final
   10302              :          * iteration we don't need the remainder, so we can save a few cycles
   10303              :          * there by not fully computing it.
   10304              :          */
   10305         3032 :         int128_to_numericvar(s_int128, &s_var);
   10306         3032 :         if (step >= 0)
   10307         2008 :             int128_to_numericvar(r_int128, &r_var);
   10308              :     }
   10309              :     else
   10310              :     {
   10311            0 :         int64_to_numericvar(s_int64, &s_var);
   10312              :         /* step < 0, so we certainly don't need r */
   10313              :     }
   10314              : #else                           /* !HAVE_INT128 */
   10315              :     int64_to_numericvar(s_int64, &s_var);
   10316              :     if (step >= 0)
   10317              :         int64_to_numericvar(r_int64, &r_var);
   10318              : #endif                          /* HAVE_INT128 */
   10319              : 
   10320              :     /*
   10321              :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10322              :      * use numeric variables.
   10323              :      */
   10324         6327 :     while (step >= 0)
   10325              :     {
   10326              :         int         tmp_len;
   10327              : 
   10328         3295 :         src_ndigits = ndigits[step];
   10329         3295 :         blen = (src_ndigits - src_idx) / 2;
   10330              : 
   10331              :         /* Extract a1 and a0 */
   10332         3295 :         if (src_idx < arg->ndigits)
   10333              :         {
   10334         1088 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10335         1088 :             alloc_var(&a1_var, tmp_len);
   10336         1088 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10337              :                    tmp_len * sizeof(NumericDigit));
   10338         1088 :             a1_var.weight = blen - 1;
   10339         1088 :             a1_var.sign = NUMERIC_POS;
   10340         1088 :             a1_var.dscale = 0;
   10341         1088 :             strip_var(&a1_var);
   10342              :         }
   10343              :         else
   10344              :         {
   10345         2207 :             zero_var(&a1_var);
   10346         2207 :             a1_var.dscale = 0;
   10347              :         }
   10348         3295 :         src_idx += blen;
   10349              : 
   10350         3295 :         if (src_idx < arg->ndigits)
   10351              :         {
   10352         1088 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10353         1088 :             alloc_var(&a0_var, tmp_len);
   10354         1088 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10355              :                    tmp_len * sizeof(NumericDigit));
   10356         1088 :             a0_var.weight = blen - 1;
   10357         1088 :             a0_var.sign = NUMERIC_POS;
   10358         1088 :             a0_var.dscale = 0;
   10359         1088 :             strip_var(&a0_var);
   10360              :         }
   10361              :         else
   10362              :         {
   10363         2207 :             zero_var(&a0_var);
   10364         2207 :             a0_var.dscale = 0;
   10365              :         }
   10366         3295 :         src_idx += blen;
   10367              : 
   10368              :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10369         3295 :         set_var_from_var(&r_var, &q_var);
   10370         3295 :         q_var.weight += blen;
   10371         3295 :         add_var(&q_var, &a1_var, &q_var);
   10372         3295 :         add_var(&s_var, &s_var, &u_var);
   10373         3295 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10374              : 
   10375              :         /* Compute s = s*b + q */
   10376         3295 :         s_var.weight += blen;
   10377         3295 :         add_var(&s_var, &q_var, &s_var);
   10378              : 
   10379              :         /*
   10380              :          * Compute r = u*b + a0 - q^2.
   10381              :          *
   10382              :          * In the final iteration, we don't actually need r; we just need to
   10383              :          * know whether it is negative, so that we know whether to adjust s.
   10384              :          * So instead of the final subtraction we can just compare.
   10385              :          */
   10386         3295 :         u_var.weight += blen;
   10387         3295 :         add_var(&u_var, &a0_var, &u_var);
   10388         3295 :         mul_var(&q_var, &q_var, &q_var, 0);
   10389              : 
   10390         3295 :         if (step > 0)
   10391              :         {
   10392              :             /* Need r for later iterations */
   10393         1287 :             sub_var(&u_var, &q_var, &r_var);
   10394         1287 :             if (r_var.sign == NUMERIC_NEG)
   10395              :             {
   10396              :                 /* s is too large by 1; set r += s, s--, r += s */
   10397           85 :                 add_var(&r_var, &s_var, &r_var);
   10398           85 :                 sub_var(&s_var, &const_one, &s_var);
   10399           85 :                 add_var(&r_var, &s_var, &r_var);
   10400              :             }
   10401              :         }
   10402              :         else
   10403              :         {
   10404              :             /* Don't need r anymore, except to test if s is too large by 1 */
   10405         2008 :             if (cmp_var(&u_var, &q_var) < 0)
   10406           27 :                 sub_var(&s_var, &const_one, &s_var);
   10407              :         }
   10408              : 
   10409              :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10410         3295 :         step--;
   10411              :     }
   10412              : 
   10413              :     /*
   10414              :      * Construct the final result, rounding it to the requested precision.
   10415              :      */
   10416         3032 :     set_var_from_var(&s_var, result);
   10417         3032 :     result->weight = res_weight;
   10418         3032 :     result->sign = NUMERIC_POS;
   10419              : 
   10420              :     /* Round to target rscale (and set result->dscale) */
   10421         3032 :     round_var(result, rscale);
   10422              : 
   10423              :     /* Strip leading and trailing zeroes */
   10424         3032 :     strip_var(result);
   10425              : 
   10426         3032 :     free_var(&s_var);
   10427         3032 :     free_var(&r_var);
   10428         3032 :     free_var(&a0_var);
   10429         3032 :     free_var(&a1_var);
   10430         3032 :     free_var(&q_var);
   10431         3032 :     free_var(&u_var);
   10432              : }
   10433              : 
   10434              : 
   10435              : /*
   10436              :  * exp_var() -
   10437              :  *
   10438              :  *  Raise e to the power of x, computed to rscale fractional digits
   10439              :  */
   10440              : static void
   10441          139 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10442              : {
   10443              :     NumericVar  x;
   10444              :     NumericVar  elem;
   10445              :     int         ni;
   10446              :     double      val;
   10447              :     int         dweight;
   10448              :     int         ndiv2;
   10449              :     int         sig_digits;
   10450              :     int         local_rscale;
   10451              : 
   10452          139 :     init_var(&x);
   10453          139 :     init_var(&elem);
   10454              : 
   10455          139 :     set_var_from_var(arg, &x);
   10456              : 
   10457              :     /*
   10458              :      * Estimate the dweight of the result using floating point arithmetic, so
   10459              :      * that we can choose an appropriate local rscale for the calculation.
   10460              :      */
   10461          139 :     val = numericvar_to_double_no_overflow(&x);
   10462              : 
   10463              :     /* Guard against overflow/underflow */
   10464              :     /* If you change this limit, see also power_var()'s limit */
   10465          139 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10466              :     {
   10467            5 :         if (val > 0)
   10468            0 :             ereport(ERROR,
   10469              :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10470              :                      errmsg("value overflows numeric format")));
   10471            5 :         zero_var(result);
   10472            5 :         result->dscale = rscale;
   10473            5 :         return;
   10474              :     }
   10475              : 
   10476              :     /* decimal weight = log10(e^x) = x * log10(e) */
   10477          134 :     dweight = (int) (val * 0.434294481903252);
   10478              : 
   10479              :     /*
   10480              :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10481              :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10482              :      *
   10483              :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10484              :      * means that ndiv2 <= 20 here.
   10485              :      */
   10486          134 :     if (fabs(val) > 0.01)
   10487              :     {
   10488          110 :         ndiv2 = 1;
   10489          110 :         val /= 2;
   10490              : 
   10491         1402 :         while (fabs(val) > 0.01)
   10492              :         {
   10493         1292 :             ndiv2++;
   10494         1292 :             val /= 2;
   10495              :         }
   10496              : 
   10497          110 :         local_rscale = x.dscale + ndiv2;
   10498          110 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10499              :     }
   10500              :     else
   10501           24 :         ndiv2 = 0;
   10502              : 
   10503              :     /*
   10504              :      * Set the scale for the Taylor series expansion.  The final result has
   10505              :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10506              :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10507              :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10508              :      * extra digits of precision (plus a few more for good measure).
   10509              :      */
   10510          134 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10511          134 :     sig_digits = Max(sig_digits, 0) + 8;
   10512              : 
   10513          134 :     local_rscale = sig_digits - 1;
   10514              : 
   10515              :     /*
   10516              :      * Use the Taylor series
   10517              :      *
   10518              :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10519              :      *
   10520              :      * Given the limited range of x, this should converge reasonably quickly.
   10521              :      * We run the series until the terms fall below the local_rscale limit.
   10522              :      */
   10523          134 :     add_var(&const_one, &x, result);
   10524              : 
   10525          134 :     mul_var(&x, &x, &elem, local_rscale);
   10526          134 :     ni = 2;
   10527          134 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10528              : 
   10529         3639 :     while (elem.ndigits != 0)
   10530              :     {
   10531         3505 :         add_var(result, &elem, result);
   10532              : 
   10533         3505 :         mul_var(&elem, &x, &elem, local_rscale);
   10534         3505 :         ni++;
   10535         3505 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10536              :     }
   10537              : 
   10538              :     /*
   10539              :      * Compensate for the argument range reduction.  Since the weight of the
   10540              :      * result doubles with each multiplication, we can reduce the local rscale
   10541              :      * as we proceed.
   10542              :      */
   10543         1536 :     while (ndiv2-- > 0)
   10544              :     {
   10545         1402 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   10546         1402 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10547         1402 :         mul_var(result, result, result, local_rscale);
   10548              :     }
   10549              : 
   10550              :     /* Round to requested rscale */
   10551          134 :     round_var(result, rscale);
   10552              : 
   10553          134 :     free_var(&x);
   10554          134 :     free_var(&elem);
   10555              : }
   10556              : 
   10557              : 
   10558              : /*
   10559              :  * Estimate the dweight of the most significant decimal digit of the natural
   10560              :  * logarithm of a number.
   10561              :  *
   10562              :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   10563              :  * determine the appropriate rscale when computing natural logarithms.
   10564              :  *
   10565              :  * Note: many callers call this before range-checking the input.  Therefore,
   10566              :  * we must be robust against values that are invalid to apply ln() to.
   10567              :  * We don't wish to throw an error here, so just return zero in such cases.
   10568              :  */
   10569              : static int
   10570          534 : estimate_ln_dweight(const NumericVar *var)
   10571              : {
   10572              :     int         ln_dweight;
   10573              : 
   10574              :     /* Caller should fail on ln(negative), but for the moment return zero */
   10575          534 :     if (var->sign != NUMERIC_POS)
   10576           28 :         return 0;
   10577              : 
   10578          953 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   10579          447 :         cmp_var(var, &const_one_point_one) <= 0)
   10580           70 :     {
   10581              :         /*
   10582              :          * 0.9 <= var <= 1.1
   10583              :          *
   10584              :          * ln(var) has a negative weight (possibly very large).  To get a
   10585              :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   10586              :          */
   10587              :         NumericVar  x;
   10588              : 
   10589           70 :         init_var(&x);
   10590           70 :         sub_var(var, &const_one, &x);
   10591              : 
   10592           70 :         if (x.ndigits > 0)
   10593              :         {
   10594              :             /* Use weight of most significant decimal digit of x */
   10595           35 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   10596              :         }
   10597              :         else
   10598              :         {
   10599              :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   10600           35 :             ln_dweight = 0;
   10601              :         }
   10602              : 
   10603           70 :         free_var(&x);
   10604              :     }
   10605              :     else
   10606              :     {
   10607              :         /*
   10608              :          * Estimate the logarithm using the first couple of digits from the
   10609              :          * input number.  This will give an accurate result whenever the input
   10610              :          * is not too close to 1.
   10611              :          */
   10612          436 :         if (var->ndigits > 0)
   10613              :         {
   10614              :             int         digits;
   10615              :             int         dweight;
   10616              :             double      ln_var;
   10617              : 
   10618          408 :             digits = var->digits[0];
   10619          408 :             dweight = var->weight * DEC_DIGITS;
   10620              : 
   10621          408 :             if (var->ndigits > 1)
   10622              :             {
   10623          250 :                 digits = digits * NBASE + var->digits[1];
   10624          250 :                 dweight -= DEC_DIGITS;
   10625              :             }
   10626              : 
   10627              :             /*----------
   10628              :              * We have var ~= digits * 10^dweight
   10629              :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   10630              :              *----------
   10631              :              */
   10632          408 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   10633          408 :             ln_dweight = (int) log10(fabs(ln_var));
   10634              :         }
   10635              :         else
   10636              :         {
   10637              :             /* Caller should fail on ln(0), but for the moment return zero */
   10638           28 :             ln_dweight = 0;
   10639              :         }
   10640              :     }
   10641              : 
   10642          506 :     return ln_dweight;
   10643              : }
   10644              : 
   10645              : 
   10646              : /*
   10647              :  * ln_var() -
   10648              :  *
   10649              :  *  Compute the natural log of x
   10650              :  */
   10651              : static void
   10652          607 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   10653              : {
   10654              :     NumericVar  x;
   10655              :     NumericVar  xx;
   10656              :     int         ni;
   10657              :     NumericVar  elem;
   10658              :     NumericVar  fact;
   10659              :     int         nsqrt;
   10660              :     int         local_rscale;
   10661              :     int         cmp;
   10662              : 
   10663          607 :     cmp = cmp_var(arg, &const_zero);
   10664          607 :     if (cmp == 0)
   10665           28 :         ereport(ERROR,
   10666              :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10667              :                  errmsg("cannot take logarithm of zero")));
   10668          579 :     else if (cmp < 0)
   10669           24 :         ereport(ERROR,
   10670              :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10671              :                  errmsg("cannot take logarithm of a negative number")));
   10672              : 
   10673          555 :     init_var(&x);
   10674          555 :     init_var(&xx);
   10675          555 :     init_var(&elem);
   10676          555 :     init_var(&fact);
   10677              : 
   10678          555 :     set_var_from_var(arg, &x);
   10679          555 :     set_var_from_var(&const_two, &fact);
   10680              : 
   10681              :     /*
   10682              :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   10683              :      *
   10684              :      * The final logarithm will have up to around rscale+6 significant digits.
   10685              :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   10686              :      * rscale as we work so that we keep this many significant digits at each
   10687              :      * step (plus a few more for good measure).
   10688              :      *
   10689              :      * Note that we allow local_rscale < 0 during this input reduction
   10690              :      * process, which implies rounding before the decimal point.  sqrt_var()
   10691              :      * explicitly supports this, and it significantly reduces the work
   10692              :      * required to reduce very large inputs to the required range.  Once the
   10693              :      * input reduction is complete, x.weight will be 0 and its display scale
   10694              :      * will be non-negative again.
   10695              :      */
   10696          555 :     nsqrt = 0;
   10697          826 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   10698              :     {
   10699          271 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10700          271 :         sqrt_var(&x, &x, local_rscale);
   10701          271 :         mul_var(&fact, &const_two, &fact, 0);
   10702          271 :         nsqrt++;
   10703              :     }
   10704         2984 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   10705              :     {
   10706         2429 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10707         2429 :         sqrt_var(&x, &x, local_rscale);
   10708         2429 :         mul_var(&fact, &const_two, &fact, 0);
   10709         2429 :         nsqrt++;
   10710              :     }
   10711              : 
   10712              :     /*
   10713              :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   10714              :      *
   10715              :      * z + z^3/3 + z^5/5 + ...
   10716              :      *
   10717              :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   10718              :      * due to the above range-reduction of x.
   10719              :      *
   10720              :      * The convergence of this is not as fast as one would like, but is
   10721              :      * tolerable given that z is small.
   10722              :      *
   10723              :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   10724              :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   10725              :      * digits of precision (plus a few more for good measure).
   10726              :      */
   10727          555 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   10728              : 
   10729          555 :     sub_var(&x, &const_one, result);
   10730          555 :     add_var(&x, &const_one, &elem);
   10731          555 :     div_var(result, &elem, result, local_rscale, true, false);
   10732          555 :     set_var_from_var(result, &xx);
   10733          555 :     mul_var(result, result, &x, local_rscale);
   10734              : 
   10735          555 :     ni = 1;
   10736              : 
   10737              :     for (;;)
   10738              :     {
   10739        10009 :         ni += 2;
   10740        10009 :         mul_var(&xx, &x, &xx, local_rscale);
   10741        10009 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   10742              : 
   10743        10009 :         if (elem.ndigits == 0)
   10744          555 :             break;
   10745              : 
   10746         9454 :         add_var(result, &elem, result);
   10747              : 
   10748         9454 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   10749            0 :             break;
   10750              :     }
   10751              : 
   10752              :     /* Compensate for argument range reduction, round to requested rscale */
   10753          555 :     mul_var(result, &fact, result, rscale);
   10754              : 
   10755          555 :     free_var(&x);
   10756          555 :     free_var(&xx);
   10757          555 :     free_var(&elem);
   10758          555 :     free_var(&fact);
   10759          555 : }
   10760              : 
   10761              : 
   10762              : /*
   10763              :  * log_var() -
   10764              :  *
   10765              :  *  Compute the logarithm of num in a given base.
   10766              :  *
   10767              :  *  Note: this routine chooses dscale of the result.
   10768              :  */
   10769              : static void
   10770          156 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   10771              : {
   10772              :     NumericVar  ln_base;
   10773              :     NumericVar  ln_num;
   10774              :     int         ln_base_dweight;
   10775              :     int         ln_num_dweight;
   10776              :     int         result_dweight;
   10777              :     int         rscale;
   10778              :     int         ln_base_rscale;
   10779              :     int         ln_num_rscale;
   10780              : 
   10781          156 :     init_var(&ln_base);
   10782          156 :     init_var(&ln_num);
   10783              : 
   10784              :     /* Estimated dweights of ln(base), ln(num) and the final result */
   10785          156 :     ln_base_dweight = estimate_ln_dweight(base);
   10786          156 :     ln_num_dweight = estimate_ln_dweight(num);
   10787          156 :     result_dweight = ln_num_dweight - ln_base_dweight;
   10788              : 
   10789              :     /*
   10790              :      * Select the scale of the result so that it will have at least
   10791              :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   10792              :      * input's display scale.
   10793              :      */
   10794          156 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   10795          156 :     rscale = Max(rscale, base->dscale);
   10796          156 :     rscale = Max(rscale, num->dscale);
   10797          156 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10798          156 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10799              : 
   10800              :     /*
   10801              :      * Set the scales for ln(base) and ln(num) so that they each have more
   10802              :      * significant digits than the final result.
   10803              :      */
   10804          156 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   10805          156 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10806              : 
   10807          156 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   10808          156 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10809              : 
   10810              :     /* Form natural logarithms */
   10811          156 :     ln_var(base, &ln_base, ln_base_rscale);
   10812          140 :     ln_var(num, &ln_num, ln_num_rscale);
   10813              : 
   10814              :     /* Divide and round to the required scale */
   10815          120 :     div_var(&ln_num, &ln_base, result, rscale, true, false);
   10816              : 
   10817          116 :     free_var(&ln_num);
   10818          116 :     free_var(&ln_base);
   10819          116 : }
   10820              : 
   10821              : 
   10822              : /*
   10823              :  * power_var() -
   10824              :  *
   10825              :  *  Raise base to the power of exp
   10826              :  *
   10827              :  *  Note: this routine chooses dscale of the result.
   10828              :  */
   10829              : static void
   10830          968 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   10831              : {
   10832              :     int         res_sign;
   10833              :     NumericVar  abs_base;
   10834              :     NumericVar  ln_base;
   10835              :     NumericVar  ln_num;
   10836              :     int         ln_dweight;
   10837              :     int         rscale;
   10838              :     int         sig_digits;
   10839              :     int         local_rscale;
   10840              :     double      val;
   10841              : 
   10842              :     /* If exp can be represented as an integer, use power_var_int */
   10843          968 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   10844              :     {
   10845              :         /* exact integer, but does it fit in int? */
   10846              :         int64       expval64;
   10847              : 
   10848          878 :         if (numericvar_to_int64(exp, &expval64))
   10849              :         {
   10850          873 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   10851              :             {
   10852              :                 /* Okay, use power_var_int */
   10853          848 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   10854          840 :                 return;
   10855              :             }
   10856              :         }
   10857              :     }
   10858              : 
   10859              :     /*
   10860              :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   10861              :      * handled by power_var_int().
   10862              :      */
   10863          120 :     if (cmp_var(base, &const_zero) == 0)
   10864              :     {
   10865           14 :         set_var_from_var(&const_zero, result);
   10866           14 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   10867           14 :         return;
   10868              :     }
   10869              : 
   10870          106 :     init_var(&abs_base);
   10871          106 :     init_var(&ln_base);
   10872          106 :     init_var(&ln_num);
   10873              : 
   10874              :     /*
   10875              :      * If base is negative, insist that exp be an integer.  The result is then
   10876              :      * positive if exp is even and negative if exp is odd.
   10877              :      */
   10878          106 :     if (base->sign == NUMERIC_NEG)
   10879              :     {
   10880              :         /*
   10881              :          * Check that exp is an integer.  This error code is defined by the
   10882              :          * SQL standard, and matches other errors in numeric_power().
   10883              :          */
   10884           27 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   10885           12 :             ereport(ERROR,
   10886              :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10887              :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   10888              : 
   10889              :         /* Test if exp is odd or even */
   10890           15 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   10891           10 :             (exp->digits[exp->ndigits - 1] & 1))
   10892            5 :             res_sign = NUMERIC_NEG;
   10893              :         else
   10894           10 :             res_sign = NUMERIC_POS;
   10895              : 
   10896              :         /* Then work with abs(base) below */
   10897           15 :         set_var_from_var(base, &abs_base);
   10898           15 :         abs_base.sign = NUMERIC_POS;
   10899           15 :         base = &abs_base;
   10900              :     }
   10901              :     else
   10902           79 :         res_sign = NUMERIC_POS;
   10903              : 
   10904              :     /*----------
   10905              :      * Decide on the scale for the ln() calculation.  For this we need an
   10906              :      * estimate of the weight of the result, which we obtain by doing an
   10907              :      * initial low-precision calculation of exp * ln(base).
   10908              :      *
   10909              :      * We want result = e ^ (exp * ln(base))
   10910              :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   10911              :      *
   10912              :      * We also perform a crude overflow test here so that we can exit early if
   10913              :      * the full-precision result is sure to overflow, and to guard against
   10914              :      * integer overflow when determining the scale for the real calculation.
   10915              :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   10916              :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   10917              :      * Since the values here are only approximations, we apply a small fuzz
   10918              :      * factor to this overflow test and let exp_var() determine the exact
   10919              :      * overflow threshold so that it is consistent for all inputs.
   10920              :      *----------
   10921              :      */
   10922           94 :     ln_dweight = estimate_ln_dweight(base);
   10923              : 
   10924              :     /*
   10925              :      * Set the scale for the low-precision calculation, computing ln(base) to
   10926              :      * around 8 significant digits.  Note that ln_dweight may be as small as
   10927              :      * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
   10928              :      * here.
   10929              :      */
   10930           94 :     local_rscale = 8 - ln_dweight;
   10931           94 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10932              : 
   10933           94 :     ln_var(base, &ln_base, local_rscale);
   10934              : 
   10935           94 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   10936              : 
   10937           94 :     val = numericvar_to_double_no_overflow(&ln_num);
   10938              : 
   10939              :     /* initial overflow/underflow test with fuzz factor */
   10940           94 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   10941              :     {
   10942            5 :         if (val > 0)
   10943            0 :             ereport(ERROR,
   10944              :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10945              :                      errmsg("value overflows numeric format")));
   10946            5 :         zero_var(result);
   10947            5 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   10948            5 :         return;
   10949              :     }
   10950              : 
   10951           89 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   10952              : 
   10953              :     /* choose the result scale */
   10954           89 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   10955           89 :     rscale = Max(rscale, base->dscale);
   10956           89 :     rscale = Max(rscale, exp->dscale);
   10957           89 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10958           89 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10959              : 
   10960              :     /* significant digits required in the result */
   10961           89 :     sig_digits = rscale + (int) val;
   10962           89 :     sig_digits = Max(sig_digits, 0);
   10963              : 
   10964              :     /* set the scale for the real exp * ln(base) calculation */
   10965           89 :     local_rscale = sig_digits - ln_dweight + 8;
   10966           89 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10967              : 
   10968              :     /* and do the real calculation */
   10969              : 
   10970           89 :     ln_var(base, &ln_base, local_rscale);
   10971              : 
   10972           89 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   10973              : 
   10974           89 :     exp_var(&ln_num, result, rscale);
   10975              : 
   10976           89 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   10977            5 :         result->sign = NUMERIC_NEG;
   10978              : 
   10979           89 :     free_var(&ln_num);
   10980           89 :     free_var(&ln_base);
   10981           89 :     free_var(&abs_base);
   10982              : }
   10983              : 
   10984              : /*
   10985              :  * power_var_int() -
   10986              :  *
   10987              :  *  Raise base to the power of exp, where exp is an integer.
   10988              :  *
   10989              :  *  Note: this routine chooses dscale of the result.
   10990              :  */
   10991              : static void
   10992          848 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   10993              :               NumericVar *result)
   10994              : {
   10995              :     double      f;
   10996              :     int         p;
   10997              :     int         i;
   10998              :     int         rscale;
   10999              :     int         sig_digits;
   11000              :     unsigned int mask;
   11001              :     bool        neg;
   11002              :     NumericVar  base_prod;
   11003              :     int         local_rscale;
   11004              : 
   11005              :     /*
   11006              :      * Choose the result scale.  For this we need an estimate of the decimal
   11007              :      * weight of the result, which we obtain by approximating using double
   11008              :      * precision arithmetic.
   11009              :      *
   11010              :      * We also perform crude overflow/underflow tests here so that we can exit
   11011              :      * early if the result is sure to overflow/underflow, and to guard against
   11012              :      * integer overflow when choosing the result scale.
   11013              :      */
   11014          848 :     if (base->ndigits != 0)
   11015              :     {
   11016              :         /*----------
   11017              :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11018              :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11019              :          *----------
   11020              :          */
   11021          826 :         f = base->digits[0];
   11022          826 :         p = base->weight * DEC_DIGITS;
   11023              : 
   11024          891 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11025              :         {
   11026           65 :             f = f * NBASE + base->digits[i];
   11027           65 :             p -= DEC_DIGITS;
   11028              :         }
   11029              : 
   11030          826 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11031              :     }
   11032              :     else
   11033           22 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11034              : 
   11035              :     /* overflow/underflow tests with fuzz factors */
   11036          848 :     if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
   11037            8 :         ereport(ERROR,
   11038              :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11039              :                  errmsg("value overflows numeric format")));
   11040          840 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11041              :     {
   11042           10 :         zero_var(result);
   11043           10 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11044          151 :         return;
   11045              :     }
   11046              : 
   11047              :     /*
   11048              :      * Choose the result scale in the same way as power_var(), so it has at
   11049              :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11050              :      * either input's display scale.
   11051              :      */
   11052          830 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11053          830 :     rscale = Max(rscale, base->dscale);
   11054          830 :     rscale = Max(rscale, exp_dscale);
   11055          830 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11056          830 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11057              : 
   11058              :     /* Handle some common special cases, as well as corner cases */
   11059          830 :     switch (exp)
   11060              :     {
   11061           52 :         case 0:
   11062              : 
   11063              :             /*
   11064              :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11065              :              * it as 1 because most programming languages do this. SQL:2003
   11066              :              * also requires a return value of 1.
   11067              :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11068              :              */
   11069           52 :             set_var_from_var(&const_one, result);
   11070           52 :             result->dscale = rscale; /* no need to round */
   11071           52 :             return;
   11072           32 :         case 1:
   11073           32 :             set_var_from_var(base, result);
   11074           32 :             round_var(result, rscale);
   11075           32 :             return;
   11076           21 :         case -1:
   11077           21 :             div_var(&const_one, base, result, rscale, true, true);
   11078           21 :             return;
   11079           36 :         case 2:
   11080           36 :             mul_var(base, base, result, rscale);
   11081           36 :             return;
   11082          689 :         default:
   11083          689 :             break;
   11084              :     }
   11085              : 
   11086              :     /* Handle the special case where the base is zero */
   11087          689 :     if (base->ndigits == 0)
   11088              :     {
   11089            0 :         if (exp < 0)
   11090            0 :             ereport(ERROR,
   11091              :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11092              :                      errmsg("division by zero")));
   11093            0 :         zero_var(result);
   11094            0 :         result->dscale = rscale;
   11095            0 :         return;
   11096              :     }
   11097              : 
   11098              :     /*
   11099              :      * The general case repeatedly multiplies base according to the bit
   11100              :      * pattern of exp.
   11101              :      *
   11102              :      * The local rscale used for each multiplication is varied to keep a fixed
   11103              :      * number of significant digits, sufficient to give the required result
   11104              :      * scale.
   11105              :      */
   11106              : 
   11107              :     /*
   11108              :      * Approximate number of significant digits in the result.  Note that the
   11109              :      * underflow test above, together with the choice of rscale, ensures that
   11110              :      * this approximation is necessarily > 0.
   11111              :      */
   11112          689 :     sig_digits = 1 + rscale + (int) f;
   11113              : 
   11114              :     /*
   11115              :      * The multiplications to produce the result may introduce an error of up
   11116              :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11117              :      * of precision (plus a few more for good measure).
   11118              :      */
   11119          689 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11120              : 
   11121              :     /*
   11122              :      * Now we can proceed with the multiplications.
   11123              :      */
   11124          689 :     neg = (exp < 0);
   11125          689 :     mask = pg_abs_s32(exp);
   11126              : 
   11127          689 :     init_var(&base_prod);
   11128          689 :     set_var_from_var(base, &base_prod);
   11129              : 
   11130          689 :     if (mask & 1)
   11131          343 :         set_var_from_var(base, result);
   11132              :     else
   11133          346 :         set_var_from_var(&const_one, result);
   11134              : 
   11135         3618 :     while ((mask >>= 1) > 0)
   11136              :     {
   11137              :         /*
   11138              :          * Do the multiplications using rscales large enough to hold the
   11139              :          * results to the required number of significant digits, but don't
   11140              :          * waste time by exceeding the scales of the numbers themselves.
   11141              :          */
   11142         2929 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11143         2929 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11144         2929 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11145              : 
   11146         2929 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11147              : 
   11148         2929 :         if (mask & 1)
   11149              :         {
   11150         1932 :             local_rscale = sig_digits -
   11151         1932 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11152         1932 :             local_rscale = Min(local_rscale,
   11153              :                                base_prod.dscale + result->dscale);
   11154         1932 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11155              : 
   11156         1932 :             mul_var(&base_prod, result, result, local_rscale);
   11157              :         }
   11158              : 
   11159              :         /*
   11160              :          * When abs(base) > 1, the number of digits to the left of the decimal
   11161              :          * point in base_prod doubles at each iteration, so if exp is large we
   11162              :          * could easily spend large amounts of time and memory space doing the
   11163              :          * multiplications.  But once the weight exceeds what will fit in
   11164              :          * int16, the final result is guaranteed to overflow (or underflow, if
   11165              :          * exp < 0), so we can give up before wasting too many cycles.
   11166              :          */
   11167         2929 :         if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
   11168         2929 :             result->weight > NUMERIC_WEIGHT_MAX)
   11169              :         {
   11170              :             /* overflow, unless neg, in which case result should be 0 */
   11171            0 :             if (!neg)
   11172            0 :                 ereport(ERROR,
   11173              :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11174              :                          errmsg("value overflows numeric format")));
   11175            0 :             zero_var(result);
   11176            0 :             neg = false;
   11177            0 :             break;
   11178              :         }
   11179              :     }
   11180              : 
   11181          689 :     free_var(&base_prod);
   11182              : 
   11183              :     /* Compensate for input sign, and round to requested rscale */
   11184          689 :     if (neg)
   11185          328 :         div_var(&const_one, result, result, rscale, true, false);
   11186              :     else
   11187          361 :         round_var(result, rscale);
   11188              : }
   11189              : 
   11190              : /*
   11191              :  * power_ten_int() -
   11192              :  *
   11193              :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11194              :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11195              :  */
   11196              : static void
   11197          152 : power_ten_int(int exp, NumericVar *result)
   11198              : {
   11199              :     /* Construct the result directly, starting from 10^0 = 1 */
   11200          152 :     set_var_from_var(&const_one, result);
   11201              : 
   11202              :     /* Scale needed to represent the result exactly */
   11203          152 :     result->dscale = exp < 0 ? -exp : 0;
   11204              : 
   11205              :     /* Base-NBASE weight of result and remaining exponent */
   11206          152 :     if (exp >= 0)
   11207          108 :         result->weight = exp / DEC_DIGITS;
   11208              :     else
   11209           44 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11210              : 
   11211          152 :     exp -= result->weight * DEC_DIGITS;
   11212              : 
   11213              :     /* Final adjustment of the result's single NBASE digit */
   11214          396 :     while (exp-- > 0)
   11215          244 :         result->digits[0] *= 10;
   11216          152 : }
   11217              : 
   11218              : /*
   11219              :  * random_var() - return a random value in the range [rmin, rmax].
   11220              :  */
   11221              : static void
   11222        22292 : random_var(pg_prng_state *state, const NumericVar *rmin,
   11223              :            const NumericVar *rmax, NumericVar *result)
   11224              : {
   11225              :     int         rscale;
   11226              :     NumericVar  rlen;
   11227              :     int         res_ndigits;
   11228              :     int         n;
   11229              :     int         pow10;
   11230              :     int         i;
   11231              :     uint64      rlen64;
   11232              :     int         rlen64_ndigits;
   11233              : 
   11234        22292 :     rscale = Max(rmin->dscale, rmax->dscale);
   11235              : 
   11236              :     /* Compute rlen = rmax - rmin and check the range bounds */
   11237        22292 :     init_var(&rlen);
   11238        22292 :     sub_var(rmax, rmin, &rlen);
   11239              : 
   11240        22292 :     if (rlen.sign == NUMERIC_NEG)
   11241            4 :         ereport(ERROR,
   11242              :                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
   11243              :                 errmsg("lower bound must be less than or equal to upper bound"));
   11244              : 
   11245              :     /* Special case for an empty range */
   11246        22288 :     if (rlen.ndigits == 0)
   11247              :     {
   11248            8 :         set_var_from_var(rmin, result);
   11249            8 :         result->dscale = rscale;
   11250            8 :         free_var(&rlen);
   11251            8 :         return;
   11252              :     }
   11253              : 
   11254              :     /*
   11255              :      * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
   11256              :      * and shift it to the required range by adding rmin.
   11257              :      */
   11258              : 
   11259              :     /* Required result digits */
   11260        22280 :     res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   11261              : 
   11262              :     /*
   11263              :      * To get the required rscale, the final result digit must be a multiple
   11264              :      * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
   11265              :      */
   11266        22280 :     n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
   11267        22280 :     pow10 = 1;
   11268        58600 :     for (i = 0; i < n; i++)
   11269        36320 :         pow10 *= 10;
   11270              : 
   11271              :     /*
   11272              :      * To choose a random value uniformly from the range [0, rlen], we choose
   11273              :      * from the slightly larger range [0, rlen2], where rlen2 is formed from
   11274              :      * rlen by copying the first 4 NBASE digits, and setting all remaining
   11275              :      * decimal digits to "9".
   11276              :      *
   11277              :      * Without loss of generality, we can ignore the weight of rlen2 and treat
   11278              :      * it as a pure integer for the purposes of this discussion.  The process
   11279              :      * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
   11280              :      * is a 64-bit integer formed from the first 4 NBASE digits copied from
   11281              :      * rlen.  Since this trivially factors into smaller pieces that fit in
   11282              :      * 64-bit integers, the task of choosing a random value uniformly from the
   11283              :      * rlen2 + 1 possible values in [0, rlen2] is much simpler.
   11284              :      *
   11285              :      * If the random value selected is too large, it is rejected, and we try
   11286              :      * again until we get a result <= rlen, ensuring that the overall result
   11287              :      * is uniform (no particular value is any more likely than any other).
   11288              :      *
   11289              :      * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
   11290              :      * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
   11291              :      * when DEC_DIGITS is 4). Therefore the probability of needing to reject
   11292              :      * the value chosen and retry is less than 1e-13.
   11293              :      */
   11294        22280 :     rlen64 = (uint64) rlen.digits[0];
   11295        22280 :     rlen64_ndigits = 1;
   11296        50808 :     while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
   11297              :     {
   11298        28528 :         rlen64 *= NBASE;
   11299        28528 :         if (rlen64_ndigits < rlen.ndigits)
   11300         4408 :             rlen64 += rlen.digits[rlen64_ndigits];
   11301        28528 :         rlen64_ndigits++;
   11302              :     }
   11303              : 
   11304              :     /* Loop until we get a result <= rlen */
   11305              :     do
   11306              :     {
   11307              :         NumericDigit *res_digits;
   11308              :         uint64      rand;
   11309              :         int         whole_ndigits;
   11310              : 
   11311        22280 :         alloc_var(result, res_ndigits);
   11312        22280 :         result->sign = NUMERIC_POS;
   11313        22280 :         result->weight = rlen.weight;
   11314        22280 :         result->dscale = rscale;
   11315        22280 :         res_digits = result->digits;
   11316              : 
   11317              :         /*
   11318              :          * Set the first rlen64_ndigits using a random value in [0, rlen64].
   11319              :          *
   11320              :          * If this is the whole result, and rscale is not a multiple of
   11321              :          * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
   11322              :          * multiple of pow10.
   11323              :          */
   11324        22280 :         if (rlen64_ndigits == res_ndigits && pow10 != 1)
   11325        14088 :             rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
   11326              :         else
   11327         8192 :             rand = pg_prng_uint64_range(state, 0, rlen64);
   11328              : 
   11329        73088 :         for (i = rlen64_ndigits - 1; i >= 0; i--)
   11330              :         {
   11331        50808 :             res_digits[i] = (NumericDigit) (rand % NBASE);
   11332        50808 :             rand = rand / NBASE;
   11333              :         }
   11334              : 
   11335              :         /*
   11336              :          * Set the remaining digits to random values in range [0, NBASE),
   11337              :          * noting that the last digit needs to be a multiple of pow10.
   11338              :          */
   11339        22280 :         whole_ndigits = res_ndigits;
   11340        22280 :         if (pow10 != 1)
   11341        22140 :             whole_ndigits--;
   11342              : 
   11343              :         /* Set whole digits in groups of 4 for best performance */
   11344        22280 :         i = rlen64_ndigits;
   11345        22320 :         while (i < whole_ndigits - 3)
   11346              :         {
   11347           40 :             rand = pg_prng_uint64_range(state, 0,
   11348              :                                         (uint64) NBASE * NBASE * NBASE * NBASE - 1);
   11349           40 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11350           40 :             rand = rand / NBASE;
   11351           40 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11352           40 :             rand = rand / NBASE;
   11353           40 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11354           40 :             rand = rand / NBASE;
   11355           40 :             res_digits[i++] = (NumericDigit) rand;
   11356              :         }
   11357              : 
   11358              :         /* Remaining whole digits */
   11359        22420 :         while (i < whole_ndigits)
   11360              :         {
   11361          140 :             rand = pg_prng_uint64_range(state, 0, NBASE - 1);
   11362          140 :             res_digits[i++] = (NumericDigit) rand;
   11363              :         }
   11364              : 
   11365              :         /* Final partial digit (multiple of pow10) */
   11366        22280 :         if (i < res_ndigits)
   11367              :         {
   11368         8052 :             rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
   11369         8052 :             res_digits[i] = (NumericDigit) rand;
   11370              :         }
   11371              : 
   11372              :         /* Remove leading/trailing zeroes */
   11373        22280 :         strip_var(result);
   11374              : 
   11375              :         /* If result > rlen, try again */
   11376              : 
   11377        22280 :     } while (cmp_var(result, &rlen) > 0);
   11378              : 
   11379              :     /* Offset the result to the required range */
   11380        22280 :     add_var(result, rmin, result);
   11381              : 
   11382        22280 :     free_var(&rlen);
   11383              : }
   11384              : 
   11385              : 
   11386              : /* ----------------------------------------------------------------------
   11387              :  *
   11388              :  * Following are the lowest level functions that operate unsigned
   11389              :  * on the variable level
   11390              :  *
   11391              :  * ----------------------------------------------------------------------
   11392              :  */
   11393              : 
   11394              : 
   11395              : /* ----------
   11396              :  * cmp_abs() -
   11397              :  *
   11398              :  *  Compare the absolute values of var1 and var2
   11399              :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11400              :  *              0  for ABS(var1) == ABS(var2)
   11401              :  *              1  for ABS(var1) > ABS(var2)
   11402              :  * ----------
   11403              :  */
   11404              : static int
   11405       469368 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11406              : {
   11407       938736 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11408       469368 :                           var2->digits, var2->ndigits, var2->weight);
   11409              : }
   11410              : 
   11411              : /* ----------
   11412              :  * cmp_abs_common() -
   11413              :  *
   11414              :  *  Main routine of cmp_abs(). This function can be used by both
   11415              :  *  NumericVar and Numeric.
   11416              :  * ----------
   11417              :  */
   11418              : static int
   11419     18443809 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11420              :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11421              : {
   11422     18443809 :     int         i1 = 0;
   11423     18443809 :     int         i2 = 0;
   11424              : 
   11425              :     /* Check any digits before the first common digit */
   11426              : 
   11427     18443809 :     while (var1weight > var2weight && i1 < var1ndigits)
   11428              :     {
   11429        16757 :         if (var1digits[i1++] != 0)
   11430        16757 :             return 1;
   11431            0 :         var1weight--;
   11432              :     }
   11433     18427052 :     while (var2weight > var1weight && i2 < var2ndigits)
   11434              :     {
   11435        99022 :         if (var2digits[i2++] != 0)
   11436        99022 :             return -1;
   11437            0 :         var2weight--;
   11438              :     }
   11439              : 
   11440              :     /* At this point, either w1 == w2 or we've run out of digits */
   11441              : 
   11442     18328030 :     if (var1weight == var2weight)
   11443              :     {
   11444     28812639 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11445              :         {
   11446     19349672 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11447              : 
   11448     19349672 :             if (stat)
   11449              :             {
   11450      8860810 :                 if (stat > 0)
   11451      5248943 :                     return 1;
   11452      3611867 :                 return -1;
   11453              :             }
   11454              :         }
   11455              :     }
   11456              : 
   11457              :     /*
   11458              :      * At this point, we've run out of digits on one side or the other; so any
   11459              :      * remaining nonzero digits imply that side is larger
   11460              :      */
   11461      9467410 :     while (i1 < var1ndigits)
   11462              :     {
   11463         6365 :         if (var1digits[i1++] != 0)
   11464         6175 :             return 1;
   11465              :     }
   11466      9461207 :     while (i2 < var2ndigits)
   11467              :     {
   11468          814 :         if (var2digits[i2++] != 0)
   11469          652 :             return -1;
   11470              :     }
   11471              : 
   11472      9460393 :     return 0;
   11473              : }
   11474              : 
   11475              : 
   11476              : /*
   11477              :  * add_abs() -
   11478              :  *
   11479              :  *  Add the absolute values of two variables into result.
   11480              :  *  result might point to one of the operands without danger.
   11481              :  */
   11482              : static void
   11483       299665 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11484              : {
   11485              :     NumericDigit *res_buf;
   11486              :     NumericDigit *res_digits;
   11487              :     int         res_ndigits;
   11488              :     int         res_weight;
   11489              :     int         res_rscale,
   11490              :                 rscale1,
   11491              :                 rscale2;
   11492              :     int         res_dscale;
   11493              :     int         i,
   11494              :                 i1,
   11495              :                 i2;
   11496       299665 :     int         carry = 0;
   11497              : 
   11498              :     /* copy these values into local vars for speed in inner loop */
   11499       299665 :     int         var1ndigits = var1->ndigits;
   11500       299665 :     int         var2ndigits = var2->ndigits;
   11501       299665 :     NumericDigit *var1digits = var1->digits;
   11502       299665 :     NumericDigit *var2digits = var2->digits;
   11503              : 
   11504       299665 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11505              : 
   11506       299665 :     res_dscale = Max(var1->dscale, var2->dscale);
   11507              : 
   11508              :     /* Note: here we are figuring rscale in base-NBASE digits */
   11509       299665 :     rscale1 = var1->ndigits - var1->weight - 1;
   11510       299665 :     rscale2 = var2->ndigits - var2->weight - 1;
   11511       299665 :     res_rscale = Max(rscale1, rscale2);
   11512              : 
   11513       299665 :     res_ndigits = res_rscale + res_weight + 1;
   11514       299665 :     if (res_ndigits <= 0)
   11515            0 :         res_ndigits = 1;
   11516              : 
   11517       299665 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11518       299665 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11519       299665 :     res_digits = res_buf + 1;
   11520              : 
   11521       299665 :     i1 = res_rscale + var1->weight + 1;
   11522       299665 :     i2 = res_rscale + var2->weight + 1;
   11523      2480640 :     for (i = res_ndigits - 1; i >= 0; i--)
   11524              :     {
   11525      2180975 :         i1--;
   11526      2180975 :         i2--;
   11527      2180975 :         if (i1 >= 0 && i1 < var1ndigits)
   11528       988141 :             carry += var1digits[i1];
   11529      2180975 :         if (i2 >= 0 && i2 < var2ndigits)
   11530       779982 :             carry += var2digits[i2];
   11531              : 
   11532      2180975 :         if (carry >= NBASE)
   11533              :         {
   11534       159500 :             res_digits[i] = carry - NBASE;
   11535       159500 :             carry = 1;
   11536              :         }
   11537              :         else
   11538              :         {
   11539      2021475 :             res_digits[i] = carry;
   11540      2021475 :             carry = 0;
   11541              :         }
   11542              :     }
   11543              : 
   11544              :     Assert(carry == 0);         /* else we failed to allow for carry out */
   11545              : 
   11546       299665 :     digitbuf_free(result->buf);
   11547       299665 :     result->ndigits = res_ndigits;
   11548       299665 :     result->buf = res_buf;
   11549       299665 :     result->digits = res_digits;
   11550       299665 :     result->weight = res_weight;
   11551       299665 :     result->dscale = res_dscale;
   11552              : 
   11553              :     /* Remove leading/trailing zeroes */
   11554       299665 :     strip_var(result);
   11555       299665 : }
   11556              : 
   11557              : 
   11558              : /*
   11559              :  * sub_abs()
   11560              :  *
   11561              :  *  Subtract the absolute value of var2 from the absolute value of var1
   11562              :  *  and store in result. result might point to one of the operands
   11563              :  *  without danger.
   11564              :  *
   11565              :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   11566              :  */
   11567              : static void
   11568       436129 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11569              : {
   11570              :     NumericDigit *res_buf;
   11571              :     NumericDigit *res_digits;
   11572              :     int         res_ndigits;
   11573              :     int         res_weight;
   11574              :     int         res_rscale,
   11575              :                 rscale1,
   11576              :                 rscale2;
   11577              :     int         res_dscale;
   11578              :     int         i,
   11579              :                 i1,
   11580              :                 i2;
   11581       436129 :     int         borrow = 0;
   11582              : 
   11583              :     /* copy these values into local vars for speed in inner loop */
   11584       436129 :     int         var1ndigits = var1->ndigits;
   11585       436129 :     int         var2ndigits = var2->ndigits;
   11586       436129 :     NumericDigit *var1digits = var1->digits;
   11587       436129 :     NumericDigit *var2digits = var2->digits;
   11588              : 
   11589       436129 :     res_weight = var1->weight;
   11590              : 
   11591       436129 :     res_dscale = Max(var1->dscale, var2->dscale);
   11592              : 
   11593              :     /* Note: here we are figuring rscale in base-NBASE digits */
   11594       436129 :     rscale1 = var1->ndigits - var1->weight - 1;
   11595       436129 :     rscale2 = var2->ndigits - var2->weight - 1;
   11596       436129 :     res_rscale = Max(rscale1, rscale2);
   11597              : 
   11598       436129 :     res_ndigits = res_rscale + res_weight + 1;
   11599       436129 :     if (res_ndigits <= 0)
   11600            0 :         res_ndigits = 1;
   11601              : 
   11602       436129 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11603       436129 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11604       436129 :     res_digits = res_buf + 1;
   11605              : 
   11606       436129 :     i1 = res_rscale + var1->weight + 1;
   11607       436129 :     i2 = res_rscale + var2->weight + 1;
   11608      3488952 :     for (i = res_ndigits - 1; i >= 0; i--)
   11609              :     {
   11610      3052823 :         i1--;
   11611      3052823 :         i2--;
   11612      3052823 :         if (i1 >= 0 && i1 < var1ndigits)
   11613      2744698 :             borrow += var1digits[i1];
   11614      3052823 :         if (i2 >= 0 && i2 < var2ndigits)
   11615      2693874 :             borrow -= var2digits[i2];
   11616              : 
   11617      3052823 :         if (borrow < 0)
   11618              :         {
   11619       330711 :             res_digits[i] = borrow + NBASE;
   11620       330711 :             borrow = -1;
   11621              :         }
   11622              :         else
   11623              :         {
   11624      2722112 :             res_digits[i] = borrow;
   11625      2722112 :             borrow = 0;
   11626              :         }
   11627              :     }
   11628              : 
   11629              :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   11630              : 
   11631       436129 :     digitbuf_free(result->buf);
   11632       436129 :     result->ndigits = res_ndigits;
   11633       436129 :     result->buf = res_buf;
   11634       436129 :     result->digits = res_digits;
   11635       436129 :     result->weight = res_weight;
   11636       436129 :     result->dscale = res_dscale;
   11637              : 
   11638              :     /* Remove leading/trailing zeroes */
   11639       436129 :     strip_var(result);
   11640       436129 : }
   11641              : 
   11642              : /*
   11643              :  * round_var
   11644              :  *
   11645              :  * Round the value of a variable to no more than rscale decimal digits
   11646              :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11647              :  * rounding before the decimal point.
   11648              :  */
   11649              : static void
   11650       168216 : round_var(NumericVar *var, int rscale)
   11651              : {
   11652       168216 :     NumericDigit *digits = var->digits;
   11653              :     int         di;
   11654              :     int         ndigits;
   11655              :     int         carry;
   11656              : 
   11657       168216 :     var->dscale = rscale;
   11658              : 
   11659              :     /* decimal digits wanted */
   11660       168216 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11661              : 
   11662              :     /*
   11663              :      * If di = 0, the value loses all digits, but could round up to 1 if its
   11664              :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   11665              :      */
   11666       168216 :     if (di < 0)
   11667              :     {
   11668           71 :         var->ndigits = 0;
   11669           71 :         var->weight = 0;
   11670           71 :         var->sign = NUMERIC_POS;
   11671              :     }
   11672              :     else
   11673              :     {
   11674              :         /* NBASE digits wanted */
   11675       168145 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11676              : 
   11677              :         /* 0, or number of decimal digits to keep in last NBASE digit */
   11678       168145 :         di %= DEC_DIGITS;
   11679              : 
   11680       168145 :         if (ndigits < var->ndigits ||
   11681        30619 :             (ndigits == var->ndigits && di > 0))
   11682              :         {
   11683       139988 :             var->ndigits = ndigits;
   11684              : 
   11685              : #if DEC_DIGITS == 1
   11686              :             /* di must be zero */
   11687              :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11688              : #else
   11689       139988 :             if (di == 0)
   11690       109923 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11691              :             else
   11692              :             {
   11693              :                 /* Must round within last NBASE digit */
   11694              :                 int         extra,
   11695              :                             pow10;
   11696              : 
   11697              : #if DEC_DIGITS == 4
   11698        30065 :                 pow10 = round_powers[di];
   11699              : #elif DEC_DIGITS == 2
   11700              :                 pow10 = 10;
   11701              : #else
   11702              : #error unsupported NBASE
   11703              : #endif
   11704        30065 :                 extra = digits[--ndigits] % pow10;
   11705        30065 :                 digits[ndigits] -= extra;
   11706        30065 :                 carry = 0;
   11707        30065 :                 if (extra >= pow10 / 2)
   11708              :                 {
   11709        14012 :                     pow10 += digits[ndigits];
   11710        14012 :                     if (pow10 >= NBASE)
   11711              :                     {
   11712          587 :                         pow10 -= NBASE;
   11713          587 :                         carry = 1;
   11714              :                     }
   11715        14012 :                     digits[ndigits] = pow10;
   11716              :                 }
   11717              :             }
   11718              : #endif
   11719              : 
   11720              :             /* Propagate carry if needed */
   11721       166862 :             while (carry)
   11722              :             {
   11723        26874 :                 carry += digits[--ndigits];
   11724        26874 :                 if (carry >= NBASE)
   11725              :                 {
   11726        20520 :                     digits[ndigits] = carry - NBASE;
   11727        20520 :                     carry = 1;
   11728              :                 }
   11729              :                 else
   11730              :                 {
   11731         6354 :                     digits[ndigits] = carry;
   11732         6354 :                     carry = 0;
   11733              :                 }
   11734              :             }
   11735              : 
   11736       139988 :             if (ndigits < 0)
   11737              :             {
   11738              :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   11739              :                 Assert(var->digits > var->buf);
   11740           65 :                 var->digits--;
   11741           65 :                 var->ndigits++;
   11742           65 :                 var->weight++;
   11743              :             }
   11744              :         }
   11745              :     }
   11746       168216 : }
   11747              : 
   11748              : /*
   11749              :  * trunc_var
   11750              :  *
   11751              :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   11752              :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11753              :  * truncation before the decimal point.
   11754              :  */
   11755              : static void
   11756       280503 : trunc_var(NumericVar *var, int rscale)
   11757              : {
   11758              :     int         di;
   11759              :     int         ndigits;
   11760              : 
   11761       280503 :     var->dscale = rscale;
   11762              : 
   11763              :     /* decimal digits wanted */
   11764       280503 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11765              : 
   11766              :     /*
   11767              :      * If di <= 0, the value loses all digits.
   11768              :      */
   11769       280503 :     if (di <= 0)
   11770              :     {
   11771           66 :         var->ndigits = 0;
   11772           66 :         var->weight = 0;
   11773           66 :         var->sign = NUMERIC_POS;
   11774              :     }
   11775              :     else
   11776              :     {
   11777              :         /* NBASE digits wanted */
   11778       280437 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11779              : 
   11780       280437 :         if (ndigits <= var->ndigits)
   11781              :         {
   11782       280249 :             var->ndigits = ndigits;
   11783              : 
   11784              : #if DEC_DIGITS == 1
   11785              :             /* no within-digit stuff to worry about */
   11786              : #else
   11787              :             /* 0, or number of decimal digits to keep in last NBASE digit */
   11788       280249 :             di %= DEC_DIGITS;
   11789              : 
   11790       280249 :             if (di > 0)
   11791              :             {
   11792              :                 /* Must truncate within last NBASE digit */
   11793           63 :                 NumericDigit *digits = var->digits;
   11794              :                 int         extra,
   11795              :                             pow10;
   11796              : 
   11797              : #if DEC_DIGITS == 4
   11798           63 :                 pow10 = round_powers[di];
   11799              : #elif DEC_DIGITS == 2
   11800              :                 pow10 = 10;
   11801              : #else
   11802              : #error unsupported NBASE
   11803              : #endif
   11804           63 :                 extra = digits[--ndigits] % pow10;
   11805           63 :                 digits[ndigits] -= extra;
   11806              :             }
   11807              : #endif
   11808              :         }
   11809              :     }
   11810       280503 : }
   11811              : 
   11812              : /*
   11813              :  * strip_var
   11814              :  *
   11815              :  * Strip any leading and trailing zeroes from a numeric variable
   11816              :  */
   11817              : static void
   11818      2189280 : strip_var(NumericVar *var)
   11819              : {
   11820      2189280 :     NumericDigit *digits = var->digits;
   11821      2189280 :     int         ndigits = var->ndigits;
   11822              : 
   11823              :     /* Strip leading zeroes */
   11824      3763295 :     while (ndigits > 0 && *digits == 0)
   11825              :     {
   11826      1574015 :         digits++;
   11827      1574015 :         var->weight--;
   11828      1574015 :         ndigits--;
   11829              :     }
   11830              : 
   11831              :     /* Strip trailing zeroes */
   11832      2640788 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   11833       451508 :         ndigits--;
   11834              : 
   11835              :     /* If it's zero, normalize the sign and weight */
   11836      2189280 :     if (ndigits == 0)
   11837              :     {
   11838        34029 :         var->sign = NUMERIC_POS;
   11839        34029 :         var->weight = 0;
   11840              :     }
   11841              : 
   11842      2189280 :     var->digits = digits;
   11843      2189280 :     var->ndigits = ndigits;
   11844      2189280 : }
   11845              : 
   11846              : 
   11847              : /* ----------------------------------------------------------------------
   11848              :  *
   11849              :  * Fast sum accumulator functions
   11850              :  *
   11851              :  * ----------------------------------------------------------------------
   11852              :  */
   11853              : 
   11854              : /*
   11855              :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   11856              :  * are not free'd.
   11857              :  */
   11858              : static void
   11859           12 : accum_sum_reset(NumericSumAccum *accum)
   11860              : {
   11861              :     int         i;
   11862              : 
   11863           12 :     accum->dscale = 0;
   11864           44 :     for (i = 0; i < accum->ndigits; i++)
   11865              :     {
   11866           32 :         accum->pos_digits[i] = 0;
   11867           32 :         accum->neg_digits[i] = 0;
   11868              :     }
   11869           12 : }
   11870              : 
   11871              : /*
   11872              :  * Accumulate a new value.
   11873              :  */
   11874              : static void
   11875      1570442 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   11876              : {
   11877              :     int32      *accum_digits;
   11878              :     int         i,
   11879              :                 val_i;
   11880              :     int         val_ndigits;
   11881              :     NumericDigit *val_digits;
   11882              : 
   11883              :     /*
   11884              :      * If we have accumulated too many values since the last carry
   11885              :      * propagation, do it now, to avoid overflowing.  (We could allow more
   11886              :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   11887              :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   11888              :      * seldom, that the performance difference is negligible.)
   11889              :      */
   11890      1570442 :     if (accum->num_uncarried == NBASE - 1)
   11891          104 :         accum_sum_carry(accum);
   11892              : 
   11893              :     /*
   11894              :      * Adjust the weight or scale of the old value, so that it can accommodate
   11895              :      * the new value.
   11896              :      */
   11897      1570442 :     accum_sum_rescale(accum, val);
   11898              : 
   11899              :     /* */
   11900      1570442 :     if (val->sign == NUMERIC_POS)
   11901      1169990 :         accum_digits = accum->pos_digits;
   11902              :     else
   11903       400452 :         accum_digits = accum->neg_digits;
   11904              : 
   11905              :     /* copy these values into local vars for speed in loop */
   11906      1570442 :     val_ndigits = val->ndigits;
   11907      1570442 :     val_digits = val->digits;
   11908              : 
   11909      1570442 :     i = accum->weight - val->weight;
   11910      7926575 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   11911              :     {
   11912      6356133 :         accum_digits[i] += (int32) val_digits[val_i];
   11913      6356133 :         i++;
   11914              :     }
   11915              : 
   11916      1570442 :     accum->num_uncarried++;
   11917      1570442 : }
   11918              : 
   11919              : /*
   11920              :  * Propagate carries.
   11921              :  */
   11922              : static void
   11923       115156 : accum_sum_carry(NumericSumAccum *accum)
   11924              : {
   11925              :     int         i;
   11926              :     int         ndigits;
   11927              :     int32      *dig;
   11928              :     int32       carry;
   11929       115156 :     int32       newdig = 0;
   11930              : 
   11931              :     /*
   11932              :      * If no new values have been added since last carry propagation, nothing
   11933              :      * to do.
   11934              :      */
   11935       115156 :     if (accum->num_uncarried == 0)
   11936           48 :         return;
   11937              : 
   11938              :     /*
   11939              :      * We maintain that the weight of the accumulator is always one larger
   11940              :      * than needed to hold the current value, before carrying, to make sure
   11941              :      * there is enough space for the possible extra digit when carry is
   11942              :      * propagated.  We cannot expand the buffer here, unless we require
   11943              :      * callers of accum_sum_final() to switch to the right memory context.
   11944              :      */
   11945              :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   11946              : 
   11947       115108 :     ndigits = accum->ndigits;
   11948              : 
   11949              :     /* Propagate carry in the positive sum */
   11950       115108 :     dig = accum->pos_digits;
   11951       115108 :     carry = 0;
   11952      1736976 :     for (i = ndigits - 1; i >= 0; i--)
   11953              :     {
   11954      1621868 :         newdig = dig[i] + carry;
   11955      1621868 :         if (newdig >= NBASE)
   11956              :         {
   11957        73872 :             carry = newdig / NBASE;
   11958        73872 :             newdig -= carry * NBASE;
   11959              :         }
   11960              :         else
   11961      1547996 :             carry = 0;
   11962      1621868 :         dig[i] = newdig;
   11963              :     }
   11964              :     /* Did we use up the digit reserved for carry propagation? */
   11965       115108 :     if (newdig > 0)
   11966         1760 :         accum->have_carry_space = false;
   11967              : 
   11968              :     /* And the same for the negative sum */
   11969       115108 :     dig = accum->neg_digits;
   11970       115108 :     carry = 0;
   11971      1736976 :     for (i = ndigits - 1; i >= 0; i--)
   11972              :     {
   11973      1621868 :         newdig = dig[i] + carry;
   11974      1621868 :         if (newdig >= NBASE)
   11975              :         {
   11976          132 :             carry = newdig / NBASE;
   11977          132 :             newdig -= carry * NBASE;
   11978              :         }
   11979              :         else
   11980      1621736 :             carry = 0;
   11981      1621868 :         dig[i] = newdig;
   11982              :     }
   11983       115108 :     if (newdig > 0)
   11984           20 :         accum->have_carry_space = false;
   11985              : 
   11986       115108 :     accum->num_uncarried = 0;
   11987              : }
   11988              : 
   11989              : /*
   11990              :  * Re-scale accumulator to accommodate new value.
   11991              :  *
   11992              :  * If the new value has more digits than the current digit buffers in the
   11993              :  * accumulator, enlarge the buffers.
   11994              :  */
   11995              : static void
   11996      1570442 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   11997              : {
   11998      1570442 :     int         old_weight = accum->weight;
   11999      1570442 :     int         old_ndigits = accum->ndigits;
   12000              :     int         accum_ndigits;
   12001              :     int         accum_weight;
   12002              :     int         accum_rscale;
   12003              :     int         val_rscale;
   12004              : 
   12005      1570442 :     accum_weight = old_weight;
   12006      1570442 :     accum_ndigits = old_ndigits;
   12007              : 
   12008              :     /*
   12009              :      * Does the new value have a larger weight? If so, enlarge the buffers,
   12010              :      * and shift the existing value to the new weight, by adding leading
   12011              :      * zeros.
   12012              :      *
   12013              :      * We enforce that the accumulator always has a weight one larger than
   12014              :      * needed for the inputs, so that we have space for an extra digit at the
   12015              :      * final carry-propagation phase, if necessary.
   12016              :      */
   12017      1570442 :     if (val->weight >= accum_weight)
   12018              :     {
   12019       174800 :         accum_weight = val->weight + 1;
   12020       174800 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   12021              :     }
   12022              : 
   12023              :     /*
   12024              :      * Even though the new value is small, we might've used up the space
   12025              :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   12026              :      * so, enlarge to make room for another one.
   12027              :      */
   12028      1395642 :     else if (!accum->have_carry_space)
   12029              :     {
   12030           52 :         accum_weight++;
   12031           52 :         accum_ndigits++;
   12032              :     }
   12033              : 
   12034              :     /* Is the new value wider on the right side? */
   12035      1570442 :     accum_rscale = accum_ndigits - accum_weight - 1;
   12036      1570442 :     val_rscale = val->ndigits - val->weight - 1;
   12037      1570442 :     if (val_rscale > accum_rscale)
   12038       114816 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   12039              : 
   12040      1570442 :     if (accum_ndigits != old_ndigits ||
   12041              :         accum_weight != old_weight)
   12042              :     {
   12043              :         int32      *new_pos_digits;
   12044              :         int32      *new_neg_digits;
   12045              :         int         weightdiff;
   12046              : 
   12047       175057 :         weightdiff = accum_weight - old_weight;
   12048              : 
   12049       175057 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   12050       175057 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   12051              : 
   12052       175057 :         if (accum->pos_digits)
   12053              :         {
   12054        60289 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   12055              :                    old_ndigits * sizeof(int32));
   12056        60289 :             pfree(accum->pos_digits);
   12057              : 
   12058        60289 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   12059              :                    old_ndigits * sizeof(int32));
   12060        60289 :             pfree(accum->neg_digits);
   12061              :         }
   12062              : 
   12063       175057 :         accum->pos_digits = new_pos_digits;
   12064       175057 :         accum->neg_digits = new_neg_digits;
   12065              : 
   12066       175057 :         accum->weight = accum_weight;
   12067       175057 :         accum->ndigits = accum_ndigits;
   12068              : 
   12069              :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12070       175057 :         accum->have_carry_space = true;
   12071              :     }
   12072              : 
   12073      1570442 :     if (val->dscale > accum->dscale)
   12074          200 :         accum->dscale = val->dscale;
   12075      1570442 : }
   12076              : 
   12077              : /*
   12078              :  * Return the current value of the accumulator.  This perform final carry
   12079              :  * propagation, and adds together the positive and negative sums.
   12080              :  *
   12081              :  * Unlike all the other routines, the caller is not required to switch to
   12082              :  * the memory context that holds the accumulator.
   12083              :  */
   12084              : static void
   12085       115052 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   12086              : {
   12087              :     int         i;
   12088              :     NumericVar  pos_var;
   12089              :     NumericVar  neg_var;
   12090              : 
   12091       115052 :     if (accum->ndigits == 0)
   12092              :     {
   12093            0 :         set_var_from_var(&const_zero, result);
   12094            0 :         return;
   12095              :     }
   12096              : 
   12097              :     /* Perform final carry */
   12098       115052 :     accum_sum_carry(accum);
   12099              : 
   12100              :     /* Create NumericVars representing the positive and negative sums */
   12101       115052 :     init_var(&pos_var);
   12102       115052 :     init_var(&neg_var);
   12103              : 
   12104       115052 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   12105       115052 :     pos_var.weight = neg_var.weight = accum->weight;
   12106       115052 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   12107       115052 :     pos_var.sign = NUMERIC_POS;
   12108       115052 :     neg_var.sign = NUMERIC_NEG;
   12109              : 
   12110       115052 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   12111       115052 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   12112              : 
   12113      1736682 :     for (i = 0; i < accum->ndigits; i++)
   12114              :     {
   12115              :         Assert(accum->pos_digits[i] < NBASE);
   12116      1621630 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   12117              : 
   12118              :         Assert(accum->neg_digits[i] < NBASE);
   12119      1621630 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   12120              :     }
   12121              : 
   12122              :     /* And add them together */
   12123       115052 :     add_var(&pos_var, &neg_var, result);
   12124              : 
   12125              :     /* Remove leading/trailing zeroes */
   12126       115052 :     strip_var(result);
   12127              : }
   12128              : 
   12129              : /*
   12130              :  * Copy an accumulator's state.
   12131              :  *
   12132              :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   12133              :  * freeing old values.
   12134              :  */
   12135              : static void
   12136           28 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   12137              : {
   12138           28 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12139           28 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12140              : 
   12141           28 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12142           28 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12143           28 :     dst->num_uncarried = src->num_uncarried;
   12144           28 :     dst->ndigits = src->ndigits;
   12145           28 :     dst->weight = src->weight;
   12146           28 :     dst->dscale = src->dscale;
   12147           28 : }
   12148              : 
   12149              : /*
   12150              :  * Add the current value of 'accum2' into 'accum'.
   12151              :  */
   12152              : static void
   12153           33 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12154              : {
   12155              :     NumericVar  tmp_var;
   12156              : 
   12157           33 :     init_var(&tmp_var);
   12158              : 
   12159           33 :     accum_sum_final(accum2, &tmp_var);
   12160           33 :     accum_sum_add(accum, &tmp_var);
   12161              : 
   12162           33 :     free_var(&tmp_var);
   12163           33 : }
        

Generated by: LCOV version 2.0-1