LCOV - code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 3787 4007 94.5 %
Date: 2024-11-21 08:14:44 Functions: 208 209 99.5 %
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-2024, 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 "funcapi.h"
      32             : #include "lib/hyperloglog.h"
      33             : #include "libpq/pqformat.h"
      34             : #include "miscadmin.h"
      35             : #include "nodes/nodeFuncs.h"
      36             : #include "nodes/supportnodes.h"
      37             : #include "utils/array.h"
      38             : #include "utils/builtins.h"
      39             : #include "utils/float.h"
      40             : #include "utils/guc.h"
      41             : #include "utils/numeric.h"
      42             : #include "utils/pg_lsn.h"
      43             : #include "utils/sortsupport.h"
      44             : 
      45             : /* ----------
      46             :  * Uncomment the following to enable compilation of dump_numeric()
      47             :  * and dump_var() and to get a dump of any result produced by make_result().
      48             :  * ----------
      49             : #define NUMERIC_DEBUG
      50             :  */
      51             : 
      52             : 
      53             : /* ----------
      54             :  * Local data types
      55             :  *
      56             :  * Numeric values are represented in a base-NBASE floating point format.
      57             :  * Each "digit" ranges from 0 to NBASE-1.  The type NumericDigit is signed
      58             :  * and wide enough to store a digit.  We assume that NBASE*NBASE can fit in
      59             :  * an int.  Although the purely calculational routines could handle any even
      60             :  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
      61             :  * in NBASE a power of ten, so that I/O conversions and decimal rounding
      62             :  * are easy.  Also, it's actually more efficient if NBASE is rather less than
      63             :  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var to
      64             :  * postpone processing carries.
      65             :  *
      66             :  * Values of NBASE other than 10000 are considered of historical interest only
      67             :  * and are no longer supported in any sense; no mechanism exists for the client
      68             :  * to discover the base, so every client supporting binary mode expects the
      69             :  * base-10000 format.  If you plan to change this, also note the numeric
      70             :  * abbreviation code, which assumes NBASE=10000.
      71             :  * ----------
      72             :  */
      73             : 
      74             : #if 0
      75             : #define NBASE       10
      76             : #define HALF_NBASE  5
      77             : #define DEC_DIGITS  1           /* decimal digits per NBASE digit */
      78             : #define MUL_GUARD_DIGITS    4   /* these are measured in NBASE digits */
      79             : #define DIV_GUARD_DIGITS    8
      80             : 
      81             : typedef signed char NumericDigit;
      82             : #endif
      83             : 
      84             : #if 0
      85             : #define NBASE       100
      86             : #define HALF_NBASE  50
      87             : #define DEC_DIGITS  2           /* decimal digits per NBASE digit */
      88             : #define MUL_GUARD_DIGITS    3   /* these are measured in NBASE digits */
      89             : #define DIV_GUARD_DIGITS    6
      90             : 
      91             : typedef signed char NumericDigit;
      92             : #endif
      93             : 
      94             : #if 1
      95             : #define NBASE       10000
      96             : #define HALF_NBASE  5000
      97             : #define DEC_DIGITS  4           /* decimal digits per NBASE digit */
      98             : #define MUL_GUARD_DIGITS    2   /* these are measured in NBASE digits */
      99             : #define DIV_GUARD_DIGITS    4
     100             : 
     101             : typedef int16 NumericDigit;
     102             : #endif
     103             : 
     104             : #define NBASE_SQR   (NBASE * NBASE)
     105             : 
     106             : /*
     107             :  * The Numeric type as stored on disk.
     108             :  *
     109             :  * If the high bits of the first word of a NumericChoice (n_header, or
     110             :  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
     111             :  * numeric follows the NumericShort format; if they are NUMERIC_POS or
     112             :  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
     113             :  * the value is a NaN or Infinity.  We currently always store SPECIAL values
     114             :  * using just two bytes (i.e. only n_header), but previous releases used only
     115             :  * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
     116             :  * on disk if a database has been migrated using pg_upgrade.  In either case,
     117             :  * the low-order bits of a special value's header are reserved and currently
     118             :  * should always be set to zero.
     119             :  *
     120             :  * In the NumericShort format, the remaining 14 bits of the header word
     121             :  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
     122             :  * negative), 6 for dynamic scale, and 7 for weight.  In practice, most
     123             :  * commonly-encountered values can be represented this way.
     124             :  *
     125             :  * In the NumericLong format, the remaining 14 bits of the header word
     126             :  * (n_long.n_sign_dscale) represent the display scale; and the weight is
     127             :  * stored separately in n_weight.
     128             :  *
     129             :  * NOTE: by convention, values in the packed form have been stripped of
     130             :  * all leading and trailing zero digits (where a "digit" is of base NBASE).
     131             :  * In particular, if the value is zero, there will be no digits at all!
     132             :  * The weight is arbitrary in that case, but we normally set it to zero.
     133             :  */
     134             : 
     135             : struct NumericShort
     136             : {
     137             :     uint16      n_header;       /* Sign + display scale + weight */
     138             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     139             : };
     140             : 
     141             : struct NumericLong
     142             : {
     143             :     uint16      n_sign_dscale;  /* Sign + display scale */
     144             :     int16       n_weight;       /* Weight of 1st digit  */
     145             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     146             : };
     147             : 
     148             : union NumericChoice
     149             : {
     150             :     uint16      n_header;       /* Header word */
     151             :     struct NumericLong n_long;  /* Long form (4-byte header) */
     152             :     struct NumericShort n_short;    /* Short form (2-byte header) */
     153             : };
     154             : 
     155             : struct NumericData
     156             : {
     157             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     158             :     union NumericChoice choice; /* choice of format */
     159             : };
     160             : 
     161             : 
     162             : /*
     163             :  * Interpretation of high bits.
     164             :  */
     165             : 
     166             : #define NUMERIC_SIGN_MASK   0xC000
     167             : #define NUMERIC_POS         0x0000
     168             : #define NUMERIC_NEG         0x4000
     169             : #define NUMERIC_SHORT       0x8000
     170             : #define NUMERIC_SPECIAL     0xC000
     171             : 
     172             : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
     173             : #define NUMERIC_IS_SHORT(n)     (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
     174             : #define NUMERIC_IS_SPECIAL(n)   (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
     175             : 
     176             : #define NUMERIC_HDRSZ   (VARHDRSZ + sizeof(uint16) + sizeof(int16))
     177             : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
     178             : 
     179             : /*
     180             :  * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
     181             :  * header; otherwise, we want the long one.  Instead of testing against each
     182             :  * value, we can just look at the high bit, for a slight efficiency gain.
     183             :  */
     184             : #define NUMERIC_HEADER_IS_SHORT(n)  (((n)->choice.n_header & 0x8000) != 0)
     185             : #define NUMERIC_HEADER_SIZE(n) \
     186             :     (VARHDRSZ + sizeof(uint16) + \
     187             :      (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
     188             : 
     189             : /*
     190             :  * Definitions for special values (NaN, positive infinity, negative infinity).
     191             :  *
     192             :  * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
     193             :  * infinity, 11 for negative infinity.  (This makes the sign bit match where
     194             :  * it is in a short-format value, though we make no use of that at present.)
     195             :  * We could mask off the remaining bits before testing the active bits, but
     196             :  * currently those bits must be zeroes, so masking would just add cycles.
     197             :  */
     198             : #define NUMERIC_EXT_SIGN_MASK   0xF000  /* high bits plus NaN/Inf flag bits */
     199             : #define NUMERIC_NAN             0xC000
     200             : #define NUMERIC_PINF            0xD000
     201             : #define NUMERIC_NINF            0xF000
     202             : #define NUMERIC_INF_SIGN_MASK   0x2000
     203             : 
     204             : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
     205             : #define NUMERIC_IS_NAN(n)       ((n)->choice.n_header == NUMERIC_NAN)
     206             : #define NUMERIC_IS_PINF(n)      ((n)->choice.n_header == NUMERIC_PINF)
     207             : #define NUMERIC_IS_NINF(n)      ((n)->choice.n_header == NUMERIC_NINF)
     208             : #define NUMERIC_IS_INF(n) \
     209             :     (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
     210             : 
     211             : /*
     212             :  * Short format definitions.
     213             :  */
     214             : 
     215             : #define NUMERIC_SHORT_SIGN_MASK         0x2000
     216             : #define NUMERIC_SHORT_DSCALE_MASK       0x1F80
     217             : #define NUMERIC_SHORT_DSCALE_SHIFT      7
     218             : #define NUMERIC_SHORT_DSCALE_MAX        \
     219             :     (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
     220             : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK  0x0040
     221             : #define NUMERIC_SHORT_WEIGHT_MASK       0x003F
     222             : #define NUMERIC_SHORT_WEIGHT_MAX        NUMERIC_SHORT_WEIGHT_MASK
     223             : #define NUMERIC_SHORT_WEIGHT_MIN        (-(NUMERIC_SHORT_WEIGHT_MASK+1))
     224             : 
     225             : /*
     226             :  * Extract sign, display scale, weight.  These macros extract field values
     227             :  * suitable for the NumericVar format from the Numeric (on-disk) format.
     228             :  *
     229             :  * Note that we don't trouble to ensure that dscale and weight read as zero
     230             :  * for an infinity; however, that doesn't matter since we never convert
     231             :  * "special" numerics to NumericVar form.  Only the constants defined below
     232             :  * (const_nan, etc) ever represent a non-finite value as a NumericVar.
     233             :  */
     234             : 
     235             : #define NUMERIC_DSCALE_MASK         0x3FFF
     236             : #define NUMERIC_DSCALE_MAX          NUMERIC_DSCALE_MASK
     237             : 
     238             : #define NUMERIC_SIGN(n) \
     239             :     (NUMERIC_IS_SHORT(n) ? \
     240             :         (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
     241             :          NUMERIC_NEG : NUMERIC_POS) : \
     242             :         (NUMERIC_IS_SPECIAL(n) ? \
     243             :          NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
     244             : #define NUMERIC_DSCALE(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     245             :     ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
     246             :         >> NUMERIC_SHORT_DSCALE_SHIFT \
     247             :     : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
     248             : #define NUMERIC_WEIGHT(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     249             :     (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
     250             :         ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
     251             :      | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
     252             :     : ((n)->choice.n_long.n_weight))
     253             : 
     254             : /*
     255             :  * Maximum weight of a stored Numeric value (based on the use of int16 for the
     256             :  * weight in NumericLong).  Note that intermediate values held in NumericVar
     257             :  * and NumericSumAccum variables may have much larger weights.
     258             :  */
     259             : #define NUMERIC_WEIGHT_MAX          PG_INT16_MAX
     260             : 
     261             : /* ----------
     262             :  * NumericVar is the format we use for arithmetic.  The digit-array part
     263             :  * is the same as the NumericData storage format, but the header is more
     264             :  * complex.
     265             :  *
     266             :  * The value represented by a NumericVar is determined by the sign, weight,
     267             :  * ndigits, and digits[] array.  If it is a "special" value (NaN or Inf)
     268             :  * then only the sign field matters; ndigits should be zero, and the weight
     269             :  * and dscale fields are ignored.
     270             :  *
     271             :  * Note: the first digit of a NumericVar's value is assumed to be multiplied
     272             :  * by NBASE ** weight.  Another way to say it is that there are weight+1
     273             :  * digits before the decimal point.  It is possible to have weight < 0.
     274             :  *
     275             :  * buf points at the physical start of the palloc'd digit buffer for the
     276             :  * NumericVar.  digits points at the first digit in actual use (the one
     277             :  * with the specified weight).  We normally leave an unused digit or two
     278             :  * (preset to zeroes) between buf and digits, so that there is room to store
     279             :  * a carry out of the top digit without reallocating space.  We just need to
     280             :  * decrement digits (and increment weight) to make room for the carry digit.
     281             :  * (There is no such extra space in a numeric value stored in the database,
     282             :  * only in a NumericVar in memory.)
     283             :  *
     284             :  * If buf is NULL then the digit buffer isn't actually palloc'd and should
     285             :  * not be freed --- see the constants below for an example.
     286             :  *
     287             :  * dscale, or display scale, is the nominal precision expressed as number
     288             :  * of digits after the decimal point (it must always be >= 0 at present).
     289             :  * dscale may be more than the number of physically stored fractional digits,
     290             :  * implying that we have suppressed storage of significant trailing zeroes.
     291             :  * It should never be less than the number of stored digits, since that would
     292             :  * imply hiding digits that are present.  NOTE that dscale is always expressed
     293             :  * in *decimal* digits, and so it may correspond to a fractional number of
     294             :  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
     295             :  *
     296             :  * rscale, or result scale, is the target precision for a computation.
     297             :  * Like dscale it is expressed as number of *decimal* digits after the decimal
     298             :  * point, and is always >= 0 at present.
     299             :  * Note that rscale is not stored in variables --- it's figured on-the-fly
     300             :  * from the dscales of the inputs.
     301             :  *
     302             :  * While we consistently use "weight" to refer to the base-NBASE weight of
     303             :  * a numeric value, it is convenient in some scale-related calculations to
     304             :  * make use of the base-10 weight (ie, the approximate log10 of the value).
     305             :  * To avoid confusion, such a decimal-units weight is called a "dweight".
     306             :  *
     307             :  * NB: All the variable-level functions are written in a style that makes it
     308             :  * possible to give one and the same variable as argument and destination.
     309             :  * This is feasible because the digit buffer is separate from the variable.
     310             :  * ----------
     311             :  */
     312             : typedef struct NumericVar
     313             : {
     314             :     int         ndigits;        /* # of digits in digits[] - can be 0! */
     315             :     int         weight;         /* weight of first digit */
     316             :     int         sign;           /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
     317             :     int         dscale;         /* display scale */
     318             :     NumericDigit *buf;          /* start of palloc'd space for digits[] */
     319             :     NumericDigit *digits;       /* base-NBASE digits */
     320             : } NumericVar;
     321             : 
     322             : 
     323             : /* ----------
     324             :  * Data for generate_series
     325             :  * ----------
     326             :  */
     327             : typedef struct
     328             : {
     329             :     NumericVar  current;
     330             :     NumericVar  stop;
     331             :     NumericVar  step;
     332             : } generate_series_numeric_fctx;
     333             : 
     334             : 
     335             : /* ----------
     336             :  * Sort support.
     337             :  * ----------
     338             :  */
     339             : typedef struct
     340             : {
     341             :     void       *buf;            /* buffer for short varlenas */
     342             :     int64       input_count;    /* number of non-null values seen */
     343             :     bool        estimating;     /* true if estimating cardinality */
     344             : 
     345             :     hyperLogLogState abbr_card; /* cardinality estimator */
     346             : } NumericSortSupport;
     347             : 
     348             : 
     349             : /* ----------
     350             :  * Fast sum accumulator.
     351             :  *
     352             :  * NumericSumAccum is used to implement SUM(), and other standard aggregates
     353             :  * that track the sum of input values.  It uses 32-bit integers to store the
     354             :  * digits, instead of the normal 16-bit integers (with NBASE=10000).  This
     355             :  * way, we can safely accumulate up to NBASE - 1 values without propagating
     356             :  * carry, before risking overflow of any of the digits.  'num_uncarried'
     357             :  * tracks how many values have been accumulated without propagating carry.
     358             :  *
     359             :  * Positive and negative values are accumulated separately, in 'pos_digits'
     360             :  * and 'neg_digits'.  This is simpler and faster than deciding whether to add
     361             :  * or subtract from the current value, for each new value (see sub_var() for
     362             :  * the logic we avoid by doing this).  Both buffers are of same size, and
     363             :  * have the same weight and scale.  In accum_sum_final(), the positive and
     364             :  * negative sums are added together to produce the final result.
     365             :  *
     366             :  * When a new value has a larger ndigits or weight than the accumulator
     367             :  * currently does, the accumulator is enlarged to accommodate the new value.
     368             :  * We normally have one zero digit reserved for carry propagation, and that
     369             :  * is indicated by the 'have_carry_space' flag.  When accum_sum_carry() uses
     370             :  * up the reserved digit, it clears the 'have_carry_space' flag.  The next
     371             :  * call to accum_sum_add() will enlarge the buffer, to make room for the
     372             :  * extra digit, and set the flag again.
     373             :  *
     374             :  * To initialize a new accumulator, simply reset all fields to zeros.
     375             :  *
     376             :  * The accumulator does not handle NaNs.
     377             :  * ----------
     378             :  */
     379             : typedef struct NumericSumAccum
     380             : {
     381             :     int         ndigits;
     382             :     int         weight;
     383             :     int         dscale;
     384             :     int         num_uncarried;
     385             :     bool        have_carry_space;
     386             :     int32      *pos_digits;
     387             :     int32      *neg_digits;
     388             : } NumericSumAccum;
     389             : 
     390             : 
     391             : /*
     392             :  * We define our own macros for packing and unpacking abbreviated-key
     393             :  * representations for numeric values in order to avoid depending on
     394             :  * USE_FLOAT8_BYVAL.  The type of abbreviation we use is based only on
     395             :  * the size of a datum, not the argument-passing convention for float8.
     396             :  *
     397             :  * The range of abbreviations for finite values is from +PG_INT64/32_MAX
     398             :  * to -PG_INT64/32_MAX.  NaN has the abbreviation PG_INT64/32_MIN, and we
     399             :  * define the sort ordering to make that work out properly (see further
     400             :  * comments below).  PINF and NINF share the abbreviations of the largest
     401             :  * and smallest finite abbreviation classes.
     402             :  */
     403             : #define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
     404             : #if SIZEOF_DATUM == 8
     405             : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     406             : #define DatumGetNumericAbbrev(X) ((int64) (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             : #else
     411             : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     412             : #define DatumGetNumericAbbrev(X) ((int32) (X))
     413             : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT32_MIN)
     414             : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT32_MAX)
     415             : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT32_MAX)
     416             : #endif
     417             : 
     418             : 
     419             : /* ----------
     420             :  * Some preinitialized constants
     421             :  * ----------
     422             :  */
     423             : static const NumericDigit const_zero_data[1] = {0};
     424             : static const NumericVar const_zero =
     425             : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
     426             : 
     427             : static const NumericDigit const_one_data[1] = {1};
     428             : static const NumericVar const_one =
     429             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
     430             : 
     431             : static const NumericVar const_minus_one =
     432             : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
     433             : 
     434             : static const NumericDigit const_two_data[1] = {2};
     435             : static const NumericVar const_two =
     436             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
     437             : 
     438             : #if DEC_DIGITS == 4
     439             : static const NumericDigit const_zero_point_nine_data[1] = {9000};
     440             : #elif DEC_DIGITS == 2
     441             : static const NumericDigit const_zero_point_nine_data[1] = {90};
     442             : #elif DEC_DIGITS == 1
     443             : static const NumericDigit const_zero_point_nine_data[1] = {9};
     444             : #endif
     445             : static const NumericVar const_zero_point_nine =
     446             : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
     447             : 
     448             : #if DEC_DIGITS == 4
     449             : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
     450             : #elif DEC_DIGITS == 2
     451             : static const NumericDigit const_one_point_one_data[2] = {1, 10};
     452             : #elif DEC_DIGITS == 1
     453             : static const NumericDigit const_one_point_one_data[2] = {1, 1};
     454             : #endif
     455             : static const NumericVar const_one_point_one =
     456             : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
     457             : 
     458             : static const NumericVar const_nan =
     459             : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
     460             : 
     461             : static const NumericVar const_pinf =
     462             : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
     463             : 
     464             : static const NumericVar const_ninf =
     465             : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
     466             : 
     467             : #if DEC_DIGITS == 4
     468             : static const int round_powers[4] = {0, 1000, 100, 10};
     469             : #endif
     470             : 
     471             : 
     472             : /* ----------
     473             :  * Local functions
     474             :  * ----------
     475             :  */
     476             : 
     477             : #ifdef NUMERIC_DEBUG
     478             : static void dump_numeric(const char *str, Numeric num);
     479             : static void dump_var(const char *str, NumericVar *var);
     480             : #else
     481             : #define dump_numeric(s,n)
     482             : #define dump_var(s,v)
     483             : #endif
     484             : 
     485             : #define digitbuf_alloc(ndigits)  \
     486             :     ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
     487             : #define digitbuf_free(buf)  \
     488             :     do { \
     489             :          if ((buf) != NULL) \
     490             :              pfree(buf); \
     491             :     } while (0)
     492             : 
     493             : #define init_var(v)     memset(v, 0, sizeof(NumericVar))
     494             : 
     495             : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
     496             :     (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
     497             : #define NUMERIC_NDIGITS(num) \
     498             :     ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
     499             : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
     500             :     ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
     501             :     (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
     502             :     (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
     503             : 
     504             : static void alloc_var(NumericVar *var, int ndigits);
     505             : static void free_var(NumericVar *var);
     506             : static void zero_var(NumericVar *var);
     507             : 
     508             : static bool set_var_from_str(const char *str, const char *cp,
     509             :                              NumericVar *dest, const char **endptr,
     510             :                              Node *escontext);
     511             : static bool set_var_from_non_decimal_integer_str(const char *str,
     512             :                                                  const char *cp, int sign,
     513             :                                                  int base, NumericVar *dest,
     514             :                                                  const char **endptr,
     515             :                                                  Node *escontext);
     516             : static void set_var_from_num(Numeric num, NumericVar *dest);
     517             : static void init_var_from_num(Numeric num, NumericVar *dest);
     518             : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
     519             : static char *get_str_from_var(const NumericVar *var);
     520             : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
     521             : 
     522             : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
     523             : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
     524             : 
     525             : static Numeric duplicate_numeric(Numeric num);
     526             : static Numeric make_result(const NumericVar *var);
     527             : static Numeric make_result_opt_error(const NumericVar *var, bool *have_error);
     528             : 
     529             : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
     530             : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
     531             : 
     532             : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
     533             : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
     534             : static void int64_to_numericvar(int64 val, NumericVar *var);
     535             : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
     536             : #ifdef HAVE_INT128
     537             : static bool numericvar_to_int128(const NumericVar *var, int128 *result);
     538             : static void int128_to_numericvar(int128 val, NumericVar *var);
     539             : #endif
     540             : static double numericvar_to_double_no_overflow(const NumericVar *var);
     541             : 
     542             : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
     543             : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
     544             : static int  numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
     545             : static int  numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
     546             : 
     547             : static Datum numeric_abbrev_convert_var(const NumericVar *var,
     548             :                                         NumericSortSupport *nss);
     549             : 
     550             : static int  cmp_numerics(Numeric num1, Numeric num2);
     551             : static int  cmp_var(const NumericVar *var1, const NumericVar *var2);
     552             : static int  cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
     553             :                            int var1weight, int var1sign,
     554             :                            const NumericDigit *var2digits, int var2ndigits,
     555             :                            int var2weight, int var2sign);
     556             : static void add_var(const NumericVar *var1, const NumericVar *var2,
     557             :                     NumericVar *result);
     558             : static void sub_var(const NumericVar *var1, const NumericVar *var2,
     559             :                     NumericVar *result);
     560             : static void mul_var(const NumericVar *var1, const NumericVar *var2,
     561             :                     NumericVar *result,
     562             :                     int rscale);
     563             : static void mul_var_short(const NumericVar *var1, const NumericVar *var2,
     564             :                           NumericVar *result);
     565             : static void div_var(const NumericVar *var1, const NumericVar *var2,
     566             :                     NumericVar *result, int rscale, bool round, bool exact);
     567             : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
     568             :                         NumericVar *result, int rscale, bool round);
     569             : #ifdef HAVE_INT128
     570             : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
     571             :                           NumericVar *result, int rscale, bool round);
     572             : #endif
     573             : static int  select_div_scale(const NumericVar *var1, const NumericVar *var2);
     574             : static void mod_var(const NumericVar *var1, const NumericVar *var2,
     575             :                     NumericVar *result);
     576             : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
     577             :                         NumericVar *quot, NumericVar *rem);
     578             : static void ceil_var(const NumericVar *var, NumericVar *result);
     579             : static void floor_var(const NumericVar *var, NumericVar *result);
     580             : 
     581             : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
     582             :                     NumericVar *result);
     583             : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
     584             : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
     585             : static int  estimate_ln_dweight(const NumericVar *var);
     586             : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
     587             : static void log_var(const NumericVar *base, const NumericVar *num,
     588             :                     NumericVar *result);
     589             : static void power_var(const NumericVar *base, const NumericVar *exp,
     590             :                       NumericVar *result);
     591             : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
     592             :                           NumericVar *result);
     593             : static void power_ten_int(int exp, NumericVar *result);
     594             : static void random_var(pg_prng_state *state, const NumericVar *rmin,
     595             :                        const NumericVar *rmax, NumericVar *result);
     596             : 
     597             : static int  cmp_abs(const NumericVar *var1, const NumericVar *var2);
     598             : static int  cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
     599             :                            int var1weight,
     600             :                            const NumericDigit *var2digits, int var2ndigits,
     601             :                            int var2weight);
     602             : static void add_abs(const NumericVar *var1, const NumericVar *var2,
     603             :                     NumericVar *result);
     604             : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
     605             :                     NumericVar *result);
     606             : static void round_var(NumericVar *var, int rscale);
     607             : static void trunc_var(NumericVar *var, int rscale);
     608             : static void strip_var(NumericVar *var);
     609             : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
     610             :                            const NumericVar *count_var,
     611             :                            NumericVar *result_var);
     612             : 
     613             : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
     614             : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
     615             : static void accum_sum_carry(NumericSumAccum *accum);
     616             : static void accum_sum_reset(NumericSumAccum *accum);
     617             : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
     618             : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
     619             : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
     620             : 
     621             : 
     622             : /* ----------------------------------------------------------------------
     623             :  *
     624             :  * Input-, output- and rounding-functions
     625             :  *
     626             :  * ----------------------------------------------------------------------
     627             :  */
     628             : 
     629             : 
     630             : /*
     631             :  * numeric_in() -
     632             :  *
     633             :  *  Input function for numeric data type
     634             :  */
     635             : Datum
     636      108188 : numeric_in(PG_FUNCTION_ARGS)
     637             : {
     638      108188 :     char       *str = PG_GETARG_CSTRING(0);
     639             : #ifdef NOT_USED
     640             :     Oid         typelem = PG_GETARG_OID(1);
     641             : #endif
     642      108188 :     int32       typmod = PG_GETARG_INT32(2);
     643      108188 :     Node       *escontext = fcinfo->context;
     644             :     Numeric     res;
     645             :     const char *cp;
     646             :     const char *numstart;
     647             :     int         sign;
     648             : 
     649             :     /* Skip leading spaces */
     650      108188 :     cp = str;
     651      108578 :     while (*cp)
     652             :     {
     653      108566 :         if (!isspace((unsigned char) *cp))
     654      108176 :             break;
     655         390 :         cp++;
     656             :     }
     657             : 
     658             :     /*
     659             :      * Process the number's sign. This duplicates logic in set_var_from_str(),
     660             :      * but it's worth doing here, since it simplifies the handling of
     661             :      * infinities and non-decimal integers.
     662             :      */
     663      108188 :     numstart = cp;
     664      108188 :     sign = NUMERIC_POS;
     665             : 
     666      108188 :     if (*cp == '+')
     667          48 :         cp++;
     668      108140 :     else if (*cp == '-')
     669             :     {
     670        3726 :         sign = NUMERIC_NEG;
     671        3726 :         cp++;
     672             :     }
     673             : 
     674             :     /*
     675             :      * Check for NaN and infinities.  We recognize the same strings allowed by
     676             :      * float8in().
     677             :      *
     678             :      * Since all other legal inputs have a digit or a decimal point after the
     679             :      * sign, we need only check for NaN/infinity if that's not the case.
     680             :      */
     681      108188 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
     682             :     {
     683             :         /*
     684             :          * The number must be NaN or infinity; anything else can only be a
     685             :          * syntax error. Note that NaN mustn't have a sign.
     686             :          */
     687        1758 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     688             :         {
     689         586 :             res = make_result(&const_nan);
     690         586 :             cp = numstart + 3;
     691             :         }
     692        1172 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     693             :         {
     694         480 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     695         480 :             cp += 8;
     696             :         }
     697         692 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
     698             :         {
     699         588 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     700         588 :             cp += 3;
     701             :         }
     702             :         else
     703         104 :             goto invalid_syntax;
     704             : 
     705             :         /*
     706             :          * Check for trailing junk; there should be nothing left but spaces.
     707             :          *
     708             :          * We intentionally do this check before applying the typmod because
     709             :          * we would like to throw any trailing-junk syntax error before any
     710             :          * semantic error resulting from apply_typmod_special().
     711             :          */
     712        1696 :         while (*cp)
     713             :         {
     714          42 :             if (!isspace((unsigned char) *cp))
     715           0 :                 goto invalid_syntax;
     716          42 :             cp++;
     717             :         }
     718             : 
     719        1654 :         if (!apply_typmod_special(res, typmod, escontext))
     720           0 :             PG_RETURN_NULL();
     721             :     }
     722             :     else
     723             :     {
     724             :         /*
     725             :          * We have a normal numeric value, which may be a non-decimal integer
     726             :          * or a regular decimal number.
     727             :          */
     728             :         NumericVar  value;
     729             :         int         base;
     730             :         bool        have_error;
     731             : 
     732      106430 :         init_var(&value);
     733             : 
     734             :         /*
     735             :          * Determine the number's base by looking for a non-decimal prefix
     736             :          * indicator ("0x", "0o", or "0b").
     737             :          */
     738      106430 :         if (cp[0] == '0')
     739             :         {
     740       27574 :             switch (cp[1])
     741             :             {
     742          72 :                 case 'x':
     743             :                 case 'X':
     744          72 :                     base = 16;
     745          72 :                     break;
     746          42 :                 case 'o':
     747             :                 case 'O':
     748          42 :                     base = 8;
     749          42 :                     break;
     750          42 :                 case 'b':
     751             :                 case 'B':
     752          42 :                     base = 2;
     753          42 :                     break;
     754       27418 :                 default:
     755       27418 :                     base = 10;
     756             :             }
     757             :         }
     758             :         else
     759       78856 :             base = 10;
     760             : 
     761             :         /* Parse the rest of the number and apply the sign */
     762      106430 :         if (base == 10)
     763             :         {
     764      106274 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     765          42 :                 PG_RETURN_NULL();
     766      106226 :             value.sign = sign;
     767             :         }
     768             :         else
     769             :         {
     770         156 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
     771             :                                                       &value, &cp, escontext))
     772           0 :                 PG_RETURN_NULL();
     773             :         }
     774             : 
     775             :         /*
     776             :          * Should be nothing left but spaces. As above, throw any typmod error
     777             :          * after finishing syntax check.
     778             :          */
     779      106442 :         while (*cp)
     780             :         {
     781         150 :             if (!isspace((unsigned char) *cp))
     782          72 :                 goto invalid_syntax;
     783          78 :             cp++;
     784             :         }
     785             : 
     786      106292 :         if (!apply_typmod(&value, typmod, escontext))
     787          24 :             PG_RETURN_NULL();
     788             : 
     789      106268 :         res = make_result_opt_error(&value, &have_error);
     790             : 
     791      106268 :         if (have_error)
     792          18 :             ereturn(escontext, (Datum) 0,
     793             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     794             :                      errmsg("value overflows numeric format")));
     795             : 
     796      106250 :         free_var(&value);
     797             :     }
     798             : 
     799      107904 :     PG_RETURN_NUMERIC(res);
     800             : 
     801         176 : invalid_syntax:
     802         176 :     ereturn(escontext, (Datum) 0,
     803             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     804             :              errmsg("invalid input syntax for type %s: \"%s\"",
     805             :                     "numeric", str)));
     806             : }
     807             : 
     808             : 
     809             : /*
     810             :  * numeric_out() -
     811             :  *
     812             :  *  Output function for numeric data type
     813             :  */
     814             : Datum
     815      788974 : numeric_out(PG_FUNCTION_ARGS)
     816             : {
     817      788974 :     Numeric     num = PG_GETARG_NUMERIC(0);
     818             :     NumericVar  x;
     819             :     char       *str;
     820             : 
     821             :     /*
     822             :      * Handle NaN and infinities
     823             :      */
     824      788974 :     if (NUMERIC_IS_SPECIAL(num))
     825             :     {
     826        3604 :         if (NUMERIC_IS_PINF(num))
     827        1040 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     828        2564 :         else if (NUMERIC_IS_NINF(num))
     829         658 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     830             :         else
     831        1906 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     832             :     }
     833             : 
     834             :     /*
     835             :      * Get the number in the variable format.
     836             :      */
     837      785370 :     init_var_from_num(num, &x);
     838             : 
     839      785370 :     str = get_str_from_var(&x);
     840             : 
     841      785370 :     PG_RETURN_CSTRING(str);
     842             : }
     843             : 
     844             : /*
     845             :  * numeric_is_nan() -
     846             :  *
     847             :  *  Is Numeric value a NaN?
     848             :  */
     849             : bool
     850       13614 : numeric_is_nan(Numeric num)
     851             : {
     852       13614 :     return NUMERIC_IS_NAN(num);
     853             : }
     854             : 
     855             : /*
     856             :  * numeric_is_inf() -
     857             :  *
     858             :  *  Is Numeric value an infinity?
     859             :  */
     860             : bool
     861         312 : numeric_is_inf(Numeric num)
     862             : {
     863         312 :     return NUMERIC_IS_INF(num);
     864             : }
     865             : 
     866             : /*
     867             :  * numeric_is_integral() -
     868             :  *
     869             :  *  Is Numeric value integral?
     870             :  */
     871             : static bool
     872          66 : numeric_is_integral(Numeric num)
     873             : {
     874             :     NumericVar  arg;
     875             : 
     876             :     /* Reject NaN, but infinities are considered integral */
     877          66 :     if (NUMERIC_IS_SPECIAL(num))
     878             :     {
     879          30 :         if (NUMERIC_IS_NAN(num))
     880           0 :             return false;
     881          30 :         return true;
     882             :     }
     883             : 
     884             :     /* Integral if there are no digits to the right of the decimal point */
     885          36 :     init_var_from_num(num, &arg);
     886             : 
     887          36 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
     888             : }
     889             : 
     890             : /*
     891             :  * make_numeric_typmod() -
     892             :  *
     893             :  *  Pack numeric precision and scale values into a typmod.  The upper 16 bits
     894             :  *  are used for the precision (though actually not all these bits are needed,
     895             :  *  since the maximum allowed precision is 1000).  The lower 16 bits are for
     896             :  *  the scale, but since the scale is constrained to the range [-1000, 1000],
     897             :  *  we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
     898             :  *  unset, for possible future use.
     899             :  *
     900             :  *  For purely historical reasons VARHDRSZ is then added to the result, thus
     901             :  *  the unused space in the upper 16 bits is not all as freely available as it
     902             :  *  might seem.  (We can't let the result overflow to a negative int32, as
     903             :  *  other parts of the system would interpret that as not-a-valid-typmod.)
     904             :  */
     905             : static inline int32
     906        1890 : make_numeric_typmod(int precision, int scale)
     907             : {
     908        1890 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
     909             : }
     910             : 
     911             : /*
     912             :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
     913             :  */
     914             : static inline bool
     915      131502 : is_valid_numeric_typmod(int32 typmod)
     916             : {
     917      131502 :     return typmod >= (int32) VARHDRSZ;
     918             : }
     919             : 
     920             : /*
     921             :  * numeric_typmod_precision() -
     922             :  *
     923             :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
     924             :  */
     925             : static inline int
     926       24292 : numeric_typmod_precision(int32 typmod)
     927             : {
     928       24292 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
     929             : }
     930             : 
     931             : /*
     932             :  * numeric_typmod_scale() -
     933             :  *
     934             :  *  Extract the scale from a numeric typmod --- see make_numeric_typmod().
     935             :  *
     936             :  *  Note that the scale may be negative, so we must do sign extension when
     937             :  *  unpacking it.  We do this using the bit hack (x^1024)-1024, which sign
     938             :  *  extends an 11-bit two's complement number x.
     939             :  */
     940             : static inline int
     941       17128 : numeric_typmod_scale(int32 typmod)
     942             : {
     943       17128 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
     944             : }
     945             : 
     946             : /*
     947             :  * numeric_maximum_size() -
     948             :  *
     949             :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
     950             :  */
     951             : int32
     952        7164 : numeric_maximum_size(int32 typmod)
     953             : {
     954             :     int         precision;
     955             :     int         numeric_digits;
     956             : 
     957        7164 :     if (!is_valid_numeric_typmod(typmod))
     958           0 :         return -1;
     959             : 
     960             :     /* precision (ie, max # of digits) is in upper bits of typmod */
     961        7164 :     precision = numeric_typmod_precision(typmod);
     962             : 
     963             :     /*
     964             :      * This formula computes the maximum number of NumericDigits we could need
     965             :      * in order to store the specified number of decimal digits. Because the
     966             :      * weight is stored as a number of NumericDigits rather than a number of
     967             :      * decimal digits, it's possible that the first NumericDigit will contain
     968             :      * only a single decimal digit.  Thus, the first two decimal digits can
     969             :      * require two NumericDigits to store, but it isn't until we reach
     970             :      * DEC_DIGITS + 2 decimal digits that we potentially need a third
     971             :      * NumericDigit.
     972             :      */
     973        7164 :     numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
     974             : 
     975             :     /*
     976             :      * In most cases, the size of a numeric will be smaller than the value
     977             :      * computed below, because the varlena header will typically get toasted
     978             :      * down to a single byte before being stored on disk, and it may also be
     979             :      * possible to use a short numeric header.  But our job here is to compute
     980             :      * the worst case.
     981             :      */
     982        7164 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
     983             : }
     984             : 
     985             : /*
     986             :  * numeric_out_sci() -
     987             :  *
     988             :  *  Output function for numeric data type in scientific notation.
     989             :  */
     990             : char *
     991         246 : numeric_out_sci(Numeric num, int scale)
     992             : {
     993             :     NumericVar  x;
     994             :     char       *str;
     995             : 
     996             :     /*
     997             :      * Handle NaN and infinities
     998             :      */
     999         246 :     if (NUMERIC_IS_SPECIAL(num))
    1000             :     {
    1001          18 :         if (NUMERIC_IS_PINF(num))
    1002           6 :             return pstrdup("Infinity");
    1003          12 :         else if (NUMERIC_IS_NINF(num))
    1004           6 :             return pstrdup("-Infinity");
    1005             :         else
    1006           6 :             return pstrdup("NaN");
    1007             :     }
    1008             : 
    1009         228 :     init_var_from_num(num, &x);
    1010             : 
    1011         228 :     str = get_str_from_var_sci(&x, scale);
    1012             : 
    1013         228 :     return str;
    1014             : }
    1015             : 
    1016             : /*
    1017             :  * numeric_normalize() -
    1018             :  *
    1019             :  *  Output function for numeric data type, suppressing insignificant trailing
    1020             :  *  zeroes and then any trailing decimal point.  The intent of this is to
    1021             :  *  produce strings that are equal if and only if the input numeric values
    1022             :  *  compare equal.
    1023             :  */
    1024             : char *
    1025       12966 : numeric_normalize(Numeric num)
    1026             : {
    1027             :     NumericVar  x;
    1028             :     char       *str;
    1029             :     int         last;
    1030             : 
    1031             :     /*
    1032             :      * Handle NaN and infinities
    1033             :      */
    1034       12966 :     if (NUMERIC_IS_SPECIAL(num))
    1035             :     {
    1036           0 :         if (NUMERIC_IS_PINF(num))
    1037           0 :             return pstrdup("Infinity");
    1038           0 :         else if (NUMERIC_IS_NINF(num))
    1039           0 :             return pstrdup("-Infinity");
    1040             :         else
    1041           0 :             return pstrdup("NaN");
    1042             :     }
    1043             : 
    1044       12966 :     init_var_from_num(num, &x);
    1045             : 
    1046       12966 :     str = get_str_from_var(&x);
    1047             : 
    1048             :     /* If there's no decimal point, there's certainly nothing to remove. */
    1049       12966 :     if (strchr(str, '.') != NULL)
    1050             :     {
    1051             :         /*
    1052             :          * Back up over trailing fractional zeroes.  Since there is a decimal
    1053             :          * point, this loop will terminate safely.
    1054             :          */
    1055          42 :         last = strlen(str) - 1;
    1056          84 :         while (str[last] == '0')
    1057          42 :             last--;
    1058             : 
    1059             :         /* We want to get rid of the decimal point too, if it's now last. */
    1060          42 :         if (str[last] == '.')
    1061          42 :             last--;
    1062             : 
    1063             :         /* Delete whatever we backed up over. */
    1064          42 :         str[last + 1] = '\0';
    1065             :     }
    1066             : 
    1067       12966 :     return str;
    1068             : }
    1069             : 
    1070             : /*
    1071             :  *      numeric_recv            - converts external binary format to numeric
    1072             :  *
    1073             :  * External format is a sequence of int16's:
    1074             :  * ndigits, weight, sign, dscale, NumericDigits.
    1075             :  */
    1076             : Datum
    1077         102 : numeric_recv(PG_FUNCTION_ARGS)
    1078             : {
    1079         102 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    1080             : 
    1081             : #ifdef NOT_USED
    1082             :     Oid         typelem = PG_GETARG_OID(1);
    1083             : #endif
    1084         102 :     int32       typmod = PG_GETARG_INT32(2);
    1085             :     NumericVar  value;
    1086             :     Numeric     res;
    1087             :     int         len,
    1088             :                 i;
    1089             : 
    1090         102 :     init_var(&value);
    1091             : 
    1092         102 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1093             : 
    1094         102 :     alloc_var(&value, len);
    1095             : 
    1096         102 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
    1097             :     /* we allow any int16 for weight --- OK? */
    1098             : 
    1099         102 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1100         102 :     if (!(value.sign == NUMERIC_POS ||
    1101           0 :           value.sign == NUMERIC_NEG ||
    1102           0 :           value.sign == NUMERIC_NAN ||
    1103           0 :           value.sign == NUMERIC_PINF ||
    1104           0 :           value.sign == NUMERIC_NINF))
    1105           0 :         ereport(ERROR,
    1106             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1107             :                  errmsg("invalid sign in external \"numeric\" value")));
    1108             : 
    1109         102 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1110         102 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
    1111           0 :         ereport(ERROR,
    1112             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1113             :                  errmsg("invalid scale in external \"numeric\" value")));
    1114             : 
    1115         274 :     for (i = 0; i < len; i++)
    1116             :     {
    1117         172 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
    1118             : 
    1119         172 :         if (d < 0 || d >= NBASE)
    1120           0 :             ereport(ERROR,
    1121             :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1122             :                      errmsg("invalid digit in external \"numeric\" value")));
    1123         172 :         value.digits[i] = d;
    1124             :     }
    1125             : 
    1126             :     /*
    1127             :      * If the given dscale would hide any digits, truncate those digits away.
    1128             :      * We could alternatively throw an error, but that would take a bunch of
    1129             :      * extra code (about as much as trunc_var involves), and it might cause
    1130             :      * client compatibility issues.  Be careful not to apply trunc_var to
    1131             :      * special values, as it could do the wrong thing; we don't need it
    1132             :      * anyway, since make_result will ignore all but the sign field.
    1133             :      *
    1134             :      * After doing that, be sure to check the typmod restriction.
    1135             :      */
    1136         102 :     if (value.sign == NUMERIC_POS ||
    1137           0 :         value.sign == NUMERIC_NEG)
    1138             :     {
    1139         102 :         trunc_var(&value, value.dscale);
    1140             : 
    1141         102 :         (void) apply_typmod(&value, typmod, NULL);
    1142             : 
    1143         102 :         res = make_result(&value);
    1144             :     }
    1145             :     else
    1146             :     {
    1147             :         /* apply_typmod_special wants us to make the Numeric first */
    1148           0 :         res = make_result(&value);
    1149             : 
    1150           0 :         (void) apply_typmod_special(res, typmod, NULL);
    1151             :     }
    1152             : 
    1153         102 :     free_var(&value);
    1154             : 
    1155         102 :     PG_RETURN_NUMERIC(res);
    1156             : }
    1157             : 
    1158             : /*
    1159             :  *      numeric_send            - converts numeric to binary format
    1160             :  */
    1161             : Datum
    1162          70 : numeric_send(PG_FUNCTION_ARGS)
    1163             : {
    1164          70 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1165             :     NumericVar  x;
    1166             :     StringInfoData buf;
    1167             :     int         i;
    1168             : 
    1169          70 :     init_var_from_num(num, &x);
    1170             : 
    1171          70 :     pq_begintypsend(&buf);
    1172             : 
    1173          70 :     pq_sendint16(&buf, x.ndigits);
    1174          70 :     pq_sendint16(&buf, x.weight);
    1175          70 :     pq_sendint16(&buf, x.sign);
    1176          70 :     pq_sendint16(&buf, x.dscale);
    1177         194 :     for (i = 0; i < x.ndigits; i++)
    1178         124 :         pq_sendint16(&buf, x.digits[i]);
    1179             : 
    1180          70 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    1181             : }
    1182             : 
    1183             : 
    1184             : /*
    1185             :  * numeric_support()
    1186             :  *
    1187             :  * Planner support function for the numeric() length coercion function.
    1188             :  *
    1189             :  * Flatten calls that solely represent increases in allowable precision.
    1190             :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
    1191             :  * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
    1192             :  * an unconstrained numeric to any constrained numeric is also unoptimizable.
    1193             :  */
    1194             : Datum
    1195         516 : numeric_support(PG_FUNCTION_ARGS)
    1196             : {
    1197         516 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1198         516 :     Node       *ret = NULL;
    1199             : 
    1200         516 :     if (IsA(rawreq, SupportRequestSimplify))
    1201             :     {
    1202         228 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
    1203         228 :         FuncExpr   *expr = req->fcall;
    1204             :         Node       *typmod;
    1205             : 
    1206             :         Assert(list_length(expr->args) >= 2);
    1207             : 
    1208         228 :         typmod = (Node *) lsecond(expr->args);
    1209             : 
    1210         228 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
    1211             :         {
    1212         228 :             Node       *source = (Node *) linitial(expr->args);
    1213         228 :             int32       old_typmod = exprTypmod(source);
    1214         228 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    1215         228 :             int32       old_scale = numeric_typmod_scale(old_typmod);
    1216         228 :             int32       new_scale = numeric_typmod_scale(new_typmod);
    1217         228 :             int32       old_precision = numeric_typmod_precision(old_typmod);
    1218         228 :             int32       new_precision = numeric_typmod_precision(new_typmod);
    1219             : 
    1220             :             /*
    1221             :              * If new_typmod is invalid, the destination is unconstrained;
    1222             :              * that's always OK.  If old_typmod is valid, the source is
    1223             :              * constrained, and we're OK if the scale is unchanged and the
    1224             :              * precision is not decreasing.  See further notes in function
    1225             :              * header comment.
    1226             :              */
    1227         456 :             if (!is_valid_numeric_typmod(new_typmod) ||
    1228         240 :                 (is_valid_numeric_typmod(old_typmod) &&
    1229           6 :                  new_scale == old_scale && new_precision >= old_precision))
    1230           6 :                 ret = relabel_to_typmod(source, new_typmod);
    1231             :         }
    1232             :     }
    1233             : 
    1234         516 :     PG_RETURN_POINTER(ret);
    1235             : }
    1236             : 
    1237             : /*
    1238             :  * numeric() -
    1239             :  *
    1240             :  *  This is a special function called by the Postgres database system
    1241             :  *  before a value is stored in a tuple's attribute. The precision and
    1242             :  *  scale of the attribute have to be applied on the value.
    1243             :  */
    1244             : Datum
    1245       11790 : numeric     (PG_FUNCTION_ARGS)
    1246             : {
    1247       11790 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1248       11790 :     int32       typmod = PG_GETARG_INT32(1);
    1249             :     Numeric     new;
    1250             :     int         precision;
    1251             :     int         scale;
    1252             :     int         ddigits;
    1253             :     int         maxdigits;
    1254             :     int         dscale;
    1255             :     NumericVar  var;
    1256             : 
    1257             :     /*
    1258             :      * Handle NaN and infinities: if apply_typmod_special doesn't complain,
    1259             :      * just return a copy of the input.
    1260             :      */
    1261       11790 :     if (NUMERIC_IS_SPECIAL(num))
    1262             :     {
    1263         210 :         (void) apply_typmod_special(num, typmod, NULL);
    1264         192 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1265             :     }
    1266             : 
    1267             :     /*
    1268             :      * If the value isn't a valid type modifier, simply return a copy of the
    1269             :      * input value
    1270             :      */
    1271       11580 :     if (!is_valid_numeric_typmod(typmod))
    1272           0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1273             : 
    1274             :     /*
    1275             :      * Get the precision and scale out of the typmod value
    1276             :      */
    1277       11580 :     precision = numeric_typmod_precision(typmod);
    1278       11580 :     scale = numeric_typmod_scale(typmod);
    1279       11580 :     maxdigits = precision - scale;
    1280             : 
    1281             :     /* The target display scale is non-negative */
    1282       11580 :     dscale = Max(scale, 0);
    1283             : 
    1284             :     /*
    1285             :      * If the number is certainly in bounds and due to the target scale no
    1286             :      * rounding could be necessary, just make a copy of the input and modify
    1287             :      * its scale fields, unless the larger scale forces us to abandon the
    1288             :      * short representation.  (Note we assume the existing dscale is
    1289             :      * honest...)
    1290             :      */
    1291       11580 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1292       11580 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
    1293        7134 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
    1294           0 :             || !NUMERIC_IS_SHORT(num)))
    1295             :     {
    1296        7134 :         new = duplicate_numeric(num);
    1297        7134 :         if (NUMERIC_IS_SHORT(num))
    1298        7134 :             new->choice.n_short.n_header =
    1299        7134 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
    1300        7134 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
    1301             :         else
    1302           0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
    1303           0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
    1304        7134 :         PG_RETURN_NUMERIC(new);
    1305             :     }
    1306             : 
    1307             :     /*
    1308             :      * We really need to fiddle with things - unpack the number into a
    1309             :      * variable and let apply_typmod() do it.
    1310             :      */
    1311        4446 :     init_var(&var);
    1312             : 
    1313        4446 :     set_var_from_num(num, &var);
    1314        4446 :     (void) apply_typmod(&var, typmod, NULL);
    1315        4386 :     new = make_result(&var);
    1316             : 
    1317        4386 :     free_var(&var);
    1318             : 
    1319        4386 :     PG_RETURN_NUMERIC(new);
    1320             : }
    1321             : 
    1322             : Datum
    1323        1932 : numerictypmodin(PG_FUNCTION_ARGS)
    1324             : {
    1325        1932 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1326             :     int32      *tl;
    1327             :     int         n;
    1328             :     int32       typmod;
    1329             : 
    1330        1932 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1331             : 
    1332        1932 :     if (n == 2)
    1333             :     {
    1334        1912 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1335          18 :             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        1894 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
    1340          12 :             ereport(ERROR,
    1341             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1342             :                      errmsg("NUMERIC scale %d must be between %d and %d",
    1343             :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
    1344        1882 :         typmod = make_numeric_typmod(tl[0], tl[1]);
    1345             :     }
    1346          20 :     else if (n == 1)
    1347             :     {
    1348           8 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1349           0 :             ereport(ERROR,
    1350             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1351             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1352             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1353             :         /* scale defaults to zero */
    1354           8 :         typmod = make_numeric_typmod(tl[0], 0);
    1355             :     }
    1356             :     else
    1357             :     {
    1358          12 :         ereport(ERROR,
    1359             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1360             :                  errmsg("invalid NUMERIC type modifier")));
    1361             :         typmod = 0;             /* keep compiler quiet */
    1362             :     }
    1363             : 
    1364        1890 :     PG_RETURN_INT32(typmod);
    1365             : }
    1366             : 
    1367             : Datum
    1368         376 : numerictypmodout(PG_FUNCTION_ARGS)
    1369             : {
    1370         376 :     int32       typmod = PG_GETARG_INT32(0);
    1371         376 :     char       *res = (char *) palloc(64);
    1372             : 
    1373         376 :     if (is_valid_numeric_typmod(typmod))
    1374         376 :         snprintf(res, 64, "(%d,%d)",
    1375             :                  numeric_typmod_precision(typmod),
    1376             :                  numeric_typmod_scale(typmod));
    1377             :     else
    1378           0 :         *res = '\0';
    1379             : 
    1380         376 :     PG_RETURN_CSTRING(res);
    1381             : }
    1382             : 
    1383             : 
    1384             : /* ----------------------------------------------------------------------
    1385             :  *
    1386             :  * Sign manipulation, rounding and the like
    1387             :  *
    1388             :  * ----------------------------------------------------------------------
    1389             :  */
    1390             : 
    1391             : Datum
    1392       19506 : numeric_abs(PG_FUNCTION_ARGS)
    1393             : {
    1394       19506 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1395             :     Numeric     res;
    1396             : 
    1397             :     /*
    1398             :      * Do it the easy way directly on the packed format
    1399             :      */
    1400       19506 :     res = duplicate_numeric(num);
    1401             : 
    1402       19506 :     if (NUMERIC_IS_SHORT(num))
    1403       19440 :         res->choice.n_short.n_header =
    1404       19440 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
    1405          66 :     else if (NUMERIC_IS_SPECIAL(num))
    1406             :     {
    1407             :         /* This changes -Inf to Inf, and doesn't affect NaN */
    1408          18 :         res->choice.n_short.n_header =
    1409          18 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
    1410             :     }
    1411             :     else
    1412          48 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
    1413             : 
    1414       19506 :     PG_RETURN_NUMERIC(res);
    1415             : }
    1416             : 
    1417             : 
    1418             : Datum
    1419         884 : numeric_uminus(PG_FUNCTION_ARGS)
    1420             : {
    1421         884 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1422             :     Numeric     res;
    1423             : 
    1424             :     /*
    1425             :      * Do it the easy way directly on the packed format
    1426             :      */
    1427         884 :     res = duplicate_numeric(num);
    1428             : 
    1429         884 :     if (NUMERIC_IS_SPECIAL(num))
    1430             :     {
    1431             :         /* Flip the sign, if it's Inf or -Inf */
    1432         126 :         if (!NUMERIC_IS_NAN(num))
    1433          84 :             res->choice.n_short.n_header =
    1434          84 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
    1435             :     }
    1436             : 
    1437             :     /*
    1438             :      * The packed format is known to be totally zero digit trimmed always. So
    1439             :      * once we've eliminated specials, we can identify a zero by the fact that
    1440             :      * there are no digits at all. Do nothing to a zero.
    1441             :      */
    1442         758 :     else if (NUMERIC_NDIGITS(num) != 0)
    1443             :     {
    1444             :         /* Else, flip the sign */
    1445         644 :         if (NUMERIC_IS_SHORT(num))
    1446         644 :             res->choice.n_short.n_header =
    1447         644 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
    1448           0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
    1449           0 :             res->choice.n_long.n_sign_dscale =
    1450           0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
    1451             :         else
    1452           0 :             res->choice.n_long.n_sign_dscale =
    1453           0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
    1454             :     }
    1455             : 
    1456         884 :     PG_RETURN_NUMERIC(res);
    1457             : }
    1458             : 
    1459             : 
    1460             : Datum
    1461         498 : numeric_uplus(PG_FUNCTION_ARGS)
    1462             : {
    1463         498 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1464             : 
    1465         498 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
    1466             : }
    1467             : 
    1468             : 
    1469             : /*
    1470             :  * numeric_sign_internal() -
    1471             :  *
    1472             :  * Returns -1 if the argument is less than 0, 0 if the argument is equal
    1473             :  * to 0, and 1 if the argument is greater than zero.  Caller must have
    1474             :  * taken care of the NaN case, but we can handle infinities here.
    1475             :  */
    1476             : static int
    1477        3570 : numeric_sign_internal(Numeric num)
    1478             : {
    1479        3570 :     if (NUMERIC_IS_SPECIAL(num))
    1480             :     {
    1481             :         Assert(!NUMERIC_IS_NAN(num));
    1482             :         /* Must be Inf or -Inf */
    1483         312 :         if (NUMERIC_IS_PINF(num))
    1484         186 :             return 1;
    1485             :         else
    1486         126 :             return -1;
    1487             :     }
    1488             : 
    1489             :     /*
    1490             :      * The packed format is known to be totally zero digit trimmed always. So
    1491             :      * once we've eliminated specials, we can identify a zero by the fact that
    1492             :      * there are no digits at all.
    1493             :      */
    1494        3258 :     else if (NUMERIC_NDIGITS(num) == 0)
    1495         228 :         return 0;
    1496        3030 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
    1497         732 :         return -1;
    1498             :     else
    1499        2298 :         return 1;
    1500             : }
    1501             : 
    1502             : /*
    1503             :  * numeric_sign() -
    1504             :  *
    1505             :  * returns -1 if the argument is less than 0, 0 if the argument is equal
    1506             :  * to 0, and 1 if the argument is greater than zero.
    1507             :  */
    1508             : Datum
    1509          48 : numeric_sign(PG_FUNCTION_ARGS)
    1510             : {
    1511          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1512             : 
    1513             :     /*
    1514             :      * Handle NaN (infinities can be handled normally)
    1515             :      */
    1516          48 :     if (NUMERIC_IS_NAN(num))
    1517           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    1518             : 
    1519          42 :     switch (numeric_sign_internal(num))
    1520             :     {
    1521           6 :         case 0:
    1522           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    1523          18 :         case 1:
    1524          18 :             PG_RETURN_NUMERIC(make_result(&const_one));
    1525          18 :         case -1:
    1526          18 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
    1527             :     }
    1528             : 
    1529             :     Assert(false);
    1530           0 :     return (Datum) 0;
    1531             : }
    1532             : 
    1533             : 
    1534             : /*
    1535             :  * numeric_round() -
    1536             :  *
    1537             :  *  Round a value to have 'scale' digits after the decimal point.
    1538             :  *  We allow negative 'scale', implying rounding before the decimal
    1539             :  *  point --- Oracle interprets rounding that way.
    1540             :  */
    1541             : Datum
    1542        7808 : numeric_round(PG_FUNCTION_ARGS)
    1543             : {
    1544        7808 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1545        7808 :     int32       scale = PG_GETARG_INT32(1);
    1546             :     Numeric     res;
    1547             :     NumericVar  arg;
    1548             : 
    1549             :     /*
    1550             :      * Handle NaN and infinities
    1551             :      */
    1552        7808 :     if (NUMERIC_IS_SPECIAL(num))
    1553          96 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1554             : 
    1555             :     /*
    1556             :      * Limit the scale value to avoid possible overflow in calculations.
    1557             :      *
    1558             :      * These limits are based on the maximum number of digits a Numeric value
    1559             :      * can have before and after the decimal point, but we must allow for one
    1560             :      * extra digit before the decimal point, in case the most significant
    1561             :      * digit rounds up; we must check if that causes Numeric overflow.
    1562             :      */
    1563        7712 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS - 1);
    1564        7712 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1565             : 
    1566             :     /*
    1567             :      * Unpack the argument and round it at the proper digit position
    1568             :      */
    1569        7712 :     init_var(&arg);
    1570        7712 :     set_var_from_num(num, &arg);
    1571             : 
    1572        7712 :     round_var(&arg, scale);
    1573             : 
    1574             :     /* We don't allow negative output dscale */
    1575        7712 :     if (scale < 0)
    1576         216 :         arg.dscale = 0;
    1577             : 
    1578             :     /*
    1579             :      * Return the rounded result
    1580             :      */
    1581        7712 :     res = make_result(&arg);
    1582             : 
    1583        7706 :     free_var(&arg);
    1584        7706 :     PG_RETURN_NUMERIC(res);
    1585             : }
    1586             : 
    1587             : 
    1588             : /*
    1589             :  * numeric_trunc() -
    1590             :  *
    1591             :  *  Truncate a value to have 'scale' digits after the decimal point.
    1592             :  *  We allow negative 'scale', implying a truncation before the decimal
    1593             :  *  point --- Oracle interprets truncation that way.
    1594             :  */
    1595             : Datum
    1596         626 : numeric_trunc(PG_FUNCTION_ARGS)
    1597             : {
    1598         626 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1599         626 :     int32       scale = PG_GETARG_INT32(1);
    1600             :     Numeric     res;
    1601             :     NumericVar  arg;
    1602             : 
    1603             :     /*
    1604             :      * Handle NaN and infinities
    1605             :      */
    1606         626 :     if (NUMERIC_IS_SPECIAL(num))
    1607          36 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1608             : 
    1609             :     /*
    1610             :      * Limit the scale value to avoid possible overflow in calculations.
    1611             :      *
    1612             :      * These limits are based on the maximum number of digits a Numeric value
    1613             :      * can have before and after the decimal point.
    1614             :      */
    1615         590 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS);
    1616         590 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1617             : 
    1618             :     /*
    1619             :      * Unpack the argument and truncate it at the proper digit position
    1620             :      */
    1621         590 :     init_var(&arg);
    1622         590 :     set_var_from_num(num, &arg);
    1623             : 
    1624         590 :     trunc_var(&arg, scale);
    1625             : 
    1626             :     /* We don't allow negative output dscale */
    1627         590 :     if (scale < 0)
    1628          24 :         arg.dscale = 0;
    1629             : 
    1630             :     /*
    1631             :      * Return the truncated result
    1632             :      */
    1633         590 :     res = make_result(&arg);
    1634             : 
    1635         590 :     free_var(&arg);
    1636         590 :     PG_RETURN_NUMERIC(res);
    1637             : }
    1638             : 
    1639             : 
    1640             : /*
    1641             :  * numeric_ceil() -
    1642             :  *
    1643             :  *  Return the smallest integer greater than or equal to the argument
    1644             :  */
    1645             : Datum
    1646         222 : numeric_ceil(PG_FUNCTION_ARGS)
    1647             : {
    1648         222 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1649             :     Numeric     res;
    1650             :     NumericVar  result;
    1651             : 
    1652             :     /*
    1653             :      * Handle NaN and infinities
    1654             :      */
    1655         222 :     if (NUMERIC_IS_SPECIAL(num))
    1656          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1657             : 
    1658         204 :     init_var_from_num(num, &result);
    1659         204 :     ceil_var(&result, &result);
    1660             : 
    1661         204 :     res = make_result(&result);
    1662         204 :     free_var(&result);
    1663             : 
    1664         204 :     PG_RETURN_NUMERIC(res);
    1665             : }
    1666             : 
    1667             : 
    1668             : /*
    1669             :  * numeric_floor() -
    1670             :  *
    1671             :  *  Return the largest integer equal to or less than the argument
    1672             :  */
    1673             : Datum
    1674         126 : numeric_floor(PG_FUNCTION_ARGS)
    1675             : {
    1676         126 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1677             :     Numeric     res;
    1678             :     NumericVar  result;
    1679             : 
    1680             :     /*
    1681             :      * Handle NaN and infinities
    1682             :      */
    1683         126 :     if (NUMERIC_IS_SPECIAL(num))
    1684          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1685             : 
    1686         108 :     init_var_from_num(num, &result);
    1687         108 :     floor_var(&result, &result);
    1688             : 
    1689         108 :     res = make_result(&result);
    1690         108 :     free_var(&result);
    1691             : 
    1692         108 :     PG_RETURN_NUMERIC(res);
    1693             : }
    1694             : 
    1695             : 
    1696             : /*
    1697             :  * generate_series_numeric() -
    1698             :  *
    1699             :  *  Generate series of numeric.
    1700             :  */
    1701             : Datum
    1702         216 : generate_series_numeric(PG_FUNCTION_ARGS)
    1703             : {
    1704         216 :     return generate_series_step_numeric(fcinfo);
    1705             : }
    1706             : 
    1707             : Datum
    1708         420 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1709             : {
    1710             :     generate_series_numeric_fctx *fctx;
    1711             :     FuncCallContext *funcctx;
    1712             :     MemoryContext oldcontext;
    1713             : 
    1714         420 :     if (SRF_IS_FIRSTCALL())
    1715             :     {
    1716         138 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1717         138 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1718         138 :         NumericVar  steploc = const_one;
    1719             : 
    1720             :         /* Reject NaN and infinities in start and stop values */
    1721         138 :         if (NUMERIC_IS_SPECIAL(start_num))
    1722             :         {
    1723          12 :             if (NUMERIC_IS_NAN(start_num))
    1724           6 :                 ereport(ERROR,
    1725             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1726             :                          errmsg("start value cannot be NaN")));
    1727             :             else
    1728           6 :                 ereport(ERROR,
    1729             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1730             :                          errmsg("start value cannot be infinity")));
    1731             :         }
    1732         126 :         if (NUMERIC_IS_SPECIAL(stop_num))
    1733             :         {
    1734          12 :             if (NUMERIC_IS_NAN(stop_num))
    1735           6 :                 ereport(ERROR,
    1736             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1737             :                          errmsg("stop value cannot be NaN")));
    1738             :             else
    1739           6 :                 ereport(ERROR,
    1740             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1741             :                          errmsg("stop value cannot be infinity")));
    1742             :         }
    1743             : 
    1744             :         /* see if we were given an explicit step size */
    1745         114 :         if (PG_NARGS() == 3)
    1746             :         {
    1747          54 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
    1748             : 
    1749          54 :             if (NUMERIC_IS_SPECIAL(step_num))
    1750             :             {
    1751          12 :                 if (NUMERIC_IS_NAN(step_num))
    1752           6 :                     ereport(ERROR,
    1753             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1754             :                              errmsg("step size cannot be NaN")));
    1755             :                 else
    1756           6 :                     ereport(ERROR,
    1757             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1758             :                              errmsg("step size cannot be infinity")));
    1759             :             }
    1760             : 
    1761          42 :             init_var_from_num(step_num, &steploc);
    1762             : 
    1763          42 :             if (cmp_var(&steploc, &const_zero) == 0)
    1764           6 :                 ereport(ERROR,
    1765             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1766             :                          errmsg("step size cannot equal zero")));
    1767             :         }
    1768             : 
    1769             :         /* create a function context for cross-call persistence */
    1770          96 :         funcctx = SRF_FIRSTCALL_INIT();
    1771             : 
    1772             :         /*
    1773             :          * Switch to memory context appropriate for multiple function calls.
    1774             :          */
    1775          96 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1776             : 
    1777             :         /* allocate memory for user context */
    1778             :         fctx = (generate_series_numeric_fctx *)
    1779          96 :             palloc(sizeof(generate_series_numeric_fctx));
    1780             : 
    1781             :         /*
    1782             :          * Use fctx to keep state from call to call. Seed current with the
    1783             :          * original start value. We must copy the start_num and stop_num
    1784             :          * values rather than pointing to them, since we may have detoasted
    1785             :          * them in the per-call context.
    1786             :          */
    1787          96 :         init_var(&fctx->current);
    1788          96 :         init_var(&fctx->stop);
    1789          96 :         init_var(&fctx->step);
    1790             : 
    1791          96 :         set_var_from_num(start_num, &fctx->current);
    1792          96 :         set_var_from_num(stop_num, &fctx->stop);
    1793          96 :         set_var_from_var(&steploc, &fctx->step);
    1794             : 
    1795          96 :         funcctx->user_fctx = fctx;
    1796          96 :         MemoryContextSwitchTo(oldcontext);
    1797             :     }
    1798             : 
    1799             :     /* stuff done on every call of the function */
    1800         378 :     funcctx = SRF_PERCALL_SETUP();
    1801             : 
    1802             :     /*
    1803             :      * Get the saved state and use current state as the result of this
    1804             :      * iteration.
    1805             :      */
    1806         378 :     fctx = funcctx->user_fctx;
    1807             : 
    1808         732 :     if ((fctx->step.sign == NUMERIC_POS &&
    1809         354 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1810         138 :         (fctx->step.sign == NUMERIC_NEG &&
    1811          24 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1812             :     {
    1813         282 :         Numeric     result = make_result(&fctx->current);
    1814             : 
    1815             :         /* switch to memory context appropriate for iteration calculation */
    1816         282 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1817             : 
    1818             :         /* increment current in preparation for next iteration */
    1819         282 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1820         282 :         MemoryContextSwitchTo(oldcontext);
    1821             : 
    1822             :         /* do when there is more left to send */
    1823         282 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1824             :     }
    1825             :     else
    1826             :         /* do when there is no more left */
    1827          96 :         SRF_RETURN_DONE(funcctx);
    1828             : }
    1829             : 
    1830             : 
    1831             : /*
    1832             :  * Implements the numeric version of the width_bucket() function
    1833             :  * defined by SQL2003. See also width_bucket_float8().
    1834             :  *
    1835             :  * 'bound1' and 'bound2' are the lower and upper bounds of the
    1836             :  * histogram's range, respectively. 'count' is the number of buckets
    1837             :  * in the histogram. width_bucket() returns an integer indicating the
    1838             :  * bucket number that 'operand' belongs to in an equiwidth histogram
    1839             :  * with the specified characteristics. An operand smaller than the
    1840             :  * lower bound is assigned to bucket 0. An operand greater than the
    1841             :  * upper bound is assigned to an additional bucket (with number
    1842             :  * count+1). We don't allow "NaN" for any of the numeric arguments.
    1843             :  */
    1844             : Datum
    1845         780 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1846             : {
    1847         780 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1848         780 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1849         780 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1850         780 :     int32       count = PG_GETARG_INT32(3);
    1851             :     NumericVar  count_var;
    1852             :     NumericVar  result_var;
    1853             :     int32       result;
    1854             : 
    1855         780 :     if (count <= 0)
    1856          12 :         ereport(ERROR,
    1857             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1858             :                  errmsg("count must be greater than zero")));
    1859             : 
    1860         768 :     if (NUMERIC_IS_SPECIAL(operand) ||
    1861         750 :         NUMERIC_IS_SPECIAL(bound1) ||
    1862         744 :         NUMERIC_IS_SPECIAL(bound2))
    1863             :     {
    1864          36 :         if (NUMERIC_IS_NAN(operand) ||
    1865          30 :             NUMERIC_IS_NAN(bound1) ||
    1866          30 :             NUMERIC_IS_NAN(bound2))
    1867           6 :             ereport(ERROR,
    1868             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1869             :                      errmsg("operand, lower bound, and upper bound cannot be NaN")));
    1870             :         /* We allow "operand" to be infinite; cmp_numerics will cope */
    1871          30 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1872          18 :             ereport(ERROR,
    1873             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1874             :                      errmsg("lower and upper bounds must be finite")));
    1875             :     }
    1876             : 
    1877         744 :     init_var(&result_var);
    1878         744 :     init_var(&count_var);
    1879             : 
    1880             :     /* Convert 'count' to a numeric, for ease of use later */
    1881         744 :     int64_to_numericvar((int64) count, &count_var);
    1882             : 
    1883         744 :     switch (cmp_numerics(bound1, bound2))
    1884             :     {
    1885           6 :         case 0:
    1886           6 :             ereport(ERROR,
    1887             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1888             :                      errmsg("lower bound cannot equal upper bound")));
    1889             :             break;
    1890             : 
    1891             :             /* bound1 < bound2 */
    1892         546 :         case -1:
    1893         546 :             if (cmp_numerics(operand, bound1) < 0)
    1894         114 :                 set_var_from_var(&const_zero, &result_var);
    1895         432 :             else if (cmp_numerics(operand, bound2) >= 0)
    1896         108 :                 add_var(&count_var, &const_one, &result_var);
    1897             :             else
    1898         324 :                 compute_bucket(operand, bound1, bound2, &count_var,
    1899             :                                &result_var);
    1900         546 :             break;
    1901             : 
    1902             :             /* bound1 > bound2 */
    1903         192 :         case 1:
    1904         192 :             if (cmp_numerics(operand, bound1) > 0)
    1905          12 :                 set_var_from_var(&const_zero, &result_var);
    1906         180 :             else if (cmp_numerics(operand, bound2) <= 0)
    1907          24 :                 add_var(&count_var, &const_one, &result_var);
    1908             :             else
    1909         156 :                 compute_bucket(operand, bound1, bound2, &count_var,
    1910             :                                &result_var);
    1911         192 :             break;
    1912             :     }
    1913             : 
    1914             :     /* if result exceeds the range of a legal int4, we ereport here */
    1915         738 :     if (!numericvar_to_int32(&result_var, &result))
    1916           0 :         ereport(ERROR,
    1917             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1918             :                  errmsg("integer out of range")));
    1919             : 
    1920         738 :     free_var(&count_var);
    1921         738 :     free_var(&result_var);
    1922             : 
    1923         738 :     PG_RETURN_INT32(result);
    1924             : }
    1925             : 
    1926             : /*
    1927             :  * 'operand' is inside the bucket range, so determine the correct
    1928             :  * bucket for it to go in. The calculations performed by this function
    1929             :  * are derived directly from the SQL2003 spec. Note however that we
    1930             :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    1931             :  */
    1932             : static void
    1933         480 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    1934             :                const NumericVar *count_var, NumericVar *result_var)
    1935             : {
    1936             :     NumericVar  bound1_var;
    1937             :     NumericVar  bound2_var;
    1938             :     NumericVar  operand_var;
    1939             : 
    1940         480 :     init_var_from_num(bound1, &bound1_var);
    1941         480 :     init_var_from_num(bound2, &bound2_var);
    1942         480 :     init_var_from_num(operand, &operand_var);
    1943             : 
    1944             :     /*
    1945             :      * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
    1946             :      * bound1 <= operand < bound2 or bound1 >= operand > bound2.  Either way,
    1947             :      * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
    1948             :      * where the quotient is computed using floor division (i.e., division to
    1949             :      * zero decimal places with truncation), which guarantees that the result
    1950             :      * is in the range [1, count].  Reversing the bounds doesn't affect the
    1951             :      * computation, because the signs cancel out when dividing.
    1952             :      */
    1953         480 :     sub_var(&operand_var, &bound1_var, &operand_var);
    1954         480 :     sub_var(&bound2_var, &bound1_var, &bound2_var);
    1955             : 
    1956         480 :     mul_var(&operand_var, count_var, &operand_var,
    1957         480 :             operand_var.dscale + count_var->dscale);
    1958         480 :     div_var(&operand_var, &bound2_var, result_var, 0, false, true);
    1959         480 :     add_var(result_var, &const_one, result_var);
    1960             : 
    1961         480 :     free_var(&bound1_var);
    1962         480 :     free_var(&bound2_var);
    1963         480 :     free_var(&operand_var);
    1964         480 : }
    1965             : 
    1966             : /* ----------------------------------------------------------------------
    1967             :  *
    1968             :  * Comparison functions
    1969             :  *
    1970             :  * Note: btree indexes need these routines not to leak memory; therefore,
    1971             :  * be careful to free working copies of toasted datums.  Most places don't
    1972             :  * need to be so careful.
    1973             :  *
    1974             :  * Sort support:
    1975             :  *
    1976             :  * We implement the sortsupport strategy routine in order to get the benefit of
    1977             :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    1978             :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    1979             :  * while this could be worked on itself, the abbreviation strategy gives more
    1980             :  * speedup in many common cases.
    1981             :  *
    1982             :  * Two different representations are used for the abbreviated form, one in
    1983             :  * int32 and one in int64, whichever fits into a by-value Datum.  In both cases
    1984             :  * the representation is negated relative to the original value, because we use
    1985             :  * the largest negative value for NaN, which sorts higher than other values. We
    1986             :  * convert the absolute value of the numeric to a 31-bit or 63-bit positive
    1987             :  * value, and then negate it if the original number was positive.
    1988             :  *
    1989             :  * We abort the abbreviation process if the abbreviation cardinality is below
    1990             :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    1991             :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    1992             :  * very small penalty), but we don't want to build up too many abbreviated
    1993             :  * values before first testing for abort, so we take the slightly pessimistic
    1994             :  * number.  We make no attempt to estimate the cardinality of the real values,
    1995             :  * since it plays no part in the cost model here (if the abbreviation is equal,
    1996             :  * the cost of comparing equal and unequal underlying values is comparable).
    1997             :  * We discontinue even checking for abort (saving us the hashing overhead) if
    1998             :  * the estimated cardinality gets to 100k; that would be enough to support many
    1999             :  * billions of rows while doing no worse than breaking even.
    2000             :  *
    2001             :  * ----------------------------------------------------------------------
    2002             :  */
    2003             : 
    2004             : /*
    2005             :  * Sort support strategy routine.
    2006             :  */
    2007             : Datum
    2008         972 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2009             : {
    2010         972 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2011             : 
    2012         972 :     ssup->comparator = numeric_fast_cmp;
    2013             : 
    2014         972 :     if (ssup->abbreviate)
    2015             :     {
    2016             :         NumericSortSupport *nss;
    2017         250 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2018             : 
    2019         250 :         nss = palloc(sizeof(NumericSortSupport));
    2020             : 
    2021             :         /*
    2022             :          * palloc a buffer for handling unaligned packed values in addition to
    2023             :          * the support struct
    2024             :          */
    2025         250 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2026             : 
    2027         250 :         nss->input_count = 0;
    2028         250 :         nss->estimating = true;
    2029         250 :         initHyperLogLog(&nss->abbr_card, 10);
    2030             : 
    2031         250 :         ssup->ssup_extra = nss;
    2032             : 
    2033         250 :         ssup->abbrev_full_comparator = ssup->comparator;
    2034         250 :         ssup->comparator = numeric_cmp_abbrev;
    2035         250 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2036         250 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2037             : 
    2038         250 :         MemoryContextSwitchTo(oldcontext);
    2039             :     }
    2040             : 
    2041         972 :     PG_RETURN_VOID();
    2042             : }
    2043             : 
    2044             : /*
    2045             :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2046             :  * (must not leak memory!)
    2047             :  */
    2048             : static Datum
    2049       19132 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2050             : {
    2051       19132 :     NumericSortSupport *nss = ssup->ssup_extra;
    2052       19132 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2053             :     Numeric     value;
    2054             :     Datum       result;
    2055             : 
    2056       19132 :     nss->input_count += 1;
    2057             : 
    2058             :     /*
    2059             :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2060             :      * we keep and reuse a buffer large enough to handle any short datum.
    2061             :      */
    2062       19132 :     if (VARATT_IS_SHORT(original_varatt))
    2063             :     {
    2064        1026 :         void       *buf = nss->buf;
    2065        1026 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2066             : 
    2067             :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2068             : 
    2069        1026 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2070        1026 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2071             : 
    2072        1026 :         value = (Numeric) buf;
    2073             :     }
    2074             :     else
    2075       18106 :         value = (Numeric) original_varatt;
    2076             : 
    2077       19132 :     if (NUMERIC_IS_SPECIAL(value))
    2078             :     {
    2079         150 :         if (NUMERIC_IS_PINF(value))
    2080          48 :             result = NUMERIC_ABBREV_PINF;
    2081         102 :         else if (NUMERIC_IS_NINF(value))
    2082          48 :             result = NUMERIC_ABBREV_NINF;
    2083             :         else
    2084          54 :             result = NUMERIC_ABBREV_NAN;
    2085             :     }
    2086             :     else
    2087             :     {
    2088             :         NumericVar  var;
    2089             : 
    2090       18982 :         init_var_from_num(value, &var);
    2091             : 
    2092       18982 :         result = numeric_abbrev_convert_var(&var, nss);
    2093             :     }
    2094             : 
    2095             :     /* should happen only for external/compressed toasts */
    2096       19132 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
    2097           0 :         pfree(original_varatt);
    2098             : 
    2099       19132 :     return result;
    2100             : }
    2101             : 
    2102             : /*
    2103             :  * Consider whether to abort abbreviation.
    2104             :  *
    2105             :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2106             :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2107             :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2108             :  * whether the underlying values are also equal.
    2109             :  */
    2110             : static bool
    2111         144 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2112             : {
    2113         144 :     NumericSortSupport *nss = ssup->ssup_extra;
    2114             :     double      abbr_card;
    2115             : 
    2116         144 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2117         144 :         return false;
    2118             : 
    2119           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2120             : 
    2121             :     /*
    2122             :      * If we have >100k distinct values, then even if we were sorting many
    2123             :      * billion rows we'd likely still break even, and the penalty of undoing
    2124             :      * that many rows of abbrevs would probably not be worth it. Stop even
    2125             :      * counting at that point.
    2126             :      */
    2127           0 :     if (abbr_card > 100000.0)
    2128             :     {
    2129           0 :         if (trace_sort)
    2130           0 :             elog(LOG,
    2131             :                  "numeric_abbrev: estimation ends at cardinality %f"
    2132             :                  " after " INT64_FORMAT " values (%d rows)",
    2133             :                  abbr_card, nss->input_count, memtupcount);
    2134           0 :         nss->estimating = false;
    2135           0 :         return false;
    2136             :     }
    2137             : 
    2138             :     /*
    2139             :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2140             :      * break even point is somewhere between one per 100k rows, where
    2141             :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2142             :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2143             :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2144             :      * abort earlier on genuinely pathological data where we've had exactly
    2145             :      * one abbreviated value in the first 10k (non-null) rows.
    2146             :      */
    2147           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2148             :     {
    2149           0 :         if (trace_sort)
    2150           0 :             elog(LOG,
    2151             :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2152             :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2153             :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2154             :                  nss->input_count, memtupcount);
    2155           0 :         return true;
    2156             :     }
    2157             : 
    2158           0 :     if (trace_sort)
    2159           0 :         elog(LOG,
    2160             :              "numeric_abbrev: cardinality %f"
    2161             :              " after " INT64_FORMAT " values (%d rows)",
    2162             :              abbr_card, nss->input_count, memtupcount);
    2163             : 
    2164           0 :     return false;
    2165             : }
    2166             : 
    2167             : /*
    2168             :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2169             :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2170             :  * are, but it is a required part of the sort support API when abbreviations
    2171             :  * are performed.
    2172             :  *
    2173             :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2174             :  * aligning short-varlena inputs, but this has not so far been considered to
    2175             :  * be worth the effort.
    2176             :  */
    2177             : static int
    2178     4548024 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2179             : {
    2180     4548024 :     Numeric     nx = DatumGetNumeric(x);
    2181     4548024 :     Numeric     ny = DatumGetNumeric(y);
    2182             :     int         result;
    2183             : 
    2184     4548024 :     result = cmp_numerics(nx, ny);
    2185             : 
    2186     4548024 :     if ((Pointer) nx != DatumGetPointer(x))
    2187      172830 :         pfree(nx);
    2188     4548024 :     if ((Pointer) ny != DatumGetPointer(y))
    2189      172824 :         pfree(ny);
    2190             : 
    2191     4548024 :     return result;
    2192             : }
    2193             : 
    2194             : /*
    2195             :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2196             :  * values differ, but if the abbreviations differ, they must reflect the
    2197             :  * ordering of the true values.)
    2198             :  */
    2199             : static int
    2200      188260 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2201             : {
    2202             :     /*
    2203             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2204             :      * negated relative to the original value, to handle NaN/infinity cases.
    2205             :      */
    2206      188260 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2207       98124 :         return 1;
    2208       90136 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2209       89914 :         return -1;
    2210         222 :     return 0;
    2211             : }
    2212             : 
    2213             : /*
    2214             :  * Abbreviate a NumericVar according to the available bit size.
    2215             :  *
    2216             :  * The 31-bit value is constructed as:
    2217             :  *
    2218             :  *  0 + 7bits digit weight + 24 bits digit value
    2219             :  *
    2220             :  * where the digit weight is in single decimal digits, not digit words, and
    2221             :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2222             :  * significant decimal digits of the value converted to binary. Values whose
    2223             :  * weights would fall outside the representable range are rounded off to zero
    2224             :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2225             :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2226             :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2227             :  * to be a serious limitation, or when values are of the same magnitude and
    2228             :  * equal in the first 7 decimal digits, which is considered to be an
    2229             :  * unavoidable limitation given the available bits. (Stealing three more bits
    2230             :  * to compare another digit would narrow the range of representable weights by
    2231             :  * a factor of 8, which starts to look like a real limiting factor.)
    2232             :  *
    2233             :  * (The value 44 for the excess is essentially arbitrary)
    2234             :  *
    2235             :  * The 63-bit value is constructed as:
    2236             :  *
    2237             :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2238             :  *
    2239             :  * The weight in this case is again stored in excess-44, but this time it is
    2240             :  * the original weight in digit words (i.e. powers of 10000). The first four
    2241             :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2242             :  * are packed into 14 bits each to form the rest of the value. Again,
    2243             :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2244             :  * representable range in this case is 10^-176 to 10^332, which is considered
    2245             :  * to be good enough for all practical purposes, and comparison of 4 words
    2246             :  * means that at least 13 decimal digits are compared, which is considered to
    2247             :  * be a reasonable compromise between effectiveness and efficiency in computing
    2248             :  * the abbreviation.
    2249             :  *
    2250             :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2251             :  * to match the value used in the 31-bit case)
    2252             :  *
    2253             :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2254             :  * and then treated as unsigned, so the smallest representable value is stored
    2255             :  * with all bits zero. This allows simple comparisons to work on the composite
    2256             :  * value.
    2257             :  */
    2258             : 
    2259             : #if NUMERIC_ABBREV_BITS == 64
    2260             : 
    2261             : static Datum
    2262       18982 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2263             : {
    2264       18982 :     int         ndigits = var->ndigits;
    2265       18982 :     int         weight = var->weight;
    2266             :     int64       result;
    2267             : 
    2268       18982 :     if (ndigits == 0 || weight < -44)
    2269             :     {
    2270          52 :         result = 0;
    2271             :     }
    2272       18930 :     else if (weight > 83)
    2273             :     {
    2274          12 :         result = PG_INT64_MAX;
    2275             :     }
    2276             :     else
    2277             :     {
    2278       18918 :         result = ((int64) (weight + 44) << 56);
    2279             : 
    2280       18918 :         switch (ndigits)
    2281             :         {
    2282           0 :             default:
    2283           0 :                 result |= ((int64) var->digits[3]);
    2284             :                 /* FALLTHROUGH */
    2285        6208 :             case 3:
    2286        6208 :                 result |= ((int64) var->digits[2]) << 14;
    2287             :                 /* FALLTHROUGH */
    2288       18270 :             case 2:
    2289       18270 :                 result |= ((int64) var->digits[1]) << 28;
    2290             :                 /* FALLTHROUGH */
    2291       18918 :             case 1:
    2292       18918 :                 result |= ((int64) var->digits[0]) << 42;
    2293       18918 :                 break;
    2294             :         }
    2295             :     }
    2296             : 
    2297             :     /* the abbrev is negated relative to the original */
    2298       18982 :     if (var->sign == NUMERIC_POS)
    2299       18884 :         result = -result;
    2300             : 
    2301       18982 :     if (nss->estimating)
    2302             :     {
    2303       18982 :         uint32      tmp = ((uint32) result
    2304       18982 :                            ^ (uint32) ((uint64) result >> 32));
    2305             : 
    2306       18982 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2307             :     }
    2308             : 
    2309       18982 :     return NumericAbbrevGetDatum(result);
    2310             : }
    2311             : 
    2312             : #endif                          /* NUMERIC_ABBREV_BITS == 64 */
    2313             : 
    2314             : #if NUMERIC_ABBREV_BITS == 32
    2315             : 
    2316             : static Datum
    2317             : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2318             : {
    2319             :     int         ndigits = var->ndigits;
    2320             :     int         weight = var->weight;
    2321             :     int32       result;
    2322             : 
    2323             :     if (ndigits == 0 || weight < -11)
    2324             :     {
    2325             :         result = 0;
    2326             :     }
    2327             :     else if (weight > 20)
    2328             :     {
    2329             :         result = PG_INT32_MAX;
    2330             :     }
    2331             :     else
    2332             :     {
    2333             :         NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
    2334             : 
    2335             :         weight = (weight + 11) * 4;
    2336             : 
    2337             :         result = var->digits[0];
    2338             : 
    2339             :         /*
    2340             :          * "result" now has 1 to 4 nonzero decimal digits. We pack in more
    2341             :          * digits to make 7 in total (largest we can fit in 24 bits)
    2342             :          */
    2343             : 
    2344             :         if (result > 999)
    2345             :         {
    2346             :             /* already have 4 digits, add 3 more */
    2347             :             result = (result * 1000) + (nxt1 / 10);
    2348             :             weight += 3;
    2349             :         }
    2350             :         else if (result > 99)
    2351             :         {
    2352             :             /* already have 3 digits, add 4 more */
    2353             :             result = (result * 10000) + nxt1;
    2354             :             weight += 2;
    2355             :         }
    2356             :         else if (result > 9)
    2357             :         {
    2358             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2359             : 
    2360             :             /* already have 2 digits, add 5 more */
    2361             :             result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
    2362             :             weight += 1;
    2363             :         }
    2364             :         else
    2365             :         {
    2366             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2367             : 
    2368             :             /* already have 1 digit, add 6 more */
    2369             :             result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
    2370             :         }
    2371             : 
    2372             :         result = result | (weight << 24);
    2373             :     }
    2374             : 
    2375             :     /* the abbrev is negated relative to the original */
    2376             :     if (var->sign == NUMERIC_POS)
    2377             :         result = -result;
    2378             : 
    2379             :     if (nss->estimating)
    2380             :     {
    2381             :         uint32      tmp = (uint32) result;
    2382             : 
    2383             :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2384             :     }
    2385             : 
    2386             :     return NumericAbbrevGetDatum(result);
    2387             : }
    2388             : 
    2389             : #endif                          /* NUMERIC_ABBREV_BITS == 32 */
    2390             : 
    2391             : /*
    2392             :  * Ordinary (non-sortsupport) comparisons follow.
    2393             :  */
    2394             : 
    2395             : Datum
    2396      759688 : numeric_cmp(PG_FUNCTION_ARGS)
    2397             : {
    2398      759688 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2399      759688 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2400             :     int         result;
    2401             : 
    2402      759688 :     result = cmp_numerics(num1, num2);
    2403             : 
    2404      759688 :     PG_FREE_IF_COPY(num1, 0);
    2405      759688 :     PG_FREE_IF_COPY(num2, 1);
    2406             : 
    2407      759688 :     PG_RETURN_INT32(result);
    2408             : }
    2409             : 
    2410             : 
    2411             : Datum
    2412      625886 : numeric_eq(PG_FUNCTION_ARGS)
    2413             : {
    2414      625886 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2415      625886 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2416             :     bool        result;
    2417             : 
    2418      625886 :     result = cmp_numerics(num1, num2) == 0;
    2419             : 
    2420      625886 :     PG_FREE_IF_COPY(num1, 0);
    2421      625886 :     PG_FREE_IF_COPY(num2, 1);
    2422             : 
    2423      625886 :     PG_RETURN_BOOL(result);
    2424             : }
    2425             : 
    2426             : Datum
    2427        5376 : numeric_ne(PG_FUNCTION_ARGS)
    2428             : {
    2429        5376 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2430        5376 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2431             :     bool        result;
    2432             : 
    2433        5376 :     result = cmp_numerics(num1, num2) != 0;
    2434             : 
    2435        5376 :     PG_FREE_IF_COPY(num1, 0);
    2436        5376 :     PG_FREE_IF_COPY(num2, 1);
    2437             : 
    2438        5376 :     PG_RETURN_BOOL(result);
    2439             : }
    2440             : 
    2441             : Datum
    2442       61388 : numeric_gt(PG_FUNCTION_ARGS)
    2443             : {
    2444       61388 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2445       61388 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2446             :     bool        result;
    2447             : 
    2448       61388 :     result = cmp_numerics(num1, num2) > 0;
    2449             : 
    2450       61388 :     PG_FREE_IF_COPY(num1, 0);
    2451       61388 :     PG_FREE_IF_COPY(num2, 1);
    2452             : 
    2453       61388 :     PG_RETURN_BOOL(result);
    2454             : }
    2455             : 
    2456             : Datum
    2457       16720 : numeric_ge(PG_FUNCTION_ARGS)
    2458             : {
    2459       16720 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2460       16720 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2461             :     bool        result;
    2462             : 
    2463       16720 :     result = cmp_numerics(num1, num2) >= 0;
    2464             : 
    2465       16720 :     PG_FREE_IF_COPY(num1, 0);
    2466       16720 :     PG_FREE_IF_COPY(num2, 1);
    2467             : 
    2468       16720 :     PG_RETURN_BOOL(result);
    2469             : }
    2470             : 
    2471             : Datum
    2472       52532 : numeric_lt(PG_FUNCTION_ARGS)
    2473             : {
    2474       52532 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2475       52532 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2476             :     bool        result;
    2477             : 
    2478       52532 :     result = cmp_numerics(num1, num2) < 0;
    2479             : 
    2480       52532 :     PG_FREE_IF_COPY(num1, 0);
    2481       52532 :     PG_FREE_IF_COPY(num2, 1);
    2482             : 
    2483       52532 :     PG_RETURN_BOOL(result);
    2484             : }
    2485             : 
    2486             : Datum
    2487       15484 : numeric_le(PG_FUNCTION_ARGS)
    2488             : {
    2489       15484 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2490       15484 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2491             :     bool        result;
    2492             : 
    2493       15484 :     result = cmp_numerics(num1, num2) <= 0;
    2494             : 
    2495       15484 :     PG_FREE_IF_COPY(num1, 0);
    2496       15484 :     PG_FREE_IF_COPY(num2, 1);
    2497             : 
    2498       15484 :     PG_RETURN_BOOL(result);
    2499             : }
    2500             : 
    2501             : static int
    2502     6106620 : cmp_numerics(Numeric num1, Numeric num2)
    2503             : {
    2504             :     int         result;
    2505             : 
    2506             :     /*
    2507             :      * We consider all NANs to be equal and larger than any non-NAN (including
    2508             :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2509             :      * a consistent sort order.
    2510             :      */
    2511     6106620 :     if (NUMERIC_IS_SPECIAL(num1))
    2512             :     {
    2513        8634 :         if (NUMERIC_IS_NAN(num1))
    2514             :         {
    2515        8544 :             if (NUMERIC_IS_NAN(num2))
    2516         970 :                 result = 0;     /* NAN = NAN */
    2517             :             else
    2518        7574 :                 result = 1;     /* NAN > non-NAN */
    2519             :         }
    2520          90 :         else if (NUMERIC_IS_PINF(num1))
    2521             :         {
    2522          72 :             if (NUMERIC_IS_NAN(num2))
    2523           0 :                 result = -1;    /* PINF < NAN */
    2524          72 :             else if (NUMERIC_IS_PINF(num2))
    2525           6 :                 result = 0;     /* PINF = PINF */
    2526             :             else
    2527          66 :                 result = 1;     /* PINF > anything else */
    2528             :         }
    2529             :         else                    /* num1 must be NINF */
    2530             :         {
    2531          18 :             if (NUMERIC_IS_NINF(num2))
    2532           6 :                 result = 0;     /* NINF = NINF */
    2533             :             else
    2534          12 :                 result = -1;    /* NINF < anything else */
    2535             :         }
    2536             :     }
    2537     6097986 :     else if (NUMERIC_IS_SPECIAL(num2))
    2538             :     {
    2539       11214 :         if (NUMERIC_IS_NINF(num2))
    2540          12 :             result = 1;         /* normal > NINF */
    2541             :         else
    2542       11202 :             result = -1;        /* normal < NAN or PINF */
    2543             :     }
    2544             :     else
    2545             :     {
    2546    12175654 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2547     6088136 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2548     6086772 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2549     6087518 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2550             :     }
    2551             : 
    2552     6106620 :     return result;
    2553             : }
    2554             : 
    2555             : /*
    2556             :  * in_range support function for numeric.
    2557             :  */
    2558             : Datum
    2559        1152 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2560             : {
    2561        1152 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2562        1152 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2563        1152 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2564        1152 :     bool        sub = PG_GETARG_BOOL(3);
    2565        1152 :     bool        less = PG_GETARG_BOOL(4);
    2566             :     bool        result;
    2567             : 
    2568             :     /*
    2569             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2570             :      * and NaN is because appropriate semantics for that seem non-obvious.
    2571             :      */
    2572        1152 :     if (NUMERIC_IS_NAN(offset) ||
    2573        1146 :         NUMERIC_IS_NINF(offset) ||
    2574        1146 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2575           6 :         ereport(ERROR,
    2576             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2577             :                  errmsg("invalid preceding or following size in window function")));
    2578             : 
    2579             :     /*
    2580             :      * Deal with cases where val and/or base is NaN, following the rule that
    2581             :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2582             :      * the conclusion.
    2583             :      */
    2584        1146 :     if (NUMERIC_IS_NAN(val))
    2585             :     {
    2586         186 :         if (NUMERIC_IS_NAN(base))
    2587          60 :             result = true;      /* NAN = NAN */
    2588             :         else
    2589         126 :             result = !less;     /* NAN > non-NAN */
    2590             :     }
    2591         960 :     else if (NUMERIC_IS_NAN(base))
    2592             :     {
    2593         126 :         result = less;          /* non-NAN < NAN */
    2594             :     }
    2595             : 
    2596             :     /*
    2597             :      * Deal with infinite offset (necessarily +Inf, at this point).
    2598             :      */
    2599         834 :     else if (NUMERIC_IS_SPECIAL(offset))
    2600             :     {
    2601             :         Assert(NUMERIC_IS_PINF(offset));
    2602         420 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2603             :         {
    2604             :             /*
    2605             :              * base +/- offset would produce NaN, so return true for any val
    2606             :              * (see in_range_float8_float8() for reasoning).
    2607             :              */
    2608         174 :             result = true;
    2609             :         }
    2610         246 :         else if (sub)
    2611             :         {
    2612             :             /* base - offset must be -inf */
    2613         150 :             if (less)
    2614          54 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2615             :             else
    2616          96 :                 result = true;  /* any val is >= sum */
    2617             :         }
    2618             :         else
    2619             :         {
    2620             :             /* base + offset must be +inf */
    2621          96 :             if (less)
    2622           0 :                 result = true;  /* any val is <= sum */
    2623             :             else
    2624          96 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2625             :         }
    2626             :     }
    2627             : 
    2628             :     /*
    2629             :      * Deal with cases where val and/or base is infinite.  The offset, being
    2630             :      * now known finite, cannot affect the conclusion.
    2631             :      */
    2632         414 :     else if (NUMERIC_IS_SPECIAL(val))
    2633             :     {
    2634          78 :         if (NUMERIC_IS_PINF(val))
    2635             :         {
    2636          36 :             if (NUMERIC_IS_PINF(base))
    2637          24 :                 result = true;  /* PINF = PINF */
    2638             :             else
    2639          12 :                 result = !less; /* PINF > any other non-NAN */
    2640             :         }
    2641             :         else                    /* val must be NINF */
    2642             :         {
    2643          42 :             if (NUMERIC_IS_NINF(base))
    2644          30 :                 result = true;  /* NINF = NINF */
    2645             :             else
    2646          12 :                 result = less;  /* NINF < anything else */
    2647             :         }
    2648             :     }
    2649         336 :     else if (NUMERIC_IS_SPECIAL(base))
    2650             :     {
    2651          24 :         if (NUMERIC_IS_NINF(base))
    2652          12 :             result = !less;     /* normal > NINF */
    2653             :         else
    2654          12 :             result = less;      /* normal < PINF */
    2655             :     }
    2656             :     else
    2657             :     {
    2658             :         /*
    2659             :          * Otherwise go ahead and compute base +/- offset.  While it's
    2660             :          * possible for this to overflow the numeric format, it's unlikely
    2661             :          * enough that we don't take measures to prevent it.
    2662             :          */
    2663             :         NumericVar  valv;
    2664             :         NumericVar  basev;
    2665             :         NumericVar  offsetv;
    2666             :         NumericVar  sum;
    2667             : 
    2668         312 :         init_var_from_num(val, &valv);
    2669         312 :         init_var_from_num(base, &basev);
    2670         312 :         init_var_from_num(offset, &offsetv);
    2671         312 :         init_var(&sum);
    2672             : 
    2673         312 :         if (sub)
    2674         156 :             sub_var(&basev, &offsetv, &sum);
    2675             :         else
    2676         156 :             add_var(&basev, &offsetv, &sum);
    2677             : 
    2678         312 :         if (less)
    2679         156 :             result = (cmp_var(&valv, &sum) <= 0);
    2680             :         else
    2681         156 :             result = (cmp_var(&valv, &sum) >= 0);
    2682             : 
    2683         312 :         free_var(&sum);
    2684             :     }
    2685             : 
    2686        1146 :     PG_FREE_IF_COPY(val, 0);
    2687        1146 :     PG_FREE_IF_COPY(base, 1);
    2688        1146 :     PG_FREE_IF_COPY(offset, 2);
    2689             : 
    2690        1146 :     PG_RETURN_BOOL(result);
    2691             : }
    2692             : 
    2693             : Datum
    2694      607512 : hash_numeric(PG_FUNCTION_ARGS)
    2695             : {
    2696      607512 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2697             :     Datum       digit_hash;
    2698             :     Datum       result;
    2699             :     int         weight;
    2700             :     int         start_offset;
    2701             :     int         end_offset;
    2702             :     int         i;
    2703             :     int         hash_len;
    2704             :     NumericDigit *digits;
    2705             : 
    2706             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2707      607512 :     if (NUMERIC_IS_SPECIAL(key))
    2708           0 :         PG_RETURN_UINT32(0);
    2709             : 
    2710      607512 :     weight = NUMERIC_WEIGHT(key);
    2711      607512 :     start_offset = 0;
    2712      607512 :     end_offset = 0;
    2713             : 
    2714             :     /*
    2715             :      * Omit any leading or trailing zeros from the input to the hash. The
    2716             :      * numeric implementation *should* guarantee that leading and trailing
    2717             :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2718             :      * starting and ending offsets in units of NumericDigits, not bytes.
    2719             :      */
    2720      607512 :     digits = NUMERIC_DIGITS(key);
    2721      607512 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2722             :     {
    2723      605874 :         if (digits[i] != (NumericDigit) 0)
    2724      605874 :             break;
    2725             : 
    2726           0 :         start_offset++;
    2727             : 
    2728             :         /*
    2729             :          * The weight is effectively the # of digits before the decimal point,
    2730             :          * so decrement it for each leading zero we skip.
    2731             :          */
    2732           0 :         weight--;
    2733             :     }
    2734             : 
    2735             :     /*
    2736             :      * If there are no non-zero digits, then the value of the number is zero,
    2737             :      * regardless of any other fields.
    2738             :      */
    2739      607512 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2740        1638 :         PG_RETURN_UINT32(-1);
    2741             : 
    2742      605874 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2743             :     {
    2744      605874 :         if (digits[i] != (NumericDigit) 0)
    2745      605874 :             break;
    2746             : 
    2747           0 :         end_offset++;
    2748             :     }
    2749             : 
    2750             :     /* If we get here, there should be at least one non-zero digit */
    2751             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2752             : 
    2753             :     /*
    2754             :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2755             :      * compare equal but have different scales. We also don't hash on the
    2756             :      * sign, although we could: since a sign difference implies inequality,
    2757             :      * this shouldn't affect correctness.
    2758             :      */
    2759      605874 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2760      605874 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2761             :                           hash_len * sizeof(NumericDigit));
    2762             : 
    2763             :     /* Mix in the weight, via XOR */
    2764      605874 :     result = digit_hash ^ weight;
    2765             : 
    2766      605874 :     PG_RETURN_DATUM(result);
    2767             : }
    2768             : 
    2769             : /*
    2770             :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2771             :  * Otherwise, similar to hash_numeric.
    2772             :  */
    2773             : Datum
    2774          84 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2775             : {
    2776          84 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2777          84 :     uint64      seed = PG_GETARG_INT64(1);
    2778             :     Datum       digit_hash;
    2779             :     Datum       result;
    2780             :     int         weight;
    2781             :     int         start_offset;
    2782             :     int         end_offset;
    2783             :     int         i;
    2784             :     int         hash_len;
    2785             :     NumericDigit *digits;
    2786             : 
    2787             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2788          84 :     if (NUMERIC_IS_SPECIAL(key))
    2789           0 :         PG_RETURN_UINT64(seed);
    2790             : 
    2791          84 :     weight = NUMERIC_WEIGHT(key);
    2792          84 :     start_offset = 0;
    2793          84 :     end_offset = 0;
    2794             : 
    2795          84 :     digits = NUMERIC_DIGITS(key);
    2796          84 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2797             :     {
    2798          72 :         if (digits[i] != (NumericDigit) 0)
    2799          72 :             break;
    2800             : 
    2801           0 :         start_offset++;
    2802             : 
    2803           0 :         weight--;
    2804             :     }
    2805             : 
    2806          84 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2807          12 :         PG_RETURN_UINT64(seed - 1);
    2808             : 
    2809          72 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2810             :     {
    2811          72 :         if (digits[i] != (NumericDigit) 0)
    2812          72 :             break;
    2813             : 
    2814           0 :         end_offset++;
    2815             :     }
    2816             : 
    2817             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2818             : 
    2819          72 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2820          72 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2821          72 :                                                       + start_offset),
    2822             :                                    hash_len * sizeof(NumericDigit),
    2823             :                                    seed);
    2824             : 
    2825          72 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2826             : 
    2827          72 :     PG_RETURN_DATUM(result);
    2828             : }
    2829             : 
    2830             : 
    2831             : /* ----------------------------------------------------------------------
    2832             :  *
    2833             :  * Basic arithmetic functions
    2834             :  *
    2835             :  * ----------------------------------------------------------------------
    2836             :  */
    2837             : 
    2838             : 
    2839             : /*
    2840             :  * numeric_add() -
    2841             :  *
    2842             :  *  Add two numerics
    2843             :  */
    2844             : Datum
    2845      251992 : numeric_add(PG_FUNCTION_ARGS)
    2846             : {
    2847      251992 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2848      251992 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2849             :     Numeric     res;
    2850             : 
    2851      251992 :     res = numeric_add_opt_error(num1, num2, NULL);
    2852             : 
    2853      251992 :     PG_RETURN_NUMERIC(res);
    2854             : }
    2855             : 
    2856             : /*
    2857             :  * numeric_add_opt_error() -
    2858             :  *
    2859             :  *  Internal version of numeric_add().  If "*have_error" flag is provided,
    2860             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2861             :  *  need to handle errors by itself.
    2862             :  */
    2863             : Numeric
    2864      253030 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2865             : {
    2866             :     NumericVar  arg1;
    2867             :     NumericVar  arg2;
    2868             :     NumericVar  result;
    2869             :     Numeric     res;
    2870             : 
    2871             :     /*
    2872             :      * Handle NaN and infinities
    2873             :      */
    2874      253030 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2875             :     {
    2876         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2877          78 :             return make_result(&const_nan);
    2878         120 :         if (NUMERIC_IS_PINF(num1))
    2879             :         {
    2880          36 :             if (NUMERIC_IS_NINF(num2))
    2881           6 :                 return make_result(&const_nan); /* Inf + -Inf */
    2882             :             else
    2883          30 :                 return make_result(&const_pinf);
    2884             :         }
    2885          84 :         if (NUMERIC_IS_NINF(num1))
    2886             :         {
    2887          36 :             if (NUMERIC_IS_PINF(num2))
    2888           6 :                 return make_result(&const_nan); /* -Inf + Inf */
    2889             :             else
    2890          30 :                 return make_result(&const_ninf);
    2891             :         }
    2892             :         /* by here, num1 must be finite, so num2 is not */
    2893          48 :         if (NUMERIC_IS_PINF(num2))
    2894          24 :             return make_result(&const_pinf);
    2895             :         Assert(NUMERIC_IS_NINF(num2));
    2896          24 :         return make_result(&const_ninf);
    2897             :     }
    2898             : 
    2899             :     /*
    2900             :      * Unpack the values, let add_var() compute the result and return it.
    2901             :      */
    2902      252832 :     init_var_from_num(num1, &arg1);
    2903      252832 :     init_var_from_num(num2, &arg2);
    2904             : 
    2905      252832 :     init_var(&result);
    2906      252832 :     add_var(&arg1, &arg2, &result);
    2907             : 
    2908      252832 :     res = make_result_opt_error(&result, have_error);
    2909             : 
    2910      252832 :     free_var(&result);
    2911             : 
    2912      252832 :     return res;
    2913             : }
    2914             : 
    2915             : 
    2916             : /*
    2917             :  * numeric_sub() -
    2918             :  *
    2919             :  *  Subtract one numeric from another
    2920             :  */
    2921             : Datum
    2922       91684 : numeric_sub(PG_FUNCTION_ARGS)
    2923             : {
    2924       91684 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2925       91684 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2926             :     Numeric     res;
    2927             : 
    2928       91684 :     res = numeric_sub_opt_error(num1, num2, NULL);
    2929             : 
    2930       91684 :     PG_RETURN_NUMERIC(res);
    2931             : }
    2932             : 
    2933             : 
    2934             : /*
    2935             :  * numeric_sub_opt_error() -
    2936             :  *
    2937             :  *  Internal version of numeric_sub().  If "*have_error" flag is provided,
    2938             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2939             :  *  need to handle errors by itself.
    2940             :  */
    2941             : Numeric
    2942       91834 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2943             : {
    2944             :     NumericVar  arg1;
    2945             :     NumericVar  arg2;
    2946             :     NumericVar  result;
    2947             :     Numeric     res;
    2948             : 
    2949             :     /*
    2950             :      * Handle NaN and infinities
    2951             :      */
    2952       91834 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2953             :     {
    2954        2426 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2955        2306 :             return make_result(&const_nan);
    2956         120 :         if (NUMERIC_IS_PINF(num1))
    2957             :         {
    2958          36 :             if (NUMERIC_IS_PINF(num2))
    2959           6 :                 return make_result(&const_nan); /* Inf - Inf */
    2960             :             else
    2961          30 :                 return make_result(&const_pinf);
    2962             :         }
    2963          84 :         if (NUMERIC_IS_NINF(num1))
    2964             :         {
    2965          36 :             if (NUMERIC_IS_NINF(num2))
    2966           6 :                 return make_result(&const_nan); /* -Inf - -Inf */
    2967             :             else
    2968          30 :                 return make_result(&const_ninf);
    2969             :         }
    2970             :         /* by here, num1 must be finite, so num2 is not */
    2971          48 :         if (NUMERIC_IS_PINF(num2))
    2972          24 :             return make_result(&const_ninf);
    2973             :         Assert(NUMERIC_IS_NINF(num2));
    2974          24 :         return make_result(&const_pinf);
    2975             :     }
    2976             : 
    2977             :     /*
    2978             :      * Unpack the values, let sub_var() compute the result and return it.
    2979             :      */
    2980       89408 :     init_var_from_num(num1, &arg1);
    2981       89408 :     init_var_from_num(num2, &arg2);
    2982             : 
    2983       89408 :     init_var(&result);
    2984       89408 :     sub_var(&arg1, &arg2, &result);
    2985             : 
    2986       89408 :     res = make_result_opt_error(&result, have_error);
    2987             : 
    2988       89408 :     free_var(&result);
    2989             : 
    2990       89408 :     return res;
    2991             : }
    2992             : 
    2993             : 
    2994             : /*
    2995             :  * numeric_mul() -
    2996             :  *
    2997             :  *  Calculate the product of two numerics
    2998             :  */
    2999             : Datum
    3000      489704 : numeric_mul(PG_FUNCTION_ARGS)
    3001             : {
    3002      489704 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3003      489704 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3004             :     Numeric     res;
    3005             : 
    3006      489704 :     res = numeric_mul_opt_error(num1, num2, NULL);
    3007             : 
    3008      489704 :     PG_RETURN_NUMERIC(res);
    3009             : }
    3010             : 
    3011             : 
    3012             : /*
    3013             :  * numeric_mul_opt_error() -
    3014             :  *
    3015             :  *  Internal version of numeric_mul().  If "*have_error" flag is provided,
    3016             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3017             :  *  need to handle errors by itself.
    3018             :  */
    3019             : Numeric
    3020      489740 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3021             : {
    3022             :     NumericVar  arg1;
    3023             :     NumericVar  arg2;
    3024             :     NumericVar  result;
    3025             :     Numeric     res;
    3026             : 
    3027             :     /*
    3028             :      * Handle NaN and infinities
    3029             :      */
    3030      489740 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3031             :     {
    3032         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3033          78 :             return make_result(&const_nan);
    3034         120 :         if (NUMERIC_IS_PINF(num1))
    3035             :         {
    3036          36 :             switch (numeric_sign_internal(num2))
    3037             :             {
    3038           6 :                 case 0:
    3039           6 :                     return make_result(&const_nan); /* Inf * 0 */
    3040          18 :                 case 1:
    3041          18 :                     return make_result(&const_pinf);
    3042          12 :                 case -1:
    3043          12 :                     return make_result(&const_ninf);
    3044             :             }
    3045             :             Assert(false);
    3046             :         }
    3047          84 :         if (NUMERIC_IS_NINF(num1))
    3048             :         {
    3049          36 :             switch (numeric_sign_internal(num2))
    3050             :             {
    3051           6 :                 case 0:
    3052           6 :                     return make_result(&const_nan); /* -Inf * 0 */
    3053          18 :                 case 1:
    3054          18 :                     return make_result(&const_ninf);
    3055          12 :                 case -1:
    3056          12 :                     return make_result(&const_pinf);
    3057             :             }
    3058             :             Assert(false);
    3059             :         }
    3060             :         /* by here, num1 must be finite, so num2 is not */
    3061          48 :         if (NUMERIC_IS_PINF(num2))
    3062             :         {
    3063          24 :             switch (numeric_sign_internal(num1))
    3064             :             {
    3065           6 :                 case 0:
    3066           6 :                     return make_result(&const_nan); /* 0 * Inf */
    3067          12 :                 case 1:
    3068          12 :                     return make_result(&const_pinf);
    3069           6 :                 case -1:
    3070           6 :                     return make_result(&const_ninf);
    3071             :             }
    3072             :             Assert(false);
    3073             :         }
    3074             :         Assert(NUMERIC_IS_NINF(num2));
    3075          24 :         switch (numeric_sign_internal(num1))
    3076             :         {
    3077           6 :             case 0:
    3078           6 :                 return make_result(&const_nan); /* 0 * -Inf */
    3079          12 :             case 1:
    3080          12 :                 return make_result(&const_ninf);
    3081           6 :             case -1:
    3082           6 :                 return make_result(&const_pinf);
    3083             :         }
    3084             :         Assert(false);
    3085             :     }
    3086             : 
    3087             :     /*
    3088             :      * Unpack the values, let mul_var() compute the result and return it.
    3089             :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3090             :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3091             :      * we request exact representation for the product (rscale = sum(dscale of
    3092             :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3093             :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3094             :      * after computing the exact result ensures that the final result is
    3095             :      * correctly rounded (rounding in mul_var() using a truncated product
    3096             :      * would not guarantee this).
    3097             :      */
    3098      489542 :     init_var_from_num(num1, &arg1);
    3099      489542 :     init_var_from_num(num2, &arg2);
    3100             : 
    3101      489542 :     init_var(&result);
    3102      489542 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3103             : 
    3104      489542 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3105           6 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3106             : 
    3107      489542 :     res = make_result_opt_error(&result, have_error);
    3108             : 
    3109      489542 :     free_var(&result);
    3110             : 
    3111      489542 :     return res;
    3112             : }
    3113             : 
    3114             : 
    3115             : /*
    3116             :  * numeric_div() -
    3117             :  *
    3118             :  *  Divide one numeric into another
    3119             :  */
    3120             : Datum
    3121      151270 : numeric_div(PG_FUNCTION_ARGS)
    3122             : {
    3123      151270 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3124      151270 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3125             :     Numeric     res;
    3126             : 
    3127      151270 :     res = numeric_div_opt_error(num1, num2, NULL);
    3128             : 
    3129      151238 :     PG_RETURN_NUMERIC(res);
    3130             : }
    3131             : 
    3132             : 
    3133             : /*
    3134             :  * numeric_div_opt_error() -
    3135             :  *
    3136             :  *  Internal version of numeric_div().  If "*have_error" flag is provided,
    3137             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3138             :  *  need to handle errors by itself.
    3139             :  */
    3140             : Numeric
    3141      152110 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3142             : {
    3143             :     NumericVar  arg1;
    3144             :     NumericVar  arg2;
    3145             :     NumericVar  result;
    3146             :     Numeric     res;
    3147             :     int         rscale;
    3148             : 
    3149      152110 :     if (have_error)
    3150          48 :         *have_error = false;
    3151             : 
    3152             :     /*
    3153             :      * Handle NaN and infinities
    3154             :      */
    3155      152110 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3156             :     {
    3157         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3158          78 :             return make_result(&const_nan);
    3159         120 :         if (NUMERIC_IS_PINF(num1))
    3160             :         {
    3161          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3162          12 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3163          24 :             switch (numeric_sign_internal(num2))
    3164             :             {
    3165           6 :                 case 0:
    3166           6 :                     if (have_error)
    3167             :                     {
    3168           0 :                         *have_error = true;
    3169           0 :                         return NULL;
    3170             :                     }
    3171           6 :                     ereport(ERROR,
    3172             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3173             :                              errmsg("division by zero")));
    3174             :                     break;
    3175          12 :                 case 1:
    3176          12 :                     return make_result(&const_pinf);
    3177           6 :                 case -1:
    3178           6 :                     return make_result(&const_ninf);
    3179             :             }
    3180          84 :             Assert(false);
    3181             :         }
    3182          84 :         if (NUMERIC_IS_NINF(num1))
    3183             :         {
    3184          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3185          12 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
    3186          24 :             switch (numeric_sign_internal(num2))
    3187             :             {
    3188           6 :                 case 0:
    3189           6 :                     if (have_error)
    3190             :                     {
    3191           0 :                         *have_error = true;
    3192           0 :                         return NULL;
    3193             :                     }
    3194           6 :                     ereport(ERROR,
    3195             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3196             :                              errmsg("division by zero")));
    3197             :                     break;
    3198          12 :                 case 1:
    3199          12 :                     return make_result(&const_ninf);
    3200           6 :                 case -1:
    3201           6 :                     return make_result(&const_pinf);
    3202             :             }
    3203          48 :             Assert(false);
    3204             :         }
    3205             :         /* by here, num1 must be finite, so num2 is not */
    3206             : 
    3207             :         /*
    3208             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3209             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3210             :          * really do underflow, so let's just return zero.
    3211             :          */
    3212          48 :         return make_result(&const_zero);
    3213             :     }
    3214             : 
    3215             :     /*
    3216             :      * Unpack the arguments
    3217             :      */
    3218      151912 :     init_var_from_num(num1, &arg1);
    3219      151912 :     init_var_from_num(num2, &arg2);
    3220             : 
    3221      151912 :     init_var(&result);
    3222             : 
    3223             :     /*
    3224             :      * Select scale for division result
    3225             :      */
    3226      151912 :     rscale = select_div_scale(&arg1, &arg2);
    3227             : 
    3228             :     /*
    3229             :      * If "have_error" is provided, check for division by zero here
    3230             :      */
    3231      151912 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3232             :     {
    3233          12 :         *have_error = true;
    3234          12 :         return NULL;
    3235             :     }
    3236             : 
    3237             :     /*
    3238             :      * Do the divide and return the result
    3239             :      */
    3240      151900 :     div_var(&arg1, &arg2, &result, rscale, true, true);
    3241             : 
    3242      151862 :     res = make_result_opt_error(&result, have_error);
    3243             : 
    3244      151862 :     free_var(&result);
    3245             : 
    3246      151862 :     return res;
    3247             : }
    3248             : 
    3249             : 
    3250             : /*
    3251             :  * numeric_div_trunc() -
    3252             :  *
    3253             :  *  Divide one numeric into another, truncating the result to an integer
    3254             :  */
    3255             : Datum
    3256        1218 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3257             : {
    3258        1218 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3259        1218 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3260             :     NumericVar  arg1;
    3261             :     NumericVar  arg2;
    3262             :     NumericVar  result;
    3263             :     Numeric     res;
    3264             : 
    3265             :     /*
    3266             :      * Handle NaN and infinities
    3267             :      */
    3268        1218 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3269             :     {
    3270         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3271          78 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3272         120 :         if (NUMERIC_IS_PINF(num1))
    3273             :         {
    3274          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3275          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3276          24 :             switch (numeric_sign_internal(num2))
    3277             :             {
    3278           6 :                 case 0:
    3279           6 :                     ereport(ERROR,
    3280             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3281             :                              errmsg("division by zero")));
    3282             :                     break;
    3283          12 :                 case 1:
    3284          12 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3285           6 :                 case -1:
    3286           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3287             :             }
    3288          84 :             Assert(false);
    3289             :         }
    3290          84 :         if (NUMERIC_IS_NINF(num1))
    3291             :         {
    3292          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3293          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3294          24 :             switch (numeric_sign_internal(num2))
    3295             :             {
    3296           6 :                 case 0:
    3297           6 :                     ereport(ERROR,
    3298             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3299             :                              errmsg("division by zero")));
    3300             :                     break;
    3301          12 :                 case 1:
    3302          12 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3303           6 :                 case -1:
    3304           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3305             :             }
    3306          48 :             Assert(false);
    3307             :         }
    3308             :         /* by here, num1 must be finite, so num2 is not */
    3309             : 
    3310             :         /*
    3311             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3312             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3313             :          * really do underflow, so let's just return zero.
    3314             :          */
    3315          48 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3316             :     }
    3317             : 
    3318             :     /*
    3319             :      * Unpack the arguments
    3320             :      */
    3321        1020 :     init_var_from_num(num1, &arg1);
    3322        1020 :     init_var_from_num(num2, &arg2);
    3323             : 
    3324        1020 :     init_var(&result);
    3325             : 
    3326             :     /*
    3327             :      * Do the divide and return the result
    3328             :      */
    3329        1020 :     div_var(&arg1, &arg2, &result, 0, false, true);
    3330             : 
    3331        1014 :     res = make_result(&result);
    3332             : 
    3333        1014 :     free_var(&result);
    3334             : 
    3335        1014 :     PG_RETURN_NUMERIC(res);
    3336             : }
    3337             : 
    3338             : 
    3339             : /*
    3340             :  * numeric_mod() -
    3341             :  *
    3342             :  *  Calculate the modulo of two numerics
    3343             :  */
    3344             : Datum
    3345       53390 : numeric_mod(PG_FUNCTION_ARGS)
    3346             : {
    3347       53390 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3348       53390 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3349             :     Numeric     res;
    3350             : 
    3351       53390 :     res = numeric_mod_opt_error(num1, num2, NULL);
    3352             : 
    3353       53372 :     PG_RETURN_NUMERIC(res);
    3354             : }
    3355             : 
    3356             : 
    3357             : /*
    3358             :  * numeric_mod_opt_error() -
    3359             :  *
    3360             :  *  Internal version of numeric_mod().  If "*have_error" flag is provided,
    3361             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3362             :  *  need to handle errors by itself.
    3363             :  */
    3364             : Numeric
    3365       53402 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3366             : {
    3367             :     Numeric     res;
    3368             :     NumericVar  arg1;
    3369             :     NumericVar  arg2;
    3370             :     NumericVar  result;
    3371             : 
    3372       53402 :     if (have_error)
    3373           0 :         *have_error = false;
    3374             : 
    3375             :     /*
    3376             :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3377             :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3378             :      * returning NaN.  We choose to throw error only for y-is-zero.
    3379             :      */
    3380       53402 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3381             :     {
    3382         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3383          78 :             return make_result(&const_nan);
    3384         120 :         if (NUMERIC_IS_INF(num1))
    3385             :         {
    3386          72 :             if (numeric_sign_internal(num2) == 0)
    3387             :             {
    3388          12 :                 if (have_error)
    3389             :                 {
    3390           0 :                     *have_error = true;
    3391           0 :                     return NULL;
    3392             :                 }
    3393          12 :                 ereport(ERROR,
    3394             :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
    3395             :                          errmsg("division by zero")));
    3396             :             }
    3397             :             /* Inf % any nonzero = NaN */
    3398          60 :             return make_result(&const_nan);
    3399             :         }
    3400             :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3401          48 :         return duplicate_numeric(num1);
    3402             :     }
    3403             : 
    3404       53204 :     init_var_from_num(num1, &arg1);
    3405       53204 :     init_var_from_num(num2, &arg2);
    3406             : 
    3407       53204 :     init_var(&result);
    3408             : 
    3409             :     /*
    3410             :      * If "have_error" is provided, check for division by zero here
    3411             :      */
    3412       53204 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3413             :     {
    3414           0 :         *have_error = true;
    3415           0 :         return NULL;
    3416             :     }
    3417             : 
    3418       53204 :     mod_var(&arg1, &arg2, &result);
    3419             : 
    3420       53192 :     res = make_result_opt_error(&result, NULL);
    3421             : 
    3422       53192 :     free_var(&result);
    3423             : 
    3424       53192 :     return res;
    3425             : }
    3426             : 
    3427             : 
    3428             : /*
    3429             :  * numeric_inc() -
    3430             :  *
    3431             :  *  Increment a number by one
    3432             :  */
    3433             : Datum
    3434          48 : numeric_inc(PG_FUNCTION_ARGS)
    3435             : {
    3436          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3437             :     NumericVar  arg;
    3438             :     Numeric     res;
    3439             : 
    3440             :     /*
    3441             :      * Handle NaN and infinities
    3442             :      */
    3443          48 :     if (NUMERIC_IS_SPECIAL(num))
    3444          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3445             : 
    3446             :     /*
    3447             :      * Compute the result and return it
    3448             :      */
    3449          30 :     init_var_from_num(num, &arg);
    3450             : 
    3451          30 :     add_var(&arg, &const_one, &arg);
    3452             : 
    3453          30 :     res = make_result(&arg);
    3454             : 
    3455          30 :     free_var(&arg);
    3456             : 
    3457          30 :     PG_RETURN_NUMERIC(res);
    3458             : }
    3459             : 
    3460             : 
    3461             : /*
    3462             :  * numeric_smaller() -
    3463             :  *
    3464             :  *  Return the smaller of two numbers
    3465             :  */
    3466             : Datum
    3467         798 : numeric_smaller(PG_FUNCTION_ARGS)
    3468             : {
    3469         798 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3470         798 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3471             : 
    3472             :     /*
    3473             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3474             :      * particularly as regards comparisons involving NaN.
    3475             :      */
    3476         798 :     if (cmp_numerics(num1, num2) < 0)
    3477         638 :         PG_RETURN_NUMERIC(num1);
    3478             :     else
    3479         160 :         PG_RETURN_NUMERIC(num2);
    3480             : }
    3481             : 
    3482             : 
    3483             : /*
    3484             :  * numeric_larger() -
    3485             :  *
    3486             :  *  Return the larger of two numbers
    3487             :  */
    3488             : Datum
    3489       18630 : numeric_larger(PG_FUNCTION_ARGS)
    3490             : {
    3491       18630 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3492       18630 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3493             : 
    3494             :     /*
    3495             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3496             :      * particularly as regards comparisons involving NaN.
    3497             :      */
    3498       18630 :     if (cmp_numerics(num1, num2) > 0)
    3499       17878 :         PG_RETURN_NUMERIC(num1);
    3500             :     else
    3501         752 :         PG_RETURN_NUMERIC(num2);
    3502             : }
    3503             : 
    3504             : 
    3505             : /* ----------------------------------------------------------------------
    3506             :  *
    3507             :  * Advanced math functions
    3508             :  *
    3509             :  * ----------------------------------------------------------------------
    3510             :  */
    3511             : 
    3512             : /*
    3513             :  * numeric_gcd() -
    3514             :  *
    3515             :  *  Calculate the greatest common divisor of two numerics
    3516             :  */
    3517             : Datum
    3518         216 : numeric_gcd(PG_FUNCTION_ARGS)
    3519             : {
    3520         216 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3521         216 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3522             :     NumericVar  arg1;
    3523             :     NumericVar  arg2;
    3524             :     NumericVar  result;
    3525             :     Numeric     res;
    3526             : 
    3527             :     /*
    3528             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3529             :      * cases.
    3530             :      */
    3531         216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3532          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3533             : 
    3534             :     /*
    3535             :      * Unpack the arguments
    3536             :      */
    3537         120 :     init_var_from_num(num1, &arg1);
    3538         120 :     init_var_from_num(num2, &arg2);
    3539             : 
    3540         120 :     init_var(&result);
    3541             : 
    3542             :     /*
    3543             :      * Find the GCD and return the result
    3544             :      */
    3545         120 :     gcd_var(&arg1, &arg2, &result);
    3546             : 
    3547         120 :     res = make_result(&result);
    3548             : 
    3549         120 :     free_var(&result);
    3550             : 
    3551         120 :     PG_RETURN_NUMERIC(res);
    3552             : }
    3553             : 
    3554             : 
    3555             : /*
    3556             :  * numeric_lcm() -
    3557             :  *
    3558             :  *  Calculate the least common multiple of two numerics
    3559             :  */
    3560             : Datum
    3561         246 : numeric_lcm(PG_FUNCTION_ARGS)
    3562             : {
    3563         246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3564         246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3565             :     NumericVar  arg1;
    3566             :     NumericVar  arg2;
    3567             :     NumericVar  result;
    3568             :     Numeric     res;
    3569             : 
    3570             :     /*
    3571             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3572             :      * cases.
    3573             :      */
    3574         246 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3575          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3576             : 
    3577             :     /*
    3578             :      * Unpack the arguments
    3579             :      */
    3580         150 :     init_var_from_num(num1, &arg1);
    3581         150 :     init_var_from_num(num2, &arg2);
    3582             : 
    3583         150 :     init_var(&result);
    3584             : 
    3585             :     /*
    3586             :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3587             :      * zero if either input is zero.
    3588             :      *
    3589             :      * Note that the division is guaranteed to be exact, returning an integer
    3590             :      * result, so the LCM is an integral multiple of both x and y.  A display
    3591             :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3592             :      * but as with other numeric functions, we choose to return a result whose
    3593             :      * display scale is no smaller than either input.
    3594             :      */
    3595         150 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3596          48 :         set_var_from_var(&const_zero, &result);
    3597             :     else
    3598             :     {
    3599         102 :         gcd_var(&arg1, &arg2, &result);
    3600         102 :         div_var(&arg1, &result, &result, 0, false, true);
    3601         102 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3602         102 :         result.sign = NUMERIC_POS;
    3603             :     }
    3604             : 
    3605         150 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3606             : 
    3607         150 :     res = make_result(&result);
    3608             : 
    3609         144 :     free_var(&result);
    3610             : 
    3611         144 :     PG_RETURN_NUMERIC(res);
    3612             : }
    3613             : 
    3614             : 
    3615             : /*
    3616             :  * numeric_fac()
    3617             :  *
    3618             :  * Compute factorial
    3619             :  */
    3620             : Datum
    3621          42 : numeric_fac(PG_FUNCTION_ARGS)
    3622             : {
    3623          42 :     int64       num = PG_GETARG_INT64(0);
    3624             :     Numeric     res;
    3625             :     NumericVar  fact;
    3626             :     NumericVar  result;
    3627             : 
    3628          42 :     if (num < 0)
    3629           6 :         ereport(ERROR,
    3630             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3631             :                  errmsg("factorial of a negative number is undefined")));
    3632          36 :     if (num <= 1)
    3633             :     {
    3634           6 :         res = make_result(&const_one);
    3635           6 :         PG_RETURN_NUMERIC(res);
    3636             :     }
    3637             :     /* Fail immediately if the result would overflow */
    3638          30 :     if (num > 32177)
    3639           6 :         ereport(ERROR,
    3640             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3641             :                  errmsg("value overflows numeric format")));
    3642             : 
    3643          24 :     init_var(&fact);
    3644          24 :     init_var(&result);
    3645             : 
    3646          24 :     int64_to_numericvar(num, &result);
    3647             : 
    3648         294 :     for (num = num - 1; num > 1; num--)
    3649             :     {
    3650             :         /* this loop can take awhile, so allow it to be interrupted */
    3651         270 :         CHECK_FOR_INTERRUPTS();
    3652             : 
    3653         270 :         int64_to_numericvar(num, &fact);
    3654             : 
    3655         270 :         mul_var(&result, &fact, &result, 0);
    3656             :     }
    3657             : 
    3658          24 :     res = make_result(&result);
    3659             : 
    3660          24 :     free_var(&fact);
    3661          24 :     free_var(&result);
    3662             : 
    3663          24 :     PG_RETURN_NUMERIC(res);
    3664             : }
    3665             : 
    3666             : 
    3667             : /*
    3668             :  * numeric_sqrt() -
    3669             :  *
    3670             :  *  Compute the square root of a numeric.
    3671             :  */
    3672             : Datum
    3673         150 : numeric_sqrt(PG_FUNCTION_ARGS)
    3674             : {
    3675         150 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3676             :     Numeric     res;
    3677             :     NumericVar  arg;
    3678             :     NumericVar  result;
    3679             :     int         sweight;
    3680             :     int         rscale;
    3681             : 
    3682             :     /*
    3683             :      * Handle NaN and infinities
    3684             :      */
    3685         150 :     if (NUMERIC_IS_SPECIAL(num))
    3686             :     {
    3687             :         /* error should match that in sqrt_var() */
    3688          18 :         if (NUMERIC_IS_NINF(num))
    3689           6 :             ereport(ERROR,
    3690             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3691             :                      errmsg("cannot take square root of a negative number")));
    3692             :         /* For NAN or PINF, just duplicate the input */
    3693          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3694             :     }
    3695             : 
    3696             :     /*
    3697             :      * Unpack the argument and determine the result scale.  We choose a scale
    3698             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3699             :      * case not less than the input's dscale.
    3700             :      */
    3701         132 :     init_var_from_num(num, &arg);
    3702             : 
    3703         132 :     init_var(&result);
    3704             : 
    3705             :     /*
    3706             :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3707             :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3708             :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3709             :      * a few cycles, since the division is exact and there is no need to round
    3710             :      * towards negative infinity.
    3711             :      */
    3712             : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3713         132 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3714             : #else
    3715             :     if (arg.weight >= 0)
    3716             :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3717             :     else
    3718             :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3719             : #endif
    3720             : 
    3721         132 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3722         132 :     rscale = Max(rscale, arg.dscale);
    3723         132 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3724         132 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3725             : 
    3726             :     /*
    3727             :      * Let sqrt_var() do the calculation and return the result.
    3728             :      */
    3729         132 :     sqrt_var(&arg, &result, rscale);
    3730             : 
    3731         126 :     res = make_result(&result);
    3732             : 
    3733         126 :     free_var(&result);
    3734             : 
    3735         126 :     PG_RETURN_NUMERIC(res);
    3736             : }
    3737             : 
    3738             : 
    3739             : /*
    3740             :  * numeric_exp() -
    3741             :  *
    3742             :  *  Raise e to the power of x
    3743             :  */
    3744             : Datum
    3745          78 : numeric_exp(PG_FUNCTION_ARGS)
    3746             : {
    3747          78 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3748             :     Numeric     res;
    3749             :     NumericVar  arg;
    3750             :     NumericVar  result;
    3751             :     int         rscale;
    3752             :     double      val;
    3753             : 
    3754             :     /*
    3755             :      * Handle NaN and infinities
    3756             :      */
    3757          78 :     if (NUMERIC_IS_SPECIAL(num))
    3758             :     {
    3759             :         /* Per POSIX, exp(-Inf) is zero */
    3760          18 :         if (NUMERIC_IS_NINF(num))
    3761           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3762             :         /* For NAN or PINF, just duplicate the input */
    3763          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3764             :     }
    3765             : 
    3766             :     /*
    3767             :      * Unpack the argument and determine the result scale.  We choose a scale
    3768             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3769             :      * case not less than the input's dscale.
    3770             :      */
    3771          60 :     init_var_from_num(num, &arg);
    3772             : 
    3773          60 :     init_var(&result);
    3774             : 
    3775             :     /* convert input to float8, ignoring overflow */
    3776          60 :     val = numericvar_to_double_no_overflow(&arg);
    3777             : 
    3778             :     /*
    3779             :      * log10(result) = num * log10(e), so this is approximately the decimal
    3780             :      * weight of the result:
    3781             :      */
    3782          60 :     val *= 0.434294481903252;
    3783             : 
    3784             :     /* limit to something that won't cause integer overflow */
    3785          60 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3786          60 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3787             : 
    3788          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3789          60 :     rscale = Max(rscale, arg.dscale);
    3790          60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3791          60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3792             : 
    3793             :     /*
    3794             :      * Let exp_var() do the calculation and return the result.
    3795             :      */
    3796          60 :     exp_var(&arg, &result, rscale);
    3797             : 
    3798          60 :     res = make_result(&result);
    3799             : 
    3800          60 :     free_var(&result);
    3801             : 
    3802          60 :     PG_RETURN_NUMERIC(res);
    3803             : }
    3804             : 
    3805             : 
    3806             : /*
    3807             :  * numeric_ln() -
    3808             :  *
    3809             :  *  Compute the natural logarithm of x
    3810             :  */
    3811             : Datum
    3812         198 : numeric_ln(PG_FUNCTION_ARGS)
    3813             : {
    3814         198 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3815             :     Numeric     res;
    3816             :     NumericVar  arg;
    3817             :     NumericVar  result;
    3818             :     int         ln_dweight;
    3819             :     int         rscale;
    3820             : 
    3821             :     /*
    3822             :      * Handle NaN and infinities
    3823             :      */
    3824         198 :     if (NUMERIC_IS_SPECIAL(num))
    3825             :     {
    3826          18 :         if (NUMERIC_IS_NINF(num))
    3827           6 :             ereport(ERROR,
    3828             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3829             :                      errmsg("cannot take logarithm of a negative number")));
    3830             :         /* For NAN or PINF, just duplicate the input */
    3831          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3832             :     }
    3833             : 
    3834         180 :     init_var_from_num(num, &arg);
    3835         180 :     init_var(&result);
    3836             : 
    3837             :     /* Estimated dweight of logarithm */
    3838         180 :     ln_dweight = estimate_ln_dweight(&arg);
    3839             : 
    3840         180 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3841         180 :     rscale = Max(rscale, arg.dscale);
    3842         180 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3843         180 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3844             : 
    3845         180 :     ln_var(&arg, &result, rscale);
    3846             : 
    3847         156 :     res = make_result(&result);
    3848             : 
    3849         156 :     free_var(&result);
    3850             : 
    3851         156 :     PG_RETURN_NUMERIC(res);
    3852             : }
    3853             : 
    3854             : 
    3855             : /*
    3856             :  * numeric_log() -
    3857             :  *
    3858             :  *  Compute the logarithm of x in a given base
    3859             :  */
    3860             : Datum
    3861         342 : numeric_log(PG_FUNCTION_ARGS)
    3862             : {
    3863         342 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3864         342 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3865             :     Numeric     res;
    3866             :     NumericVar  arg1;
    3867             :     NumericVar  arg2;
    3868             :     NumericVar  result;
    3869             : 
    3870             :     /*
    3871             :      * Handle NaN and infinities
    3872             :      */
    3873         342 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3874             :     {
    3875             :         int         sign1,
    3876             :                     sign2;
    3877             : 
    3878         126 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3879          54 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3880             :         /* fail on negative inputs including -Inf, as log_var would */
    3881          72 :         sign1 = numeric_sign_internal(num1);
    3882          72 :         sign2 = numeric_sign_internal(num2);
    3883          72 :         if (sign1 < 0 || sign2 < 0)
    3884          24 :             ereport(ERROR,
    3885             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3886             :                      errmsg("cannot take logarithm of a negative number")));
    3887             :         /* fail on zero inputs, as log_var would */
    3888          48 :         if (sign1 == 0 || sign2 == 0)
    3889           6 :             ereport(ERROR,
    3890             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3891             :                      errmsg("cannot take logarithm of zero")));
    3892          42 :         if (NUMERIC_IS_PINF(num1))
    3893             :         {
    3894             :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    3895          18 :             if (NUMERIC_IS_PINF(num2))
    3896           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    3897             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    3898          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3899             :         }
    3900             :         Assert(NUMERIC_IS_PINF(num2));
    3901             :         /* log(finite-positive, Inf) is Inf */
    3902          24 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    3903             :     }
    3904             : 
    3905             :     /*
    3906             :      * Initialize things
    3907             :      */
    3908         216 :     init_var_from_num(num1, &arg1);
    3909         216 :     init_var_from_num(num2, &arg2);
    3910         216 :     init_var(&result);
    3911             : 
    3912             :     /*
    3913             :      * Call log_var() to compute and return the result; note it handles scale
    3914             :      * selection itself.
    3915             :      */
    3916         216 :     log_var(&arg1, &arg2, &result);
    3917             : 
    3918         156 :     res = make_result(&result);
    3919             : 
    3920         156 :     free_var(&result);
    3921             : 
    3922         156 :     PG_RETURN_NUMERIC(res);
    3923             : }
    3924             : 
    3925             : 
    3926             : /*
    3927             :  * numeric_power() -
    3928             :  *
    3929             :  *  Raise x to the power of y
    3930             :  */
    3931             : Datum
    3932        1644 : numeric_power(PG_FUNCTION_ARGS)
    3933             : {
    3934        1644 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3935        1644 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3936             :     Numeric     res;
    3937             :     NumericVar  arg1;
    3938             :     NumericVar  arg2;
    3939             :     NumericVar  result;
    3940             :     int         sign1,
    3941             :                 sign2;
    3942             : 
    3943             :     /*
    3944             :      * Handle NaN and infinities
    3945             :      */
    3946        1644 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3947             :     {
    3948             :         /*
    3949             :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    3950             :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    3951             :          * (with no error).
    3952             :          */
    3953         234 :         if (NUMERIC_IS_NAN(num1))
    3954             :         {
    3955          54 :             if (!NUMERIC_IS_SPECIAL(num2))
    3956             :             {
    3957          36 :                 init_var_from_num(num2, &arg2);
    3958          36 :                 if (cmp_var(&arg2, &const_zero) == 0)
    3959          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3960             :             }
    3961          42 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3962             :         }
    3963         180 :         if (NUMERIC_IS_NAN(num2))
    3964             :         {
    3965          42 :             if (!NUMERIC_IS_SPECIAL(num1))
    3966             :             {
    3967          36 :                 init_var_from_num(num1, &arg1);
    3968          36 :                 if (cmp_var(&arg1, &const_one) == 0)
    3969          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3970             :             }
    3971          30 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3972             :         }
    3973             :         /* At least one input is infinite, but error rules still apply */
    3974         138 :         sign1 = numeric_sign_internal(num1);
    3975         138 :         sign2 = numeric_sign_internal(num2);
    3976         138 :         if (sign1 == 0 && sign2 < 0)
    3977           6 :             ereport(ERROR,
    3978             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3979             :                      errmsg("zero raised to a negative power is undefined")));
    3980         132 :         if (sign1 < 0 && !numeric_is_integral(num2))
    3981           6 :             ereport(ERROR,
    3982             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3983             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    3984             : 
    3985             :         /*
    3986             :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    3987             :          *
    3988             :          * For any value of y, if x is +1, 1.0 shall be returned.
    3989             :          */
    3990         126 :         if (!NUMERIC_IS_SPECIAL(num1))
    3991             :         {
    3992          42 :             init_var_from_num(num1, &arg1);
    3993          42 :             if (cmp_var(&arg1, &const_one) == 0)
    3994           6 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    3995             :         }
    3996             : 
    3997             :         /*
    3998             :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    3999             :          */
    4000         120 :         if (sign2 == 0)
    4001          12 :             PG_RETURN_NUMERIC(make_result(&const_one));
    4002             : 
    4003             :         /*
    4004             :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    4005             :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    4006             :          * be returned.  (Since we don't deal in minus zero, we need not
    4007             :          * distinguish these two cases.)
    4008             :          */
    4009         108 :         if (sign1 == 0 && sign2 > 0)
    4010           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4011             : 
    4012             :         /*
    4013             :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    4014             :          *
    4015             :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4016             :          *
    4017             :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4018             :          *
    4019             :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4020             :          *
    4021             :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4022             :          */
    4023         102 :         if (NUMERIC_IS_INF(num2))
    4024             :         {
    4025             :             bool        abs_x_gt_one;
    4026             : 
    4027          54 :             if (NUMERIC_IS_SPECIAL(num1))
    4028          24 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4029             :             else
    4030             :             {
    4031          30 :                 init_var_from_num(num1, &arg1);
    4032          30 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4033           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4034          24 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4035          24 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4036             :             }
    4037          48 :             if (abs_x_gt_one == (sign2 > 0))
    4038          30 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4039             :             else
    4040          18 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4041             :         }
    4042             : 
    4043             :         /*
    4044             :          * For y < 0, if x is +Inf, +0 shall be returned.
    4045             :          *
    4046             :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4047             :          */
    4048          48 :         if (NUMERIC_IS_PINF(num1))
    4049             :         {
    4050          24 :             if (sign2 > 0)
    4051          18 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4052             :             else
    4053           6 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4054             :         }
    4055             : 
    4056             :         Assert(NUMERIC_IS_NINF(num1));
    4057             : 
    4058             :         /*
    4059             :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4060             :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4061             :          * (Again, we need not distinguish these two cases.)
    4062             :          */
    4063          24 :         if (sign2 < 0)
    4064          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4065             : 
    4066             :         /*
    4067             :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4068             :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4069             :          */
    4070          12 :         init_var_from_num(num2, &arg2);
    4071          12 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4072          12 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4073           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4074             :         else
    4075           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4076             :     }
    4077             : 
    4078             :     /*
    4079             :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4080             :      * certain error conditions.  Specifically, we don't return a
    4081             :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4082             :      * non-integer power must produce the same error code, but that case is
    4083             :      * handled in power_var().
    4084             :      */
    4085        1410 :     sign1 = numeric_sign_internal(num1);
    4086        1410 :     sign2 = numeric_sign_internal(num2);
    4087             : 
    4088        1410 :     if (sign1 == 0 && sign2 < 0)
    4089          12 :         ereport(ERROR,
    4090             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4091             :                  errmsg("zero raised to a negative power is undefined")));
    4092             : 
    4093             :     /*
    4094             :      * Initialize things
    4095             :      */
    4096        1398 :     init_var(&result);
    4097        1398 :     init_var_from_num(num1, &arg1);
    4098        1398 :     init_var_from_num(num2, &arg2);
    4099             : 
    4100             :     /*
    4101             :      * Call power_var() to compute and return the result; note it handles
    4102             :      * scale selection itself.
    4103             :      */
    4104        1398 :     power_var(&arg1, &arg2, &result);
    4105             : 
    4106        1368 :     res = make_result(&result);
    4107             : 
    4108        1368 :     free_var(&result);
    4109             : 
    4110        1368 :     PG_RETURN_NUMERIC(res);
    4111             : }
    4112             : 
    4113             : /*
    4114             :  * numeric_scale() -
    4115             :  *
    4116             :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4117             :  */
    4118             : Datum
    4119         108 : numeric_scale(PG_FUNCTION_ARGS)
    4120             : {
    4121         108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4122             : 
    4123         108 :     if (NUMERIC_IS_SPECIAL(num))
    4124          18 :         PG_RETURN_NULL();
    4125             : 
    4126          90 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4127             : }
    4128             : 
    4129             : /*
    4130             :  * Calculate minimum scale for value.
    4131             :  */
    4132             : static int
    4133         372 : get_min_scale(NumericVar *var)
    4134             : {
    4135             :     int         min_scale;
    4136             :     int         last_digit_pos;
    4137             : 
    4138             :     /*
    4139             :      * Ordinarily, the input value will be "stripped" so that the last
    4140             :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4141             :      * loop if it isn't, so explicitly find the last nonzero digit.
    4142             :      */
    4143         372 :     last_digit_pos = var->ndigits - 1;
    4144         372 :     while (last_digit_pos >= 0 &&
    4145         342 :            var->digits[last_digit_pos] == 0)
    4146           0 :         last_digit_pos--;
    4147             : 
    4148         372 :     if (last_digit_pos >= 0)
    4149             :     {
    4150             :         /* compute min_scale assuming that last ndigit has no zeroes */
    4151         342 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4152             : 
    4153             :         /*
    4154             :          * We could get a negative result if there are no digits after the
    4155             :          * decimal point.  In this case the min_scale must be zero.
    4156             :          */
    4157         342 :         if (min_scale > 0)
    4158             :         {
    4159             :             /*
    4160             :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4161             :              * zero.
    4162             :              */
    4163         186 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4164             : 
    4165         498 :             while (last_digit % 10 == 0)
    4166             :             {
    4167         312 :                 min_scale--;
    4168         312 :                 last_digit /= 10;
    4169             :             }
    4170             :         }
    4171             :         else
    4172         156 :             min_scale = 0;
    4173             :     }
    4174             :     else
    4175          30 :         min_scale = 0;          /* result if input is zero */
    4176             : 
    4177         372 :     return min_scale;
    4178             : }
    4179             : 
    4180             : /*
    4181             :  * Returns minimum scale required to represent supplied value without loss.
    4182             :  */
    4183             : Datum
    4184          72 : numeric_min_scale(PG_FUNCTION_ARGS)
    4185             : {
    4186          72 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4187             :     NumericVar  arg;
    4188             :     int         min_scale;
    4189             : 
    4190          72 :     if (NUMERIC_IS_SPECIAL(num))
    4191          12 :         PG_RETURN_NULL();
    4192             : 
    4193          60 :     init_var_from_num(num, &arg);
    4194          60 :     min_scale = get_min_scale(&arg);
    4195          60 :     free_var(&arg);
    4196             : 
    4197          60 :     PG_RETURN_INT32(min_scale);
    4198             : }
    4199             : 
    4200             : /*
    4201             :  * Reduce scale of numeric value to represent supplied value without loss.
    4202             :  */
    4203             : Datum
    4204         324 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4205             : {
    4206         324 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4207             :     Numeric     res;
    4208             :     NumericVar  result;
    4209             : 
    4210         324 :     if (NUMERIC_IS_SPECIAL(num))
    4211          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4212             : 
    4213         312 :     init_var_from_num(num, &result);
    4214         312 :     result.dscale = get_min_scale(&result);
    4215         312 :     res = make_result(&result);
    4216         312 :     free_var(&result);
    4217             : 
    4218         312 :     PG_RETURN_NUMERIC(res);
    4219             : }
    4220             : 
    4221             : /*
    4222             :  * Return a random numeric value in the range [rmin, rmax].
    4223             :  */
    4224             : Numeric
    4225       33462 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
    4226             : {
    4227             :     NumericVar  rmin_var;
    4228             :     NumericVar  rmax_var;
    4229             :     NumericVar  result;
    4230             :     Numeric     res;
    4231             : 
    4232             :     /* Range bounds must not be NaN/infinity */
    4233       33462 :     if (NUMERIC_IS_SPECIAL(rmin))
    4234             :     {
    4235          12 :         if (NUMERIC_IS_NAN(rmin))
    4236           6 :             ereport(ERROR,
    4237             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4238             :                     errmsg("lower bound cannot be NaN"));
    4239             :         else
    4240           6 :             ereport(ERROR,
    4241             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4242             :                     errmsg("lower bound cannot be infinity"));
    4243             :     }
    4244       33450 :     if (NUMERIC_IS_SPECIAL(rmax))
    4245             :     {
    4246          12 :         if (NUMERIC_IS_NAN(rmax))
    4247           6 :             ereport(ERROR,
    4248             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4249             :                     errmsg("upper bound cannot be NaN"));
    4250             :         else
    4251           6 :             ereport(ERROR,
    4252             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4253             :                     errmsg("upper bound cannot be infinity"));
    4254             :     }
    4255             : 
    4256             :     /* Return a random value in the range [rmin, rmax] */
    4257       33438 :     init_var_from_num(rmin, &rmin_var);
    4258       33438 :     init_var_from_num(rmax, &rmax_var);
    4259             : 
    4260       33438 :     init_var(&result);
    4261             : 
    4262       33438 :     random_var(state, &rmin_var, &rmax_var, &result);
    4263             : 
    4264       33432 :     res = make_result(&result);
    4265             : 
    4266       33432 :     free_var(&result);
    4267             : 
    4268       33432 :     return res;
    4269             : }
    4270             : 
    4271             : 
    4272             : /* ----------------------------------------------------------------------
    4273             :  *
    4274             :  * Type conversion functions
    4275             :  *
    4276             :  * ----------------------------------------------------------------------
    4277             :  */
    4278             : 
    4279             : Numeric
    4280     1848664 : int64_to_numeric(int64 val)
    4281             : {
    4282             :     Numeric     res;
    4283             :     NumericVar  result;
    4284             : 
    4285     1848664 :     init_var(&result);
    4286             : 
    4287     1848664 :     int64_to_numericvar(val, &result);
    4288             : 
    4289     1848664 :     res = make_result(&result);
    4290             : 
    4291     1848664 :     free_var(&result);
    4292             : 
    4293     1848664 :     return res;
    4294             : }
    4295             : 
    4296             : /*
    4297             :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4298             :  * numeric division.
    4299             :  */
    4300             : Numeric
    4301       29380 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4302             : {
    4303             :     Numeric     res;
    4304             :     NumericVar  result;
    4305             :     int         rscale;
    4306             :     int         w;
    4307             :     int         m;
    4308             : 
    4309       29380 :     init_var(&result);
    4310             : 
    4311             :     /* result scale */
    4312       29380 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4313             : 
    4314             :     /* how much to decrease the weight by */
    4315       29380 :     w = log10val2 / DEC_DIGITS;
    4316             :     /* how much is left to divide by */
    4317       29380 :     m = log10val2 % DEC_DIGITS;
    4318       29380 :     if (m < 0)
    4319             :     {
    4320           0 :         m += DEC_DIGITS;
    4321           0 :         w--;
    4322             :     }
    4323             : 
    4324             :     /*
    4325             :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4326             :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4327             :      * one more.
    4328             :      */
    4329       29380 :     if (m > 0)
    4330             :     {
    4331             : #if DEC_DIGITS == 4
    4332             :         static const int pow10[] = {1, 10, 100, 1000};
    4333             : #elif DEC_DIGITS == 2
    4334             :         static const int pow10[] = {1, 10};
    4335             : #elif DEC_DIGITS == 1
    4336             :         static const int pow10[] = {1};
    4337             : #else
    4338             : #error unsupported NBASE
    4339             : #endif
    4340       29380 :         int64       factor = pow10[DEC_DIGITS - m];
    4341             :         int64       new_val1;
    4342             : 
    4343             :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4344             : 
    4345       29380 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4346             :         {
    4347             : #ifdef HAVE_INT128
    4348             :             /* do the multiplication using 128-bit integers */
    4349             :             int128      tmp;
    4350             : 
    4351          12 :             tmp = (int128) val1 * (int128) factor;
    4352             : 
    4353          12 :             int128_to_numericvar(tmp, &result);
    4354             : #else
    4355             :             /* do the multiplication using numerics */
    4356             :             NumericVar  tmp;
    4357             : 
    4358             :             init_var(&tmp);
    4359             : 
    4360             :             int64_to_numericvar(val1, &result);
    4361             :             int64_to_numericvar(factor, &tmp);
    4362             :             mul_var(&result, &tmp, &result, 0);
    4363             : 
    4364             :             free_var(&tmp);
    4365             : #endif
    4366             :         }
    4367             :         else
    4368       29368 :             int64_to_numericvar(new_val1, &result);
    4369             : 
    4370       29380 :         w++;
    4371             :     }
    4372             :     else
    4373           0 :         int64_to_numericvar(val1, &result);
    4374             : 
    4375       29380 :     result.weight -= w;
    4376       29380 :     result.dscale = rscale;
    4377             : 
    4378       29380 :     res = make_result(&result);
    4379             : 
    4380       29380 :     free_var(&result);
    4381             : 
    4382       29380 :     return res;
    4383             : }
    4384             : 
    4385             : Datum
    4386     1530668 : int4_numeric(PG_FUNCTION_ARGS)
    4387             : {
    4388     1530668 :     int32       val = PG_GETARG_INT32(0);
    4389             : 
    4390     1530668 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4391             : }
    4392             : 
    4393             : int32
    4394        7680 : numeric_int4_opt_error(Numeric num, bool *have_error)
    4395             : {
    4396             :     NumericVar  x;
    4397             :     int32       result;
    4398             : 
    4399        7680 :     if (have_error)
    4400        1584 :         *have_error = false;
    4401             : 
    4402        7680 :     if (NUMERIC_IS_SPECIAL(num))
    4403             :     {
    4404          18 :         if (have_error)
    4405             :         {
    4406           0 :             *have_error = true;
    4407           0 :             return 0;
    4408             :         }
    4409             :         else
    4410             :         {
    4411          18 :             if (NUMERIC_IS_NAN(num))
    4412           6 :                 ereport(ERROR,
    4413             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4414             :                          errmsg("cannot convert NaN to %s", "integer")));
    4415             :             else
    4416          12 :                 ereport(ERROR,
    4417             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4418             :                          errmsg("cannot convert infinity to %s", "integer")));
    4419             :         }
    4420             :     }
    4421             : 
    4422             :     /* Convert to variable format, then convert to int4 */
    4423        7662 :     init_var_from_num(num, &x);
    4424             : 
    4425        7662 :     if (!numericvar_to_int32(&x, &result))
    4426             :     {
    4427          90 :         if (have_error)
    4428             :         {
    4429          78 :             *have_error = true;
    4430          78 :             return 0;
    4431             :         }
    4432             :         else
    4433             :         {
    4434          12 :             ereport(ERROR,
    4435             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4436             :                      errmsg("integer out of range")));
    4437             :         }
    4438             :     }
    4439             : 
    4440        7572 :     return result;
    4441             : }
    4442             : 
    4443             : Datum
    4444        6096 : numeric_int4(PG_FUNCTION_ARGS)
    4445             : {
    4446        6096 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4447             : 
    4448        6096 :     PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
    4449             : }
    4450             : 
    4451             : /*
    4452             :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4453             :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4454             :  * The input NumericVar is *not* free'd.
    4455             :  */
    4456             : static bool
    4457        8400 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4458             : {
    4459             :     int64       val;
    4460             : 
    4461        8400 :     if (!numericvar_to_int64(var, &val))
    4462           6 :         return false;
    4463             : 
    4464        8394 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4465          84 :         return false;
    4466             : 
    4467             :     /* Down-convert to int4 */
    4468        8310 :     *result = (int32) val;
    4469             : 
    4470        8310 :     return true;
    4471             : }
    4472             : 
    4473             : Datum
    4474       36850 : int8_numeric(PG_FUNCTION_ARGS)
    4475             : {
    4476       36850 :     int64       val = PG_GETARG_INT64(0);
    4477             : 
    4478       36850 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4479             : }
    4480             : 
    4481             : int64
    4482         564 : numeric_int8_opt_error(Numeric num, bool *have_error)
    4483             : {
    4484             :     NumericVar  x;
    4485             :     int64       result;
    4486             : 
    4487         564 :     if (have_error)
    4488          48 :         *have_error = false;
    4489             : 
    4490         564 :     if (NUMERIC_IS_SPECIAL(num))
    4491             :     {
    4492          18 :         if (have_error)
    4493             :         {
    4494           0 :             *have_error = true;
    4495           0 :             return 0;
    4496             :         }
    4497             :         else
    4498             :         {
    4499          18 :             if (NUMERIC_IS_NAN(num))
    4500           6 :                 ereport(ERROR,
    4501             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4502             :                          errmsg("cannot convert NaN to %s", "bigint")));
    4503             :             else
    4504          12 :                 ereport(ERROR,
    4505             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4506             :                          errmsg("cannot convert infinity to %s", "bigint")));
    4507             :         }
    4508             :     }
    4509             : 
    4510             :     /* Convert to variable format, then convert to int8 */
    4511         546 :     init_var_from_num(num, &x);
    4512             : 
    4513         546 :     if (!numericvar_to_int64(&x, &result))
    4514             :     {
    4515          60 :         if (have_error)
    4516             :         {
    4517          12 :             *have_error = true;
    4518          12 :             return 0;
    4519             :         }
    4520             :         else
    4521             :         {
    4522          48 :             ereport(ERROR,
    4523             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4524             :                      errmsg("bigint out of range")));
    4525             :         }
    4526             :     }
    4527             : 
    4528         486 :     return result;
    4529             : }
    4530             : 
    4531             : Datum
    4532         516 : numeric_int8(PG_FUNCTION_ARGS)
    4533             : {
    4534         516 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4535             : 
    4536         516 :     PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
    4537             : }
    4538             : 
    4539             : 
    4540             : Datum
    4541           6 : int2_numeric(PG_FUNCTION_ARGS)
    4542             : {
    4543           6 :     int16       val = PG_GETARG_INT16(0);
    4544             : 
    4545           6 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4546             : }
    4547             : 
    4548             : 
    4549             : Datum
    4550          96 : numeric_int2(PG_FUNCTION_ARGS)
    4551             : {
    4552          96 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4553             :     NumericVar  x;
    4554             :     int64       val;
    4555             :     int16       result;
    4556             : 
    4557          96 :     if (NUMERIC_IS_SPECIAL(num))
    4558             :     {
    4559          18 :         if (NUMERIC_IS_NAN(num))
    4560           6 :             ereport(ERROR,
    4561             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4562             :                      errmsg("cannot convert NaN to %s", "smallint")));
    4563             :         else
    4564          12 :             ereport(ERROR,
    4565             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4566             :                      errmsg("cannot convert infinity to %s", "smallint")));
    4567             :     }
    4568             : 
    4569             :     /* Convert to variable format and thence to int8 */
    4570          78 :     init_var_from_num(num, &x);
    4571             : 
    4572          78 :     if (!numericvar_to_int64(&x, &val))
    4573           0 :         ereport(ERROR,
    4574             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4575             :                  errmsg("smallint out of range")));
    4576             : 
    4577          78 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4578          12 :         ereport(ERROR,
    4579             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4580             :                  errmsg("smallint out of range")));
    4581             : 
    4582             :     /* Down-convert to int2 */
    4583          66 :     result = (int16) val;
    4584             : 
    4585          66 :     PG_RETURN_INT16(result);
    4586             : }
    4587             : 
    4588             : 
    4589             : Datum
    4590        1074 : float8_numeric(PG_FUNCTION_ARGS)
    4591             : {
    4592        1074 :     float8      val = PG_GETARG_FLOAT8(0);
    4593             :     Numeric     res;
    4594             :     NumericVar  result;
    4595             :     char        buf[DBL_DIG + 100];
    4596             :     const char *endptr;
    4597             : 
    4598        1074 :     if (isnan(val))
    4599           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4600             : 
    4601        1068 :     if (isinf(val))
    4602             :     {
    4603          12 :         if (val < 0)
    4604           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4605             :         else
    4606           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4607             :     }
    4608             : 
    4609        1056 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4610             : 
    4611        1056 :     init_var(&result);
    4612             : 
    4613             :     /* Assume we need not worry about leading/trailing spaces */
    4614        1056 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4615             : 
    4616        1056 :     res = make_result(&result);
    4617             : 
    4618        1056 :     free_var(&result);
    4619             : 
    4620        1056 :     PG_RETURN_NUMERIC(res);
    4621             : }
    4622             : 
    4623             : 
    4624             : Datum
    4625      519450 : numeric_float8(PG_FUNCTION_ARGS)
    4626             : {
    4627      519450 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4628             :     char       *tmp;
    4629             :     Datum       result;
    4630             : 
    4631      519450 :     if (NUMERIC_IS_SPECIAL(num))
    4632             :     {
    4633          78 :         if (NUMERIC_IS_PINF(num))
    4634          24 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4635          54 :         else if (NUMERIC_IS_NINF(num))
    4636          24 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4637             :         else
    4638          30 :             PG_RETURN_FLOAT8(get_float8_nan());
    4639             :     }
    4640             : 
    4641      519372 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4642             :                                               NumericGetDatum(num)));
    4643             : 
    4644      519372 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
    4645             : 
    4646      519372 :     pfree(tmp);
    4647             : 
    4648      519372 :     PG_RETURN_DATUM(result);
    4649             : }
    4650             : 
    4651             : 
    4652             : /*
    4653             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4654             :  *
    4655             :  * (internal helper function, not directly callable from SQL)
    4656             :  */
    4657             : Datum
    4658        3100 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4659             : {
    4660        3100 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4661             :     double      val;
    4662             : 
    4663        3100 :     if (NUMERIC_IS_SPECIAL(num))
    4664             :     {
    4665           0 :         if (NUMERIC_IS_PINF(num))
    4666           0 :             val = HUGE_VAL;
    4667           0 :         else if (NUMERIC_IS_NINF(num))
    4668           0 :             val = -HUGE_VAL;
    4669             :         else
    4670           0 :             val = get_float8_nan();
    4671             :     }
    4672             :     else
    4673             :     {
    4674             :         NumericVar  x;
    4675             : 
    4676        3100 :         init_var_from_num(num, &x);
    4677        3100 :         val = numericvar_to_double_no_overflow(&x);
    4678             :     }
    4679             : 
    4680        3100 :     PG_RETURN_FLOAT8(val);
    4681             : }
    4682             : 
    4683             : Datum
    4684       21942 : float4_numeric(PG_FUNCTION_ARGS)
    4685             : {
    4686       21942 :     float4      val = PG_GETARG_FLOAT4(0);
    4687             :     Numeric     res;
    4688             :     NumericVar  result;
    4689             :     char        buf[FLT_DIG + 100];
    4690             :     const char *endptr;
    4691             : 
    4692       21942 :     if (isnan(val))
    4693           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4694             : 
    4695       21936 :     if (isinf(val))
    4696             :     {
    4697          12 :         if (val < 0)
    4698           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4699             :         else
    4700           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4701             :     }
    4702             : 
    4703       21924 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4704             : 
    4705       21924 :     init_var(&result);
    4706             : 
    4707             :     /* Assume we need not worry about leading/trailing spaces */
    4708       21924 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4709             : 
    4710       21924 :     res = make_result(&result);
    4711             : 
    4712       21924 :     free_var(&result);
    4713             : 
    4714       21924 :     PG_RETURN_NUMERIC(res);
    4715             : }
    4716             : 
    4717             : 
    4718             : Datum
    4719        2936 : numeric_float4(PG_FUNCTION_ARGS)
    4720             : {
    4721        2936 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4722             :     char       *tmp;
    4723             :     Datum       result;
    4724             : 
    4725        2936 :     if (NUMERIC_IS_SPECIAL(num))
    4726             :     {
    4727          78 :         if (NUMERIC_IS_PINF(num))
    4728          24 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4729          54 :         else if (NUMERIC_IS_NINF(num))
    4730          24 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4731             :         else
    4732          30 :             PG_RETURN_FLOAT4(get_float4_nan());
    4733             :     }
    4734             : 
    4735        2858 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4736             :                                               NumericGetDatum(num)));
    4737             : 
    4738        2858 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
    4739             : 
    4740        2858 :     pfree(tmp);
    4741             : 
    4742        2858 :     PG_RETURN_DATUM(result);
    4743             : }
    4744             : 
    4745             : 
    4746             : Datum
    4747         120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4748             : {
    4749         120 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4750             :     NumericVar  x;
    4751             :     XLogRecPtr  result;
    4752             : 
    4753         120 :     if (NUMERIC_IS_SPECIAL(num))
    4754             :     {
    4755           6 :         if (NUMERIC_IS_NAN(num))
    4756           6 :             ereport(ERROR,
    4757             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4758             :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4759             :         else
    4760           0 :             ereport(ERROR,
    4761             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4762             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4763             :     }
    4764             : 
    4765             :     /* Convert to variable format and thence to pg_lsn */
    4766         114 :     init_var_from_num(num, &x);
    4767             : 
    4768         114 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4769          24 :         ereport(ERROR,
    4770             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4771             :                  errmsg("pg_lsn out of range")));
    4772             : 
    4773          90 :     PG_RETURN_LSN(result);
    4774             : }
    4775             : 
    4776             : 
    4777             : /* ----------------------------------------------------------------------
    4778             :  *
    4779             :  * Aggregate functions
    4780             :  *
    4781             :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4782             :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4783             :  * context.  The digit buffers for the NumericVars will be there too.
    4784             :  *
    4785             :  * On platforms which support 128-bit integers some aggregates instead use a
    4786             :  * 128-bit integer based transition datatype to speed up calculations.
    4787             :  *
    4788             :  * ----------------------------------------------------------------------
    4789             :  */
    4790             : 
    4791             : typedef struct NumericAggState
    4792             : {
    4793             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4794             :     MemoryContext agg_context;  /* context we're calculating in */
    4795             :     int64       N;              /* count of processed numbers */
    4796             :     NumericSumAccum sumX;       /* sum of processed numbers */
    4797             :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4798             :     int         maxScale;       /* maximum scale seen so far */
    4799             :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4800             :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4801             :     int64       NaNcount;       /* count of NaN values */
    4802             :     int64       pInfcount;      /* count of +Inf values */
    4803             :     int64       nInfcount;      /* count of -Inf values */
    4804             : } NumericAggState;
    4805             : 
    4806             : #define NA_TOTAL_COUNT(na) \
    4807             :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4808             : 
    4809             : /*
    4810             :  * Prepare state data for a numeric aggregate function that needs to compute
    4811             :  * sum, count and optionally sum of squares of the input.
    4812             :  */
    4813             : static NumericAggState *
    4814      171116 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4815             : {
    4816             :     NumericAggState *state;
    4817             :     MemoryContext agg_context;
    4818             :     MemoryContext old_context;
    4819             : 
    4820      171116 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4821           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4822             : 
    4823      171116 :     old_context = MemoryContextSwitchTo(agg_context);
    4824             : 
    4825      171116 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4826      171116 :     state->calcSumX2 = calcSumX2;
    4827      171116 :     state->agg_context = agg_context;
    4828             : 
    4829      171116 :     MemoryContextSwitchTo(old_context);
    4830             : 
    4831      171116 :     return state;
    4832             : }
    4833             : 
    4834             : /*
    4835             :  * Like makeNumericAggState(), but allocate the state in the current memory
    4836             :  * context.
    4837             :  */
    4838             : static NumericAggState *
    4839          60 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4840             : {
    4841             :     NumericAggState *state;
    4842             : 
    4843          60 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4844          60 :     state->calcSumX2 = calcSumX2;
    4845          60 :     state->agg_context = CurrentMemoryContext;
    4846             : 
    4847          60 :     return state;
    4848             : }
    4849             : 
    4850             : /*
    4851             :  * Accumulate a new input value for numeric aggregate functions.
    4852             :  */
    4853             : static void
    4854     2113552 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4855             : {
    4856             :     NumericVar  X;
    4857             :     NumericVar  X2;
    4858             :     MemoryContext old_context;
    4859             : 
    4860             :     /* Count NaN/infinity inputs separately from all else */
    4861     2113552 :     if (NUMERIC_IS_SPECIAL(newval))
    4862             :     {
    4863         162 :         if (NUMERIC_IS_PINF(newval))
    4864          72 :             state->pInfcount++;
    4865          90 :         else if (NUMERIC_IS_NINF(newval))
    4866          36 :             state->nInfcount++;
    4867             :         else
    4868          54 :             state->NaNcount++;
    4869         162 :         return;
    4870             :     }
    4871             : 
    4872             :     /* load processed number in short-lived context */
    4873     2113390 :     init_var_from_num(newval, &X);
    4874             : 
    4875             :     /*
    4876             :      * Track the highest input dscale that we've seen, to support inverse
    4877             :      * transitions (see do_numeric_discard).
    4878             :      */
    4879     2113390 :     if (X.dscale > state->maxScale)
    4880             :     {
    4881         156 :         state->maxScale = X.dscale;
    4882         156 :         state->maxScaleCount = 1;
    4883             :     }
    4884     2113234 :     else if (X.dscale == state->maxScale)
    4885     2113198 :         state->maxScaleCount++;
    4886             : 
    4887             :     /* if we need X^2, calculate that in short-lived context */
    4888     2113390 :     if (state->calcSumX2)
    4889             :     {
    4890      240732 :         init_var(&X2);
    4891      240732 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4892             :     }
    4893             : 
    4894             :     /* The rest of this needs to work in the aggregate context */
    4895     2113390 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4896             : 
    4897     2113390 :     state->N++;
    4898             : 
    4899             :     /* Accumulate sums */
    4900     2113390 :     accum_sum_add(&(state->sumX), &X);
    4901             : 
    4902     2113390 :     if (state->calcSumX2)
    4903      240732 :         accum_sum_add(&(state->sumX2), &X2);
    4904             : 
    4905     2113390 :     MemoryContextSwitchTo(old_context);
    4906             : }
    4907             : 
    4908             : /*
    4909             :  * Attempt to remove an input value from the aggregated state.
    4910             :  *
    4911             :  * If the value cannot be removed then the function will return false; the
    4912             :  * possible reasons for failing are described below.
    4913             :  *
    4914             :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    4915             :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    4916             :  * won't be able to tell what the new aggregated value's dscale should be.
    4917             :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    4918             :  * have been zero if we'd really aggregated only 2.
    4919             :  *
    4920             :  * Note: alternatively, we could count the number of inputs with each possible
    4921             :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    4922             :  */
    4923             : static bool
    4924         342 : do_numeric_discard(NumericAggState *state, Numeric newval)
    4925             : {
    4926             :     NumericVar  X;
    4927             :     NumericVar  X2;
    4928             :     MemoryContext old_context;
    4929             : 
    4930             :     /* Count NaN/infinity inputs separately from all else */
    4931         342 :     if (NUMERIC_IS_SPECIAL(newval))
    4932             :     {
    4933           6 :         if (NUMERIC_IS_PINF(newval))
    4934           0 :             state->pInfcount--;
    4935           6 :         else if (NUMERIC_IS_NINF(newval))
    4936           0 :             state->nInfcount--;
    4937             :         else
    4938           6 :             state->NaNcount--;
    4939           6 :         return true;
    4940             :     }
    4941             : 
    4942             :     /* load processed number in short-lived context */
    4943         336 :     init_var_from_num(newval, &X);
    4944             : 
    4945             :     /*
    4946             :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    4947             :      * Removing the last input with that dscale would require us to recompute
    4948             :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    4949             :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    4950             :      * and force the aggregation to be redone from scratch.
    4951             :      */
    4952         336 :     if (X.dscale == state->maxScale)
    4953             :     {
    4954         336 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    4955             :         {
    4956             :             /*
    4957             :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    4958             :              * above zero anyway
    4959             :              */
    4960         318 :             state->maxScaleCount--;
    4961             :         }
    4962          18 :         else if (state->N == 1)
    4963             :         {
    4964             :             /* No remaining non-NaN inputs at all, so reset maxScale */
    4965          12 :             state->maxScale = 0;
    4966          12 :             state->maxScaleCount = 0;
    4967             :         }
    4968             :         else
    4969             :         {
    4970             :             /* Correct new maxScale is uncertain, must fail */
    4971           6 :             return false;
    4972             :         }
    4973             :     }
    4974             : 
    4975             :     /* if we need X^2, calculate that in short-lived context */
    4976         330 :     if (state->calcSumX2)
    4977             :     {
    4978         288 :         init_var(&X2);
    4979         288 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4980             :     }
    4981             : 
    4982             :     /* The rest of this needs to work in the aggregate context */
    4983         330 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4984             : 
    4985         330 :     if (state->N-- > 1)
    4986             :     {
    4987             :         /* Negate X, to subtract it from the sum */
    4988         312 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    4989         312 :         accum_sum_add(&(state->sumX), &X);
    4990             : 
    4991         312 :         if (state->calcSumX2)
    4992             :         {
    4993             :             /* Negate X^2. X^2 is always positive */
    4994         288 :             X2.sign = NUMERIC_NEG;
    4995         288 :             accum_sum_add(&(state->sumX2), &X2);
    4996             :         }
    4997             :     }
    4998             :     else
    4999             :     {
    5000             :         /* Zero the sums */
    5001             :         Assert(state->N == 0);
    5002             : 
    5003          18 :         accum_sum_reset(&state->sumX);
    5004          18 :         if (state->calcSumX2)
    5005           0 :             accum_sum_reset(&state->sumX2);
    5006             :     }
    5007             : 
    5008         330 :     MemoryContextSwitchTo(old_context);
    5009             : 
    5010         330 :     return true;
    5011             : }
    5012             : 
    5013             : /*
    5014             :  * Generic transition function for numeric aggregates that require sumX2.
    5015             :  */
    5016             : Datum
    5017         642 : numeric_accum(PG_FUNCTION_ARGS)
    5018             : {
    5019             :     NumericAggState *state;
    5020             : 
    5021         642 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5022             : 
    5023             :     /* Create the state data on the first call */
    5024         642 :     if (state == NULL)
    5025         174 :         state = makeNumericAggState(fcinfo, true);
    5026             : 
    5027         642 :     if (!PG_ARGISNULL(1))
    5028         624 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5029             : 
    5030         642 :     PG_RETURN_POINTER(state);
    5031             : }
    5032             : 
    5033             : /*
    5034             :  * Generic combine function for numeric aggregates which require sumX2
    5035             :  */
    5036             : Datum
    5037          24 : numeric_combine(PG_FUNCTION_ARGS)
    5038             : {
    5039             :     NumericAggState *state1;
    5040             :     NumericAggState *state2;
    5041             :     MemoryContext agg_context;
    5042             :     MemoryContext old_context;
    5043             : 
    5044          24 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5045           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5046             : 
    5047          24 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5048          24 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5049             : 
    5050          24 :     if (state2 == NULL)
    5051           0 :         PG_RETURN_POINTER(state1);
    5052             : 
    5053             :     /* manually copy all fields from state2 to state1 */
    5054          24 :     if (state1 == NULL)
    5055             :     {
    5056          18 :         old_context = MemoryContextSwitchTo(agg_context);
    5057             : 
    5058          18 :         state1 = makeNumericAggStateCurrentContext(true);
    5059          18 :         state1->N = state2->N;
    5060          18 :         state1->NaNcount = state2->NaNcount;
    5061          18 :         state1->pInfcount = state2->pInfcount;
    5062          18 :         state1->nInfcount = state2->nInfcount;
    5063          18 :         state1->maxScale = state2->maxScale;
    5064          18 :         state1->maxScaleCount = state2->maxScaleCount;
    5065             : 
    5066          18 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5067          18 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5068             : 
    5069          18 :         MemoryContextSwitchTo(old_context);
    5070             : 
    5071          18 :         PG_RETURN_POINTER(state1);
    5072             :     }
    5073             : 
    5074           6 :     state1->N += state2->N;
    5075           6 :     state1->NaNcount += state2->NaNcount;
    5076           6 :     state1->pInfcount += state2->pInfcount;
    5077           6 :     state1->nInfcount += state2->nInfcount;
    5078             : 
    5079           6 :     if (state2->N > 0)
    5080             :     {
    5081             :         /*
    5082             :          * These are currently only needed for moving aggregates, but let's do
    5083             :          * the right thing anyway...
    5084             :          */
    5085           6 :         if (state2->maxScale > state1->maxScale)
    5086             :         {
    5087           0 :             state1->maxScale = state2->maxScale;
    5088           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5089             :         }
    5090           6 :         else if (state2->maxScale == state1->maxScale)
    5091           6 :             state1->maxScaleCount += state2->maxScaleCount;
    5092             : 
    5093             :         /* The rest of this needs to work in the aggregate context */
    5094           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5095             : 
    5096             :         /* Accumulate sums */
    5097           6 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5098           6 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5099             : 
    5100           6 :         MemoryContextSwitchTo(old_context);
    5101             :     }
    5102           6 :     PG_RETURN_POINTER(state1);
    5103             : }
    5104             : 
    5105             : /*
    5106             :  * Generic transition function for numeric aggregates that don't require sumX2.
    5107             :  */
    5108             : Datum
    5109     1872808 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5110             : {
    5111             :     NumericAggState *state;
    5112             : 
    5113     1872808 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5114             : 
    5115             :     /* Create the state data on the first call */
    5116     1872808 :     if (state == NULL)
    5117      170894 :         state = makeNumericAggState(fcinfo, false);
    5118             : 
    5119     1872808 :     if (!PG_ARGISNULL(1))
    5120     1872748 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5121             : 
    5122     1872808 :     PG_RETURN_POINTER(state);
    5123             : }
    5124             : 
    5125             : /*
    5126             :  * Combine function for numeric aggregates which don't require sumX2
    5127             :  */
    5128             : Datum
    5129          12 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5130             : {
    5131             :     NumericAggState *state1;
    5132             :     NumericAggState *state2;
    5133             :     MemoryContext agg_context;
    5134             :     MemoryContext old_context;
    5135             : 
    5136          12 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5137           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5138             : 
    5139          12 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5140          12 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5141             : 
    5142          12 :     if (state2 == NULL)
    5143           0 :         PG_RETURN_POINTER(state1);
    5144             : 
    5145             :     /* manually copy all fields from state2 to state1 */
    5146          12 :     if (state1 == NULL)
    5147             :     {
    5148           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5149             : 
    5150           6 :         state1 = makeNumericAggStateCurrentContext(false);
    5151           6 :         state1->N = state2->N;
    5152           6 :         state1->NaNcount = state2->NaNcount;
    5153           6 :         state1->pInfcount = state2->pInfcount;
    5154           6 :         state1->nInfcount = state2->nInfcount;
    5155           6 :         state1->maxScale = state2->maxScale;
    5156           6 :         state1->maxScaleCount = state2->maxScaleCount;
    5157             : 
    5158           6 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5159             : 
    5160           6 :         MemoryContextSwitchTo(old_context);
    5161             : 
    5162           6 :         PG_RETURN_POINTER(state1);
    5163             :     }
    5164             : 
    5165           6 :     state1->N += state2->N;
    5166           6 :     state1->NaNcount += state2->NaNcount;
    5167           6 :     state1->pInfcount += state2->pInfcount;
    5168           6 :     state1->nInfcount += state2->nInfcount;
    5169             : 
    5170           6 :     if (state2->N > 0)
    5171             :     {
    5172             :         /*
    5173             :          * These are currently only needed for moving aggregates, but let's do
    5174             :          * the right thing anyway...
    5175             :          */
    5176           6 :         if (state2->maxScale > state1->maxScale)
    5177             :         {
    5178           0 :             state1->maxScale = state2->maxScale;
    5179           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5180             :         }
    5181           6 :         else if (state2->maxScale == state1->maxScale)
    5182           6 :             state1->maxScaleCount += state2->maxScaleCount;
    5183             : 
    5184             :         /* The rest of this needs to work in the aggregate context */
    5185           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5186             : 
    5187             :         /* Accumulate sums */
    5188           6 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5189             : 
    5190           6 :         MemoryContextSwitchTo(old_context);
    5191             :     }
    5192           6 :     PG_RETURN_POINTER(state1);
    5193             : }
    5194             : 
    5195             : /*
    5196             :  * numeric_avg_serialize
    5197             :  *      Serialize NumericAggState for numeric aggregates that don't require
    5198             :  *      sumX2.
    5199             :  */
    5200             : Datum
    5201          12 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5202             : {
    5203             :     NumericAggState *state;
    5204             :     StringInfoData buf;
    5205             :     bytea      *result;
    5206             :     NumericVar  tmp_var;
    5207             : 
    5208             :     /* Ensure we disallow calling when not in aggregate context */
    5209          12 :     if (!AggCheckCallContext(fcinfo, NULL))
    5210           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5211             : 
    5212          12 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5213             : 
    5214          12 :     init_var(&tmp_var);
    5215             : 
    5216          12 :     pq_begintypsend(&buf);
    5217             : 
    5218             :     /* N */
    5219          12 :     pq_sendint64(&buf, state->N);
    5220             : 
    5221             :     /* sumX */
    5222          12 :     accum_sum_final(&state->sumX, &tmp_var);
    5223          12 :     numericvar_serialize(&buf, &tmp_var);
    5224             : 
    5225             :     /* maxScale */
    5226          12 :     pq_sendint32(&buf, state->maxScale);
    5227             : 
    5228             :     /* maxScaleCount */
    5229          12 :     pq_sendint64(&buf, state->maxScaleCount);
    5230             : 
    5231             :     /* NaNcount */
    5232          12 :     pq_sendint64(&buf, state->NaNcount);
    5233             : 
    5234             :     /* pInfcount */
    5235          12 :     pq_sendint64(&buf, state->pInfcount);
    5236             : 
    5237             :     /* nInfcount */
    5238          12 :     pq_sendint64(&buf, state->nInfcount);
    5239             : 
    5240          12 :     result = pq_endtypsend(&buf);
    5241             : 
    5242          12 :     free_var(&tmp_var);
    5243             : 
    5244          12 :     PG_RETURN_BYTEA_P(result);
    5245             : }
    5246             : 
    5247             : /*
    5248             :  * numeric_avg_deserialize
    5249             :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5250             :  *      don't require sumX2.
    5251             :  */
    5252             : Datum
    5253          12 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5254             : {
    5255             :     bytea      *sstate;
    5256             :     NumericAggState *result;
    5257             :     StringInfoData buf;
    5258             :     NumericVar  tmp_var;
    5259             : 
    5260          12 :     if (!AggCheckCallContext(fcinfo, NULL))
    5261           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5262             : 
    5263          12 :     sstate = PG_GETARG_BYTEA_PP(0);
    5264             : 
    5265          12 :     init_var(&tmp_var);
    5266             : 
    5267             :     /*
    5268             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5269             :      * recv-function infrastructure.
    5270             :      */
    5271          12 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5272          12 :                            VARSIZE_ANY_EXHDR(sstate));
    5273             : 
    5274          12 :     result = makeNumericAggStateCurrentContext(false);
    5275             : 
    5276             :     /* N */
    5277          12 :     result->N = pq_getmsgint64(&buf);
    5278             : 
    5279             :     /* sumX */
    5280          12 :     numericvar_deserialize(&buf, &tmp_var);
    5281          12 :     accum_sum_add(&(result->sumX), &tmp_var);
    5282             : 
    5283             :     /* maxScale */
    5284          12 :     result->maxScale = pq_getmsgint(&buf, 4);
    5285             : 
    5286             :     /* maxScaleCount */
    5287          12 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5288             : 
    5289             :     /* NaNcount */
    5290          12 :     result->NaNcount = pq_getmsgint64(&buf);
    5291             : 
    5292             :     /* pInfcount */
    5293          12 :     result->pInfcount = pq_getmsgint64(&buf);
    5294             : 
    5295             :     /* nInfcount */
    5296          12 :     result->nInfcount = pq_getmsgint64(&buf);
    5297             : 
    5298          12 :     pq_getmsgend(&buf);
    5299             : 
    5300          12 :     free_var(&tmp_var);
    5301             : 
    5302          12 :     PG_RETURN_POINTER(result);
    5303             : }
    5304             : 
    5305             : /*
    5306             :  * numeric_serialize
    5307             :  *      Serialization function for NumericAggState for numeric aggregates that
    5308             :  *      require sumX2.
    5309             :  */
    5310             : Datum
    5311          24 : numeric_serialize(PG_FUNCTION_ARGS)
    5312             : {
    5313             :     NumericAggState *state;
    5314             :     StringInfoData buf;
    5315             :     bytea      *result;
    5316             :     NumericVar  tmp_var;
    5317             : 
    5318             :     /* Ensure we disallow calling when not in aggregate context */
    5319          24 :     if (!AggCheckCallContext(fcinfo, NULL))
    5320           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5321             : 
    5322          24 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5323             : 
    5324          24 :     init_var(&tmp_var);
    5325             : 
    5326          24 :     pq_begintypsend(&buf);
    5327             : 
    5328             :     /* N */
    5329          24 :     pq_sendint64(&buf, state->N);
    5330             : 
    5331             :     /* sumX */
    5332          24 :     accum_sum_final(&state->sumX, &tmp_var);
    5333          24 :     numericvar_serialize(&buf, &tmp_var);
    5334             : 
    5335             :     /* sumX2 */
    5336          24 :     accum_sum_final(&state->sumX2, &tmp_var);
    5337          24 :     numericvar_serialize(&buf, &tmp_var);
    5338             : 
    5339             :     /* maxScale */
    5340          24 :     pq_sendint32(&buf, state->maxScale);
    5341             : 
    5342             :     /* maxScaleCount */
    5343          24 :     pq_sendint64(&buf, state->maxScaleCount);
    5344             : 
    5345             :     /* NaNcount */
    5346          24 :     pq_sendint64(&buf, state->NaNcount);
    5347             : 
    5348             :     /* pInfcount */
    5349          24 :     pq_sendint64(&buf, state->pInfcount);
    5350             : 
    5351             :     /* nInfcount */
    5352          24 :     pq_sendint64(&buf, state->nInfcount);
    5353             : 
    5354          24 :     result = pq_endtypsend(&buf);
    5355             : 
    5356          24 :     free_var(&tmp_var);
    5357             : 
    5358          24 :     PG_RETURN_BYTEA_P(result);
    5359             : }
    5360             : 
    5361             : /*
    5362             :  * numeric_deserialize
    5363             :  *      Deserialization function for NumericAggState for numeric aggregates that
    5364             :  *      require sumX2.
    5365             :  */
    5366             : Datum
    5367          24 : numeric_deserialize(PG_FUNCTION_ARGS)
    5368             : {
    5369             :     bytea      *sstate;
    5370             :     NumericAggState *result;
    5371             :     StringInfoData buf;
    5372             :     NumericVar  tmp_var;
    5373             : 
    5374          24 :     if (!AggCheckCallContext(fcinfo, NULL))
    5375           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5376             : 
    5377          24 :     sstate = PG_GETARG_BYTEA_PP(0);
    5378             : 
    5379          24 :     init_var(&tmp_var);
    5380             : 
    5381             :     /*
    5382             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5383             :      * recv-function infrastructure.
    5384             :      */
    5385          24 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5386          24 :                            VARSIZE_ANY_EXHDR(sstate));
    5387             : 
    5388          24 :     result = makeNumericAggStateCurrentContext(false);
    5389             : 
    5390             :     /* N */
    5391          24 :     result->N = pq_getmsgint64(&buf);
    5392             : 
    5393             :     /* sumX */
    5394          24 :     numericvar_deserialize(&buf, &tmp_var);
    5395          24 :     accum_sum_add(&(result->sumX), &tmp_var);
    5396             : 
    5397             :     /* sumX2 */
    5398          24 :     numericvar_deserialize(&buf, &tmp_var);
    5399          24 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5400             : 
    5401             :     /* maxScale */
    5402          24 :     result->maxScale = pq_getmsgint(&buf, 4);
    5403             : 
    5404             :     /* maxScaleCount */
    5405          24 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5406             : 
    5407             :     /* NaNcount */
    5408          24 :     result->NaNcount = pq_getmsgint64(&buf);
    5409             : 
    5410             :     /* pInfcount */
    5411          24 :     result->pInfcount = pq_getmsgint64(&buf);
    5412             : 
    5413             :     /* nInfcount */
    5414          24 :     result->nInfcount = pq_getmsgint64(&buf);
    5415             : 
    5416          24 :     pq_getmsgend(&buf);
    5417             : 
    5418          24 :     free_var(&tmp_var);
    5419             : 
    5420          24 :     PG_RETURN_POINTER(result);
    5421             : }
    5422             : 
    5423             : /*
    5424             :  * Generic inverse transition function for numeric aggregates
    5425             :  * (with or without requirement for X^2).
    5426             :  */
    5427             : Datum
    5428         228 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5429             : {
    5430             :     NumericAggState *state;
    5431             : 
    5432         228 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5433             : 
    5434             :     /* Should not get here with no state */
    5435         228 :     if (state == NULL)
    5436           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5437             : 
    5438         228 :     if (!PG_ARGISNULL(1))
    5439             :     {
    5440             :         /* If we fail to perform the inverse transition, return NULL */
    5441         198 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5442           6 :             PG_RETURN_NULL();
    5443             :     }
    5444             : 
    5445         222 :     PG_RETURN_POINTER(state);
    5446             : }
    5447             : 
    5448             : 
    5449             : /*
    5450             :  * Integer data types in general use Numeric accumulators to share code
    5451             :  * and avoid risk of overflow.
    5452             :  *
    5453             :  * However for performance reasons optimized special-purpose accumulator
    5454             :  * routines are used when possible.
    5455             :  *
    5456             :  * On platforms with 128-bit integer support, the 128-bit routines will be
    5457             :  * used when sum(X) or sum(X*X) fit into 128-bit.
    5458             :  *
    5459             :  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
    5460             :  * accumulators will be used for SUM and AVG of these data types.
    5461             :  */
    5462             : 
    5463             : #ifdef HAVE_INT128
    5464             : typedef struct Int128AggState
    5465             : {
    5466             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5467             :     int64       N;              /* count of processed numbers */
    5468             :     int128      sumX;           /* sum of processed numbers */
    5469             :     int128      sumX2;          /* sum of squares of processed numbers */
    5470             : } Int128AggState;
    5471             : 
    5472             : /*
    5473             :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5474             :  * sum, count and optionally sum of squares of the input.
    5475             :  */
    5476             : static Int128AggState *
    5477         668 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5478             : {
    5479             :     Int128AggState *state;
    5480             :     MemoryContext agg_context;
    5481             :     MemoryContext old_context;
    5482             : 
    5483         668 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5484           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5485             : 
    5486         668 :     old_context = MemoryContextSwitchTo(agg_context);
    5487             : 
    5488         668 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5489         668 :     state->calcSumX2 = calcSumX2;
    5490             : 
    5491         668 :     MemoryContextSwitchTo(old_context);
    5492             : 
    5493         668 :     return state;
    5494             : }
    5495             : 
    5496             : /*
    5497             :  * Like makeInt128AggState(), but allocate the state in the current memory
    5498             :  * context.
    5499             :  */
    5500             : static Int128AggState *
    5501          26 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5502             : {
    5503             :     Int128AggState *state;
    5504             : 
    5505          26 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5506          26 :     state->calcSumX2 = calcSumX2;
    5507             : 
    5508          26 :     return state;
    5509             : }
    5510             : 
    5511             : /*
    5512             :  * Accumulate a new input value for 128-bit aggregate functions.
    5513             :  */
    5514             : static void
    5515      553538 : do_int128_accum(Int128AggState *state, int128 newval)
    5516             : {
    5517      553538 :     if (state->calcSumX2)
    5518      242360 :         state->sumX2 += newval * newval;
    5519             : 
    5520      553538 :     state->sumX += newval;
    5521      553538 :     state->N++;
    5522      553538 : }
    5523             : 
    5524             : /*
    5525             :  * Remove an input value from the aggregated state.
    5526             :  */
    5527             : static void
    5528         312 : do_int128_discard(Int128AggState *state, int128 newval)
    5529             : {
    5530         312 :     if (state->calcSumX2)
    5531         288 :         state->sumX2 -= newval * newval;
    5532             : 
    5533         312 :     state->sumX -= newval;
    5534         312 :     state->N--;
    5535         312 : }
    5536             : 
    5537             : typedef Int128AggState PolyNumAggState;
    5538             : #define makePolyNumAggState makeInt128AggState
    5539             : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
    5540             : #else
    5541             : typedef NumericAggState PolyNumAggState;
    5542             : #define makePolyNumAggState makeNumericAggState
    5543             : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
    5544             : #endif
    5545             : 
    5546             : Datum
    5547         198 : int2_accum(PG_FUNCTION_ARGS)
    5548             : {
    5549             :     PolyNumAggState *state;
    5550             : 
    5551         198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5552             : 
    5553             :     /* Create the state data on the first call */
    5554         198 :     if (state == NULL)
    5555          36 :         state = makePolyNumAggState(fcinfo, true);
    5556             : 
    5557         198 :     if (!PG_ARGISNULL(1))
    5558             :     {
    5559             : #ifdef HAVE_INT128
    5560         180 :         do_int128_accum(state, (int128) PG_GETARG_INT16(1));
    5561             : #else
    5562             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
    5563             : #endif
    5564             :     }
    5565             : 
    5566         198 :     PG_RETURN_POINTER(state);
    5567             : }
    5568             : 
    5569             : Datum
    5570      242198 : int4_accum(PG_FUNCTION_ARGS)
    5571             : {
    5572             :     PolyNumAggState *state;
    5573             : 
    5574      242198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5575             : 
    5576             :     /* Create the state data on the first call */
    5577      242198 :     if (state == NULL)
    5578          66 :         state = makePolyNumAggState(fcinfo, true);
    5579             : 
    5580      242198 :     if (!PG_ARGISNULL(1))
    5581             :     {
    5582             : #ifdef HAVE_INT128
    5583      242180 :         do_int128_accum(state, (int128) PG_GETARG_INT32(1));
    5584             : #else
    5585             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
    5586             : #endif
    5587             :     }
    5588             : 
    5589      242198 :     PG_RETURN_POINTER(state);
    5590             : }
    5591             : 
    5592             : Datum
    5593      240198 : int8_accum(PG_FUNCTION_ARGS)
    5594             : {
    5595             :     NumericAggState *state;
    5596             : 
    5597      240198 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5598             : 
    5599             :     /* Create the state data on the first call */
    5600      240198 :     if (state == NULL)
    5601          48 :         state = makeNumericAggState(fcinfo, true);
    5602             : 
    5603      240198 :     if (!PG_ARGISNULL(1))
    5604      240180 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5605             : 
    5606      240198 :     PG_RETURN_POINTER(state);
    5607             : }
    5608             : 
    5609             : /*
    5610             :  * Combine function for numeric aggregates which require sumX2
    5611             :  */
    5612             : Datum
    5613          10 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5614             : {
    5615             :     PolyNumAggState *state1;
    5616             :     PolyNumAggState *state2;
    5617             :     MemoryContext agg_context;
    5618             :     MemoryContext old_context;
    5619             : 
    5620          10 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5621           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5622             : 
    5623          10 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5624          10 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5625             : 
    5626          10 :     if (state2 == NULL)
    5627           0 :         PG_RETURN_POINTER(state1);
    5628             : 
    5629             :     /* manually copy all fields from state2 to state1 */
    5630          10 :     if (state1 == NULL)
    5631             :     {
    5632           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5633             : 
    5634           6 :         state1 = makePolyNumAggState(fcinfo, true);
    5635           6 :         state1->N = state2->N;
    5636             : 
    5637             : #ifdef HAVE_INT128
    5638           6 :         state1->sumX = state2->sumX;
    5639           6 :         state1->sumX2 = state2->sumX2;
    5640             : #else
    5641             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5642             :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5643             : #endif
    5644             : 
    5645           6 :         MemoryContextSwitchTo(old_context);
    5646             : 
    5647           6 :         PG_RETURN_POINTER(state1);
    5648             :     }
    5649             : 
    5650           4 :     if (state2->N > 0)
    5651             :     {
    5652           4 :         state1->N += state2->N;
    5653             : 
    5654             : #ifdef HAVE_INT128
    5655           4 :         state1->sumX += state2->sumX;
    5656           4 :         state1->sumX2 += state2->sumX2;
    5657             : #else
    5658             :         /* The rest of this needs to work in the aggregate context */
    5659             :         old_context = MemoryContextSwitchTo(agg_context);
    5660             : 
    5661             :         /* Accumulate sums */
    5662             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5663             :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5664             : 
    5665             :         MemoryContextSwitchTo(old_context);
    5666             : #endif
    5667             : 
    5668             :     }
    5669           4 :     PG_RETURN_POINTER(state1);
    5670             : }
    5671             : 
    5672             : /*
    5673             :  * numeric_poly_serialize
    5674             :  *      Serialize PolyNumAggState into bytea for aggregate functions which
    5675             :  *      require sumX2.
    5676             :  */
    5677             : Datum
    5678          10 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5679             : {
    5680             :     PolyNumAggState *state;
    5681             :     StringInfoData buf;
    5682             :     bytea      *result;
    5683             :     NumericVar  tmp_var;
    5684             : 
    5685             :     /* Ensure we disallow calling when not in aggregate context */
    5686          10 :     if (!AggCheckCallContext(fcinfo, NULL))
    5687           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5688             : 
    5689          10 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5690             : 
    5691             :     /*
    5692             :      * If the platform supports int128 then sumX and sumX2 will be a 128 bit
    5693             :      * integer type. Here we'll convert that into a numeric type so that the
    5694             :      * combine state is in the same format for both int128 enabled machines
    5695             :      * and machines which don't support that type. The logic here is that one
    5696             :      * day we might like to send these over to another server for further
    5697             :      * processing and we want a standard format to work with.
    5698             :      */
    5699             : 
    5700          10 :     init_var(&tmp_var);
    5701             : 
    5702          10 :     pq_begintypsend(&buf);
    5703             : 
    5704             :     /* N */
    5705          10 :     pq_sendint64(&buf, state->N);
    5706             : 
    5707             :     /* sumX */
    5708             : #ifdef HAVE_INT128
    5709          10 :     int128_to_numericvar(state->sumX, &tmp_var);
    5710             : #else
    5711             :     accum_sum_final(&state->sumX, &tmp_var);
    5712             : #endif
    5713          10 :     numericvar_serialize(&buf, &tmp_var);
    5714             : 
    5715             :     /* sumX2 */
    5716             : #ifdef HAVE_INT128
    5717          10 :     int128_to_numericvar(state->sumX2, &tmp_var);
    5718             : #else
    5719             :     accum_sum_final(&state->sumX2, &tmp_var);
    5720             : #endif
    5721          10 :     numericvar_serialize(&buf, &tmp_var);
    5722             : 
    5723          10 :     result = pq_endtypsend(&buf);
    5724             : 
    5725          10 :     free_var(&tmp_var);
    5726             : 
    5727          10 :     PG_RETURN_BYTEA_P(result);
    5728             : }
    5729             : 
    5730             : /*
    5731             :  * numeric_poly_deserialize
    5732             :  *      Deserialize PolyNumAggState from bytea for aggregate functions which
    5733             :  *      require sumX2.
    5734             :  */
    5735             : Datum
    5736          10 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5737             : {
    5738             :     bytea      *sstate;
    5739             :     PolyNumAggState *result;
    5740             :     StringInfoData buf;
    5741             :     NumericVar  tmp_var;
    5742             : 
    5743          10 :     if (!AggCheckCallContext(fcinfo, NULL))
    5744           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5745             : 
    5746          10 :     sstate = PG_GETARG_BYTEA_PP(0);
    5747             : 
    5748          10 :     init_var(&tmp_var);
    5749             : 
    5750             :     /*
    5751             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5752             :      * recv-function infrastructure.
    5753             :      */
    5754          10 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5755          10 :                            VARSIZE_ANY_EXHDR(sstate));
    5756             : 
    5757          10 :     result = makePolyNumAggStateCurrentContext(false);
    5758             : 
    5759             :     /* N */
    5760          10 :     result->N = pq_getmsgint64(&buf);
    5761             : 
    5762             :     /* sumX */
    5763          10 :     numericvar_deserialize(&buf, &tmp_var);
    5764             : #ifdef HAVE_INT128
    5765          10 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5766             : #else
    5767             :     accum_sum_add(&result->sumX, &tmp_var);
    5768             : #endif
    5769             : 
    5770             :     /* sumX2 */
    5771          10 :     numericvar_deserialize(&buf, &tmp_var);
    5772             : #ifdef HAVE_INT128
    5773          10 :     numericvar_to_int128(&tmp_var, &result->sumX2);
    5774             : #else
    5775             :     accum_sum_add(&result->sumX2, &tmp_var);
    5776             : #endif
    5777             : 
    5778          10 :     pq_getmsgend(&buf);
    5779             : 
    5780          10 :     free_var(&tmp_var);
    5781             : 
    5782          10 :     PG_RETURN_POINTER(result);
    5783             : }
    5784             : 
    5785             : /*
    5786             :  * Transition function for int8 input when we don't need sumX2.
    5787             :  */
    5788             : Datum
    5789      312294 : int8_avg_accum(PG_FUNCTION_ARGS)
    5790             : {
    5791             :     PolyNumAggState *state;
    5792             : 
    5793      312294 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5794             : 
    5795             :     /* Create the state data on the first call */
    5796      312294 :     if (state == NULL)
    5797         548 :         state = makePolyNumAggState(fcinfo, false);
    5798             : 
    5799      312294 :     if (!PG_ARGISNULL(1))
    5800             :     {
    5801             : #ifdef HAVE_INT128
    5802      311178 :         do_int128_accum(state, (int128) PG_GETARG_INT64(1));
    5803             : #else
    5804             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5805             : #endif
    5806             :     }
    5807             : 
    5808      312294 :     PG_RETURN_POINTER(state);
    5809             : }
    5810             : 
    5811             : /*
    5812             :  * Combine function for PolyNumAggState for aggregates which don't require
    5813             :  * sumX2
    5814             :  */
    5815             : Datum
    5816          16 : int8_avg_combine(PG_FUNCTION_ARGS)
    5817             : {
    5818             :     PolyNumAggState *state1;
    5819             :     PolyNumAggState *state2;
    5820             :     MemoryContext agg_context;
    5821             :     MemoryContext old_context;
    5822             : 
    5823          16 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5824           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5825             : 
    5826          16 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5827          16 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5828             : 
    5829          16 :     if (state2 == NULL)
    5830           0 :         PG_RETURN_POINTER(state1);
    5831             : 
    5832             :     /* manually copy all fields from state2 to state1 */
    5833          16 :     if (state1 == NULL)
    5834             :     {
    5835          12 :         old_context = MemoryContextSwitchTo(agg_context);
    5836             : 
    5837          12 :         state1 = makePolyNumAggState(fcinfo, false);
    5838          12 :         state1->N = state2->N;
    5839             : 
    5840             : #ifdef HAVE_INT128
    5841          12 :         state1->sumX = state2->sumX;
    5842             : #else
    5843             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5844             : #endif
    5845          12 :         MemoryContextSwitchTo(old_context);
    5846             : 
    5847          12 :         PG_RETURN_POINTER(state1);
    5848             :     }
    5849             : 
    5850           4 :     if (state2->N > 0)
    5851             :     {
    5852           4 :         state1->N += state2->N;
    5853             : 
    5854             : #ifdef HAVE_INT128
    5855           4 :         state1->sumX += state2->sumX;
    5856             : #else
    5857             :         /* The rest of this needs to work in the aggregate context */
    5858             :         old_context = MemoryContextSwitchTo(agg_context);
    5859             : 
    5860             :         /* Accumulate sums */
    5861             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5862             : 
    5863             :         MemoryContextSwitchTo(old_context);
    5864             : #endif
    5865             : 
    5866             :     }
    5867           4 :     PG_RETURN_POINTER(state1);
    5868             : }
    5869             : 
    5870             : /*
    5871             :  * int8_avg_serialize
    5872             :  *      Serialize PolyNumAggState into bytea using the standard
    5873             :  *      recv-function infrastructure.
    5874             :  */
    5875             : Datum
    5876          16 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5877             : {
    5878             :     PolyNumAggState *state;
    5879             :     StringInfoData buf;
    5880             :     bytea      *result;
    5881             :     NumericVar  tmp_var;
    5882             : 
    5883             :     /* Ensure we disallow calling when not in aggregate context */
    5884          16 :     if (!AggCheckCallContext(fcinfo, NULL))
    5885           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5886             : 
    5887          16 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5888             : 
    5889             :     /*
    5890             :      * If the platform supports int128 then sumX will be a 128 integer type.
    5891             :      * Here we'll convert that into a numeric type so that the combine state
    5892             :      * is in the same format for both int128 enabled machines and machines
    5893             :      * which don't support that type. The logic here is that one day we might
    5894             :      * like to send these over to another server for further processing and we
    5895             :      * want a standard format to work with.
    5896             :      */
    5897             : 
    5898          16 :     init_var(&tmp_var);
    5899             : 
    5900          16 :     pq_begintypsend(&buf);
    5901             : 
    5902             :     /* N */
    5903          16 :     pq_sendint64(&buf, state->N);
    5904             : 
    5905             :     /* sumX */
    5906             : #ifdef HAVE_INT128
    5907          16 :     int128_to_numericvar(state->sumX, &tmp_var);
    5908             : #else
    5909             :     accum_sum_final(&state->sumX, &tmp_var);
    5910             : #endif
    5911          16 :     numericvar_serialize(&buf, &tmp_var);
    5912             : 
    5913          16 :     result = pq_endtypsend(&buf);
    5914             : 
    5915          16 :     free_var(&tmp_var);
    5916             : 
    5917          16 :     PG_RETURN_BYTEA_P(result);
    5918             : }
    5919             : 
    5920             : /*
    5921             :  * int8_avg_deserialize
    5922             :  *      Deserialize bytea back into PolyNumAggState.
    5923             :  */
    5924             : Datum
    5925          16 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    5926             : {
    5927             :     bytea      *sstate;
    5928             :     PolyNumAggState *result;
    5929             :     StringInfoData buf;
    5930             :     NumericVar  tmp_var;
    5931             : 
    5932          16 :     if (!AggCheckCallContext(fcinfo, NULL))
    5933           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5934             : 
    5935          16 :     sstate = PG_GETARG_BYTEA_PP(0);
    5936             : 
    5937          16 :     init_var(&tmp_var);
    5938             : 
    5939             :     /*
    5940             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5941             :      * recv-function infrastructure.
    5942             :      */
    5943          16 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5944          16 :                            VARSIZE_ANY_EXHDR(sstate));
    5945             : 
    5946          16 :     result = makePolyNumAggStateCurrentContext(false);
    5947             : 
    5948             :     /* N */
    5949          16 :     result->N = pq_getmsgint64(&buf);
    5950             : 
    5951             :     /* sumX */
    5952          16 :     numericvar_deserialize(&buf, &tmp_var);
    5953             : #ifdef HAVE_INT128
    5954          16 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5955             : #else
    5956             :     accum_sum_add(&result->sumX, &tmp_var);
    5957             : #endif
    5958             : 
    5959          16 :     pq_getmsgend(&buf);
    5960             : 
    5961          16 :     free_var(&tmp_var);
    5962             : 
    5963          16 :     PG_RETURN_POINTER(result);
    5964             : }
    5965             : 
    5966             : /*
    5967             :  * Inverse transition functions to go with the above.
    5968             :  */
    5969             : 
    5970             : Datum
    5971         162 : int2_accum_inv(PG_FUNCTION_ARGS)
    5972             : {
    5973             :     PolyNumAggState *state;
    5974             : 
    5975         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5976             : 
    5977             :     /* Should not get here with no state */
    5978         162 :     if (state == NULL)
    5979           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    5980             : 
    5981         162 :     if (!PG_ARGISNULL(1))
    5982             :     {
    5983             : #ifdef HAVE_INT128
    5984         144 :         do_int128_discard(state, (int128) PG_GETARG_INT16(1));
    5985             : #else
    5986             :         /* Should never fail, all inputs have dscale 0 */
    5987             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
    5988             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5989             : #endif
    5990             :     }
    5991             : 
    5992         162 :     PG_RETURN_POINTER(state);
    5993             : }
    5994             : 
    5995             : Datum
    5996         162 : int4_accum_inv(PG_FUNCTION_ARGS)
    5997             : {
    5998             :     PolyNumAggState *state;
    5999             : 
    6000         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6001             : 
    6002             :     /* Should not get here with no state */
    6003         162 :     if (state == NULL)
    6004           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    6005             : 
    6006         162 :     if (!PG_ARGISNULL(1))
    6007             :     {
    6008             : #ifdef HAVE_INT128
    6009         144 :         do_int128_discard(state, (int128) PG_GETARG_INT32(1));
    6010             : #else
    6011             :         /* Should never fail, all inputs have dscale 0 */
    6012             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
    6013             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6014             : #endif
    6015             :     }
    6016             : 
    6017         162 :     PG_RETURN_POINTER(state);
    6018             : }
    6019             : 
    6020             : Datum
    6021         162 : int8_accum_inv(PG_FUNCTION_ARGS)
    6022             : {
    6023             :     NumericAggState *state;
    6024             : 
    6025         162 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6026             : 
    6027             :     /* Should not get here with no state */
    6028         162 :     if (state == NULL)
    6029           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    6030             : 
    6031         162 :     if (!PG_ARGISNULL(1))
    6032             :     {
    6033             :         /* Should never fail, all inputs have dscale 0 */
    6034         144 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6035           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6036             :     }
    6037             : 
    6038         162 :     PG_RETURN_POINTER(state);
    6039             : }
    6040             : 
    6041             : Datum
    6042          36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    6043             : {
    6044             :     PolyNumAggState *state;
    6045             : 
    6046          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6047             : 
    6048             :     /* Should not get here with no state */
    6049          36 :     if (state == NULL)
    6050           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    6051             : 
    6052          36 :     if (!PG_ARGISNULL(1))
    6053             :     {
    6054             : #ifdef HAVE_INT128
    6055          24 :         do_int128_discard(state, (int128) PG_GETARG_INT64(1));
    6056             : #else
    6057             :         /* Should never fail, all inputs have dscale 0 */
    6058             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6059             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6060             : #endif
    6061             :     }
    6062             : 
    6063          36 :     PG_RETURN_POINTER(state);
    6064             : }
    6065             : 
    6066             : Datum
    6067         778 : numeric_poly_sum(PG_FUNCTION_ARGS)
    6068             : {
    6069             : #ifdef HAVE_INT128
    6070             :     PolyNumAggState *state;
    6071             :     Numeric     res;
    6072             :     NumericVar  result;
    6073             : 
    6074         778 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6075             : 
    6076             :     /* If there were no non-null inputs, return NULL */
    6077         778 :     if (state == NULL || state->N == 0)
    6078          24 :         PG_RETURN_NULL();
    6079             : 
    6080         754 :     init_var(&result);
    6081             : 
    6082         754 :     int128_to_numericvar(state->sumX, &result);
    6083             : 
    6084         754 :     res = make_result(&result);
    6085             : 
    6086         754 :     free_var(&result);
    6087             : 
    6088         754 :     PG_RETURN_NUMERIC(res);
    6089             : #else
    6090             :     return numeric_sum(fcinfo);
    6091             : #endif
    6092             : }
    6093             : 
    6094             : Datum
    6095          36 : numeric_poly_avg(PG_FUNCTION_ARGS)
    6096             : {
    6097             : #ifdef HAVE_INT128
    6098             :     PolyNumAggState *state;
    6099             :     NumericVar  result;
    6100             :     Datum       countd,
    6101             :                 sumd;
    6102             : 
    6103          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6104             : 
    6105             :     /* If there were no non-null inputs, return NULL */
    6106          36 :     if (state == NULL || state->N == 0)
    6107          18 :         PG_RETURN_NULL();
    6108             : 
    6109          18 :     init_var(&result);
    6110             : 
    6111          18 :     int128_to_numericvar(state->sumX, &result);
    6112             : 
    6113          18 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    6114          18 :     sumd = NumericGetDatum(make_result(&result));
    6115             : 
    6116          18 :     free_var(&result);
    6117             : 
    6118          18 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6119             : #else
    6120             :     return numeric_avg(fcinfo);
    6121             : #endif
    6122             : }
    6123             : 
    6124             : Datum
    6125          78 : numeric_avg(PG_FUNCTION_ARGS)
    6126             : {
    6127             :     NumericAggState *state;
    6128             :     Datum       N_datum;
    6129             :     Datum       sumX_datum;
    6130             :     NumericVar  sumX_var;
    6131             : 
    6132          78 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6133             : 
    6134             :     /* If there were no non-null inputs, return NULL */
    6135          78 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6136          18 :         PG_RETURN_NULL();
    6137             : 
    6138          60 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6139           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6140             : 
    6141             :     /* adding plus and minus infinities gives NaN */
    6142          54 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6143           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6144          48 :     if (state->pInfcount > 0)
    6145          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6146          30 :     if (state->nInfcount > 0)
    6147           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6148             : 
    6149          24 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    6150             : 
    6151          24 :     init_var(&sumX_var);
    6152          24 :     accum_sum_final(&state->sumX, &sumX_var);
    6153          24 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    6154          24 :     free_var(&sumX_var);
    6155             : 
    6156          24 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    6157             : }
    6158             : 
    6159             : Datum
    6160      170906 : numeric_sum(PG_FUNCTION_ARGS)
    6161             : {
    6162             :     NumericAggState *state;
    6163             :     NumericVar  sumX_var;
    6164             :     Numeric     result;
    6165             : 
    6166      170906 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6167             : 
    6168             :     /* If there were no non-null inputs, return NULL */
    6169      170906 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6170          18 :         PG_RETURN_NULL();
    6171             : 
    6172      170888 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6173          18 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6174             : 
    6175             :     /* adding plus and minus infinities gives NaN */
    6176      170870 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6177           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6178      170864 :     if (state->pInfcount > 0)
    6179          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6180      170846 :     if (state->nInfcount > 0)
    6181           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6182             : 
    6183      170840 :     init_var(&sumX_var);
    6184      170840 :     accum_sum_final(&state->sumX, &sumX_var);
    6185      170840 :     result = make_result(&sumX_var);
    6186      170840 :     free_var(&sumX_var);
    6187             : 
    6188      170840 :     PG_RETURN_NUMERIC(result);
    6189             : }
    6190             : 
    6191             : /*
    6192             :  * Workhorse routine for the standard deviance and variance
    6193             :  * aggregates. 'state' is aggregate's transition state.
    6194             :  * 'variance' specifies whether we should calculate the
    6195             :  * variance or the standard deviation. 'sample' indicates whether the
    6196             :  * caller is interested in the sample or the population
    6197             :  * variance/stddev.
    6198             :  *
    6199             :  * If appropriate variance statistic is undefined for the input,
    6200             :  * *is_null is set to true and NULL is returned.
    6201             :  */
    6202             : static Numeric
    6203         986 : numeric_stddev_internal(NumericAggState *state,
    6204             :                         bool variance, bool sample,
    6205             :                         bool *is_null)
    6206             : {
    6207             :     Numeric     res;
    6208             :     NumericVar  vN,
    6209             :                 vsumX,
    6210             :                 vsumX2,
    6211             :                 vNminus1;
    6212             :     int64       totCount;
    6213             :     int         rscale;
    6214             : 
    6215             :     /*
    6216             :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6217             :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6218             :      * and infinities count as normal inputs for this purpose).
    6219             :      */
    6220         986 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6221             :     {
    6222           0 :         *is_null = true;
    6223           0 :         return NULL;
    6224             :     }
    6225             : 
    6226         986 :     if (sample && totCount <= 1)
    6227             :     {
    6228         132 :         *is_null = true;
    6229         132 :         return NULL;
    6230             :     }
    6231             : 
    6232         854 :     *is_null = false;
    6233             : 
    6234             :     /*
    6235             :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6236             :      * float8 functions, any infinity input produces NaN output.
    6237             :      */
    6238         854 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6239          54 :         return make_result(&const_nan);
    6240             : 
    6241             :     /* OK, normal calculation applies */
    6242         800 :     init_var(&vN);
    6243         800 :     init_var(&vsumX);
    6244         800 :     init_var(&vsumX2);
    6245             : 
    6246         800 :     int64_to_numericvar(state->N, &vN);
    6247         800 :     accum_sum_final(&(state->sumX), &vsumX);
    6248         800 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6249             : 
    6250         800 :     init_var(&vNminus1);
    6251         800 :     sub_var(&vN, &const_one, &vNminus1);
    6252             : 
    6253             :     /* compute rscale for mul_var calls */
    6254         800 :     rscale = vsumX.dscale * 2;
    6255             : 
    6256         800 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6257         800 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6258         800 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6259             : 
    6260         800 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6261             :     {
    6262             :         /* Watch out for roundoff error producing a negative numerator */
    6263          80 :         res = make_result(&const_zero);
    6264             :     }
    6265             :     else
    6266             :     {
    6267         720 :         if (sample)
    6268         492 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6269             :         else
    6270         228 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6271         720 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6272         720 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true);    /* variance */
    6273         720 :         if (!variance)
    6274         378 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6275             : 
    6276         720 :         res = make_result(&vsumX);
    6277             :     }
    6278             : 
    6279         800 :     free_var(&vNminus1);
    6280         800 :     free_var(&vsumX);
    6281         800 :     free_var(&vsumX2);
    6282             : 
    6283         800 :     return res;
    6284             : }
    6285             : 
    6286             : Datum
    6287         180 : numeric_var_samp(PG_FUNCTION_ARGS)
    6288             : {
    6289             :     NumericAggState *state;
    6290             :     Numeric     res;
    6291             :     bool        is_null;
    6292             : 
    6293         180 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6294             : 
    6295         180 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6296             : 
    6297         180 :     if (is_null)
    6298          42 :         PG_RETURN_NULL();
    6299             :     else
    6300         138 :         PG_RETURN_NUMERIC(res);
    6301             : }
    6302             : 
    6303             : Datum
    6304         174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6305             : {
    6306             :     NumericAggState *state;
    6307             :     Numeric     res;
    6308             :     bool        is_null;
    6309             : 
    6310         174 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6311             : 
    6312         174 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6313             : 
    6314         174 :     if (is_null)
    6315          42 :         PG_RETURN_NULL();
    6316             :     else
    6317         132 :         PG_RETURN_NUMERIC(res);
    6318             : }
    6319             : 
    6320             : Datum
    6321         114 : numeric_var_pop(PG_FUNCTION_ARGS)
    6322             : {
    6323             :     NumericAggState *state;
    6324             :     Numeric     res;
    6325             :     bool        is_null;
    6326             : 
    6327         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6328             : 
    6329         114 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6330             : 
    6331         114 :     if (is_null)
    6332           0 :         PG_RETURN_NULL();
    6333             :     else
    6334         114 :         PG_RETURN_NUMERIC(res);
    6335             : }
    6336             : 
    6337             : Datum
    6338          96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6339             : {
    6340             :     NumericAggState *state;
    6341             :     Numeric     res;
    6342             :     bool        is_null;
    6343             : 
    6344          96 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6345             : 
    6346          96 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6347             : 
    6348          96 :     if (is_null)
    6349           0 :         PG_RETURN_NULL();
    6350             :     else
    6351          96 :         PG_RETURN_NUMERIC(res);
    6352             : }
    6353             : 
    6354             : #ifdef HAVE_INT128
    6355             : static Numeric
    6356         422 : numeric_poly_stddev_internal(Int128AggState *state,
    6357             :                              bool variance, bool sample,
    6358             :                              bool *is_null)
    6359             : {
    6360             :     NumericAggState numstate;
    6361             :     Numeric     res;
    6362             : 
    6363             :     /* Initialize an empty agg state */
    6364         422 :     memset(&numstate, 0, sizeof(NumericAggState));
    6365             : 
    6366         422 :     if (state)
    6367             :     {
    6368             :         NumericVar  tmp_var;
    6369             : 
    6370         422 :         numstate.N = state->N;
    6371             : 
    6372         422 :         init_var(&tmp_var);
    6373             : 
    6374         422 :         int128_to_numericvar(state->sumX, &tmp_var);
    6375         422 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6376             : 
    6377         422 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6378         422 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6379             : 
    6380         422 :         free_var(&tmp_var);
    6381             :     }
    6382             : 
    6383         422 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6384             : 
    6385         422 :     if (numstate.sumX.ndigits > 0)
    6386             :     {
    6387         422 :         pfree(numstate.sumX.pos_digits);
    6388         422 :         pfree(numstate.sumX.neg_digits);
    6389             :     }
    6390         422 :     if (numstate.sumX2.ndigits > 0)
    6391             :     {
    6392         422 :         pfree(numstate.sumX2.pos_digits);
    6393         422 :         pfree(numstate.sumX2.neg_digits);
    6394             :     }
    6395             : 
    6396         422 :     return res;
    6397             : }
    6398             : #endif
    6399             : 
    6400             : Datum
    6401         126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6402             : {
    6403             : #ifdef HAVE_INT128
    6404             :     PolyNumAggState *state;
    6405             :     Numeric     res;
    6406             :     bool        is_null;
    6407             : 
    6408         126 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6409             : 
    6410         126 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6411             : 
    6412         126 :     if (is_null)
    6413          24 :         PG_RETURN_NULL();
    6414             :     else
    6415         102 :         PG_RETURN_NUMERIC(res);
    6416             : #else
    6417             :     return numeric_var_samp(fcinfo);
    6418             : #endif
    6419             : }
    6420             : 
    6421             : Datum
    6422         164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6423             : {
    6424             : #ifdef HAVE_INT128
    6425             :     PolyNumAggState *state;
    6426             :     Numeric     res;
    6427             :     bool        is_null;
    6428             : 
    6429         164 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6430             : 
    6431         164 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6432             : 
    6433         164 :     if (is_null)
    6434          24 :         PG_RETURN_NULL();
    6435             :     else
    6436         140 :         PG_RETURN_NUMERIC(res);
    6437             : #else
    6438             :     return numeric_stddev_samp(fcinfo);
    6439             : #endif
    6440             : }
    6441             : 
    6442             : Datum
    6443          60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6444             : {
    6445             : #ifdef HAVE_INT128
    6446             :     PolyNumAggState *state;
    6447             :     Numeric     res;
    6448             :     bool        is_null;
    6449             : 
    6450          60 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6451             : 
    6452          60 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6453             : 
    6454          60 :     if (is_null)
    6455           0 :         PG_RETURN_NULL();
    6456             :     else
    6457          60 :         PG_RETURN_NUMERIC(res);
    6458             : #else
    6459             :     return numeric_var_pop(fcinfo);
    6460             : #endif
    6461             : }
    6462             : 
    6463             : Datum
    6464          72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6465             : {
    6466             : #ifdef HAVE_INT128
    6467             :     PolyNumAggState *state;
    6468             :     Numeric     res;
    6469             :     bool        is_null;
    6470             : 
    6471          72 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6472             : 
    6473          72 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6474             : 
    6475          72 :     if (is_null)
    6476           0 :         PG_RETURN_NULL();
    6477             :     else
    6478          72 :         PG_RETURN_NUMERIC(res);
    6479             : #else
    6480             :     return numeric_stddev_pop(fcinfo);
    6481             : #endif
    6482             : }
    6483             : 
    6484             : /*
    6485             :  * SUM transition functions for integer datatypes.
    6486             :  *
    6487             :  * To avoid overflow, we use accumulators wider than the input datatype.
    6488             :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6489             :  * inputs, we use int8 accumulators which should be sufficient for practical
    6490             :  * purposes.  (The latter two therefore don't really belong in this file,
    6491             :  * but we keep them here anyway.)
    6492             :  *
    6493             :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6494             :  * the initial condition of the transition data value needs to be NULL. This
    6495             :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6496             :  * data value into the transition data: it doesn't know how to do the type
    6497             :  * conversion.  The upshot is that these routines have to be marked non-strict
    6498             :  * and handle substitution of the first non-null input themselves.
    6499             :  *
    6500             :  * Note: these functions are used only in plain aggregation mode.
    6501             :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6502             :  */
    6503             : 
    6504             : Datum
    6505          24 : int2_sum(PG_FUNCTION_ARGS)
    6506             : {
    6507             :     int64       newval;
    6508             : 
    6509          24 :     if (PG_ARGISNULL(0))
    6510             :     {
    6511             :         /* No non-null input seen so far... */
    6512           6 :         if (PG_ARGISNULL(1))
    6513           0 :             PG_RETURN_NULL();   /* still no non-null */
    6514             :         /* This is the first non-null input. */
    6515           6 :         newval = (int64) PG_GETARG_INT16(1);
    6516           6 :         PG_RETURN_INT64(newval);
    6517             :     }
    6518             : 
    6519             :     /*
    6520             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6521             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6522             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6523             :      * then of course this is useless as well as incorrect, so just ifdef it
    6524             :      * out.)
    6525             :      */
    6526             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6527             :     if (AggCheckCallContext(fcinfo, NULL))
    6528             :     {
    6529             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6530             : 
    6531             :         /* Leave the running sum unchanged in the new input is null */
    6532             :         if (!PG_ARGISNULL(1))
    6533             :             *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
    6534             : 
    6535             :         PG_RETURN_POINTER(oldsum);
    6536             :     }
    6537             :     else
    6538             : #endif
    6539             :     {
    6540          18 :         int64       oldsum = PG_GETARG_INT64(0);
    6541             : 
    6542             :         /* Leave sum unchanged if new input is null. */
    6543          18 :         if (PG_ARGISNULL(1))
    6544           0 :             PG_RETURN_INT64(oldsum);
    6545             : 
    6546             :         /* OK to do the addition. */
    6547          18 :         newval = oldsum + (int64) PG_GETARG_INT16(1);
    6548             : 
    6549          18 :         PG_RETURN_INT64(newval);
    6550             :     }
    6551             : }
    6552             : 
    6553             : Datum
    6554     3602120 : int4_sum(PG_FUNCTION_ARGS)
    6555             : {
    6556             :     int64       newval;
    6557             : 
    6558     3602120 :     if (PG_ARGISNULL(0))
    6559             :     {
    6560             :         /* No non-null input seen so far... */
    6561      206522 :         if (PG_ARGISNULL(1))
    6562         986 :             PG_RETURN_NULL();   /* still no non-null */
    6563             :         /* This is the first non-null input. */
    6564      205536 :         newval = (int64) PG_GETARG_INT32(1);
    6565      205536 :         PG_RETURN_INT64(newval);
    6566             :     }
    6567             : 
    6568             :     /*
    6569             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6570             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6571             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6572             :      * then of course this is useless as well as incorrect, so just ifdef it
    6573             :      * out.)
    6574             :      */
    6575             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6576             :     if (AggCheckCallContext(fcinfo, NULL))
    6577             :     {
    6578             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6579             : 
    6580             :         /* Leave the running sum unchanged in the new input is null */
    6581             :         if (!PG_ARGISNULL(1))
    6582             :             *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
    6583             : 
    6584             :         PG_RETURN_POINTER(oldsum);
    6585             :     }
    6586             :     else
    6587             : #endif
    6588             :     {
    6589     3395598 :         int64       oldsum = PG_GETARG_INT64(0);
    6590             : 
    6591             :         /* Leave sum unchanged if new input is null. */
    6592     3395598 :         if (PG_ARGISNULL(1))
    6593         874 :             PG_RETURN_INT64(oldsum);
    6594             : 
    6595             :         /* OK to do the addition. */
    6596     3394724 :         newval = oldsum + (int64) PG_GETARG_INT32(1);
    6597             : 
    6598     3394724 :         PG_RETURN_INT64(newval);
    6599             :     }
    6600             : }
    6601             : 
    6602             : /*
    6603             :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6604             :  */
    6605             : Datum
    6606           0 : int8_sum(PG_FUNCTION_ARGS)
    6607             : {
    6608             :     Numeric     oldsum;
    6609             : 
    6610           0 :     if (PG_ARGISNULL(0))
    6611             :     {
    6612             :         /* No non-null input seen so far... */
    6613           0 :         if (PG_ARGISNULL(1))
    6614           0 :             PG_RETURN_NULL();   /* still no non-null */
    6615             :         /* This is the first non-null input. */
    6616           0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6617             :     }
    6618             : 
    6619             :     /*
    6620             :      * Note that we cannot special-case the aggregate case here, as we do for
    6621             :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6622             :      * our first parameter in-place.
    6623             :      */
    6624             : 
    6625           0 :     oldsum = PG_GETARG_NUMERIC(0);
    6626             : 
    6627             :     /* Leave sum unchanged if new input is null. */
    6628           0 :     if (PG_ARGISNULL(1))
    6629           0 :         PG_RETURN_NUMERIC(oldsum);
    6630             : 
    6631             :     /* OK to do the addition. */
    6632           0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6633             :                                         NumericGetDatum(oldsum),
    6634             :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6635             : }
    6636             : 
    6637             : 
    6638             : /*
    6639             :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6640             :  * is a two-element int8 array, holding count and sum.
    6641             :  *
    6642             :  * These functions are also used for sum(int2) and sum(int4) when
    6643             :  * operating in moving-aggregate mode, since for correct inverse transitions
    6644             :  * we need to count the inputs.
    6645             :  */
    6646             : 
    6647             : typedef struct Int8TransTypeData
    6648             : {
    6649             :     int64       count;
    6650             :     int64       sum;
    6651             : } Int8TransTypeData;
    6652             : 
    6653             : Datum
    6654          42 : int2_avg_accum(PG_FUNCTION_ARGS)
    6655             : {
    6656             :     ArrayType  *transarray;
    6657          42 :     int16       newval = PG_GETARG_INT16(1);
    6658             :     Int8TransTypeData *transdata;
    6659             : 
    6660             :     /*
    6661             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6662             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6663             :      * a copy of it before scribbling on it.
    6664             :      */
    6665          42 :     if (AggCheckCallContext(fcinfo, NULL))
    6666          42 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6667             :     else
    6668           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6669             : 
    6670          42 :     if (ARR_HASNULL(transarray) ||
    6671          42 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6672           0 :         elog(ERROR, "expected 2-element int8 array");
    6673             : 
    6674          42 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6675          42 :     transdata->count++;
    6676          42 :     transdata->sum += newval;
    6677             : 
    6678          42 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6679             : }
    6680             : 
    6681             : Datum
    6682     2620302 : int4_avg_accum(PG_FUNCTION_ARGS)
    6683             : {
    6684             :     ArrayType  *transarray;
    6685     2620302 :     int32       newval = PG_GETARG_INT32(1);
    6686             :     Int8TransTypeData *transdata;
    6687             : 
    6688             :     /*
    6689             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6690             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6691             :      * a copy of it before scribbling on it.
    6692             :      */
    6693     2620302 :     if (AggCheckCallContext(fcinfo, NULL))
    6694     2620302 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6695             :     else
    6696           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6697             : 
    6698     2620302 :     if (ARR_HASNULL(transarray) ||
    6699     2620302 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6700           0 :         elog(ERROR, "expected 2-element int8 array");
    6701             : 
    6702     2620302 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6703     2620302 :     transdata->count++;
    6704     2620302 :     transdata->sum += newval;
    6705             : 
    6706     2620302 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6707             : }
    6708             : 
    6709             : Datum
    6710        3522 : int4_avg_combine(PG_FUNCTION_ARGS)
    6711             : {
    6712             :     ArrayType  *transarray1;
    6713             :     ArrayType  *transarray2;
    6714             :     Int8TransTypeData *state1;
    6715             :     Int8TransTypeData *state2;
    6716             : 
    6717        3522 :     if (!AggCheckCallContext(fcinfo, NULL))
    6718           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6719             : 
    6720        3522 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6721        3522 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6722             : 
    6723        3522 :     if (ARR_HASNULL(transarray1) ||
    6724        3522 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6725           0 :         elog(ERROR, "expected 2-element int8 array");
    6726             : 
    6727        3522 :     if (ARR_HASNULL(transarray2) ||
    6728        3522 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6729           0 :         elog(ERROR, "expected 2-element int8 array");
    6730             : 
    6731        3522 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6732        3522 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6733             : 
    6734        3522 :     state1->count += state2->count;
    6735        3522 :     state1->sum += state2->sum;
    6736             : 
    6737        3522 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6738             : }
    6739             : 
    6740             : Datum
    6741          12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6742             : {
    6743             :     ArrayType  *transarray;
    6744          12 :     int16       newval = PG_GETARG_INT16(1);
    6745             :     Int8TransTypeData *transdata;
    6746             : 
    6747             :     /*
    6748             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6749             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6750             :      * a copy of it before scribbling on it.
    6751             :      */
    6752          12 :     if (AggCheckCallContext(fcinfo, NULL))
    6753          12 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6754             :     else
    6755           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6756             : 
    6757          12 :     if (ARR_HASNULL(transarray) ||
    6758          12 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6759           0 :         elog(ERROR, "expected 2-element int8 array");
    6760             : 
    6761          12 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6762          12 :     transdata->count--;
    6763          12 :     transdata->sum -= newval;
    6764             : 
    6765          12 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6766             : }
    6767             : 
    6768             : Datum
    6769        1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6770             : {
    6771             :     ArrayType  *transarray;
    6772        1452 :     int32       newval = PG_GETARG_INT32(1);
    6773             :     Int8TransTypeData *transdata;
    6774             : 
    6775             :     /*
    6776             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6777             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6778             :      * a copy of it before scribbling on it.
    6779             :      */
    6780        1452 :     if (AggCheckCallContext(fcinfo, NULL))
    6781        1452 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6782             :     else
    6783           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6784             : 
    6785        1452 :     if (ARR_HASNULL(transarray) ||
    6786        1452 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6787           0 :         elog(ERROR, "expected 2-element int8 array");
    6788             : 
    6789        1452 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6790        1452 :     transdata->count--;
    6791        1452 :     transdata->sum -= newval;
    6792             : 
    6793        1452 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6794             : }
    6795             : 
    6796             : Datum
    6797       10774 : int8_avg(PG_FUNCTION_ARGS)
    6798             : {
    6799       10774 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6800             :     Int8TransTypeData *transdata;
    6801             :     Datum       countd,
    6802             :                 sumd;
    6803             : 
    6804       10774 :     if (ARR_HASNULL(transarray) ||
    6805       10774 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6806           0 :         elog(ERROR, "expected 2-element int8 array");
    6807       10774 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6808             : 
    6809             :     /* SQL defines AVG of no values to be NULL */
    6810       10774 :     if (transdata->count == 0)
    6811         118 :         PG_RETURN_NULL();
    6812             : 
    6813       10656 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6814       10656 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6815             : 
    6816       10656 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6817             : }
    6818             : 
    6819             : /*
    6820             :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6821             :  * final function for both.
    6822             :  */
    6823             : Datum
    6824        3834 : int2int4_sum(PG_FUNCTION_ARGS)
    6825             : {
    6826        3834 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6827             :     Int8TransTypeData *transdata;
    6828             : 
    6829        3834 :     if (ARR_HASNULL(transarray) ||
    6830        3834 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6831           0 :         elog(ERROR, "expected 2-element int8 array");
    6832        3834 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6833             : 
    6834             :     /* SQL defines SUM of no values to be NULL */
    6835        3834 :     if (transdata->count == 0)
    6836         480 :         PG_RETURN_NULL();
    6837             : 
    6838        3354 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6839             : }
    6840             : 
    6841             : 
    6842             : /* ----------------------------------------------------------------------
    6843             :  *
    6844             :  * Debug support
    6845             :  *
    6846             :  * ----------------------------------------------------------------------
    6847             :  */
    6848             : 
    6849             : #ifdef NUMERIC_DEBUG
    6850             : 
    6851             : /*
    6852             :  * dump_numeric() - Dump a value in the db storage format for debugging
    6853             :  */
    6854             : static void
    6855             : dump_numeric(const char *str, Numeric num)
    6856             : {
    6857             :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6858             :     int         ndigits;
    6859             :     int         i;
    6860             : 
    6861             :     ndigits = NUMERIC_NDIGITS(num);
    6862             : 
    6863             :     printf("%s: NUMERIC w=%d d=%d ", str,
    6864             :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6865             :     switch (NUMERIC_SIGN(num))
    6866             :     {
    6867             :         case NUMERIC_POS:
    6868             :             printf("POS");
    6869             :             break;
    6870             :         case NUMERIC_NEG:
    6871             :             printf("NEG");
    6872             :             break;
    6873             :         case NUMERIC_NAN:
    6874             :             printf("NaN");
    6875             :             break;
    6876             :         case NUMERIC_PINF:
    6877             :             printf("Infinity");
    6878             :             break;
    6879             :         case NUMERIC_NINF:
    6880             :             printf("-Infinity");
    6881             :             break;
    6882             :         default:
    6883             :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    6884             :             break;
    6885             :     }
    6886             : 
    6887             :     for (i = 0; i < ndigits; i++)
    6888             :         printf(" %0*d", DEC_DIGITS, digits[i]);
    6889             :     printf("\n");
    6890             : }
    6891             : 
    6892             : 
    6893             : /*
    6894             :  * dump_var() - Dump a value in the variable format for debugging
    6895             :  */
    6896             : static void
    6897             : dump_var(const char *str, NumericVar *var)
    6898             : {
    6899             :     int         i;
    6900             : 
    6901             :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    6902             :     switch (var->sign)
    6903             :     {
    6904             :         case NUMERIC_POS:
    6905             :             printf("POS");
    6906             :             break;
    6907             :         case NUMERIC_NEG:
    6908             :             printf("NEG");
    6909             :             break;
    6910             :         case NUMERIC_NAN:
    6911             :             printf("NaN");
    6912             :             break;
    6913             :         case NUMERIC_PINF:
    6914             :             printf("Infinity");
    6915             :             break;
    6916             :         case NUMERIC_NINF:
    6917             :             printf("-Infinity");
    6918             :             break;
    6919             :         default:
    6920             :             printf("SIGN=0x%x", var->sign);
    6921             :             break;
    6922             :     }
    6923             : 
    6924             :     for (i = 0; i < var->ndigits; i++)
    6925             :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    6926             : 
    6927             :     printf("\n");
    6928             : }
    6929             : #endif                          /* NUMERIC_DEBUG */
    6930             : 
    6931             : 
    6932             : /* ----------------------------------------------------------------------
    6933             :  *
    6934             :  * Local functions follow
    6935             :  *
    6936             :  * In general, these do not support "special" (NaN or infinity) inputs;
    6937             :  * callers should handle those possibilities first.
    6938             :  * (There are one or two exceptions, noted in their header comments.)
    6939             :  *
    6940             :  * ----------------------------------------------------------------------
    6941             :  */
    6942             : 
    6943             : 
    6944             : /*
    6945             :  * alloc_var() -
    6946             :  *
    6947             :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    6948             :  */
    6949             : static void
    6950     2104584 : alloc_var(NumericVar *var, int ndigits)
    6951             : {
    6952     2104584 :     digitbuf_free(var->buf);
    6953     2104584 :     var->buf = digitbuf_alloc(ndigits + 1);
    6954     2104584 :     var->buf[0] = 0;         /* spare digit for rounding */
    6955     2104584 :     var->digits = var->buf + 1;
    6956     2104584 :     var->ndigits = ndigits;
    6957     2104584 : }
    6958             : 
    6959             : 
    6960             : /*
    6961             :  * free_var() -
    6962             :  *
    6963             :  *  Return the digit buffer of a variable to the free pool
    6964             :  */
    6965             : static void
    6966     3409894 : free_var(NumericVar *var)
    6967             : {
    6968     3409894 :     digitbuf_free(var->buf);
    6969     3409894 :     var->buf = NULL;
    6970     3409894 :     var->digits = NULL;
    6971     3409894 :     var->sign = NUMERIC_NAN;
    6972     3409894 : }
    6973             : 
    6974             : 
    6975             : /*
    6976             :  * zero_var() -
    6977             :  *
    6978             :  *  Set a variable to ZERO.
    6979             :  *  Note: its dscale is not touched.
    6980             :  */
    6981             : static void
    6982       39870 : zero_var(NumericVar *var)
    6983             : {
    6984       39870 :     digitbuf_free(var->buf);
    6985       39870 :     var->buf = NULL;
    6986       39870 :     var->digits = NULL;
    6987       39870 :     var->ndigits = 0;
    6988       39870 :     var->weight = 0;         /* by convention; doesn't really matter */
    6989       39870 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    6990       39870 : }
    6991             : 
    6992             : 
    6993             : /*
    6994             :  * set_var_from_str()
    6995             :  *
    6996             :  *  Parse a string and put the number into a variable
    6997             :  *
    6998             :  * This function does not handle leading or trailing spaces.  It returns
    6999             :  * the end+1 position parsed into *endptr, so that caller can check for
    7000             :  * trailing spaces/garbage if deemed necessary.
    7001             :  *
    7002             :  * cp is the place to actually start parsing; str is what to use in error
    7003             :  * reports.  (Typically cp would be the same except advanced over spaces.)
    7004             :  *
    7005             :  * Returns true on success, false on failure (if escontext points to an
    7006             :  * ErrorSaveContext; otherwise errors are thrown).
    7007             :  */
    7008             : static bool
    7009      129254 : set_var_from_str(const char *str, const char *cp,
    7010             :                  NumericVar *dest, const char **endptr,
    7011             :                  Node *escontext)
    7012             : {
    7013      129254 :     bool        have_dp = false;
    7014             :     int         i;
    7015             :     unsigned char *decdigits;
    7016      129254 :     int         sign = NUMERIC_POS;
    7017      129254 :     int         dweight = -1;
    7018             :     int         ddigits;
    7019      129254 :     int         dscale = 0;
    7020             :     int         weight;
    7021             :     int         ndigits;
    7022             :     int         offset;
    7023             :     NumericDigit *digits;
    7024             : 
    7025             :     /*
    7026             :      * We first parse the string to extract decimal digits and determine the
    7027             :      * correct decimal weight.  Then convert to NBASE representation.
    7028             :      */
    7029      129254 :     switch (*cp)
    7030             :     {
    7031           0 :         case '+':
    7032           0 :             sign = NUMERIC_POS;
    7033           0 :             cp++;
    7034           0 :             break;
    7035             : 
    7036         300 :         case '-':
    7037         300 :             sign = NUMERIC_NEG;
    7038         300 :             cp++;
    7039         300 :             break;
    7040             :     }
    7041             : 
    7042      129254 :     if (*cp == '.')
    7043             :     {
    7044         384 :         have_dp = true;
    7045         384 :         cp++;
    7046             :     }
    7047             : 
    7048      129254 :     if (!isdigit((unsigned char) *cp))
    7049           0 :         goto invalid_syntax;
    7050             : 
    7051      129254 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    7052             : 
    7053             :     /* leading padding for digit alignment later */
    7054      129254 :     memset(decdigits, 0, DEC_DIGITS);
    7055      129254 :     i = DEC_DIGITS;
    7056             : 
    7057      568992 :     while (*cp)
    7058             :     {
    7059      441070 :         if (isdigit((unsigned char) *cp))
    7060             :         {
    7061      422498 :             decdigits[i++] = *cp++ - '0';
    7062      422498 :             if (!have_dp)
    7063      349978 :                 dweight++;
    7064             :             else
    7065       72520 :                 dscale++;
    7066             :         }
    7067       18572 :         else if (*cp == '.')
    7068             :         {
    7069       17078 :             if (have_dp)
    7070           0 :                 goto invalid_syntax;
    7071       17078 :             have_dp = true;
    7072       17078 :             cp++;
    7073             :             /* decimal point must not be followed by underscore */
    7074       17078 :             if (*cp == '_')
    7075           6 :                 goto invalid_syntax;
    7076             :         }
    7077        1494 :         else if (*cp == '_')
    7078             :         {
    7079             :             /* underscore must be followed by more digits */
    7080         186 :             cp++;
    7081         186 :             if (!isdigit((unsigned char) *cp))
    7082          18 :                 goto invalid_syntax;
    7083             :         }
    7084             :         else
    7085        1308 :             break;
    7086             :     }
    7087             : 
    7088      129230 :     ddigits = i - DEC_DIGITS;
    7089             :     /* trailing padding for digit alignment later */
    7090      129230 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    7091             : 
    7092             :     /* Handle exponent, if any */
    7093      129230 :     if (*cp == 'e' || *cp == 'E')
    7094             :     {
    7095        1260 :         int64       exponent = 0;
    7096        1260 :         bool        neg = false;
    7097             : 
    7098             :         /*
    7099             :          * At this point, dweight and dscale can't be more than about
    7100             :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    7101             :          * constraining the exponent similarly should be enough to prevent
    7102             :          * integer overflow in this function.  If the value is too large to
    7103             :          * fit in storage format, make_result() will complain about it later;
    7104             :          * for consistency use the same ereport errcode/text as make_result().
    7105             :          */
    7106             : 
    7107             :         /* exponent sign */
    7108        1260 :         cp++;
    7109        1260 :         if (*cp == '+')
    7110         154 :             cp++;
    7111        1106 :         else if (*cp == '-')
    7112             :         {
    7113         470 :             neg = true;
    7114         470 :             cp++;
    7115             :         }
    7116             : 
    7117             :         /* exponent digits */
    7118        1260 :         if (!isdigit((unsigned char) *cp))
    7119           6 :             goto invalid_syntax;
    7120             : 
    7121        4440 :         while (*cp)
    7122             :         {
    7123        3204 :             if (isdigit((unsigned char) *cp))
    7124             :             {
    7125        3162 :                 exponent = exponent * 10 + (*cp++ - '0');
    7126        3162 :                 if (exponent > PG_INT32_MAX / 2)
    7127           6 :                     goto out_of_range;
    7128             :             }
    7129          42 :             else if (*cp == '_')
    7130             :             {
    7131             :                 /* underscore must be followed by more digits */
    7132          42 :                 cp++;
    7133          42 :                 if (!isdigit((unsigned char) *cp))
    7134          12 :                     goto invalid_syntax;
    7135             :             }
    7136             :             else
    7137           0 :                 break;
    7138             :         }
    7139             : 
    7140        1236 :         if (neg)
    7141         470 :             exponent = -exponent;
    7142             : 
    7143        1236 :         dweight += (int) exponent;
    7144        1236 :         dscale -= (int) exponent;
    7145        1236 :         if (dscale < 0)
    7146         562 :             dscale = 0;
    7147             :     }
    7148             : 
    7149             :     /*
    7150             :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    7151             :      * to determine the converted weight and ndigits.  offset is the number of
    7152             :      * decimal zeroes to insert before the first given digit to have a
    7153             :      * correctly aligned first NBASE digit.
    7154             :      */
    7155      129206 :     if (dweight >= 0)
    7156      128454 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    7157             :     else
    7158         752 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    7159      129206 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    7160      129206 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    7161             : 
    7162      129206 :     alloc_var(dest, ndigits);
    7163      129206 :     dest->sign = sign;
    7164      129206 :     dest->weight = weight;
    7165      129206 :     dest->dscale = dscale;
    7166             : 
    7167      129206 :     i = DEC_DIGITS - offset;
    7168      129206 :     digits = dest->digits;
    7169             : 
    7170      322534 :     while (ndigits-- > 0)
    7171             :     {
    7172             : #if DEC_DIGITS == 4
    7173      193328 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    7174      193328 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    7175             : #elif DEC_DIGITS == 2
    7176             :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    7177             : #elif DEC_DIGITS == 1
    7178             :         *digits++ = decdigits[i];
    7179             : #else
    7180             : #error unsupported NBASE
    7181             : #endif
    7182      193328 :         i += DEC_DIGITS;
    7183             :     }
    7184             : 
    7185      129206 :     pfree(decdigits);
    7186             : 
    7187             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    7188      129206 :     strip_var(dest);
    7189             : 
    7190             :     /* Return end+1 position for caller */
    7191      129206 :     *endptr = cp;
    7192             : 
    7193      129206 :     return true;
    7194             : 
    7195           6 : out_of_range:
    7196           6 :     ereturn(escontext, false,
    7197             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7198             :              errmsg("value overflows numeric format")));
    7199             : 
    7200          42 : invalid_syntax:
    7201          42 :     ereturn(escontext, false,
    7202             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7203             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7204             :                     "numeric", str)));
    7205             : }
    7206             : 
    7207             : 
    7208             : /*
    7209             :  * Return the numeric value of a single hex digit.
    7210             :  */
    7211             : static inline int
    7212         708 : xdigit_value(char dig)
    7213             : {
    7214         894 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    7215         294 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    7216         108 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    7217             : }
    7218             : 
    7219             : /*
    7220             :  * set_var_from_non_decimal_integer_str()
    7221             :  *
    7222             :  *  Parse a string containing a non-decimal integer
    7223             :  *
    7224             :  * This function does not handle leading or trailing spaces.  It returns
    7225             :  * the end+1 position parsed into *endptr, so that caller can check for
    7226             :  * trailing spaces/garbage if deemed necessary.
    7227             :  *
    7228             :  * cp is the place to actually start parsing; str is what to use in error
    7229             :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    7230             :  * assumed to have already been parsed, so cp should point to the number's
    7231             :  * first digit in the base specified.
    7232             :  *
    7233             :  * base is expected to be 2, 8 or 16.
    7234             :  *
    7235             :  * Returns true on success, false on failure (if escontext points to an
    7236             :  * ErrorSaveContext; otherwise errors are thrown).
    7237             :  */
    7238             : static bool
    7239         156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7240             :                                      int base, NumericVar *dest,
    7241             :                                      const char **endptr, Node *escontext)
    7242             : {
    7243         156 :     const char *firstdigit = cp;
    7244             :     int64       tmp;
    7245             :     int64       mul;
    7246             :     NumericVar  tmp_var;
    7247             : 
    7248         156 :     init_var(&tmp_var);
    7249             : 
    7250         156 :     zero_var(dest);
    7251             : 
    7252             :     /*
    7253             :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7254             :      * value of the digits in the group, and "mul" is base^n, where n is the
    7255             :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7256             :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7257             :      */
    7258         156 :     tmp = 0;
    7259         156 :     mul = 1;
    7260             : 
    7261         156 :     if (base == 16)
    7262             :     {
    7263         828 :         while (*cp)
    7264             :         {
    7265         798 :             if (isxdigit((unsigned char) *cp))
    7266             :             {
    7267         708 :                 if (mul > PG_INT64_MAX / 16)
    7268             :                 {
    7269             :                     /* Add the contribution from this group of digits */
    7270          30 :                     int64_to_numericvar(mul, &tmp_var);
    7271          30 :                     mul_var(dest, &tmp_var, dest, 0);
    7272          30 :                     int64_to_numericvar(tmp, &tmp_var);
    7273          30 :                     add_var(dest, &tmp_var, dest);
    7274             : 
    7275             :                     /* Result will overflow if weight overflows int16 */
    7276          30 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7277           0 :                         goto out_of_range;
    7278             : 
    7279             :                     /* Begin a new group */
    7280          30 :                     tmp = 0;
    7281          30 :                     mul = 1;
    7282             :                 }
    7283             : 
    7284         708 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7285         708 :                 mul = mul * 16;
    7286             :             }
    7287          90 :             else if (*cp == '_')
    7288             :             {
    7289             :                 /* Underscore must be followed by more digits */
    7290          66 :                 cp++;
    7291          66 :                 if (!isxdigit((unsigned char) *cp))
    7292          18 :                     goto invalid_syntax;
    7293             :             }
    7294             :             else
    7295          24 :                 break;
    7296             :         }
    7297             :     }
    7298          84 :     else if (base == 8)
    7299             :     {
    7300         636 :         while (*cp)
    7301             :         {
    7302         606 :             if (*cp >= '0' && *cp <= '7')
    7303             :             {
    7304         558 :                 if (mul > PG_INT64_MAX / 8)
    7305             :                 {
    7306             :                     /* Add the contribution from this group of digits */
    7307          18 :                     int64_to_numericvar(mul, &tmp_var);
    7308          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7309          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7310          18 :                     add_var(dest, &tmp_var, dest);
    7311             : 
    7312             :                     /* Result will overflow if weight overflows int16 */
    7313          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7314           0 :                         goto out_of_range;
    7315             : 
    7316             :                     /* Begin a new group */
    7317          18 :                     tmp = 0;
    7318          18 :                     mul = 1;
    7319             :                 }
    7320             : 
    7321         558 :                 tmp = tmp * 8 + (*cp++ - '0');
    7322         558 :                 mul = mul * 8;
    7323             :             }
    7324          48 :             else if (*cp == '_')
    7325             :             {
    7326             :                 /* Underscore must be followed by more digits */
    7327          36 :                 cp++;
    7328          36 :                 if (*cp < '0' || *cp > '7')
    7329           0 :                     goto invalid_syntax;
    7330             :             }
    7331             :             else
    7332          12 :                 break;
    7333             :         }
    7334             :     }
    7335          42 :     else if (base == 2)
    7336             :     {
    7337        1560 :         while (*cp)
    7338             :         {
    7339        1530 :             if (*cp >= '0' && *cp <= '1')
    7340             :             {
    7341        1416 :                 if (mul > PG_INT64_MAX / 2)
    7342             :                 {
    7343             :                     /* Add the contribution from this group of digits */
    7344          18 :                     int64_to_numericvar(mul, &tmp_var);
    7345          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7346          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7347          18 :                     add_var(dest, &tmp_var, dest);
    7348             : 
    7349             :                     /* Result will overflow if weight overflows int16 */
    7350          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7351           0 :                         goto out_of_range;
    7352             : 
    7353             :                     /* Begin a new group */
    7354          18 :                     tmp = 0;
    7355          18 :                     mul = 1;
    7356             :                 }
    7357             : 
    7358        1416 :                 tmp = tmp * 2 + (*cp++ - '0');
    7359        1416 :                 mul = mul * 2;
    7360             :             }
    7361         114 :             else if (*cp == '_')
    7362             :             {
    7363             :                 /* Underscore must be followed by more digits */
    7364         102 :                 cp++;
    7365         102 :                 if (*cp < '0' || *cp > '1')
    7366           0 :                     goto invalid_syntax;
    7367             :             }
    7368             :             else
    7369          12 :                 break;
    7370             :         }
    7371             :     }
    7372             :     else
    7373             :         /* Should never happen; treat as invalid input */
    7374           0 :         goto invalid_syntax;
    7375             : 
    7376             :     /* Check that we got at least one digit */
    7377         138 :     if (unlikely(cp == firstdigit))
    7378           0 :         goto invalid_syntax;
    7379             : 
    7380             :     /* Add the contribution from the final group of digits */
    7381         138 :     int64_to_numericvar(mul, &tmp_var);
    7382         138 :     mul_var(dest, &tmp_var, dest, 0);
    7383         138 :     int64_to_numericvar(tmp, &tmp_var);
    7384         138 :     add_var(dest, &tmp_var, dest);
    7385             : 
    7386         138 :     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7387           0 :         goto out_of_range;
    7388             : 
    7389         138 :     dest->sign = sign;
    7390             : 
    7391         138 :     free_var(&tmp_var);
    7392             : 
    7393             :     /* Return end+1 position for caller */
    7394         138 :     *endptr = cp;
    7395             : 
    7396         138 :     return true;
    7397             : 
    7398           0 : out_of_range:
    7399           0 :     ereturn(escontext, false,
    7400             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7401             :              errmsg("value overflows numeric format")));
    7402             : 
    7403          18 : invalid_syntax:
    7404          18 :     ereturn(escontext, false,
    7405             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7406             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7407             :                     "numeric", str)));
    7408             : }
    7409             : 
    7410             : 
    7411             : /*
    7412             :  * set_var_from_num() -
    7413             :  *
    7414             :  *  Convert the packed db format into a variable
    7415             :  */
    7416             : static void
    7417       12940 : set_var_from_num(Numeric num, NumericVar *dest)
    7418             : {
    7419             :     int         ndigits;
    7420             : 
    7421       12940 :     ndigits = NUMERIC_NDIGITS(num);
    7422             : 
    7423       12940 :     alloc_var(dest, ndigits);
    7424             : 
    7425       12940 :     dest->weight = NUMERIC_WEIGHT(num);
    7426       12940 :     dest->sign = NUMERIC_SIGN(num);
    7427       12940 :     dest->dscale = NUMERIC_DSCALE(num);
    7428             : 
    7429       12940 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7430       12940 : }
    7431             : 
    7432             : 
    7433             : /*
    7434             :  * init_var_from_num() -
    7435             :  *
    7436             :  *  Initialize a variable from packed db format. The digits array is not
    7437             :  *  copied, which saves some cycles when the resulting var is not modified.
    7438             :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7439             :  *  other value to it (with set_var_* functions, or by using the var as the
    7440             :  *  destination of a function like add_var())
    7441             :  *
    7442             :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7443             :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7444             :  *  propagate to the original Numeric! It's OK to use it as the destination
    7445             :  *  argument of one of the calculational functions, though.
    7446             :  */
    7447             : static void
    7448     5093018 : init_var_from_num(Numeric num, NumericVar *dest)
    7449             : {
    7450     5093018 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7451     5093018 :     dest->weight = NUMERIC_WEIGHT(num);
    7452     5093018 :     dest->sign = NUMERIC_SIGN(num);
    7453     5093018 :     dest->dscale = NUMERIC_DSCALE(num);
    7454     5093018 :     dest->digits = NUMERIC_DIGITS(num);
    7455     5093018 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7456     5093018 : }
    7457             : 
    7458             : 
    7459             : /*
    7460             :  * set_var_from_var() -
    7461             :  *
    7462             :  *  Copy one variable into another
    7463             :  */
    7464             : static void
    7465       35172 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7466             : {
    7467             :     NumericDigit *newbuf;
    7468             : 
    7469       35172 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7470       35172 :     newbuf[0] = 0;              /* spare digit for rounding */
    7471       35172 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7472       34226 :         memcpy(newbuf + 1, value->digits,
    7473       34226 :                value->ndigits * sizeof(NumericDigit));
    7474             : 
    7475       35172 :     digitbuf_free(dest->buf);
    7476             : 
    7477       35172 :     memmove(dest, value, sizeof(NumericVar));
    7478       35172 :     dest->buf = newbuf;
    7479       35172 :     dest->digits = newbuf + 1;
    7480       35172 : }
    7481             : 
    7482             : 
    7483             : /*
    7484             :  * get_str_from_var() -
    7485             :  *
    7486             :  *  Convert a var to text representation (guts of numeric_out).
    7487             :  *  The var is displayed to the number of digits indicated by its dscale.
    7488             :  *  Returns a palloc'd string.
    7489             :  */
    7490             : static char *
    7491      802030 : get_str_from_var(const NumericVar *var)
    7492             : {
    7493             :     int         dscale;
    7494             :     char       *str;
    7495             :     char       *cp;
    7496             :     char       *endcp;
    7497             :     int         i;
    7498             :     int         d;
    7499             :     NumericDigit dig;
    7500             : 
    7501             : #if DEC_DIGITS > 1
    7502             :     NumericDigit d1;
    7503             : #endif
    7504             : 
    7505      802030 :     dscale = var->dscale;
    7506             : 
    7507             :     /*
    7508             :      * Allocate space for the result.
    7509             :      *
    7510             :      * i is set to the # of decimal digits before decimal point. dscale is the
    7511             :      * # of decimal digits we will print after decimal point. We may generate
    7512             :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7513             :      * need room for sign, decimal point, null terminator.
    7514             :      */
    7515      802030 :     i = (var->weight + 1) * DEC_DIGITS;
    7516      802030 :     if (i <= 0)
    7517      140642 :         i = 1;
    7518             : 
    7519      802030 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7520      802030 :     cp = str;
    7521             : 
    7522             :     /*
    7523             :      * Output a dash for negative values
    7524             :      */
    7525      802030 :     if (var->sign == NUMERIC_NEG)
    7526        5566 :         *cp++ = '-';
    7527             : 
    7528             :     /*
    7529             :      * Output all digits before the decimal point
    7530             :      */
    7531      802030 :     if (var->weight < 0)
    7532             :     {
    7533      140642 :         d = var->weight + 1;
    7534      140642 :         *cp++ = '0';
    7535             :     }
    7536             :     else
    7537             :     {
    7538     1428688 :         for (d = 0; d <= var->weight; d++)
    7539             :         {
    7540      767300 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7541             :             /* In the first digit, suppress extra leading decimal zeroes */
    7542             : #if DEC_DIGITS == 4
    7543             :             {
    7544      767300 :                 bool        putit = (d > 0);
    7545             : 
    7546      767300 :                 d1 = dig / 1000;
    7547      767300 :                 dig -= d1 * 1000;
    7548      767300 :                 putit |= (d1 > 0);
    7549      767300 :                 if (putit)
    7550      112842 :                     *cp++ = d1 + '0';
    7551      767300 :                 d1 = dig / 100;
    7552      767300 :                 dig -= d1 * 100;
    7553      767300 :                 putit |= (d1 > 0);
    7554      767300 :                 if (putit)
    7555      517924 :                     *cp++ = d1 + '0';
    7556      767300 :                 d1 = dig / 10;
    7557      767300 :                 dig -= d1 * 10;
    7558      767300 :                 putit |= (d1 > 0);
    7559      767300 :                 if (putit)
    7560      645130 :                     *cp++ = d1 + '0';
    7561      767300 :                 *cp++ = dig + '0';
    7562             :             }
    7563             : #elif DEC_DIGITS == 2
    7564             :             d1 = dig / 10;
    7565             :             dig -= d1 * 10;
    7566             :             if (d1 > 0 || d > 0)
    7567             :                 *cp++ = d1 + '0';
    7568             :             *cp++ = dig + '0';
    7569             : #elif DEC_DIGITS == 1
    7570             :             *cp++ = dig + '0';
    7571             : #else
    7572             : #error unsupported NBASE
    7573             : #endif
    7574             :         }
    7575             :     }
    7576             : 
    7577             :     /*
    7578             :      * If requested, output a decimal point and all the digits that follow it.
    7579             :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7580             :      * needed.
    7581             :      */
    7582      802030 :     if (dscale > 0)
    7583             :     {
    7584      646334 :         *cp++ = '.';
    7585      646334 :         endcp = cp + dscale;
    7586     2018486 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7587             :         {
    7588     1372152 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7589             : #if DEC_DIGITS == 4
    7590     1372152 :             d1 = dig / 1000;
    7591     1372152 :             dig -= d1 * 1000;
    7592     1372152 :             *cp++ = d1 + '0';
    7593     1372152 :             d1 = dig / 100;
    7594     1372152 :             dig -= d1 * 100;
    7595     1372152 :             *cp++ = d1 + '0';
    7596     1372152 :             d1 = dig / 10;
    7597     1372152 :             dig -= d1 * 10;
    7598     1372152 :             *cp++ = d1 + '0';
    7599     1372152 :             *cp++ = dig + '0';
    7600             : #elif DEC_DIGITS == 2
    7601             :             d1 = dig / 10;
    7602             :             dig -= d1 * 10;
    7603             :             *cp++ = d1 + '0';
    7604             :             *cp++ = dig + '0';
    7605             : #elif DEC_DIGITS == 1
    7606             :             *cp++ = dig + '0';
    7607             : #else
    7608             : #error unsupported NBASE
    7609             : #endif
    7610             :         }
    7611      646334 :         cp = endcp;
    7612             :     }
    7613             : 
    7614             :     /*
    7615             :      * terminate the string and return it
    7616             :      */
    7617      802030 :     *cp = '\0';
    7618      802030 :     return str;
    7619             : }
    7620             : 
    7621             : /*
    7622             :  * get_str_from_var_sci() -
    7623             :  *
    7624             :  *  Convert a var to a normalised scientific notation text representation.
    7625             :  *  This function does the heavy lifting for numeric_out_sci().
    7626             :  *
    7627             :  *  This notation has the general form a * 10^b, where a is known as the
    7628             :  *  "significand" and b is known as the "exponent".
    7629             :  *
    7630             :  *  Because we can't do superscript in ASCII (and because we want to copy
    7631             :  *  printf's behaviour) we display the exponent using E notation, with a
    7632             :  *  minimum of two exponent digits.
    7633             :  *
    7634             :  *  For example, the value 1234 could be output as 1.2e+03.
    7635             :  *
    7636             :  *  We assume that the exponent can fit into an int32.
    7637             :  *
    7638             :  *  rscale is the number of decimal digits desired after the decimal point in
    7639             :  *  the output, negative values will be treated as meaning zero.
    7640             :  *
    7641             :  *  Returns a palloc'd string.
    7642             :  */
    7643             : static char *
    7644         228 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7645             : {
    7646             :     int32       exponent;
    7647             :     NumericVar  tmp_var;
    7648             :     size_t      len;
    7649             :     char       *str;
    7650             :     char       *sig_out;
    7651             : 
    7652         228 :     if (rscale < 0)
    7653           0 :         rscale = 0;
    7654             : 
    7655             :     /*
    7656             :      * Determine the exponent of this number in normalised form.
    7657             :      *
    7658             :      * This is the exponent required to represent the number with only one
    7659             :      * significant digit before the decimal place.
    7660             :      */
    7661         228 :     if (var->ndigits > 0)
    7662             :     {
    7663         210 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7664             : 
    7665             :         /*
    7666             :          * Compensate for leading decimal zeroes in the first numeric digit by
    7667             :          * decrementing the exponent.
    7668             :          */
    7669         210 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7670             :     }
    7671             :     else
    7672             :     {
    7673             :         /*
    7674             :          * If var has no digits, then it must be zero.
    7675             :          *
    7676             :          * Zero doesn't technically have a meaningful exponent in normalised
    7677             :          * notation, but we just display the exponent as zero for consistency
    7678             :          * of output.
    7679             :          */
    7680          18 :         exponent = 0;
    7681             :     }
    7682             : 
    7683             :     /*
    7684             :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7685             :      * decimal digits in the process.
    7686             :      */
    7687         228 :     init_var(&tmp_var);
    7688             : 
    7689         228 :     power_ten_int(exponent, &tmp_var);
    7690         228 :     div_var(var, &tmp_var, &tmp_var, rscale, true, true);
    7691         228 :     sig_out = get_str_from_var(&tmp_var);
    7692             : 
    7693         228 :     free_var(&tmp_var);
    7694             : 
    7695             :     /*
    7696             :      * Allocate space for the result.
    7697             :      *
    7698             :      * In addition to the significand, we need room for the exponent
    7699             :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7700             :      * exponent itself, and of course the null terminator.
    7701             :      */
    7702         228 :     len = strlen(sig_out) + 13;
    7703         228 :     str = palloc(len);
    7704         228 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7705             : 
    7706         228 :     pfree(sig_out);
    7707             : 
    7708         228 :     return str;
    7709             : }
    7710             : 
    7711             : 
    7712             : /*
    7713             :  * numericvar_serialize - serialize NumericVar to binary format
    7714             :  *
    7715             :  * At variable level, no checks are performed on the weight or dscale, allowing
    7716             :  * us to pass around intermediate values with higher precision than supported
    7717             :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7718             :  * which use 16-bit integers for these fields.
    7719             :  */
    7720             : static void
    7721          96 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7722             : {
    7723             :     int         i;
    7724             : 
    7725          96 :     pq_sendint32(buf, var->ndigits);
    7726          96 :     pq_sendint32(buf, var->weight);
    7727          96 :     pq_sendint32(buf, var->sign);
    7728          96 :     pq_sendint32(buf, var->dscale);
    7729      637786 :     for (i = 0; i < var->ndigits; i++)
    7730      637690 :         pq_sendint16(buf, var->digits[i]);
    7731          96 : }
    7732             : 
    7733             : /*
    7734             :  * numericvar_deserialize - deserialize binary format to NumericVar
    7735             :  */
    7736             : static void
    7737          96 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7738             : {
    7739             :     int         len,
    7740             :                 i;
    7741             : 
    7742          96 :     len = pq_getmsgint(buf, sizeof(int32));
    7743             : 
    7744          96 :     alloc_var(var, len);        /* sets var->ndigits */
    7745             : 
    7746          96 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7747          96 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7748          96 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7749      637786 :     for (i = 0; i < len; i++)
    7750      637690 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7751          96 : }
    7752             : 
    7753             : 
    7754             : /*
    7755             :  * duplicate_numeric() - copy a packed-format Numeric
    7756             :  *
    7757             :  * This will handle NaN and Infinity cases.
    7758             :  */
    7759             : static Numeric
    7760       28496 : duplicate_numeric(Numeric num)
    7761             : {
    7762             :     Numeric     res;
    7763             : 
    7764       28496 :     res = (Numeric) palloc(VARSIZE(num));
    7765       28496 :     memcpy(res, num, VARSIZE(num));
    7766       28496 :     return res;
    7767             : }
    7768             : 
    7769             : /*
    7770             :  * make_result_opt_error() -
    7771             :  *
    7772             :  *  Create the packed db numeric format in palloc()'d memory from
    7773             :  *  a variable.  This will handle NaN and Infinity cases.
    7774             :  *
    7775             :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
    7776             :  *  NULL is returned.  This is helpful when caller needs to handle errors.
    7777             :  */
    7778             : static Numeric
    7779     3272626 : make_result_opt_error(const NumericVar *var, bool *have_error)
    7780             : {
    7781             :     Numeric     result;
    7782     3272626 :     NumericDigit *digits = var->digits;
    7783     3272626 :     int         weight = var->weight;
    7784     3272626 :     int         sign = var->sign;
    7785             :     int         n;
    7786             :     Size        len;
    7787             : 
    7788     3272626 :     if (have_error)
    7789      106676 :         *have_error = false;
    7790             : 
    7791     3272626 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7792             :     {
    7793             :         /*
    7794             :          * Verify valid special value.  This could be just an Assert, perhaps,
    7795             :          * but it seems worthwhile to expend a few cycles to ensure that we
    7796             :          * never write any nonzero reserved bits to disk.
    7797             :          */
    7798        5478 :         if (!(sign == NUMERIC_NAN ||
    7799             :               sign == NUMERIC_PINF ||
    7800             :               sign == NUMERIC_NINF))
    7801           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7802             : 
    7803        5478 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7804             : 
    7805        5478 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7806        5478 :         result->choice.n_header = sign;
    7807             :         /* the header word is all we need */
    7808             : 
    7809             :         dump_numeric("make_result()", result);
    7810        5478 :         return result;
    7811             :     }
    7812             : 
    7813     3267148 :     n = var->ndigits;
    7814             : 
    7815             :     /* truncate leading zeroes */
    7816     3267184 :     while (n > 0 && *digits == 0)
    7817             :     {
    7818          36 :         digits++;
    7819          36 :         weight--;
    7820          36 :         n--;
    7821             :     }
    7822             :     /* truncate trailing zeroes */
    7823     3352484 :     while (n > 0 && digits[n - 1] == 0)
    7824       85336 :         n--;
    7825             : 
    7826             :     /* If zero result, force to weight=0 and positive sign */
    7827     3267148 :     if (n == 0)
    7828             :     {
    7829       94568 :         weight = 0;
    7830       94568 :         sign = NUMERIC_POS;
    7831             :     }
    7832             : 
    7833             :     /* Build the result */
    7834     3267148 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7835             :     {
    7836     3261854 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7837     3261854 :         result = (Numeric) palloc(len);
    7838     3261854 :         SET_VARSIZE(result, len);
    7839     3261854 :         result->choice.n_short.n_header =
    7840             :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7841             :              : NUMERIC_SHORT)
    7842     3261854 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7843     3261854 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7844     3261854 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7845             :     }
    7846             :     else
    7847             :     {
    7848        5294 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7849        5294 :         result = (Numeric) palloc(len);
    7850        5294 :         SET_VARSIZE(result, len);
    7851        5294 :         result->choice.n_long.n_sign_dscale =
    7852        5294 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7853        5294 :         result->choice.n_long.n_weight = weight;
    7854             :     }
    7855             : 
    7856             :     Assert(NUMERIC_NDIGITS(result) == n);
    7857     3267148 :     if (n > 0)
    7858     3172580 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7859             : 
    7860             :     /* Check for overflow of int16 fields */
    7861     3267148 :     if (NUMERIC_WEIGHT(result) != weight ||
    7862     3267118 :         NUMERIC_DSCALE(result) != var->dscale)
    7863             :     {
    7864          30 :         if (have_error)
    7865             :         {
    7866          18 :             *have_error = true;
    7867          18 :             return NULL;
    7868             :         }
    7869             :         else
    7870             :         {
    7871          12 :             ereport(ERROR,
    7872             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7873             :                      errmsg("value overflows numeric format")));
    7874             :         }
    7875             :     }
    7876             : 
    7877             :     dump_numeric("make_result()", result);
    7878     3267118 :     return result;
    7879             : }
    7880             : 
    7881             : 
    7882             : /*
    7883             :  * make_result() -
    7884             :  *
    7885             :  *  An interface to make_result_opt_error() without "have_error" argument.
    7886             :  */
    7887             : static Numeric
    7888     2129522 : make_result(const NumericVar *var)
    7889             : {
    7890     2129522 :     return make_result_opt_error(var, NULL);
    7891             : }
    7892             : 
    7893             : 
    7894             : /*
    7895             :  * apply_typmod() -
    7896             :  *
    7897             :  *  Do bounds checking and rounding according to the specified typmod.
    7898             :  *  Note that this is only applied to normal finite values.
    7899             :  *
    7900             :  * Returns true on success, false on failure (if escontext points to an
    7901             :  * ErrorSaveContext; otherwise errors are thrown).
    7902             :  */
    7903             : static bool
    7904      110840 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    7905             : {
    7906             :     int         precision;
    7907             :     int         scale;
    7908             :     int         maxdigits;
    7909             :     int         ddigits;
    7910             :     int         i;
    7911             : 
    7912             :     /* Do nothing if we have an invalid typmod */
    7913      110840 :     if (!is_valid_numeric_typmod(typmod))
    7914      106142 :         return true;
    7915             : 
    7916        4698 :     precision = numeric_typmod_precision(typmod);
    7917        4698 :     scale = numeric_typmod_scale(typmod);
    7918        4698 :     maxdigits = precision - scale;
    7919             : 
    7920             :     /* Round to target scale (and set var->dscale) */
    7921        4698 :     round_var(var, scale);
    7922             : 
    7923             :     /* but don't allow var->dscale to be negative */
    7924        4698 :     if (var->dscale < 0)
    7925         126 :         var->dscale = 0;
    7926             : 
    7927             :     /*
    7928             :      * Check for overflow - note we can't do this before rounding, because
    7929             :      * rounding could raise the weight.  Also note that the var's weight could
    7930             :      * be inflated by leading zeroes, which will be stripped before storage
    7931             :      * but perhaps might not have been yet. In any case, we must recognize a
    7932             :      * true zero, whose weight doesn't mean anything.
    7933             :      */
    7934        4698 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    7935        4698 :     if (ddigits > maxdigits)
    7936             :     {
    7937             :         /* Determine true weight; and check for all-zero result */
    7938         410 :         for (i = 0; i < var->ndigits; i++)
    7939             :         {
    7940         394 :             NumericDigit dig = var->digits[i];
    7941             : 
    7942         394 :             if (dig)
    7943             :             {
    7944             :                 /* Adjust for any high-order decimal zero digits */
    7945             : #if DEC_DIGITS == 4
    7946         394 :                 if (dig < 10)
    7947         252 :                     ddigits -= 3;
    7948         142 :                 else if (dig < 100)
    7949          72 :                     ddigits -= 2;
    7950          70 :                 else if (dig < 1000)
    7951          52 :                     ddigits -= 1;
    7952             : #elif DEC_DIGITS == 2
    7953             :                 if (dig < 10)
    7954             :                     ddigits -= 1;
    7955             : #elif DEC_DIGITS == 1
    7956             :                 /* no adjustment */
    7957             : #else
    7958             : #error unsupported NBASE
    7959             : #endif
    7960         394 :                 if (ddigits > maxdigits)
    7961          84 :                     ereturn(escontext, false,
    7962             :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7963             :                              errmsg("numeric field overflow"),
    7964             :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    7965             :                                        precision, scale,
    7966             :                     /* Display 10^0 as 1 */
    7967             :                                        maxdigits ? "10^" : "",
    7968             :                                        maxdigits ? maxdigits : 1
    7969             :                                        )));
    7970         310 :                 break;
    7971             :             }
    7972           0 :             ddigits -= DEC_DIGITS;
    7973             :         }
    7974             :     }
    7975             : 
    7976        4614 :     return true;
    7977             : }
    7978             : 
    7979             : /*
    7980             :  * apply_typmod_special() -
    7981             :  *
    7982             :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    7983             :  *  For convenience of most callers, the value is presented in packed form.
    7984             :  *
    7985             :  * Returns true on success, false on failure (if escontext points to an
    7986             :  * ErrorSaveContext; otherwise errors are thrown).
    7987             :  */
    7988             : static bool
    7989        1864 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    7990             : {
    7991             :     int         precision;
    7992             :     int         scale;
    7993             : 
    7994             :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    7995             : 
    7996             :     /*
    7997             :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    7998             :      * but it's a longstanding behavior.  Inf is rejected if we have any
    7999             :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    8000             :      * any finite number of digits.
    8001             :      */
    8002        1864 :     if (NUMERIC_IS_NAN(num))
    8003         778 :         return true;
    8004             : 
    8005             :     /* Do nothing if we have a default typmod (-1) */
    8006        1086 :     if (!is_valid_numeric_typmod(typmod))
    8007        1068 :         return true;
    8008             : 
    8009          18 :     precision = numeric_typmod_precision(typmod);
    8010          18 :     scale = numeric_typmod_scale(typmod);
    8011             : 
    8012          18 :     ereturn(escontext, false,
    8013             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    8014             :              errmsg("numeric field overflow"),
    8015             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    8016             :                        precision, scale)));
    8017             : }
    8018             : 
    8019             : 
    8020             : /*
    8021             :  * Convert numeric to int8, rounding if needed.
    8022             :  *
    8023             :  * If overflow, return false (no error is raised).  Return true if okay.
    8024             :  */
    8025             : static bool
    8026       10296 : numericvar_to_int64(const NumericVar *var, int64 *result)
    8027             : {
    8028             :     NumericDigit *digits;
    8029             :     int         ndigits;
    8030             :     int         weight;
    8031             :     int         i;
    8032             :     int64       val;
    8033             :     bool        neg;
    8034             :     NumericVar  rounded;
    8035             : 
    8036             :     /* Round to nearest integer */
    8037       10296 :     init_var(&rounded);
    8038       10296 :     set_var_from_var(var, &rounded);
    8039       10296 :     round_var(&rounded, 0);
    8040             : 
    8041             :     /* Check for zero input */
    8042       10296 :     strip_var(&rounded);
    8043       10296 :     ndigits = rounded.ndigits;
    8044       10296 :     if (ndigits == 0)
    8045             :     {
    8046         478 :         *result = 0;
    8047         478 :         free_var(&rounded);
    8048         478 :         return true;
    8049             :     }
    8050             : 
    8051             :     /*
    8052             :      * For input like 10000000000, we must treat stripped digits as real. So
    8053             :      * the loop assumes there are weight+1 digits before the decimal point.
    8054             :      */
    8055        9818 :     weight = rounded.weight;
    8056             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8057             : 
    8058             :     /*
    8059             :      * Construct the result. To avoid issues with converting a value
    8060             :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    8061             :      * bit two's complement integer), accumulate value as a negative number.
    8062             :      */
    8063        9818 :     digits = rounded.digits;
    8064        9818 :     neg = (rounded.sign == NUMERIC_NEG);
    8065        9818 :     val = -digits[0];
    8066       14030 :     for (i = 1; i <= weight; i++)
    8067             :     {
    8068        4260 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    8069             :         {
    8070          30 :             free_var(&rounded);
    8071          30 :             return false;
    8072             :         }
    8073             : 
    8074        4230 :         if (i < ndigits)
    8075             :         {
    8076        3948 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    8077             :             {
    8078          18 :                 free_var(&rounded);
    8079          18 :                 return false;
    8080             :             }
    8081             :         }
    8082             :     }
    8083             : 
    8084        9770 :     free_var(&rounded);
    8085             : 
    8086        9770 :     if (!neg)
    8087             :     {
    8088        8978 :         if (unlikely(val == PG_INT64_MIN))
    8089          24 :             return false;
    8090        8954 :         val = -val;
    8091             :     }
    8092        9746 :     *result = val;
    8093             : 
    8094        9746 :     return true;
    8095             : }
    8096             : 
    8097             : /*
    8098             :  * Convert int8 value to numeric.
    8099             :  */
    8100             : static void
    8101     1880278 : int64_to_numericvar(int64 val, NumericVar *var)
    8102             : {
    8103             :     uint64      uval,
    8104             :                 newuval;
    8105             :     NumericDigit *ptr;
    8106             :     int         ndigits;
    8107             : 
    8108             :     /* int64 can require at most 19 decimal digits; add one for safety */
    8109     1880278 :     alloc_var(var, 20 / DEC_DIGITS);
    8110     1880278 :     if (val < 0)
    8111             :     {
    8112        1814 :         var->sign = NUMERIC_NEG;
    8113        1814 :         uval = pg_abs_s64(val);
    8114             :     }
    8115             :     else
    8116             :     {
    8117     1878464 :         var->sign = NUMERIC_POS;
    8118     1878464 :         uval = val;
    8119             :     }
    8120     1880278 :     var->dscale = 0;
    8121     1880278 :     if (val == 0)
    8122             :     {
    8123       35300 :         var->ndigits = 0;
    8124       35300 :         var->weight = 0;
    8125       35300 :         return;
    8126             :     }
    8127     1844978 :     ptr = var->digits + var->ndigits;
    8128     1844978 :     ndigits = 0;
    8129             :     do
    8130             :     {
    8131     2168734 :         ptr--;
    8132     2168734 :         ndigits++;
    8133     2168734 :         newuval = uval / NBASE;
    8134     2168734 :         *ptr = uval - newuval * NBASE;
    8135     2168734 :         uval = newuval;
    8136     2168734 :     } while (uval);
    8137     1844978 :     var->digits = ptr;
    8138     1844978 :     var->ndigits = ndigits;
    8139     1844978 :     var->weight = ndigits - 1;
    8140             : }
    8141             : 
    8142             : /*
    8143             :  * Convert numeric to uint64, rounding if needed.
    8144             :  *
    8145             :  * If overflow, return false (no error is raised).  Return true if okay.
    8146             :  */
    8147             : static bool
    8148         114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    8149             : {
    8150             :     NumericDigit *digits;
    8151             :     int         ndigits;
    8152             :     int         weight;
    8153             :     int         i;
    8154             :     uint64      val;
    8155             :     NumericVar  rounded;
    8156             : 
    8157             :     /* Round to nearest integer */
    8158         114 :     init_var(&rounded);
    8159         114 :     set_var_from_var(var, &rounded);
    8160         114 :     round_var(&rounded, 0);
    8161             : 
    8162             :     /* Check for zero input */
    8163         114 :     strip_var(&rounded);
    8164         114 :     ndigits = rounded.ndigits;
    8165         114 :     if (ndigits == 0)
    8166             :     {
    8167          18 :         *result = 0;
    8168          18 :         free_var(&rounded);
    8169          18 :         return true;
    8170             :     }
    8171             : 
    8172             :     /* Check for negative input */
    8173          96 :     if (rounded.sign == NUMERIC_NEG)
    8174             :     {
    8175          12 :         free_var(&rounded);
    8176          12 :         return false;
    8177             :     }
    8178             : 
    8179             :     /*
    8180             :      * For input like 10000000000, we must treat stripped digits as real. So
    8181             :      * the loop assumes there are weight+1 digits before the decimal point.
    8182             :      */
    8183          84 :     weight = rounded.weight;
    8184             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8185             : 
    8186             :     /* Construct the result */
    8187          84 :     digits = rounded.digits;
    8188          84 :     val = digits[0];
    8189         246 :     for (i = 1; i <= weight; i++)
    8190             :     {
    8191         174 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    8192             :         {
    8193           0 :             free_var(&rounded);
    8194           0 :             return false;
    8195             :         }
    8196             : 
    8197         174 :         if (i < ndigits)
    8198             :         {
    8199         174 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    8200             :             {
    8201          12 :                 free_var(&rounded);
    8202          12 :                 return false;
    8203             :             }
    8204             :         }
    8205             :     }
    8206             : 
    8207          72 :     free_var(&rounded);
    8208             : 
    8209          72 :     *result = val;
    8210             : 
    8211          72 :     return true;
    8212             : }
    8213             : 
    8214             : #ifdef HAVE_INT128
    8215             : /*
    8216             :  * Convert numeric to int128, rounding if needed.
    8217             :  *
    8218             :  * If overflow, return false (no error is raised).  Return true if okay.
    8219             :  */
    8220             : static bool
    8221          36 : numericvar_to_int128(const NumericVar *var, int128 *result)
    8222             : {
    8223             :     NumericDigit *digits;
    8224             :     int         ndigits;
    8225             :     int         weight;
    8226             :     int         i;
    8227             :     int128      val,
    8228             :                 oldval;
    8229             :     bool        neg;
    8230             :     NumericVar  rounded;
    8231             : 
    8232             :     /* Round to nearest integer */
    8233          36 :     init_var(&rounded);
    8234          36 :     set_var_from_var(var, &rounded);
    8235          36 :     round_var(&rounded, 0);
    8236             : 
    8237             :     /* Check for zero input */
    8238          36 :     strip_var(&rounded);
    8239          36 :     ndigits = rounded.ndigits;
    8240          36 :     if (ndigits == 0)
    8241             :     {
    8242           0 :         *result = 0;
    8243           0 :         free_var(&rounded);
    8244           0 :         return true;
    8245             :     }
    8246             : 
    8247             :     /*
    8248             :      * For input like 10000000000, we must treat stripped digits as real. So
    8249             :      * the loop assumes there are weight+1 digits before the decimal point.
    8250             :      */
    8251          36 :     weight = rounded.weight;
    8252             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8253             : 
    8254             :     /* Construct the result */
    8255          36 :     digits = rounded.digits;
    8256          36 :     neg = (rounded.sign == NUMERIC_NEG);
    8257          36 :     val = digits[0];
    8258         100 :     for (i = 1; i <= weight; i++)
    8259             :     {
    8260          64 :         oldval = val;
    8261          64 :         val *= NBASE;
    8262          64 :         if (i < ndigits)
    8263          52 :             val += digits[i];
    8264             : 
    8265             :         /*
    8266             :          * The overflow check is a bit tricky because we want to accept
    8267             :          * INT128_MIN, which will overflow the positive accumulator.  We can
    8268             :          * detect this case easily though because INT128_MIN is the only
    8269             :          * nonzero value for which -val == val (on a two's complement machine,
    8270             :          * anyway).
    8271             :          */
    8272          64 :         if ((val / NBASE) != oldval)    /* possible overflow? */
    8273             :         {
    8274           0 :             if (!neg || (-val) != val || val == 0 || oldval < 0)
    8275             :             {
    8276           0 :                 free_var(&rounded);
    8277           0 :                 return false;
    8278             :             }
    8279             :         }
    8280             :     }
    8281             : 
    8282          36 :     free_var(&rounded);
    8283             : 
    8284          36 :     *result = neg ? -val : val;
    8285          36 :     return true;
    8286             : }
    8287             : 
    8288             : /*
    8289             :  * Convert 128 bit integer to numeric.
    8290             :  */
    8291             : static void
    8292        8558 : int128_to_numericvar(int128 val, NumericVar *var)
    8293             : {
    8294             :     uint128     uval,
    8295             :                 newuval;
    8296             :     NumericDigit *ptr;
    8297             :     int         ndigits;
    8298             : 
    8299             :     /* int128 can require at most 39 decimal digits; add one for safety */
    8300        8558 :     alloc_var(var, 40 / DEC_DIGITS);
    8301        8558 :     if (val < 0)
    8302             :     {
    8303           0 :         var->sign = NUMERIC_NEG;
    8304           0 :         uval = -val;
    8305             :     }
    8306             :     else
    8307             :     {
    8308        8558 :         var->sign = NUMERIC_POS;
    8309        8558 :         uval = val;
    8310             :     }
    8311        8558 :     var->dscale = 0;
    8312        8558 :     if (val == 0)
    8313             :     {
    8314         124 :         var->ndigits = 0;
    8315         124 :         var->weight = 0;
    8316         124 :         return;
    8317             :     }
    8318        8434 :     ptr = var->digits + var->ndigits;
    8319        8434 :     ndigits = 0;
    8320             :     do
    8321             :     {
    8322       44914 :         ptr--;
    8323       44914 :         ndigits++;
    8324       44914 :         newuval = uval / NBASE;
    8325       44914 :         *ptr = uval - newuval * NBASE;
    8326       44914 :         uval = newuval;
    8327       44914 :     } while (uval);
    8328        8434 :     var->digits = ptr;
    8329        8434 :     var->ndigits = ndigits;
    8330        8434 :     var->weight = ndigits - 1;
    8331             : }
    8332             : #endif
    8333             : 
    8334             : /*
    8335             :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    8336             :  */
    8337             : static double
    8338        3466 : numericvar_to_double_no_overflow(const NumericVar *var)
    8339             : {
    8340             :     char       *tmp;
    8341             :     double      val;
    8342             :     char       *endptr;
    8343             : 
    8344        3466 :     tmp = get_str_from_var(var);
    8345             : 
    8346             :     /* unlike float8in, we ignore ERANGE from strtod */
    8347        3466 :     val = strtod(tmp, &endptr);
    8348        3466 :     if (*endptr != '\0')
    8349             :     {
    8350             :         /* shouldn't happen ... */
    8351           0 :         ereport(ERROR,
    8352             :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8353             :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8354             :                         "double precision", tmp)));
    8355             :     }
    8356             : 
    8357        3466 :     pfree(tmp);
    8358             : 
    8359        3466 :     return val;
    8360             : }
    8361             : 
    8362             : 
    8363             : /*
    8364             :  * cmp_var() -
    8365             :  *
    8366             :  *  Compare two values on variable level.  We assume zeroes have been
    8367             :  *  truncated to no digits.
    8368             :  */
    8369             : static int
    8370       49706 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8371             : {
    8372       99412 :     return cmp_var_common(var1->digits, var1->ndigits,
    8373             :                           var1->weight, var1->sign,
    8374       49706 :                           var2->digits, var2->ndigits,
    8375             :                           var2->weight, var2->sign);
    8376             : }
    8377             : 
    8378             : /*
    8379             :  * cmp_var_common() -
    8380             :  *
    8381             :  *  Main routine of cmp_var(). This function can be used by both
    8382             :  *  NumericVar and Numeric.
    8383             :  */
    8384             : static int
    8385     6136478 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8386             :                int var1weight, int var1sign,
    8387             :                const NumericDigit *var2digits, int var2ndigits,
    8388             :                int var2weight, int var2sign)
    8389             : {
    8390     6136478 :     if (var1ndigits == 0)
    8391             :     {
    8392      183784 :         if (var2ndigits == 0)
    8393      155892 :             return 0;
    8394       27892 :         if (var2sign == NUMERIC_NEG)
    8395        4156 :             return 1;
    8396       23736 :         return -1;
    8397             :     }
    8398     5952694 :     if (var2ndigits == 0)
    8399             :     {
    8400       31696 :         if (var1sign == NUMERIC_POS)
    8401       25010 :             return 1;
    8402        6686 :         return -1;
    8403             :     }
    8404             : 
    8405     5920998 :     if (var1sign == NUMERIC_POS)
    8406             :     {
    8407     5833926 :         if (var2sign == NUMERIC_NEG)
    8408       26458 :             return 1;
    8409     5807468 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8410             :                               var2digits, var2ndigits, var2weight);
    8411             :     }
    8412             : 
    8413       87072 :     if (var2sign == NUMERIC_POS)
    8414       28766 :         return -1;
    8415             : 
    8416       58306 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8417             :                           var1digits, var1ndigits, var1weight);
    8418             : }
    8419             : 
    8420             : 
    8421             : /*
    8422             :  * add_var() -
    8423             :  *
    8424             :  *  Full version of add functionality on variable level (handling signs).
    8425             :  *  result might point to one of the operands too without danger.
    8426             :  */
    8427             : static void
    8428      497464 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8429             : {
    8430             :     /*
    8431             :      * Decide on the signs of the two variables what to do
    8432             :      */
    8433      497464 :     if (var1->sign == NUMERIC_POS)
    8434             :     {
    8435      495898 :         if (var2->sign == NUMERIC_POS)
    8436             :         {
    8437             :             /*
    8438             :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8439             :              */
    8440      295744 :             add_abs(var1, var2, result);
    8441      295744 :             result->sign = NUMERIC_POS;
    8442             :         }
    8443             :         else
    8444             :         {
    8445             :             /*
    8446             :              * var1 is positive, var2 is negative Must compare absolute values
    8447             :              */
    8448      200154 :             switch (cmp_abs(var1, var2))
    8449             :             {
    8450         188 :                 case 0:
    8451             :                     /* ----------
    8452             :                      * ABS(var1) == ABS(var2)
    8453             :                      * result = ZERO
    8454             :                      * ----------
    8455             :                      */
    8456         188 :                     zero_var(result);
    8457         188 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8458         188 :                     break;
    8459             : 
    8460      185904 :                 case 1:
    8461             :                     /* ----------
    8462             :                      * ABS(var1) > ABS(var2)
    8463             :                      * result = +(ABS(var1) - ABS(var2))
    8464             :                      * ----------
    8465             :                      */
    8466      185904 :                     sub_abs(var1, var2, result);
    8467      185904 :                     result->sign = NUMERIC_POS;
    8468      185904 :                     break;
    8469             : 
    8470       14062 :                 case -1:
    8471             :                     /* ----------
    8472             :                      * ABS(var1) < ABS(var2)
    8473             :                      * result = -(ABS(var2) - ABS(var1))
    8474             :                      * ----------
    8475             :                      */
    8476       14062 :                     sub_abs(var2, var1, result);
    8477       14062 :                     result->sign = NUMERIC_NEG;
    8478       14062 :                     break;
    8479             :             }
    8480      495898 :         }
    8481             :     }
    8482             :     else
    8483             :     {
    8484        1566 :         if (var2->sign == NUMERIC_POS)
    8485             :         {
    8486             :             /* ----------
    8487             :              * var1 is negative, var2 is positive
    8488             :              * Must compare absolute values
    8489             :              * ----------
    8490             :              */
    8491         468 :             switch (cmp_abs(var1, var2))
    8492             :             {
    8493          30 :                 case 0:
    8494             :                     /* ----------
    8495             :                      * ABS(var1) == ABS(var2)
    8496             :                      * result = ZERO
    8497             :                      * ----------
    8498             :                      */
    8499          30 :                     zero_var(result);
    8500          30 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8501          30 :                     break;
    8502             : 
    8503         294 :                 case 1:
    8504             :                     /* ----------
    8505             :                      * ABS(var1) > ABS(var2)
    8506             :                      * result = -(ABS(var1) - ABS(var2))
    8507             :                      * ----------
    8508             :                      */
    8509         294 :                     sub_abs(var1, var2, result);
    8510         294 :                     result->sign = NUMERIC_NEG;
    8511         294 :                     break;
    8512             : 
    8513         144 :                 case -1:
    8514             :                     /* ----------
    8515             :                      * ABS(var1) < ABS(var2)
    8516             :                      * result = +(ABS(var2) - ABS(var1))
    8517             :                      * ----------
    8518             :                      */
    8519         144 :                     sub_abs(var2, var1, result);
    8520         144 :                     result->sign = NUMERIC_POS;
    8521         144 :                     break;
    8522             :             }
    8523         468 :         }
    8524             :         else
    8525             :         {
    8526             :             /* ----------
    8527             :              * Both are negative
    8528             :              * result = -(ABS(var1) + ABS(var2))
    8529             :              * ----------
    8530             :              */
    8531        1098 :             add_abs(var1, var2, result);
    8532        1098 :             result->sign = NUMERIC_NEG;
    8533             :         }
    8534             :     }
    8535      497464 : }
    8536             : 
    8537             : 
    8538             : /*
    8539             :  * sub_var() -
    8540             :  *
    8541             :  *  Full version of sub functionality on variable level (handling signs).
    8542             :  *  result might point to one of the operands too without danger.
    8543             :  */
    8544             : static void
    8545      186686 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8546             : {
    8547             :     /*
    8548             :      * Decide on the signs of the two variables what to do
    8549             :      */
    8550      186686 :     if (var1->sign == NUMERIC_POS)
    8551             :     {
    8552      183914 :         if (var2->sign == NUMERIC_NEG)
    8553             :         {
    8554             :             /* ----------
    8555             :              * var1 is positive, var2 is negative
    8556             :              * result = +(ABS(var1) + ABS(var2))
    8557             :              * ----------
    8558             :              */
    8559       33254 :             add_abs(var1, var2, result);
    8560       33254 :             result->sign = NUMERIC_POS;
    8561             :         }
    8562             :         else
    8563             :         {
    8564             :             /* ----------
    8565             :              * Both are positive
    8566             :              * Must compare absolute values
    8567             :              * ----------
    8568             :              */
    8569      150660 :             switch (cmp_abs(var1, var2))
    8570             :             {
    8571       29120 :                 case 0:
    8572             :                     /* ----------
    8573             :                      * ABS(var1) == ABS(var2)
    8574             :                      * result = ZERO
    8575             :                      * ----------
    8576             :                      */
    8577       29120 :                     zero_var(result);
    8578       29120 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8579       29120 :                     break;
    8580             : 
    8581      112986 :                 case 1:
    8582             :                     /* ----------
    8583             :                      * ABS(var1) > ABS(var2)
    8584             :                      * result = +(ABS(var1) - ABS(var2))
    8585             :                      * ----------
    8586             :                      */
    8587      112986 :                     sub_abs(var1, var2, result);
    8588      112986 :                     result->sign = NUMERIC_POS;
    8589      112986 :                     break;
    8590             : 
    8591        8554 :                 case -1:
    8592             :                     /* ----------
    8593             :                      * ABS(var1) < ABS(var2)
    8594             :                      * result = -(ABS(var2) - ABS(var1))
    8595             :                      * ----------
    8596             :                      */
    8597        8554 :                     sub_abs(var2, var1, result);
    8598        8554 :                     result->sign = NUMERIC_NEG;
    8599        8554 :                     break;
    8600             :             }
    8601      183914 :         }
    8602             :     }
    8603             :     else
    8604             :     {
    8605        2772 :         if (var2->sign == NUMERIC_NEG)
    8606             :         {
    8607             :             /* ----------
    8608             :              * Both are negative
    8609             :              * Must compare absolute values
    8610             :              * ----------
    8611             :              */
    8612        2322 :             switch (cmp_abs(var1, var2))
    8613             :             {
    8614         166 :                 case 0:
    8615             :                     /* ----------
    8616             :                      * ABS(var1) == ABS(var2)
    8617             :                      * result = ZERO
    8618             :                      * ----------
    8619             :                      */
    8620         166 :                     zero_var(result);
    8621         166 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8622         166 :                     break;
    8623             : 
    8624         240 :                 case 1:
    8625             :                     /* ----------
    8626             :                      * ABS(var1) > ABS(var2)
    8627             :                      * result = -(ABS(var1) - ABS(var2))
    8628             :                      * ----------
    8629             :                      */
    8630         240 :                     sub_abs(var1, var2, result);
    8631         240 :                     result->sign = NUMERIC_NEG;
    8632         240 :                     break;
    8633             : 
    8634        1916 :                 case -1:
    8635             :                     /* ----------
    8636             :                      * ABS(var1) < ABS(var2)
    8637             :                      * result = +(ABS(var2) - ABS(var1))
    8638             :                      * ----------
    8639             :                      */
    8640        1916 :                     sub_abs(var2, var1, result);
    8641        1916 :                     result->sign = NUMERIC_POS;
    8642        1916 :                     break;
    8643             :             }
    8644        2322 :         }
    8645             :         else
    8646             :         {
    8647             :             /* ----------
    8648             :              * var1 is negative, var2 is positive
    8649             :              * result = -(ABS(var1) + ABS(var2))
    8650             :              * ----------
    8651             :              */
    8652         450 :             add_abs(var1, var2, result);
    8653         450 :             result->sign = NUMERIC_NEG;
    8654             :         }
    8655             :     }
    8656      186686 : }
    8657             : 
    8658             : 
    8659             : /*
    8660             :  * mul_var() -
    8661             :  *
    8662             :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8663             :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8664             :  */
    8665             : static void
    8666      829808 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8667             :         int rscale)
    8668             : {
    8669             :     int         res_ndigits;
    8670             :     int         res_ndigitpairs;
    8671             :     int         res_sign;
    8672             :     int         res_weight;
    8673             :     int         pair_offset;
    8674             :     int         maxdigits;
    8675             :     int         maxdigitpairs;
    8676             :     uint64     *dig,
    8677             :                *dig_i1_off;
    8678             :     uint64      maxdig;
    8679             :     uint64      carry;
    8680             :     uint64      newdig;
    8681             :     int         var1ndigits;
    8682             :     int         var2ndigits;
    8683             :     int         var1ndigitpairs;
    8684             :     int         var2ndigitpairs;
    8685             :     NumericDigit *var1digits;
    8686             :     NumericDigit *var2digits;
    8687             :     uint32      var1digitpair;
    8688             :     uint32     *var2digitpairs;
    8689             :     NumericDigit *res_digits;
    8690             :     int         i,
    8691             :                 i1,
    8692             :                 i2,
    8693             :                 i2limit;
    8694             : 
    8695             :     /*
    8696             :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8697             :      * performance because the inner multiplication loop is much simpler than
    8698             :      * the outer loop, so it's better to have a smaller number of iterations
    8699             :      * of the outer loop.  This also reduces the number of times that the
    8700             :      * accumulator array needs to be normalized.
    8701             :      */
    8702      829808 :     if (var1->ndigits > var2->ndigits)
    8703             :     {
    8704       14052 :         const NumericVar *tmp = var1;
    8705             : 
    8706       14052 :         var1 = var2;
    8707       14052 :         var2 = tmp;
    8708             :     }
    8709             : 
    8710             :     /* copy these values into local vars for speed in inner loop */
    8711      829808 :     var1ndigits = var1->ndigits;
    8712      829808 :     var2ndigits = var2->ndigits;
    8713      829808 :     var1digits = var1->digits;
    8714      829808 :     var2digits = var2->digits;
    8715             : 
    8716      829808 :     if (var1ndigits == 0)
    8717             :     {
    8718             :         /* one or both inputs is zero; so is result */
    8719        1712 :         zero_var(result);
    8720        1712 :         result->dscale = rscale;
    8721        1712 :         return;
    8722             :     }
    8723             : 
    8724             :     /*
    8725             :      * If var1 has 1-6 digits and the exact result was requested, delegate to
    8726             :      * mul_var_short() which uses a faster direct multiplication algorithm.
    8727             :      */
    8728      828096 :     if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
    8729             :     {
    8730      799620 :         mul_var_short(var1, var2, result);
    8731      799620 :         return;
    8732             :     }
    8733             : 
    8734             :     /* Determine result sign */
    8735       28476 :     if (var1->sign == var2->sign)
    8736       26994 :         res_sign = NUMERIC_POS;
    8737             :     else
    8738        1482 :         res_sign = NUMERIC_NEG;
    8739             : 
    8740             :     /*
    8741             :      * Determine the number of result digits to compute and the (maximum
    8742             :      * possible) result weight.  If the exact result would have more than
    8743             :      * rscale fractional digits, truncate the computation with
    8744             :      * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
    8745             :      * only contribute to the right of that.  (This will give the exact
    8746             :      * rounded-to-rscale answer unless carries out of the ignored positions
    8747             :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8748             :      *
    8749             :      * Note: an exact computation could not produce more than var1ndigits +
    8750             :      * var2ndigits digits, but we allocate at least one extra output digit in
    8751             :      * case rscale-driven rounding produces a carry out of the highest exact
    8752             :      * digit.
    8753             :      *
    8754             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    8755             :      * actually process the input digits in pairs, producing a base-NBASE^2
    8756             :      * intermediate result.  This significantly improves performance, since
    8757             :      * schoolbook multiplication is O(N^2) in the number of input digits, and
    8758             :      * working in base NBASE^2 effectively halves "N".
    8759             :      *
    8760             :      * Note: in a truncated computation, we must compute at least one extra
    8761             :      * output digit to ensure that all the guard digits are fully computed.
    8762             :      */
    8763             :     /* digit pairs in each input */
    8764       28476 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    8765       28476 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    8766             : 
    8767             :     /* digits in exact result */
    8768       28476 :     res_ndigits = var1ndigits + var2ndigits;
    8769             : 
    8770             :     /* digit pairs in exact result with at least one extra output digit */
    8771       28476 :     res_ndigitpairs = res_ndigits / 2 + 1;
    8772             : 
    8773             :     /* pair offset to align result to end of dig[] */
    8774       28476 :     pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
    8775             : 
    8776             :     /* maximum possible result weight (odd-length inputs shifted up below) */
    8777       28476 :     res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
    8778       28476 :         res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
    8779             : 
    8780             :     /* rscale-based truncation with at least one extra output digit */
    8781       28476 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8782             :         MUL_GUARD_DIGITS;
    8783       28476 :     maxdigitpairs = maxdigits / 2 + 1;
    8784             : 
    8785       28476 :     res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
    8786       28476 :     res_ndigits = 2 * res_ndigitpairs;
    8787             : 
    8788             :     /*
    8789             :      * In the computation below, digit pair i1 of var1 and digit pair i2 of
    8790             :      * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
    8791             :      * input digit pairs with index >= res_ndigitpairs - pair_offset don't
    8792             :      * contribute to the result, and can be ignored.
    8793             :      */
    8794       28476 :     if (res_ndigitpairs <= pair_offset)
    8795             :     {
    8796             :         /* All input digits will be ignored; so result is zero */
    8797          12 :         zero_var(result);
    8798          12 :         result->dscale = rscale;
    8799          12 :         return;
    8800             :     }
    8801       28464 :     var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
    8802       28464 :     var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
    8803             : 
    8804             :     /*
    8805             :      * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
    8806             :      * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
    8807             :      * headroom to avoid normalizing carries immediately.
    8808             :      *
    8809             :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8810             :      * threatens to exceed PG_UINT64_MAX, we take the time to propagate
    8811             :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    8812             :      * during the carry propagation passes either.  The carry values could be
    8813             :      * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
    8814             :      * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
    8815             :      *
    8816             :      * To avoid overflow in maxdig itself, it actually represents the maximum
    8817             :      * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
    8818             :      * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
    8819             :      *
    8820             :      * The conversion of var1 to base NBASE^2 is done on the fly, as each new
    8821             :      * digit is required.  The digits of var2 are converted upfront, and
    8822             :      * stored at the end of dig[].  To avoid loss of precision, the input
    8823             :      * digits are aligned with the start of digit pair array, effectively
    8824             :      * shifting them up (multiplying by NBASE) if the inputs have an odd
    8825             :      * number of NBASE digits.
    8826             :      */
    8827       28464 :     dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
    8828             :                             var2ndigitpairs * sizeof(uint32));
    8829             : 
    8830             :     /* convert var2 to base NBASE^2, shifting up if its length is odd */
    8831       28464 :     var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
    8832             : 
    8833     1547190 :     for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
    8834     1518726 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8835             : 
    8836       28464 :     if (2 * i2 + 1 < var2ndigits)
    8837       20448 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8838             :     else
    8839        8016 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
    8840             : 
    8841             :     /*
    8842             :      * Start by multiplying var2 by the least significant contributing digit
    8843             :      * pair from var1, storing the results at the end of dig[], and filling
    8844             :      * the leading digits with zeros.
    8845             :      *
    8846             :      * The loop here is the same as the inner loop below, except that we set
    8847             :      * the results in dig[], rather than adding to them.  This is the
    8848             :      * performance bottleneck for multiplication, so we want to keep it simple
    8849             :      * enough so that it can be auto-vectorized.  Accordingly, process the
    8850             :      * digits left-to-right even though schoolbook multiplication would
    8851             :      * suggest right-to-left.  Since we aren't propagating carries in this
    8852             :      * loop, the order does not matter.
    8853             :      */
    8854       28464 :     i1 = var1ndigitpairs - 1;
    8855       28464 :     if (2 * i1 + 1 < var1ndigits)
    8856       12720 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8857             :     else
    8858       15744 :         var1digitpair = var1digits[2 * i1] * NBASE;
    8859       28464 :     maxdig = var1digitpair;
    8860             : 
    8861       28464 :     i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8862       28464 :     dig_i1_off = &dig[i1 + pair_offset];
    8863             : 
    8864       28464 :     memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
    8865     1376622 :     for (i2 = 0; i2 < i2limit; i2++)
    8866     1348158 :         dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
    8867             : 
    8868             :     /*
    8869             :      * Next, multiply var2 by the remaining digit pairs from var1, adding the
    8870             :      * results to dig[] at the appropriate offsets, and normalizing whenever
    8871             :      * there is a risk of any dig[] entry overflowing.
    8872             :      */
    8873     1501710 :     for (i1 = i1 - 1; i1 >= 0; i1--)
    8874             :     {
    8875     1473246 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8876     1473246 :         if (var1digitpair == 0)
    8877     1179516 :             continue;
    8878             : 
    8879             :         /* Time to normalize? */
    8880      293730 :         maxdig += var1digitpair;
    8881      293730 :         if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
    8882             :         {
    8883             :             /* Yes, do it (to base NBASE^2) */
    8884          30 :             carry = 0;
    8885      119964 :             for (i = res_ndigitpairs - 1; i >= 0; i--)
    8886             :             {
    8887      119934 :                 newdig = dig[i] + carry;
    8888      119934 :                 if (newdig >= NBASE_SQR)
    8889             :                 {
    8890      115242 :                     carry = newdig / NBASE_SQR;
    8891      115242 :                     newdig -= carry * NBASE_SQR;
    8892             :                 }
    8893             :                 else
    8894        4692 :                     carry = 0;
    8895      119934 :                 dig[i] = newdig;
    8896             :             }
    8897             :             Assert(carry == 0);
    8898             :             /* Reset maxdig to indicate new worst-case */
    8899          30 :             maxdig = 1 + var1digitpair;
    8900             :         }
    8901             : 
    8902             :         /* Multiply and add */
    8903      293730 :         i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8904      293730 :         dig_i1_off = &dig[i1 + pair_offset];
    8905             : 
    8906   124047846 :         for (i2 = 0; i2 < i2limit; i2++)
    8907   123754116 :             dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
    8908             :     }
    8909             : 
    8910             :     /*
    8911             :      * Now we do a final carry propagation pass to normalize back to base
    8912             :      * NBASE^2, and construct the base-NBASE result digits.  Note that this is
    8913             :      * still done at full precision w/guard digits.
    8914             :      */
    8915       28464 :     alloc_var(result, res_ndigits);
    8916       28464 :     res_digits = result->digits;
    8917       28464 :     carry = 0;
    8918     2882922 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    8919             :     {
    8920     2854458 :         newdig = dig[i] + carry;
    8921     2854458 :         if (newdig >= NBASE_SQR)
    8922             :         {
    8923      406914 :             carry = newdig / NBASE_SQR;
    8924      406914 :             newdig -= carry * NBASE_SQR;
    8925             :         }
    8926             :         else
    8927     2447544 :             carry = 0;
    8928     2854458 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    8929     2854458 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    8930             :     }
    8931             :     Assert(carry == 0);
    8932             : 
    8933       28464 :     pfree(dig);
    8934             : 
    8935             :     /*
    8936             :      * Finally, round the result to the requested precision.
    8937             :      */
    8938       28464 :     result->weight = res_weight;
    8939       28464 :     result->sign = res_sign;
    8940             : 
    8941             :     /* Round to target rscale (and set result->dscale) */
    8942       28464 :     round_var(result, rscale);
    8943             : 
    8944             :     /* Strip leading and trailing zeroes */
    8945       28464 :     strip_var(result);
    8946             : }
    8947             : 
    8948             : 
    8949             : /*
    8950             :  * mul_var_short() -
    8951             :  *
    8952             :  *  Special-case multiplication function used when var1 has 1-6 digits, var2
    8953             :  *  has at least as many digits as var1, and the exact product var1 * var2 is
    8954             :  *  requested.
    8955             :  */
    8956             : static void
    8957      799620 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
    8958             :               NumericVar *result)
    8959             : {
    8960      799620 :     int         var1ndigits = var1->ndigits;
    8961      799620 :     int         var2ndigits = var2->ndigits;
    8962      799620 :     NumericDigit *var1digits = var1->digits;
    8963      799620 :     NumericDigit *var2digits = var2->digits;
    8964             :     int         res_sign;
    8965             :     int         res_weight;
    8966             :     int         res_ndigits;
    8967             :     NumericDigit *res_buf;
    8968             :     NumericDigit *res_digits;
    8969      799620 :     uint32      carry = 0;
    8970             :     uint32      term;
    8971             : 
    8972             :     /* Check preconditions */
    8973             :     Assert(var1ndigits >= 1);
    8974             :     Assert(var1ndigits <= 6);
    8975             :     Assert(var2ndigits >= var1ndigits);
    8976             : 
    8977             :     /*
    8978             :      * Determine the result sign, weight, and number of digits to calculate.
    8979             :      * The weight figured here is correct if the product has no leading zero
    8980             :      * digits; otherwise strip_var() will fix things up.  Note that, unlike
    8981             :      * mul_var(), we do not need to allocate an extra output digit, because we
    8982             :      * are not rounding here.
    8983             :      */
    8984      799620 :     if (var1->sign == var2->sign)
    8985      798428 :         res_sign = NUMERIC_POS;
    8986             :     else
    8987        1192 :         res_sign = NUMERIC_NEG;
    8988      799620 :     res_weight = var1->weight + var2->weight + 1;
    8989      799620 :     res_ndigits = var1ndigits + var2ndigits;
    8990             : 
    8991             :     /* Allocate result digit array */
    8992      799620 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    8993      799620 :     res_buf[0] = 0;             /* spare digit for later rounding */
    8994      799620 :     res_digits = res_buf + 1;
    8995             : 
    8996             :     /*
    8997             :      * Compute the result digits in reverse, in one pass, propagating the
    8998             :      * carry up as we go.  The i'th result digit consists of the sum of the
    8999             :      * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
    9000             :      */
    9001             : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
    9002             : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
    9003             : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
    9004             : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
    9005             : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
    9006             : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
    9007             : 
    9008      799620 :     switch (var1ndigits)
    9009             :     {
    9010      793914 :         case 1:
    9011             :             /* ---------
    9012             :              * 1-digit case:
    9013             :              *      var1ndigits = 1
    9014             :              *      var2ndigits >= 1
    9015             :              *      res_ndigits = var2ndigits + 1
    9016             :              * ----------
    9017             :              */
    9018     2887628 :             for (int i = var2ndigits - 1; i >= 0; i--)
    9019             :             {
    9020     2093714 :                 term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
    9021     2093714 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9022     2093714 :                 carry = term / NBASE;
    9023             :             }
    9024      793914 :             res_digits[0] = (NumericDigit) carry;
    9025      793914 :             break;
    9026             : 
    9027         756 :         case 2:
    9028             :             /* ---------
    9029             :              * 2-digit case:
    9030             :              *      var1ndigits = 2
    9031             :              *      var2ndigits >= 2
    9032             :              *      res_ndigits = var2ndigits + 2
    9033             :              * ----------
    9034             :              */
    9035             :             /* last result digit and carry */
    9036         756 :             term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
    9037         756 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9038         756 :             carry = term / NBASE;
    9039             : 
    9040             :             /* remaining digits, except for the first two */
    9041        2304 :             for (int i = var2ndigits - 1; i >= 1; i--)
    9042             :             {
    9043        1548 :                 term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
    9044        1548 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9045        1548 :                 carry = term / NBASE;
    9046             :             }
    9047         756 :             break;
    9048             : 
    9049         204 :         case 3:
    9050             :             /* ---------
    9051             :              * 3-digit case:
    9052             :              *      var1ndigits = 3
    9053             :              *      var2ndigits >= 3
    9054             :              *      res_ndigits = var2ndigits + 3
    9055             :              * ----------
    9056             :              */
    9057             :             /* last two result digits */
    9058         204 :             term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
    9059         204 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9060         204 :             carry = term / NBASE;
    9061             : 
    9062         204 :             term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9063         204 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9064         204 :             carry = term / NBASE;
    9065             : 
    9066             :             /* remaining digits, except for the first three */
    9067         546 :             for (int i = var2ndigits - 1; i >= 2; i--)
    9068             :             {
    9069         342 :                 term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
    9070         342 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9071         342 :                 carry = term / NBASE;
    9072             :             }
    9073         204 :             break;
    9074             : 
    9075        4038 :         case 4:
    9076             :             /* ---------
    9077             :              * 4-digit case:
    9078             :              *      var1ndigits = 4
    9079             :              *      var2ndigits >= 4
    9080             :              *      res_ndigits = var2ndigits + 4
    9081             :              * ----------
    9082             :              */
    9083             :             /* last three result digits */
    9084        4038 :             term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
    9085        4038 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9086        4038 :             carry = term / NBASE;
    9087             : 
    9088        4038 :             term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9089        4038 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9090        4038 :             carry = term / NBASE;
    9091             : 
    9092        4038 :             term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9093        4038 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9094        4038 :             carry = term / NBASE;
    9095             : 
    9096             :             /* remaining digits, except for the first four */
    9097       11268 :             for (int i = var2ndigits - 1; i >= 3; i--)
    9098             :             {
    9099        7230 :                 term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
    9100        7230 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9101        7230 :                 carry = term / NBASE;
    9102             :             }
    9103        4038 :             break;
    9104             : 
    9105         114 :         case 5:
    9106             :             /* ---------
    9107             :              * 5-digit case:
    9108             :              *      var1ndigits = 5
    9109             :              *      var2ndigits >= 5
    9110             :              *      res_ndigits = var2ndigits + 5
    9111             :              * ----------
    9112             :              */
    9113             :             /* last four result digits */
    9114         114 :             term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
    9115         114 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9116         114 :             carry = term / NBASE;
    9117             : 
    9118         114 :             term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    9119         114 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9120         114 :             carry = term / NBASE;
    9121             : 
    9122         114 :             term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9123         114 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9124         114 :             carry = term / NBASE;
    9125             : 
    9126         114 :             term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9127         114 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    9128         114 :             carry = term / NBASE;
    9129             : 
    9130             :             /* remaining digits, except for the first five */
    9131         300 :             for (int i = var2ndigits - 1; i >= 4; i--)
    9132             :             {
    9133         186 :                 term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
    9134         186 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9135         186 :                 carry = term / NBASE;
    9136             :             }
    9137         114 :             break;
    9138             : 
    9139         594 :         case 6:
    9140             :             /* ---------
    9141             :              * 6-digit case:
    9142             :              *      var1ndigits = 6
    9143             :              *      var2ndigits >= 6
    9144             :              *      res_ndigits = var2ndigits + 6
    9145             :              * ----------
    9146             :              */
    9147             :             /* last five result digits */
    9148         594 :             term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
    9149         594 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9150         594 :             carry = term / NBASE;
    9151             : 
    9152         594 :             term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
    9153         594 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9154         594 :             carry = term / NBASE;
    9155             : 
    9156         594 :             term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    9157         594 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9158         594 :             carry = term / NBASE;
    9159             : 
    9160         594 :             term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9161         594 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    9162         594 :             carry = term / NBASE;
    9163             : 
    9164         594 :             term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9165         594 :             res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
    9166         594 :             carry = term / NBASE;
    9167             : 
    9168             :             /* remaining digits, except for the first six */
    9169        1656 :             for (int i = var2ndigits - 1; i >= 5; i--)
    9170             :             {
    9171        1062 :                 term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
    9172        1062 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9173        1062 :                 carry = term / NBASE;
    9174             :             }
    9175         594 :             break;
    9176             :     }
    9177             : 
    9178             :     /*
    9179             :      * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
    9180             :      * significant result digits.
    9181             :      */
    9182      799620 :     switch (var1ndigits)
    9183             :     {
    9184         594 :         case 6:
    9185         594 :             term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
    9186         594 :             res_digits[5] = (NumericDigit) (term % NBASE);
    9187         594 :             carry = term / NBASE;
    9188             :             /* FALLTHROUGH */
    9189         708 :         case 5:
    9190         708 :             term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
    9191         708 :             res_digits[4] = (NumericDigit) (term % NBASE);
    9192         708 :             carry = term / NBASE;
    9193             :             /* FALLTHROUGH */
    9194        4746 :         case 4:
    9195        4746 :             term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
    9196        4746 :             res_digits[3] = (NumericDigit) (term % NBASE);
    9197        4746 :             carry = term / NBASE;
    9198             :             /* FALLTHROUGH */
    9199        4950 :         case 3:
    9200        4950 :             term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
    9201        4950 :             res_digits[2] = (NumericDigit) (term % NBASE);
    9202        4950 :             carry = term / NBASE;
    9203             :             /* FALLTHROUGH */
    9204        5706 :         case 2:
    9205        5706 :             term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
    9206        5706 :             res_digits[1] = (NumericDigit) (term % NBASE);
    9207        5706 :             res_digits[0] = (NumericDigit) (term / NBASE);
    9208        5706 :             break;
    9209             :     }
    9210             : 
    9211             :     /* Store the product in result */
    9212      799620 :     digitbuf_free(result->buf);
    9213      799620 :     result->ndigits = res_ndigits;
    9214      799620 :     result->buf = res_buf;
    9215      799620 :     result->digits = res_digits;
    9216      799620 :     result->weight = res_weight;
    9217      799620 :     result->sign = res_sign;
    9218      799620 :     result->dscale = var1->dscale + var2->dscale;
    9219             : 
    9220             :     /* Strip leading and trailing zeroes */
    9221      799620 :     strip_var(result);
    9222      799620 : }
    9223             : 
    9224             : 
    9225             : /*
    9226             :  * div_var() -
    9227             :  *
    9228             :  *  Compute the quotient var1 / var2 to rscale fractional digits.
    9229             :  *
    9230             :  *  If "round" is true, the result is rounded at the rscale'th digit; if
    9231             :  *  false, it is truncated (towards zero) at that digit.
    9232             :  *
    9233             :  *  If "exact" is true, the exact result is computed to the specified rscale;
    9234             :  *  if false, successive quotient digits are approximated up to rscale plus
    9235             :  *  DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
    9236             :  *  the right of that, before rounding or truncating to the specified rscale.
    9237             :  *  This can be significantly faster, and usually gives the same result as the
    9238             :  *  exact computation, but it may occasionally be off by one in the final
    9239             :  *  digit, if contributions from the ignored digits would have propagated
    9240             :  *  through the guard digits.  This is good enough for the transcendental
    9241             :  *  functions, where small errors are acceptable.
    9242             :  */
    9243             : static void
    9244      214194 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    9245             :         int rscale, bool round, bool exact)
    9246             : {
    9247      214194 :     int         var1ndigits = var1->ndigits;
    9248      214194 :     int         var2ndigits = var2->ndigits;
    9249             :     int         res_sign;
    9250             :     int         res_weight;
    9251             :     int         res_ndigits;
    9252             :     int         var1ndigitpairs;
    9253             :     int         var2ndigitpairs;
    9254             :     int         res_ndigitpairs;
    9255             :     int         div_ndigitpairs;
    9256             :     int64      *dividend;
    9257             :     int32      *divisor;
    9258             :     double      fdivisor,
    9259             :                 fdivisorinverse,
    9260             :                 fdividend,
    9261             :                 fquotient;
    9262             :     int64       maxdiv;
    9263             :     int         qi;
    9264             :     int32       qdigit;
    9265             :     int64       carry;
    9266             :     int64       newdig;
    9267             :     int64      *remainder;
    9268             :     NumericDigit *res_digits;
    9269             :     int         i;
    9270             : 
    9271             :     /*
    9272             :      * First of all division by zero check; we must not be handed an
    9273             :      * unnormalized divisor.
    9274             :      */
    9275      214194 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    9276          62 :         ereport(ERROR,
    9277             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    9278             :                  errmsg("division by zero")));
    9279             : 
    9280             :     /*
    9281             :      * If the divisor has just one or two digits, delegate to div_var_int(),
    9282             :      * which uses fast short division.
    9283             :      *
    9284             :      * Similarly, on platforms with 128-bit integer support, delegate to
    9285             :      * div_var_int64() for divisors with three or four digits.
    9286             :      */
    9287      214132 :     if (var2ndigits <= 2)
    9288             :     {
    9289             :         int         idivisor;
    9290             :         int         idivisor_weight;
    9291             : 
    9292      205054 :         idivisor = var2->digits[0];
    9293      205054 :         idivisor_weight = var2->weight;
    9294      205054 :         if (var2ndigits == 2)
    9295             :         {
    9296        3914 :             idivisor = idivisor * NBASE + var2->digits[1];
    9297        3914 :             idivisor_weight--;
    9298             :         }
    9299      205054 :         if (var2->sign == NUMERIC_NEG)
    9300         642 :             idivisor = -idivisor;
    9301             : 
    9302      205054 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    9303      205054 :         return;
    9304             :     }
    9305             : #ifdef HAVE_INT128
    9306        9078 :     if (var2ndigits <= 4)
    9307             :     {
    9308             :         int64       idivisor;
    9309             :         int         idivisor_weight;
    9310             : 
    9311         546 :         idivisor = var2->digits[0];
    9312         546 :         idivisor_weight = var2->weight;
    9313        2040 :         for (i = 1; i < var2ndigits; i++)
    9314             :         {
    9315        1494 :             idivisor = idivisor * NBASE + var2->digits[i];
    9316        1494 :             idivisor_weight--;
    9317             :         }
    9318         546 :         if (var2->sign == NUMERIC_NEG)
    9319         120 :             idivisor = -idivisor;
    9320             : 
    9321         546 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    9322         546 :         return;
    9323             :     }
    9324             : #endif
    9325             : 
    9326             :     /*
    9327             :      * Otherwise, perform full long division.
    9328             :      */
    9329             : 
    9330             :     /* Result zero check */
    9331        8532 :     if (var1ndigits == 0)
    9332             :     {
    9333          36 :         zero_var(result);
    9334          36 :         result->dscale = rscale;
    9335          36 :         return;
    9336             :     }
    9337             : 
    9338             :     /*
    9339             :      * The approximate computation can be significantly faster than the exact
    9340             :      * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
    9341             :      * shorter below.  However, that comes with the tradeoff of computing
    9342             :      * DIV_GUARD_DIGITS extra base-NBASE result digits.  Ignoring all other
    9343             :      * overheads, that suggests that, in theory, the approximate computation
    9344             :      * will only be faster than the exact one when var2ndigits is greater than
    9345             :      * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
    9346             :      *
    9347             :      * Thus, we're better off doing an exact computation when var2 is shorter
    9348             :      * than this.  Empirically, it has been found that the exact threshold is
    9349             :      * a little higher, due to other overheads in the outer division loop.
    9350             :      */
    9351        8496 :     if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
    9352        5630 :         exact = true;
    9353             : 
    9354             :     /*
    9355             :      * Determine the result sign, weight and number of digits to calculate.
    9356             :      * The weight figured here is correct if the emitted quotient has no
    9357             :      * leading zero digits; otherwise strip_var() will fix things up.
    9358             :      */
    9359        8496 :     if (var1->sign == var2->sign)
    9360        8364 :         res_sign = NUMERIC_POS;
    9361             :     else
    9362         132 :         res_sign = NUMERIC_NEG;
    9363        8496 :     res_weight = var1->weight - var2->weight + 1;
    9364             :     /* The number of accurate result digits we need to produce: */
    9365        8496 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9366             :     /* ... but always at least 1 */
    9367        8496 :     res_ndigits = Max(res_ndigits, 1);
    9368             :     /* If rounding needed, figure one more digit to ensure correct result */
    9369        8496 :     if (round)
    9370        3960 :         res_ndigits++;
    9371             :     /* Add guard digits for roundoff error when producing approx result */
    9372        8496 :     if (!exact)
    9373        1722 :         res_ndigits += DIV_GUARD_DIGITS;
    9374             : 
    9375             :     /*
    9376             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    9377             :      * actually process the input digits in pairs, producing a base-NBASE^2
    9378             :      * intermediate result.  This significantly improves performance, since
    9379             :      * the computation is O(N^2) in the number of input digits, and working in
    9380             :      * base NBASE^2 effectively halves "N".
    9381             :      */
    9382        8496 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    9383        8496 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    9384        8496 :     res_ndigitpairs = (res_ndigits + 1) / 2;
    9385        8496 :     res_ndigits = 2 * res_ndigitpairs;
    9386             : 
    9387             :     /*
    9388             :      * We do the arithmetic in an array "dividend[]" of signed 64-bit
    9389             :      * integers.  Since PG_INT64_MAX is much larger than NBASE^4, this gives
    9390             :      * us a lot of headroom to avoid normalizing carries immediately.
    9391             :      *
    9392             :      * When performing an exact computation, the working dividend requires
    9393             :      * res_ndigitpairs + var2ndigitpairs digits.  If var1 is larger than that,
    9394             :      * the extra digits do not contribute to the result, and are ignored.
    9395             :      *
    9396             :      * When performing an approximate computation, the working dividend only
    9397             :      * requires res_ndigitpairs digits (which includes the extra guard
    9398             :      * digits).  All input digits beyond that are ignored.
    9399             :      */
    9400        8496 :     if (exact)
    9401             :     {
    9402        6774 :         div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
    9403        6774 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9404             :     }
    9405             :     else
    9406             :     {
    9407        1722 :         div_ndigitpairs = res_ndigitpairs;
    9408        1722 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9409        1722 :         var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
    9410             :     }
    9411             : 
    9412             :     /*
    9413             :      * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
    9414             :      * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
    9415             :      *
    9416             :      * For convenience, we allocate one extra dividend digit, which is set to
    9417             :      * zero and not counted in div_ndigitpairs, so that the main loop below
    9418             :      * can safely read and write the (qi+1)'th digit in the approximate case.
    9419             :      */
    9420        8496 :     dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
    9421             :                                 var2ndigitpairs * sizeof(int32));
    9422        8496 :     divisor = (int32 *) (dividend + div_ndigitpairs + 1);
    9423             : 
    9424             :     /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
    9425       60342 :     for (i = 0; i < var1ndigitpairs - 1; i++)
    9426       51846 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9427             : 
    9428        8496 :     if (2 * i + 1 < var1ndigits)
    9429        4846 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9430             :     else
    9431        3650 :         dividend[i] = var1->digits[2 * i] * NBASE;
    9432             : 
    9433        8496 :     memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
    9434             : 
    9435             :     /* load var2 into divisor[0 .. var2ndigitpairs-1] */
    9436      107304 :     for (i = 0; i < var2ndigitpairs - 1; i++)
    9437       98808 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9438             : 
    9439        8496 :     if (2 * i + 1 < var2ndigits)
    9440        2956 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9441             :     else
    9442        5540 :         divisor[i] = var2->digits[2 * i] * NBASE;
    9443             : 
    9444             :     /*
    9445             :      * We estimate each quotient digit using floating-point arithmetic, taking
    9446             :      * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
    9447             :      * This must be float to avoid overflow.
    9448             :      *
    9449             :      * Since the floating-point dividend and divisor use 4 base-NBASE input
    9450             :      * digits, they include roughly 40-53 bits of information from their
    9451             :      * respective inputs (assuming NBASE is 10000), which fits well in IEEE
    9452             :      * double-precision variables.  The relative error in the floating-point
    9453             :      * quotient digit will then be less than around 2/NBASE^3, so the
    9454             :      * estimated base-NBASE^2 quotient digit will typically be correct, and
    9455             :      * should not be off by more than one from the correct value.
    9456             :      */
    9457        8496 :     fdivisor = (double) divisor[0] * NBASE_SQR;
    9458        8496 :     if (var2ndigitpairs > 1)
    9459        8496 :         fdivisor += (double) divisor[1];
    9460        8496 :     fdivisorinverse = 1.0 / fdivisor;
    9461             : 
    9462             :     /*
    9463             :      * maxdiv tracks the maximum possible absolute value of any dividend[]
    9464             :      * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
    9465             :      * propagate carries.  Furthermore, we need to ensure that overflow
    9466             :      * doesn't occur during the carry propagation passes either.  The carry
    9467             :      * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
    9468             :      * so really we must normalize when digits threaten to exceed PG_INT64_MAX
    9469             :      * - PG_INT64_MAX/NBASE^2 - 1.
    9470             :      *
    9471             :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9472             :      * value divided by NBASE^2-1, i.e., at the top of the loop it is known
    9473             :      * that no dividend[] entry has an absolute value exceeding maxdiv *
    9474             :      * (NBASE^2-1).
    9475             :      *
    9476             :      * Actually, though, that holds good only for dividend[] entries after
    9477             :      * dividend[qi]; the adjustment done at the bottom of the loop may cause
    9478             :      * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
    9479             :      * the next iteration is beyond the limit.  This does not cause problems,
    9480             :      * as explained below.
    9481             :      */
    9482        8496 :     maxdiv = 1;
    9483             : 
    9484             :     /*
    9485             :      * Outer loop computes next quotient digit, which goes in dividend[qi].
    9486             :      */
    9487       64896 :     for (qi = 0; qi < res_ndigitpairs; qi++)
    9488             :     {
    9489             :         /* Approximate the current dividend value */
    9490       56400 :         fdividend = (double) dividend[qi] * NBASE_SQR;
    9491       56400 :         fdividend += (double) dividend[qi + 1];
    9492             : 
    9493             :         /* Compute the (approximate) quotient digit */
    9494       56400 :         fquotient = fdividend * fdivisorinverse;
    9495       56400 :         qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9496           6 :             (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9497             : 
    9498       56400 :         if (qdigit != 0)
    9499             :         {
    9500             :             /* Do we need to normalize now? */
    9501       50176 :             maxdiv += i64abs(qdigit);
    9502       50176 :             if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
    9503             :             {
    9504             :                 /*
    9505             :                  * Yes, do it.  Note that if var2ndigitpairs is much smaller
    9506             :                  * than div_ndigitpairs, we can save a significant amount of
    9507             :                  * effort here by noting that we only need to normalise those
    9508             :                  * dividend[] entries touched where prior iterations
    9509             :                  * subtracted multiples of the divisor.
    9510             :                  */
    9511           6 :                 carry = 0;
    9512        6750 :                 for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
    9513             :                 {
    9514        6744 :                     newdig = dividend[i] + carry;
    9515        6744 :                     if (newdig < 0)
    9516             :                     {
    9517        6744 :                         carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9518        6744 :                         newdig -= carry * NBASE_SQR;
    9519             :                     }
    9520           0 :                     else if (newdig >= NBASE_SQR)
    9521             :                     {
    9522           0 :                         carry = newdig / NBASE_SQR;
    9523           0 :                         newdig -= carry * NBASE_SQR;
    9524             :                     }
    9525             :                     else
    9526           0 :                         carry = 0;
    9527        6744 :                     dividend[i] = newdig;
    9528             :                 }
    9529           6 :                 dividend[qi] += carry;
    9530             : 
    9531             :                 /*
    9532             :                  * All the dividend[] digits except possibly dividend[qi] are
    9533             :                  * now in the range 0..NBASE^2-1.  We do not need to consider
    9534             :                  * dividend[qi] in the maxdiv value anymore, so we can reset
    9535             :                  * maxdiv to 1.
    9536             :                  */
    9537           6 :                 maxdiv = 1;
    9538             : 
    9539             :                 /*
    9540             :                  * Recompute the quotient digit since new info may have
    9541             :                  * propagated into the top two dividend digits.
    9542             :                  */
    9543           6 :                 fdividend = (double) dividend[qi] * NBASE_SQR;
    9544           6 :                 fdividend += (double) dividend[qi + 1];
    9545           6 :                 fquotient = fdividend * fdivisorinverse;
    9546           6 :                 qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9547           0 :                     (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9548             : 
    9549           6 :                 maxdiv += i64abs(qdigit);
    9550             :             }
    9551             : 
    9552             :             /*
    9553             :              * Subtract off the appropriate multiple of the divisor.
    9554             :              *
    9555             :              * The digits beyond dividend[qi] cannot overflow, because we know
    9556             :              * they will fall within the maxdiv limit.  As for dividend[qi]
    9557             :              * itself, note that qdigit is approximately trunc(dividend[qi] /
    9558             :              * divisor[0]), which would make the new value simply dividend[qi]
    9559             :              * mod divisor[0].  The lower-order terms in qdigit can change
    9560             :              * this result by not more than about twice PG_INT64_MAX/NBASE^2,
    9561             :              * so overflow is impossible.
    9562             :              *
    9563             :              * This inner loop is the performance bottleneck for division, so
    9564             :              * code it in the same way as the inner loop of mul_var() so that
    9565             :              * it can be auto-vectorized.
    9566             :              */
    9567       50176 :             if (qdigit != 0)
    9568             :             {
    9569       50176 :                 int         istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
    9570       50176 :                 int64      *dividend_qi = &dividend[qi];
    9571             : 
    9572     8073828 :                 for (i = 0; i < istop; i++)
    9573     8023652 :                     dividend_qi[i] -= (int64) qdigit * divisor[i];
    9574             :             }
    9575             :         }
    9576             : 
    9577             :         /*
    9578             :          * The dividend digit we are about to replace might still be nonzero.
    9579             :          * Fold it into the next digit position.
    9580             :          *
    9581             :          * There is no risk of overflow here, although proving that requires
    9582             :          * some care.  Much as with the argument for dividend[qi] not
    9583             :          * overflowing, if we consider the first two terms in the numerator
    9584             :          * and denominator of qdigit, we can see that the final value of
    9585             :          * dividend[qi + 1] will be approximately a remainder mod
    9586             :          * (divisor[0]*NBASE^2 + divisor[1]).  Accounting for the lower-order
    9587             :          * terms is a bit complicated but ends up adding not much more than
    9588             :          * PG_INT64_MAX/NBASE^2 to the possible range.  Thus, dividend[qi + 1]
    9589             :          * cannot overflow here, and in its role as dividend[qi] in the next
    9590             :          * loop iteration, it can't be large enough to cause overflow in the
    9591             :          * carry propagation step (if any), either.
    9592             :          *
    9593             :          * But having said that: dividend[qi] can be more than
    9594             :          * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
    9595             :          * dividend[qi] * NBASE^2 *can* overflow.  When that happens, adding
    9596             :          * it to dividend[qi + 1] will always cause a canceling overflow so
    9597             :          * that the end result is correct.  We could avoid the intermediate
    9598             :          * overflow by doing the multiplication and addition using unsigned
    9599             :          * int64 arithmetic, which is modulo 2^64, but so far there appears no
    9600             :          * need.
    9601             :          */
    9602       56400 :         dividend[qi + 1] += dividend[qi] * NBASE_SQR;
    9603             : 
    9604       56400 :         dividend[qi] = qdigit;
    9605             :     }
    9606             : 
    9607             :     /*
    9608             :      * If an exact result was requested, use the remainder to correct the
    9609             :      * approximate quotient.  The remainder is in dividend[], immediately
    9610             :      * after the quotient digits.  Note, however, that although the remainder
    9611             :      * starts at dividend[qi = res_ndigitpairs], the first digit is the result
    9612             :      * of folding two remainder digits into one above, and the remainder
    9613             :      * currently only occupies var2ndigitpairs - 1 digits (the last digit of
    9614             :      * the working dividend was untouched by the computation above).  Thus we
    9615             :      * expand the remainder down by one base-NBASE^2 digit when we normalize
    9616             :      * it, so that it completely fills the last var2ndigitpairs digits of the
    9617             :      * dividend array.
    9618             :      */
    9619        8496 :     if (exact)
    9620             :     {
    9621             :         /* Normalize the remainder, expanding it down by one digit */
    9622        6774 :         remainder = &dividend[qi];
    9623        6774 :         carry = 0;
    9624       87678 :         for (i = var2ndigitpairs - 2; i >= 0; i--)
    9625             :         {
    9626       80904 :             newdig = remainder[i] + carry;
    9627       80904 :             if (newdig < 0)
    9628             :             {
    9629       74040 :                 carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9630       74040 :                 newdig -= carry * NBASE_SQR;
    9631             :             }
    9632        6864 :             else if (newdig >= NBASE_SQR)
    9633             :             {
    9634        6718 :                 carry = newdig / NBASE_SQR;
    9635        6718 :                 newdig -= carry * NBASE_SQR;
    9636             :             }
    9637             :             else
    9638         146 :                 carry = 0;
    9639       80904 :             remainder[i + 1] = newdig;
    9640             :         }
    9641        6774 :         remainder[0] = carry;
    9642             : 
    9643        6774 :         if (remainder[0] < 0)
    9644             :         {
    9645             :             /*
    9646             :              * The remainder is negative, so the approximate quotient is too
    9647             :              * large.  Correct by reducing the quotient by one and adding the
    9648             :              * divisor to the remainder until the remainder is positive.  We
    9649             :              * expect the quotient to be off by at most one, which has been
    9650             :              * borne out in all testing, but not conclusively proven, so we
    9651             :              * allow for larger corrections, just in case.
    9652             :              */
    9653             :             do
    9654             :             {
    9655             :                 /* Add the divisor to the remainder */
    9656          26 :                 carry = 0;
    9657        1138 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9658             :                 {
    9659        1112 :                     newdig = remainder[i] + divisor[i] + carry;
    9660        1112 :                     if (newdig >= NBASE_SQR)
    9661             :                     {
    9662         966 :                         remainder[i] = newdig - NBASE_SQR;
    9663         966 :                         carry = 1;
    9664             :                     }
    9665             :                     else
    9666             :                     {
    9667         146 :                         remainder[i] = newdig;
    9668         146 :                         carry = 0;
    9669             :                     }
    9670             :                 }
    9671          26 :                 remainder[0] += divisor[0] + carry;
    9672             : 
    9673             :                 /* Subtract 1 from the quotient (propagating carries later) */
    9674          26 :                 dividend[qi - 1]--;
    9675             : 
    9676          26 :             } while (remainder[0] < 0);
    9677             :         }
    9678             :         else
    9679             :         {
    9680             :             /*
    9681             :              * The remainder is nonnegative.  If it's greater than or equal to
    9682             :              * the divisor, then the approximate quotient is too small and
    9683             :              * must be corrected.  As above, we don't expect to have to apply
    9684             :              * more than one correction, but allow for it just in case.
    9685             :              */
    9686             :             while (true)
    9687           6 :             {
    9688        6754 :                 bool        less = false;
    9689             : 
    9690             :                 /* Is remainder < divisor? */
    9691        6772 :                 for (i = 0; i < var2ndigitpairs; i++)
    9692             :                 {
    9693        6766 :                     if (remainder[i] < divisor[i])
    9694             :                     {
    9695        6748 :                         less = true;
    9696        6748 :                         break;
    9697             :                     }
    9698          18 :                     if (remainder[i] > divisor[i])
    9699           0 :                         break;  /* remainder > divisor */
    9700             :                 }
    9701        6754 :                 if (less)
    9702        6748 :                     break;      /* quotient is correct */
    9703             : 
    9704             :                 /* Subtract the divisor from the remainder */
    9705           6 :                 carry = 0;
    9706          18 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9707             :                 {
    9708          12 :                     newdig = remainder[i] - divisor[i] + carry;
    9709          12 :                     if (newdig < 0)
    9710             :                     {
    9711           0 :                         remainder[i] = newdig + NBASE_SQR;
    9712           0 :                         carry = -1;
    9713             :                     }
    9714             :                     else
    9715             :                     {
    9716          12 :                         remainder[i] = newdig;
    9717          12 :                         carry = 0;
    9718             :                     }
    9719             :                 }
    9720           6 :                 remainder[0] = remainder[0] - divisor[0] + carry;
    9721             : 
    9722             :                 /* Add 1 to the quotient (propagating carries later) */
    9723           6 :                 dividend[qi - 1]++;
    9724             :             }
    9725             :         }
    9726             :     }
    9727             : 
    9728             :     /*
    9729             :      * Because the quotient digits were estimates that might have been off by
    9730             :      * one (and we didn't bother propagating carries when adjusting the
    9731             :      * quotient above), some quotient digits might be out of range, so do a
    9732             :      * final carry propagation pass to normalize back to base NBASE^2, and
    9733             :      * construct the base-NBASE result digits.  Note that this is still done
    9734             :      * at full precision w/guard digits.
    9735             :      */
    9736        8496 :     alloc_var(result, res_ndigits);
    9737        8496 :     res_digits = result->digits;
    9738        8496 :     carry = 0;
    9739       64896 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9740             :     {
    9741       56400 :         newdig = dividend[i] + carry;
    9742       56400 :         if (newdig < 0)
    9743             :         {
    9744          66 :             carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9745          66 :             newdig -= carry * NBASE_SQR;
    9746             :         }
    9747       56334 :         else if (newdig >= NBASE_SQR)
    9748             :         {
    9749           0 :             carry = newdig / NBASE_SQR;
    9750           0 :             newdig -= carry * NBASE_SQR;
    9751             :         }
    9752             :         else
    9753       56334 :             carry = 0;
    9754       56400 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9755       56400 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9756             :     }
    9757             :     Assert(carry == 0);
    9758             : 
    9759        8496 :     pfree(dividend);
    9760             : 
    9761             :     /*
    9762             :      * Finally, round or truncate the result to the requested precision.
    9763             :      */
    9764        8496 :     result->weight = res_weight;
    9765        8496 :     result->sign = res_sign;
    9766             : 
    9767             :     /* Round or truncate to target rscale (and set result->dscale) */
    9768        8496 :     if (round)
    9769        3960 :         round_var(result, rscale);
    9770             :     else
    9771        4536 :         trunc_var(result, rscale);
    9772             : 
    9773             :     /* Strip leading and trailing zeroes */
    9774        8496 :     strip_var(result);
    9775             : }
    9776             : 
    9777             : 
    9778             : /*
    9779             :  * div_var_int() -
    9780             :  *
    9781             :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9782             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9783             :  */
    9784             : static void
    9785      224212 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9786             :             NumericVar *result, int rscale, bool round)
    9787             : {
    9788      224212 :     NumericDigit *var_digits = var->digits;
    9789      224212 :     int         var_ndigits = var->ndigits;
    9790             :     int         res_sign;
    9791             :     int         res_weight;
    9792             :     int         res_ndigits;
    9793             :     NumericDigit *res_buf;
    9794             :     NumericDigit *res_digits;
    9795             :     uint32      divisor;
    9796             :     int         i;
    9797             : 
    9798             :     /* Guard against division by zero */
    9799      224212 :     if (ival == 0)
    9800           0 :         ereport(ERROR,
    9801             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9802             :                 errmsg("division by zero"));
    9803             : 
    9804             :     /* Result zero check */
    9805      224212 :     if (var_ndigits == 0)
    9806             :     {
    9807        2300 :         zero_var(result);
    9808        2300 :         result->dscale = rscale;
    9809        2300 :         return;
    9810             :     }
    9811             : 
    9812             :     /*
    9813             :      * Determine the result sign, weight and number of digits to calculate.
    9814             :      * The weight figured here is correct if the emitted quotient has no
    9815             :      * leading zero digits; otherwise strip_var() will fix things up.
    9816             :      */
    9817      221912 :     if (var->sign == NUMERIC_POS)
    9818      218936 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9819             :     else
    9820        2976 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9821      221912 :     res_weight = var->weight - ival_weight;
    9822             :     /* The number of accurate result digits we need to produce: */
    9823      221912 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9824             :     /* ... but always at least 1 */
    9825      221912 :     res_ndigits = Max(res_ndigits, 1);
    9826             :     /* If rounding needed, figure one more digit to ensure correct result */
    9827      221912 :     if (round)
    9828      166626 :         res_ndigits++;
    9829             : 
    9830      221912 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9831      221912 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9832      221912 :     res_digits = res_buf + 1;
    9833             : 
    9834             :     /*
    9835             :      * Now compute the quotient digits.  This is the short division algorithm
    9836             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9837             :      * allow the divisor to exceed the internal base.
    9838             :      *
    9839             :      * In this algorithm, the carry from one digit to the next is at most
    9840             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9841             :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9842             :      * integer if this exceeds UINT_MAX.
    9843             :      */
    9844      221912 :     divisor = abs(ival);
    9845             : 
    9846      221912 :     if (divisor <= UINT_MAX / NBASE)
    9847             :     {
    9848             :         /* carry cannot overflow 32 bits */
    9849      218586 :         uint32      carry = 0;
    9850             : 
    9851     2124320 :         for (i = 0; i < res_ndigits; i++)
    9852             :         {
    9853     1905734 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9854     1905734 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9855     1905734 :             carry = carry % divisor;
    9856             :         }
    9857             :     }
    9858             :     else
    9859             :     {
    9860             :         /* carry may exceed 32 bits */
    9861        3326 :         uint64      carry = 0;
    9862             : 
    9863       10644 :         for (i = 0; i < res_ndigits; i++)
    9864             :         {
    9865        7318 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9866        7318 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9867        7318 :             carry = carry % divisor;
    9868             :         }
    9869             :     }
    9870             : 
    9871             :     /* Store the quotient in result */
    9872      221912 :     digitbuf_free(result->buf);
    9873      221912 :     result->ndigits = res_ndigits;
    9874      221912 :     result->buf = res_buf;
    9875      221912 :     result->digits = res_digits;
    9876      221912 :     result->weight = res_weight;
    9877      221912 :     result->sign = res_sign;
    9878             : 
    9879             :     /* Round or truncate to target rscale (and set result->dscale) */
    9880      221912 :     if (round)
    9881      166626 :         round_var(result, rscale);
    9882             :     else
    9883       55286 :         trunc_var(result, rscale);
    9884             : 
    9885             :     /* Strip leading/trailing zeroes */
    9886      221912 :     strip_var(result);
    9887             : }
    9888             : 
    9889             : 
    9890             : #ifdef HAVE_INT128
    9891             : /*
    9892             :  * div_var_int64() -
    9893             :  *
    9894             :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
    9895             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9896             :  *
    9897             :  *  This duplicates the logic in div_var_int(), so any changes made there
    9898             :  *  should be made here too.
    9899             :  */
    9900             : static void
    9901         546 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
    9902             :               NumericVar *result, int rscale, bool round)
    9903             : {
    9904         546 :     NumericDigit *var_digits = var->digits;
    9905         546 :     int         var_ndigits = var->ndigits;
    9906             :     int         res_sign;
    9907             :     int         res_weight;
    9908             :     int         res_ndigits;
    9909             :     NumericDigit *res_buf;
    9910             :     NumericDigit *res_digits;
    9911             :     uint64      divisor;
    9912             :     int         i;
    9913             : 
    9914             :     /* Guard against division by zero */
    9915         546 :     if (ival == 0)
    9916           0 :         ereport(ERROR,
    9917             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9918             :                 errmsg("division by zero"));
    9919             : 
    9920             :     /* Result zero check */
    9921         546 :     if (var_ndigits == 0)
    9922             :     {
    9923          96 :         zero_var(result);
    9924          96 :         result->dscale = rscale;
    9925          96 :         return;
    9926             :     }
    9927             : 
    9928             :     /*
    9929             :      * Determine the result sign, weight and number of digits to calculate.
    9930             :      * The weight figured here is correct if the emitted quotient has no
    9931             :      * leading zero digits; otherwise strip_var() will fix things up.
    9932             :      */
    9933         450 :     if (var->sign == NUMERIC_POS)
    9934         276 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9935             :     else
    9936         174 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9937         450 :     res_weight = var->weight - ival_weight;
    9938             :     /* The number of accurate result digits we need to produce: */
    9939         450 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9940             :     /* ... but always at least 1 */
    9941         450 :     res_ndigits = Max(res_ndigits, 1);
    9942             :     /* If rounding needed, figure one more digit to ensure correct result */
    9943         450 :     if (round)
    9944         444 :         res_ndigits++;
    9945             : 
    9946         450 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9947         450 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9948         450 :     res_digits = res_buf + 1;
    9949             : 
    9950             :     /*
    9951             :      * Now compute the quotient digits.  This is the short division algorithm
    9952             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9953             :      * allow the divisor to exceed the internal base.
    9954             :      *
    9955             :      * In this algorithm, the carry from one digit to the next is at most
    9956             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9957             :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
    9958             :      * integer if this exceeds PG_UINT64_MAX.
    9959             :      */
    9960         450 :     divisor = i64abs(ival);
    9961             : 
    9962         450 :     if (divisor <= PG_UINT64_MAX / NBASE)
    9963             :     {
    9964             :         /* carry cannot overflow 64 bits */
    9965         354 :         uint64      carry = 0;
    9966             : 
    9967        3608 :         for (i = 0; i < res_ndigits; i++)
    9968             :         {
    9969        3254 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9970        3254 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9971        3254 :             carry = carry % divisor;
    9972             :         }
    9973             :     }
    9974             :     else
    9975             :     {
    9976             :         /* carry may exceed 64 bits */
    9977          96 :         uint128     carry = 0;
    9978             : 
    9979        1032 :         for (i = 0; i < res_ndigits; i++)
    9980             :         {
    9981         936 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9982         936 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9983         936 :             carry = carry % divisor;
    9984             :         }
    9985             :     }
    9986             : 
    9987             :     /* Store the quotient in result */
    9988         450 :     digitbuf_free(result->buf);
    9989         450 :     result->ndigits = res_ndigits;
    9990         450 :     result->buf = res_buf;
    9991         450 :     result->digits = res_digits;
    9992         450 :     result->weight = res_weight;
    9993         450 :     result->sign = res_sign;
    9994             : 
    9995             :     /* Round or truncate to target rscale (and set result->dscale) */
    9996         450 :     if (round)
    9997         444 :         round_var(result, rscale);
    9998             :     else
    9999           6 :         trunc_var(result, rscale);
   10000             : 
   10001             :     /* Strip leading/trailing zeroes */
   10002         450 :     strip_var(result);
   10003             : }
   10004             : #endif
   10005             : 
   10006             : 
   10007             : /*
   10008             :  * Default scale selection for division
   10009             :  *
   10010             :  * Returns the appropriate result scale for the division result.
   10011             :  */
   10012             : static int
   10013      152632 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
   10014             : {
   10015             :     int         weight1,
   10016             :                 weight2,
   10017             :                 qweight,
   10018             :                 i;
   10019             :     NumericDigit firstdigit1,
   10020             :                 firstdigit2;
   10021             :     int         rscale;
   10022             : 
   10023             :     /*
   10024             :      * The result scale of a division isn't specified in any SQL standard. For
   10025             :      * PostgreSQL we select a result scale that will give at least
   10026             :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
   10027             :      * result no less accurate than float8; but use a scale not less than
   10028             :      * either input's display scale.
   10029             :      */
   10030             : 
   10031             :     /* Get the actual (normalized) weight and first digit of each input */
   10032             : 
   10033      152632 :     weight1 = 0;                /* values to use if var1 is zero */
   10034      152632 :     firstdigit1 = 0;
   10035      152632 :     for (i = 0; i < var1->ndigits; i++)
   10036             :     {
   10037      150932 :         firstdigit1 = var1->digits[i];
   10038      150932 :         if (firstdigit1 != 0)
   10039             :         {
   10040      150932 :             weight1 = var1->weight - i;
   10041      150932 :             break;
   10042             :         }
   10043             :     }
   10044             : 
   10045      152632 :     weight2 = 0;                /* values to use if var2 is zero */
   10046      152632 :     firstdigit2 = 0;
   10047      152632 :     for (i = 0; i < var2->ndigits; i++)
   10048             :     {
   10049      152582 :         firstdigit2 = var2->digits[i];
   10050      152582 :         if (firstdigit2 != 0)
   10051             :         {
   10052      152582 :             weight2 = var2->weight - i;
   10053      152582 :             break;
   10054             :         }
   10055             :     }
   10056             : 
   10057             :     /*
   10058             :      * Estimate weight of quotient.  If the two first digits are equal, we
   10059             :      * can't be sure, but assume that var1 is less than var2.
   10060             :      */
   10061      152632 :     qweight = weight1 - weight2;
   10062      152632 :     if (firstdigit1 <= firstdigit2)
   10063      135334 :         qweight--;
   10064             : 
   10065             :     /* Select result scale */
   10066      152632 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
   10067      152632 :     rscale = Max(rscale, var1->dscale);
   10068      152632 :     rscale = Max(rscale, var2->dscale);
   10069      152632 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10070      152632 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10071             : 
   10072      152632 :     return rscale;
   10073             : }
   10074             : 
   10075             : 
   10076             : /*
   10077             :  * mod_var() -
   10078             :  *
   10079             :  *  Calculate the modulo of two numerics at variable level
   10080             :  */
   10081             : static void
   10082       53792 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   10083             : {
   10084             :     NumericVar  tmp;
   10085             : 
   10086       53792 :     init_var(&tmp);
   10087             : 
   10088             :     /* ---------
   10089             :      * We do this using the equation
   10090             :      *      mod(x,y) = x - trunc(x/y)*y
   10091             :      * div_var can be persuaded to give us trunc(x/y) directly.
   10092             :      * ----------
   10093             :      */
   10094       53792 :     div_var(var1, var2, &tmp, 0, false, true);
   10095             : 
   10096       53780 :     mul_var(var2, &tmp, &tmp, var2->dscale);
   10097             : 
   10098       53780 :     sub_var(var1, &tmp, result);
   10099             : 
   10100       53780 :     free_var(&tmp);
   10101       53780 : }
   10102             : 
   10103             : 
   10104             : /*
   10105             :  * div_mod_var() -
   10106             :  *
   10107             :  *  Calculate the truncated integer quotient and numeric remainder of two
   10108             :  *  numeric variables.  The remainder is precise to var2's dscale.
   10109             :  */
   10110             : static void
   10111        4518 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
   10112             :             NumericVar *quot, NumericVar *rem)
   10113             : {
   10114             :     NumericVar  q;
   10115             :     NumericVar  r;
   10116             : 
   10117        4518 :     init_var(&q);
   10118        4518 :     init_var(&r);
   10119             : 
   10120             :     /*
   10121             :      * Use div_var() with exact = false to get an initial estimate for the
   10122             :      * integer quotient (truncated towards zero).  This might be slightly
   10123             :      * inaccurate, but we correct it below.
   10124             :      */
   10125        4518 :     div_var(var1, var2, &q, 0, false, false);
   10126             : 
   10127             :     /* Compute initial estimate of remainder using the quotient estimate. */
   10128        4518 :     mul_var(var2, &q, &r, var2->dscale);
   10129        4518 :     sub_var(var1, &r, &r);
   10130             : 
   10131             :     /*
   10132             :      * Adjust the results if necessary --- the remainder should have the same
   10133             :      * sign as var1, and its absolute value should be less than the absolute
   10134             :      * value of var2.
   10135             :      */
   10136        4518 :     while (r.ndigits != 0 && r.sign != var1->sign)
   10137             :     {
   10138             :         /* The absolute value of the quotient is too large */
   10139           0 :         if (var1->sign == var2->sign)
   10140             :         {
   10141           0 :             sub_var(&q, &const_one, &q);
   10142           0 :             add_var(&r, var2, &r);
   10143             :         }
   10144             :         else
   10145             :         {
   10146           0 :             add_var(&q, &const_one, &q);
   10147           0 :             sub_var(&r, var2, &r);
   10148             :         }
   10149             :     }
   10150             : 
   10151        4518 :     while (cmp_abs(&r, var2) >= 0)
   10152             :     {
   10153             :         /* The absolute value of the quotient is too small */
   10154           0 :         if (var1->sign == var2->sign)
   10155             :         {
   10156           0 :             add_var(&q, &const_one, &q);
   10157           0 :             sub_var(&r, var2, &r);
   10158             :         }
   10159             :         else
   10160             :         {
   10161           0 :             sub_var(&q, &const_one, &q);
   10162           0 :             add_var(&r, var2, &r);
   10163             :         }
   10164             :     }
   10165             : 
   10166        4518 :     set_var_from_var(&q, quot);
   10167        4518 :     set_var_from_var(&r, rem);
   10168             : 
   10169        4518 :     free_var(&q);
   10170        4518 :     free_var(&r);
   10171        4518 : }
   10172             : 
   10173             : 
   10174             : /*
   10175             :  * ceil_var() -
   10176             :  *
   10177             :  *  Return the smallest integer greater than or equal to the argument
   10178             :  *  on variable level
   10179             :  */
   10180             : static void
   10181         204 : ceil_var(const NumericVar *var, NumericVar *result)
   10182             : {
   10183             :     NumericVar  tmp;
   10184             : 
   10185         204 :     init_var(&tmp);
   10186         204 :     set_var_from_var(var, &tmp);
   10187             : 
   10188         204 :     trunc_var(&tmp, 0);
   10189             : 
   10190         204 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
   10191          60 :         add_var(&tmp, &const_one, &tmp);
   10192             : 
   10193         204 :     set_var_from_var(&tmp, result);
   10194         204 :     free_var(&tmp);
   10195         204 : }
   10196             : 
   10197             : 
   10198             : /*
   10199             :  * floor_var() -
   10200             :  *
   10201             :  *  Return the largest integer equal to or less than the argument
   10202             :  *  on variable level
   10203             :  */
   10204             : static void
   10205         108 : floor_var(const NumericVar *var, NumericVar *result)
   10206             : {
   10207             :     NumericVar  tmp;
   10208             : 
   10209         108 :     init_var(&tmp);
   10210         108 :     set_var_from_var(var, &tmp);
   10211             : 
   10212         108 :     trunc_var(&tmp, 0);
   10213             : 
   10214         108 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
   10215          30 :         sub_var(&tmp, &const_one, &tmp);
   10216             : 
   10217         108 :     set_var_from_var(&tmp, result);
   10218         108 :     free_var(&tmp);
   10219         108 : }
   10220             : 
   10221             : 
   10222             : /*
   10223             :  * gcd_var() -
   10224             :  *
   10225             :  *  Calculate the greatest common divisor of two numerics at variable level
   10226             :  */
   10227             : static void
   10228         222 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   10229             : {
   10230             :     int         res_dscale;
   10231             :     int         cmp;
   10232             :     NumericVar  tmp_arg;
   10233             :     NumericVar  mod;
   10234             : 
   10235         222 :     res_dscale = Max(var1->dscale, var2->dscale);
   10236             : 
   10237             :     /*
   10238             :      * Arrange for var1 to be the number with the greater absolute value.
   10239             :      *
   10240             :      * This would happen automatically in the loop below, but avoids an
   10241             :      * expensive modulo operation.
   10242             :      */
   10243         222 :     cmp = cmp_abs(var1, var2);
   10244         222 :     if (cmp < 0)
   10245             :     {
   10246          84 :         const NumericVar *tmp = var1;
   10247             : 
   10248          84 :         var1 = var2;
   10249          84 :         var2 = tmp;
   10250             :     }
   10251             : 
   10252             :     /*
   10253             :      * Also avoid the taking the modulo if the inputs have the same absolute
   10254             :      * value, or if the smaller input is zero.
   10255             :      */
   10256         222 :     if (cmp == 0 || var2->ndigits == 0)
   10257             :     {
   10258          72 :         set_var_from_var(var1, result);
   10259          72 :         result->sign = NUMERIC_POS;
   10260          72 :         result->dscale = res_dscale;
   10261          72 :         return;
   10262             :     }
   10263             : 
   10264         150 :     init_var(&tmp_arg);
   10265         150 :     init_var(&mod);
   10266             : 
   10267             :     /* Use the Euclidean algorithm to find the GCD */
   10268         150 :     set_var_from_var(var1, &tmp_arg);
   10269         150 :     set_var_from_var(var2, result);
   10270             : 
   10271             :     for (;;)
   10272             :     {
   10273             :         /* this loop can take a while, so allow it to be interrupted */
   10274         588 :         CHECK_FOR_INTERRUPTS();
   10275             : 
   10276         588 :         mod_var(&tmp_arg, result, &mod);
   10277         588 :         if (mod.ndigits == 0)
   10278         150 :             break;
   10279         438 :         set_var_from_var(result, &tmp_arg);
   10280         438 :         set_var_from_var(&mod, result);
   10281             :     }
   10282         150 :     result->sign = NUMERIC_POS;
   10283         150 :     result->dscale = res_dscale;
   10284             : 
   10285         150 :     free_var(&tmp_arg);
   10286         150 :     free_var(&mod);
   10287             : }
   10288             : 
   10289             : 
   10290             : /*
   10291             :  * sqrt_var() -
   10292             :  *
   10293             :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
   10294             :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
   10295             :  *  point.
   10296             :  */
   10297             : static void
   10298        4194 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
   10299             : {
   10300             :     int         stat;
   10301             :     int         res_weight;
   10302             :     int         res_ndigits;
   10303             :     int         src_ndigits;
   10304             :     int         step;
   10305             :     int         ndigits[32];
   10306             :     int         blen;
   10307             :     int64       arg_int64;
   10308             :     int         src_idx;
   10309             :     int64       s_int64;
   10310             :     int64       r_int64;
   10311             :     NumericVar  s_var;
   10312             :     NumericVar  r_var;
   10313             :     NumericVar  a0_var;
   10314             :     NumericVar  a1_var;
   10315             :     NumericVar  q_var;
   10316             :     NumericVar  u_var;
   10317             : 
   10318        4194 :     stat = cmp_var(arg, &const_zero);
   10319        4194 :     if (stat == 0)
   10320             :     {
   10321          18 :         zero_var(result);
   10322          18 :         result->dscale = rscale;
   10323          18 :         return;
   10324             :     }
   10325             : 
   10326             :     /*
   10327             :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
   10328             :      * SQLSTATE error code if the operand is negative.
   10329             :      */
   10330        4176 :     if (stat < 0)
   10331           6 :         ereport(ERROR,
   10332             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10333             :                  errmsg("cannot take square root of a negative number")));
   10334             : 
   10335        4170 :     init_var(&s_var);
   10336        4170 :     init_var(&r_var);
   10337        4170 :     init_var(&a0_var);
   10338        4170 :     init_var(&a1_var);
   10339        4170 :     init_var(&q_var);
   10340        4170 :     init_var(&u_var);
   10341             : 
   10342             :     /*
   10343             :      * The result weight is half the input weight, rounded towards minus
   10344             :      * infinity --- res_weight = floor(arg->weight / 2).
   10345             :      */
   10346        4170 :     if (arg->weight >= 0)
   10347        3858 :         res_weight = arg->weight / 2;
   10348             :     else
   10349         312 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10350             : 
   10351             :     /*
   10352             :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10353             :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10354             :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10355             :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10356             :      */
   10357        4170 :     if (rscale + 1 >= 0)
   10358        4170 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10359             :     else
   10360           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10361        4170 :     res_ndigits = Max(res_ndigits, 1);
   10362             : 
   10363             :     /*
   10364             :      * Number of source NBASE digits logically required to produce a result
   10365             :      * with this precision --- every digit before the decimal point, plus 2
   10366             :      * for each result digit after the decimal point (or minus 2 for each
   10367             :      * result digit we round before the decimal point).
   10368             :      */
   10369        4170 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10370        4170 :     src_ndigits = Max(src_ndigits, 1);
   10371             : 
   10372             :     /* ----------
   10373             :      * From this point on, we treat the input and the result as integers and
   10374             :      * compute the integer square root and remainder using the Karatsuba
   10375             :      * Square Root algorithm, which may be written recursively as follows:
   10376             :      *
   10377             :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10378             :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10379             :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10380             :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10381             :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10382             :      *      Let s = s*b + q
   10383             :      *      Let r = u*b + a0 - q^2
   10384             :      *      If r < 0 Then
   10385             :      *          Let r = r + s
   10386             :      *          Let s = s - 1
   10387             :      *          Let r = r + s
   10388             :      *      Return (s,r)
   10389             :      *
   10390             :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10391             :      * RR-3805, November 1999.  At the time of writing this was available
   10392             :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10393             :      *
   10394             :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10395             :      * "choose a base b such that n requires at least four base-b digits to
   10396             :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10397             :      * than b".  For optimal performance, b should have approximately a
   10398             :      * quarter the number of digits in the input, so that the outer square
   10399             :      * root computes roughly twice as many digits as the inner one.  For
   10400             :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10401             :      *
   10402             :      * We implement the algorithm iteratively rather than recursively, to
   10403             :      * allow the working variables to be reused.  With this approach, each
   10404             :      * digit of the input is read precisely once --- src_idx tracks the number
   10405             :      * of input digits used so far.
   10406             :      *
   10407             :      * The array ndigits[] holds the number of NBASE digits of the input that
   10408             :      * will have been used at the end of each iteration, which roughly doubles
   10409             :      * each time.  Note that the array elements are stored in reverse order,
   10410             :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10411             :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10412             :      * the square root of the 3 most significant NBASE digits.
   10413             :      *
   10414             :      * In each iteration, we choose blen to be the largest integer for which
   10415             :      * the input number has a3 >= b/4, when written in the form above.  In
   10416             :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10417             :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10418             :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10419             :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10420             :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10421             :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10422             :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10423             :      * the first input digit.
   10424             :      *
   10425             :      * Additionally, we can put an upper bound on the number of steps required
   10426             :      * as follows --- suppose that the number of source digits is an n-bit
   10427             :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10428             :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10429             :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10430             :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10431             :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10432             :      * This pattern repeats, and in the worst case the array ndigits[] will
   10433             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10434             :      * will require n steps.  Therefore, since all digit array sizes are
   10435             :      * signed 32-bit integers, the number of steps required is guaranteed to
   10436             :      * be less than 32.
   10437             :      * ----------
   10438             :      */
   10439        4170 :     step = 0;
   10440       19962 :     while ((ndigits[step] = src_ndigits) > 4)
   10441             :     {
   10442             :         /* Choose b so that a3 >= b/4, as described above */
   10443       15792 :         blen = src_ndigits / 4;
   10444       15792 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10445         324 :             blen--;
   10446             : 
   10447             :         /* Number of digits in the next step (inner square root) */
   10448       15792 :         src_ndigits -= 2 * blen;
   10449       15792 :         step++;
   10450             :     }
   10451             : 
   10452             :     /*
   10453             :      * First iteration (innermost square root and remainder):
   10454             :      *
   10455             :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10456             :      * has at most 9 decimal digits, so estimate it using double precision
   10457             :      * arithmetic, which will in fact almost certainly return the correct
   10458             :      * result with no further correction required.
   10459             :      */
   10460        4170 :     arg_int64 = arg->digits[0];
   10461       13314 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10462             :     {
   10463        9144 :         arg_int64 *= NBASE;
   10464        9144 :         if (src_idx < arg->ndigits)
   10465        7686 :             arg_int64 += arg->digits[src_idx];
   10466             :     }
   10467             : 
   10468        4170 :     s_int64 = (int64) sqrt((double) arg_int64);
   10469        4170 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10470             : 
   10471             :     /*
   10472             :      * Use Newton's method to correct the result, if necessary.
   10473             :      *
   10474             :      * This uses integer division with truncation to compute the truncated
   10475             :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10476             :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10477             :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10478             :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10479             :      * checking the remainder.
   10480             :      */
   10481        4170 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10482             :     {
   10483           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10484           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10485             :     }
   10486             : 
   10487             :     /*
   10488             :      * Iterations with src_ndigits <= 8:
   10489             :      *
   10490             :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10491             :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10492             :      * input no longer does) and we can continue to compute using int64
   10493             :      * variables to avoid more expensive numeric computations.
   10494             :      *
   10495             :      * It is fairly easy to see that there is no risk of the intermediate
   10496             :      * values below overflowing 64-bit integers.  In the worst case, the
   10497             :      * previous iteration will have computed a 3-digit square root (of a
   10498             :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10499             :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10500             :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10501             :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10502             :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10503             :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10504             :      * in 64-bit integers.
   10505             :      */
   10506        4170 :     step--;
   10507       10566 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10508             :     {
   10509             :         int         b;
   10510             :         int         a0;
   10511             :         int         a1;
   10512             :         int         i;
   10513             :         int64       numer;
   10514             :         int64       denom;
   10515             :         int64       q;
   10516             :         int64       u;
   10517             : 
   10518        6396 :         blen = (src_ndigits - src_idx) / 2;
   10519             : 
   10520             :         /* Extract a1 and a0, and compute b */
   10521        6396 :         a0 = 0;
   10522        6396 :         a1 = 0;
   10523        6396 :         b = 1;
   10524             : 
   10525       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10526             :         {
   10527        6540 :             b *= NBASE;
   10528        6540 :             a1 *= NBASE;
   10529        6540 :             if (src_idx < arg->ndigits)
   10530        4800 :                 a1 += arg->digits[src_idx];
   10531             :         }
   10532             : 
   10533       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10534             :         {
   10535        6540 :             a0 *= NBASE;
   10536        6540 :             if (src_idx < arg->ndigits)
   10537        4644 :                 a0 += arg->digits[src_idx];
   10538             :         }
   10539             : 
   10540             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10541        6396 :         numer = r_int64 * b + a1;
   10542        6396 :         denom = 2 * s_int64;
   10543        6396 :         q = numer / denom;
   10544        6396 :         u = numer - q * denom;
   10545             : 
   10546             :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10547        6396 :         s_int64 = s_int64 * b + q;
   10548        6396 :         r_int64 = u * b + a0 - q * q;
   10549             : 
   10550        6396 :         if (r_int64 < 0)
   10551             :         {
   10552             :             /* s is too large by 1; set r += s, s--, r += s */
   10553         210 :             r_int64 += s_int64;
   10554         210 :             s_int64--;
   10555         210 :             r_int64 += s_int64;
   10556             :         }
   10557             : 
   10558             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10559        6396 :         step--;
   10560             :     }
   10561             : 
   10562             :     /*
   10563             :      * On platforms with 128-bit integer support, we can further delay the
   10564             :      * need to use numeric variables.
   10565             :      */
   10566             : #ifdef HAVE_INT128
   10567        4170 :     if (step >= 0)
   10568             :     {
   10569             :         int128      s_int128;
   10570             :         int128      r_int128;
   10571             : 
   10572        4170 :         s_int128 = s_int64;
   10573        4170 :         r_int128 = r_int64;
   10574             : 
   10575             :         /*
   10576             :          * Iterations with src_ndigits <= 16:
   10577             :          *
   10578             :          * The result fits in an int128 (even though the input doesn't) so we
   10579             :          * use int128 variables to avoid more expensive numeric computations.
   10580             :          */
   10581        9048 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10582             :         {
   10583             :             int64       b;
   10584             :             int64       a0;
   10585             :             int64       a1;
   10586             :             int64       i;
   10587             :             int128      numer;
   10588             :             int128      denom;
   10589             :             int128      q;
   10590             :             int128      u;
   10591             : 
   10592        4878 :             blen = (src_ndigits - src_idx) / 2;
   10593             : 
   10594             :             /* Extract a1 and a0, and compute b */
   10595        4878 :             a0 = 0;
   10596        4878 :             a1 = 0;
   10597        4878 :             b = 1;
   10598             : 
   10599       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10600             :             {
   10601       11202 :                 b *= NBASE;
   10602       11202 :                 a1 *= NBASE;
   10603       11202 :                 if (src_idx < arg->ndigits)
   10604        6606 :                     a1 += arg->digits[src_idx];
   10605             :             }
   10606             : 
   10607       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10608             :             {
   10609       11202 :                 a0 *= NBASE;
   10610       11202 :                 if (src_idx < arg->ndigits)
   10611        4470 :                     a0 += arg->digits[src_idx];
   10612             :             }
   10613             : 
   10614             :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10615        4878 :             numer = r_int128 * b + a1;
   10616        4878 :             denom = 2 * s_int128;
   10617        4878 :             q = numer / denom;
   10618        4878 :             u = numer - q * denom;
   10619             : 
   10620             :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10621        4878 :             s_int128 = s_int128 * b + q;
   10622        4878 :             r_int128 = u * b + a0 - q * q;
   10623             : 
   10624        4878 :             if (r_int128 < 0)
   10625             :             {
   10626             :                 /* s is too large by 1; set r += s, s--, r += s */
   10627         192 :                 r_int128 += s_int128;
   10628         192 :                 s_int128--;
   10629         192 :                 r_int128 += s_int128;
   10630             :             }
   10631             : 
   10632             :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10633        4878 :             step--;
   10634             :         }
   10635             : 
   10636             :         /*
   10637             :          * All remaining iterations require numeric variables.  Convert the
   10638             :          * integer values to NumericVar and continue.  Note that in the final
   10639             :          * iteration we don't need the remainder, so we can save a few cycles
   10640             :          * there by not fully computing it.
   10641             :          */
   10642        4170 :         int128_to_numericvar(s_int128, &s_var);
   10643        4170 :         if (step >= 0)
   10644        2724 :             int128_to_numericvar(r_int128, &r_var);
   10645             :     }
   10646             :     else
   10647             :     {
   10648           0 :         int64_to_numericvar(s_int64, &s_var);
   10649             :         /* step < 0, so we certainly don't need r */
   10650             :     }
   10651             : #else                           /* !HAVE_INT128 */
   10652             :     int64_to_numericvar(s_int64, &s_var);
   10653             :     if (step >= 0)
   10654             :         int64_to_numericvar(r_int64, &r_var);
   10655             : #endif                          /* HAVE_INT128 */
   10656             : 
   10657             :     /*
   10658             :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10659             :      * use numeric variables.
   10660             :      */
   10661        8688 :     while (step >= 0)
   10662             :     {
   10663             :         int         tmp_len;
   10664             : 
   10665        4518 :         src_ndigits = ndigits[step];
   10666        4518 :         blen = (src_ndigits - src_idx) / 2;
   10667             : 
   10668             :         /* Extract a1 and a0 */
   10669        4518 :         if (src_idx < arg->ndigits)
   10670             :         {
   10671        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10672        1512 :             alloc_var(&a1_var, tmp_len);
   10673        1512 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10674             :                    tmp_len * sizeof(NumericDigit));
   10675        1512 :             a1_var.weight = blen - 1;
   10676        1512 :             a1_var.sign = NUMERIC_POS;
   10677        1512 :             a1_var.dscale = 0;
   10678        1512 :             strip_var(&a1_var);
   10679             :         }
   10680             :         else
   10681             :         {
   10682        3006 :             zero_var(&a1_var);
   10683        3006 :             a1_var.dscale = 0;
   10684             :         }
   10685        4518 :         src_idx += blen;
   10686             : 
   10687        4518 :         if (src_idx < arg->ndigits)
   10688             :         {
   10689        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10690        1512 :             alloc_var(&a0_var, tmp_len);
   10691        1512 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10692             :                    tmp_len * sizeof(NumericDigit));
   10693        1512 :             a0_var.weight = blen - 1;
   10694        1512 :             a0_var.sign = NUMERIC_POS;
   10695        1512 :             a0_var.dscale = 0;
   10696        1512 :             strip_var(&a0_var);
   10697             :         }
   10698             :         else
   10699             :         {
   10700        3006 :             zero_var(&a0_var);
   10701        3006 :             a0_var.dscale = 0;
   10702             :         }
   10703        4518 :         src_idx += blen;
   10704             : 
   10705             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10706        4518 :         set_var_from_var(&r_var, &q_var);
   10707        4518 :         q_var.weight += blen;
   10708        4518 :         add_var(&q_var, &a1_var, &q_var);
   10709        4518 :         add_var(&s_var, &s_var, &u_var);
   10710        4518 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10711             : 
   10712             :         /* Compute s = s*b + q */
   10713        4518 :         s_var.weight += blen;
   10714        4518 :         add_var(&s_var, &q_var, &s_var);
   10715             : 
   10716             :         /*
   10717             :          * Compute r = u*b + a0 - q^2.
   10718             :          *
   10719             :          * In the final iteration, we don't actually need r; we just need to
   10720             :          * know whether it is negative, so that we know whether to adjust s.
   10721             :          * So instead of the final subtraction we can just compare.
   10722             :          */
   10723        4518 :         u_var.weight += blen;
   10724        4518 :         add_var(&u_var, &a0_var, &u_var);
   10725        4518 :         mul_var(&q_var, &q_var, &q_var, 0);
   10726             : 
   10727        4518 :         if (step > 0)
   10728             :         {
   10729             :             /* Need r for later iterations */
   10730        1794 :             sub_var(&u_var, &q_var, &r_var);
   10731        1794 :             if (r_var.sign == NUMERIC_NEG)
   10732             :             {
   10733             :                 /* s is too large by 1; set r += s, s--, r += s */
   10734         120 :                 add_var(&r_var, &s_var, &r_var);
   10735         120 :                 sub_var(&s_var, &const_one, &s_var);
   10736         120 :                 add_var(&r_var, &s_var, &r_var);
   10737             :             }
   10738             :         }
   10739             :         else
   10740             :         {
   10741             :             /* Don't need r anymore, except to test if s is too large by 1 */
   10742        2724 :             if (cmp_var(&u_var, &q_var) < 0)
   10743          36 :                 sub_var(&s_var, &const_one, &s_var);
   10744             :         }
   10745             : 
   10746             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10747        4518 :         step--;
   10748             :     }
   10749             : 
   10750             :     /*
   10751             :      * Construct the final result, rounding it to the requested precision.
   10752             :      */
   10753        4170 :     set_var_from_var(&s_var, result);
   10754        4170 :     result->weight = res_weight;
   10755        4170 :     result->sign = NUMERIC_POS;
   10756             : 
   10757             :     /* Round to target rscale (and set result->dscale) */
   10758        4170 :     round_var(result, rscale);
   10759             : 
   10760             :     /* Strip leading and trailing zeroes */
   10761        4170 :     strip_var(result);
   10762             : 
   10763        4170 :     free_var(&s_var);
   10764        4170 :     free_var(&r_var);
   10765        4170 :     free_var(&a0_var);
   10766        4170 :     free_var(&a1_var);
   10767        4170 :     free_var(&q_var);
   10768        4170 :     free_var(&u_var);
   10769             : }
   10770             : 
   10771             : 
   10772             : /*
   10773             :  * exp_var() -
   10774             :  *
   10775             :  *  Raise e to the power of x, computed to rscale fractional digits
   10776             :  */
   10777             : static void
   10778         180 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10779             : {
   10780             :     NumericVar  x;
   10781             :     NumericVar  elem;
   10782             :     int         ni;
   10783             :     double      val;
   10784             :     int         dweight;
   10785             :     int         ndiv2;
   10786             :     int         sig_digits;
   10787             :     int         local_rscale;
   10788             : 
   10789         180 :     init_var(&x);
   10790         180 :     init_var(&elem);
   10791             : 
   10792         180 :     set_var_from_var(arg, &x);
   10793             : 
   10794             :     /*
   10795             :      * Estimate the dweight of the result using floating point arithmetic, so
   10796             :      * that we can choose an appropriate local rscale for the calculation.
   10797             :      */
   10798         180 :     val = numericvar_to_double_no_overflow(&x);
   10799             : 
   10800             :     /* Guard against overflow/underflow */
   10801             :     /* If you change this limit, see also power_var()'s limit */
   10802         180 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10803             :     {
   10804           6 :         if (val > 0)
   10805           0 :             ereport(ERROR,
   10806             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10807             :                      errmsg("value overflows numeric format")));
   10808           6 :         zero_var(result);
   10809           6 :         result->dscale = rscale;
   10810           6 :         return;
   10811             :     }
   10812             : 
   10813             :     /* decimal weight = log10(e^x) = x * log10(e) */
   10814         174 :     dweight = (int) (val * 0.434294481903252);
   10815             : 
   10816             :     /*
   10817             :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10818             :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10819             :      *
   10820             :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10821             :      * means that ndiv2 <= 20 here.
   10822             :      */
   10823         174 :     if (fabs(val) > 0.01)
   10824             :     {
   10825         144 :         ndiv2 = 1;
   10826         144 :         val /= 2;
   10827             : 
   10828        1818 :         while (fabs(val) > 0.01)
   10829             :         {
   10830        1674 :             ndiv2++;
   10831        1674 :             val /= 2;
   10832             :         }
   10833             : 
   10834         144 :         local_rscale = x.dscale + ndiv2;
   10835         144 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10836             :     }
   10837             :     else
   10838          30 :         ndiv2 = 0;
   10839             : 
   10840             :     /*
   10841             :      * Set the scale for the Taylor series expansion.  The final result has
   10842             :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10843             :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10844             :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10845             :      * extra digits of precision (plus a few more for good measure).
   10846             :      */
   10847         174 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10848         174 :     sig_digits = Max(sig_digits, 0) + 8;
   10849             : 
   10850         174 :     local_rscale = sig_digits - 1;
   10851             : 
   10852             :     /*
   10853             :      * Use the Taylor series
   10854             :      *
   10855             :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10856             :      *
   10857             :      * Given the limited range of x, this should converge reasonably quickly.
   10858             :      * We run the series until the terms fall below the local_rscale limit.
   10859             :      */
   10860         174 :     add_var(&const_one, &x, result);
   10861             : 
   10862         174 :     mul_var(&x, &x, &elem, local_rscale);
   10863         174 :     ni = 2;
   10864         174 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10865             : 
   10866        4992 :     while (elem.ndigits != 0)
   10867             :     {
   10868        4818 :         add_var(result, &elem, result);
   10869             : 
   10870        4818 :         mul_var(&elem, &x, &elem, local_rscale);
   10871        4818 :         ni++;
   10872        4818 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10873             :     }
   10874             : 
   10875             :     /*
   10876             :      * Compensate for the argument range reduction.  Since the weight of the
   10877             :      * result doubles with each multiplication, we can reduce the local rscale
   10878             :      * as we proceed.
   10879             :      */
   10880        1992 :     while (ndiv2-- > 0)
   10881             :     {
   10882        1818 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   10883        1818 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10884        1818 :         mul_var(result, result, result, local_rscale);
   10885             :     }
   10886             : 
   10887             :     /* Round to requested rscale */
   10888         174 :     round_var(result, rscale);
   10889             : 
   10890         174 :     free_var(&x);
   10891         174 :     free_var(&elem);
   10892             : }
   10893             : 
   10894             : 
   10895             : /*
   10896             :  * Estimate the dweight of the most significant decimal digit of the natural
   10897             :  * logarithm of a number.
   10898             :  *
   10899             :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   10900             :  * determine the appropriate rscale when computing natural logarithms.
   10901             :  *
   10902             :  * Note: many callers call this before range-checking the input.  Therefore,
   10903             :  * we must be robust against values that are invalid to apply ln() to.
   10904             :  * We don't wish to throw an error here, so just return zero in such cases.
   10905             :  */
   10906             : static int
   10907         738 : estimate_ln_dweight(const NumericVar *var)
   10908             : {
   10909             :     int         ln_dweight;
   10910             : 
   10911             :     /* Caller should fail on ln(negative), but for the moment return zero */
   10912         738 :     if (var->sign != NUMERIC_POS)
   10913          42 :         return 0;
   10914             : 
   10915        1314 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   10916         618 :         cmp_var(var, &const_one_point_one) <= 0)
   10917          90 :     {
   10918             :         /*
   10919             :          * 0.9 <= var <= 1.1
   10920             :          *
   10921             :          * ln(var) has a negative weight (possibly very large).  To get a
   10922             :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   10923             :          */
   10924             :         NumericVar  x;
   10925             : 
   10926          90 :         init_var(&x);
   10927          90 :         sub_var(var, &const_one, &x);
   10928             : 
   10929          90 :         if (x.ndigits > 0)
   10930             :         {
   10931             :             /* Use weight of most significant decimal digit of x */
   10932          42 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   10933             :         }
   10934             :         else
   10935             :         {
   10936             :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   10937          48 :             ln_dweight = 0;
   10938             :         }
   10939             : 
   10940          90 :         free_var(&x);
   10941             :     }
   10942             :     else
   10943             :     {
   10944             :         /*
   10945             :          * Estimate the logarithm using the first couple of digits from the
   10946             :          * input number.  This will give an accurate result whenever the input
   10947             :          * is not too close to 1.
   10948             :          */
   10949         606 :         if (var->ndigits > 0)
   10950             :         {
   10951             :             int         digits;
   10952             :             int         dweight;
   10953             :             double      ln_var;
   10954             : 
   10955         564 :             digits = var->digits[0];
   10956         564 :             dweight = var->weight * DEC_DIGITS;
   10957             : 
   10958         564 :             if (var->ndigits > 1)
   10959             :             {
   10960         342 :                 digits = digits * NBASE + var->digits[1];
   10961         342 :                 dweight -= DEC_DIGITS;
   10962             :             }
   10963             : 
   10964             :             /*----------
   10965             :              * We have var ~= digits * 10^dweight
   10966             :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   10967             :              *----------
   10968             :              */
   10969         564 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   10970         564 :             ln_dweight = (int) log10(fabs(ln_var));
   10971             :         }
   10972             :         else
   10973             :         {
   10974             :             /* Caller should fail on ln(0), but for the moment return zero */
   10975          42 :             ln_dweight = 0;
   10976             :         }
   10977             :     }
   10978             : 
   10979         696 :     return ln_dweight;
   10980             : }
   10981             : 
   10982             : 
   10983             : /*
   10984             :  * ln_var() -
   10985             :  *
   10986             :  *  Compute the natural log of x
   10987             :  */
   10988             : static void
   10989         834 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   10990             : {
   10991             :     NumericVar  x;
   10992             :     NumericVar  xx;
   10993             :     int         ni;
   10994             :     NumericVar  elem;
   10995             :     NumericVar  fact;
   10996             :     int         nsqrt;
   10997             :     int         local_rscale;
   10998             :     int         cmp;
   10999             : 
   11000         834 :     cmp = cmp_var(arg, &const_zero);
   11001         834 :     if (cmp == 0)
   11002          42 :         ereport(ERROR,
   11003             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   11004             :                  errmsg("cannot take logarithm of zero")));
   11005         792 :     else if (cmp < 0)
   11006          36 :         ereport(ERROR,
   11007             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   11008             :                  errmsg("cannot take logarithm of a negative number")));
   11009             : 
   11010         756 :     init_var(&x);
   11011         756 :     init_var(&xx);
   11012         756 :     init_var(&elem);
   11013         756 :     init_var(&fact);
   11014             : 
   11015         756 :     set_var_from_var(arg, &x);
   11016         756 :     set_var_from_var(&const_two, &fact);
   11017             : 
   11018             :     /*
   11019             :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   11020             :      *
   11021             :      * The final logarithm will have up to around rscale+6 significant digits.
   11022             :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   11023             :      * rscale as we work so that we keep this many significant digits at each
   11024             :      * step (plus a few more for good measure).
   11025             :      *
   11026             :      * Note that we allow local_rscale < 0 during this input reduction
   11027             :      * process, which implies rounding before the decimal point.  sqrt_var()
   11028             :      * explicitly supports this, and it significantly reduces the work
   11029             :      * required to reduce very large inputs to the required range.  Once the
   11030             :      * input reduction is complete, x.weight will be 0 and its display scale
   11031             :      * will be non-negative again.
   11032             :      */
   11033         756 :     nsqrt = 0;
   11034        1068 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   11035             :     {
   11036         312 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   11037         312 :         sqrt_var(&x, &x, local_rscale);
   11038         312 :         mul_var(&fact, &const_two, &fact, 0);
   11039         312 :         nsqrt++;
   11040             :     }
   11041        4128 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   11042             :     {
   11043        3372 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   11044        3372 :         sqrt_var(&x, &x, local_rscale);
   11045        3372 :         mul_var(&fact, &const_two, &fact, 0);
   11046        3372 :         nsqrt++;
   11047             :     }
   11048             : 
   11049             :     /*
   11050             :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   11051             :      *
   11052             :      * z + z^3/3 + z^5/5 + ...
   11053             :      *
   11054             :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   11055             :      * due to the above range-reduction of x.
   11056             :      *
   11057             :      * The convergence of this is not as fast as one would like, but is
   11058             :      * tolerable given that z is small.
   11059             :      *
   11060             :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   11061             :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   11062             :      * digits of precision (plus a few more for good measure).
   11063             :      */
   11064         756 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   11065             : 
   11066         756 :     sub_var(&x, &const_one, result);
   11067         756 :     add_var(&x, &const_one, &elem);
   11068         756 :     div_var(result, &elem, result, local_rscale, true, false);
   11069         756 :     set_var_from_var(result, &xx);
   11070         756 :     mul_var(result, result, &x, local_rscale);
   11071             : 
   11072         756 :     ni = 1;
   11073             : 
   11074             :     for (;;)
   11075             :     {
   11076       14022 :         ni += 2;
   11077       14022 :         mul_var(&xx, &x, &xx, local_rscale);
   11078       14022 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   11079             : 
   11080       14022 :         if (elem.ndigits == 0)
   11081         756 :             break;
   11082             : 
   11083       13266 :         add_var(result, &elem, result);
   11084             : 
   11085       13266 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   11086           0 :             break;
   11087             :     }
   11088             : 
   11089             :     /* Compensate for argument range reduction, round to requested rscale */
   11090         756 :     mul_var(result, &fact, result, rscale);
   11091             : 
   11092         756 :     free_var(&x);
   11093         756 :     free_var(&xx);
   11094         756 :     free_var(&elem);
   11095         756 :     free_var(&fact);
   11096         756 : }
   11097             : 
   11098             : 
   11099             : /*
   11100             :  * log_var() -
   11101             :  *
   11102             :  *  Compute the logarithm of num in a given base.
   11103             :  *
   11104             :  *  Note: this routine chooses dscale of the result.
   11105             :  */
   11106             : static void
   11107         216 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   11108             : {
   11109             :     NumericVar  ln_base;
   11110             :     NumericVar  ln_num;
   11111             :     int         ln_base_dweight;
   11112             :     int         ln_num_dweight;
   11113             :     int         result_dweight;
   11114             :     int         rscale;
   11115             :     int         ln_base_rscale;
   11116             :     int         ln_num_rscale;
   11117             : 
   11118         216 :     init_var(&ln_base);
   11119         216 :     init_var(&ln_num);
   11120             : 
   11121             :     /* Estimated dweights of ln(base), ln(num) and the final result */
   11122         216 :     ln_base_dweight = estimate_ln_dweight(base);
   11123         216 :     ln_num_dweight = estimate_ln_dweight(num);
   11124         216 :     result_dweight = ln_num_dweight - ln_base_dweight;
   11125             : 
   11126             :     /*
   11127             :      * Select the scale of the result so that it will have at least
   11128             :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   11129             :      * input's display scale.
   11130             :      */
   11131         216 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   11132         216 :     rscale = Max(rscale, base->dscale);
   11133         216 :     rscale = Max(rscale, num->dscale);
   11134         216 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11135         216 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11136             : 
   11137             :     /*
   11138             :      * Set the scales for ln(base) and ln(num) so that they each have more
   11139             :      * significant digits than the final result.
   11140             :      */
   11141         216 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   11142         216 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11143             : 
   11144         216 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   11145         216 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11146             : 
   11147             :     /* Form natural logarithms */
   11148         216 :     ln_var(base, &ln_base, ln_base_rscale);
   11149         192 :     ln_var(num, &ln_num, ln_num_rscale);
   11150             : 
   11151             :     /* Divide and round to the required scale */
   11152         162 :     div_var(&ln_num, &ln_base, result, rscale, true, false);
   11153             : 
   11154         156 :     free_var(&ln_num);
   11155         156 :     free_var(&ln_base);
   11156         156 : }
   11157             : 
   11158             : 
   11159             : /*
   11160             :  * power_var() -
   11161             :  *
   11162             :  *  Raise base to the power of exp
   11163             :  *
   11164             :  *  Note: this routine chooses dscale of the result.
   11165             :  */
   11166             : static void
   11167        1398 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   11168             : {
   11169             :     int         res_sign;
   11170             :     NumericVar  abs_base;
   11171             :     NumericVar  ln_base;
   11172             :     NumericVar  ln_num;
   11173             :     int         ln_dweight;
   11174             :     int         rscale;
   11175             :     int         sig_digits;
   11176             :     int         local_rscale;
   11177             :     double      val;
   11178             : 
   11179             :     /* If exp can be represented as an integer, use power_var_int */
   11180        1398 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   11181             :     {
   11182             :         /* exact integer, but does it fit in int? */
   11183             :         int64       expval64;
   11184             : 
   11185        1272 :         if (numericvar_to_int64(exp, &expval64))
   11186             :         {
   11187        1266 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   11188             :             {
   11189             :                 /* Okay, use power_var_int */
   11190        1236 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   11191        1224 :                 return;
   11192             :             }
   11193             :         }
   11194             :     }
   11195             : 
   11196             :     /*
   11197             :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   11198             :      * handled by power_var_int().
   11199             :      */
   11200         162 :     if (cmp_var(base, &const_zero) == 0)
   11201             :     {
   11202          18 :         set_var_from_var(&const_zero, result);
   11203          18 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   11204          18 :         return;
   11205             :     }
   11206             : 
   11207         144 :     init_var(&abs_base);
   11208         144 :     init_var(&ln_base);
   11209         144 :     init_var(&ln_num);
   11210             : 
   11211             :     /*
   11212             :      * If base is negative, insist that exp be an integer.  The result is then
   11213             :      * positive if exp is even and negative if exp is odd.
   11214             :      */
   11215         144 :     if (base->sign == NUMERIC_NEG)
   11216             :     {
   11217             :         /*
   11218             :          * Check that exp is an integer.  This error code is defined by the
   11219             :          * SQL standard, and matches other errors in numeric_power().
   11220             :          */
   11221          36 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   11222          18 :             ereport(ERROR,
   11223             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   11224             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   11225             : 
   11226             :         /* Test if exp is odd or even */
   11227          18 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   11228          12 :             (exp->digits[exp->ndigits - 1] & 1))
   11229           6 :             res_sign = NUMERIC_NEG;
   11230             :         else
   11231          12 :             res_sign = NUMERIC_POS;
   11232             : 
   11233             :         /* Then work with abs(base) below */
   11234          18 :         set_var_from_var(base, &abs_base);
   11235          18 :         abs_base.sign = NUMERIC_POS;
   11236          18 :         base = &abs_base;
   11237             :     }
   11238             :     else
   11239         108 :         res_sign = NUMERIC_POS;
   11240             : 
   11241             :     /*----------
   11242             :      * Decide on the scale for the ln() calculation.  For this we need an
   11243             :      * estimate of the weight of the result, which we obtain by doing an
   11244             :      * initial low-precision calculation of exp * ln(base).
   11245             :      *
   11246             :      * We want result = e ^ (exp * ln(base))
   11247             :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   11248             :      *
   11249             :      * We also perform a crude overflow test here so that we can exit early if
   11250             :      * the full-precision result is sure to overflow, and to guard against
   11251             :      * integer overflow when determining the scale for the real calculation.
   11252             :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   11253             :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   11254             :      * Since the values here are only approximations, we apply a small fuzz
   11255             :      * factor to this overflow test and let exp_var() determine the exact
   11256             :      * overflow threshold so that it is consistent for all inputs.
   11257             :      *----------
   11258             :      */
   11259         126 :     ln_dweight = estimate_ln_dweight(base);
   11260             : 
   11261             :     /*
   11262             :      * Set the scale for the low-precision calculation, computing ln(base) to
   11263             :      * around 8 significant digits.  Note that ln_dweight may be as small as
   11264             :      * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
   11265             :      * here.
   11266             :      */
   11267         126 :     local_rscale = 8 - ln_dweight;
   11268         126 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11269             : 
   11270         126 :     ln_var(base, &ln_base, local_rscale);
   11271             : 
   11272         126 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11273             : 
   11274         126 :     val = numericvar_to_double_no_overflow(&ln_num);
   11275             : 
   11276             :     /* initial overflow/underflow test with fuzz factor */
   11277         126 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   11278             :     {
   11279           6 :         if (val > 0)
   11280           0 :             ereport(ERROR,
   11281             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11282             :                      errmsg("value overflows numeric format")));
   11283           6 :         zero_var(result);
   11284           6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11285           6 :         return;
   11286             :     }
   11287             : 
   11288         120 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   11289             : 
   11290             :     /* choose the result scale */
   11291         120 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   11292         120 :     rscale = Max(rscale, base->dscale);
   11293         120 :     rscale = Max(rscale, exp->dscale);
   11294         120 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11295         120 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11296             : 
   11297             :     /* significant digits required in the result */
   11298         120 :     sig_digits = rscale + (int) val;
   11299         120 :     sig_digits = Max(sig_digits, 0);
   11300             : 
   11301             :     /* set the scale for the real exp * ln(base) calculation */
   11302         120 :     local_rscale = sig_digits - ln_dweight + 8;
   11303         120 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11304             : 
   11305             :     /* and do the real calculation */
   11306             : 
   11307         120 :     ln_var(base, &ln_base, local_rscale);
   11308             : 
   11309         120 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11310             : 
   11311         120 :     exp_var(&ln_num, result, rscale);
   11312             : 
   11313         120 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   11314           6 :         result->sign = NUMERIC_NEG;
   11315             : 
   11316         120 :     free_var(&ln_num);
   11317         120 :     free_var(&ln_base);
   11318         120 :     free_var(&abs_base);
   11319             : }
   11320             : 
   11321             : /*
   11322             :  * power_var_int() -
   11323             :  *
   11324             :  *  Raise base to the power of exp, where exp is an integer.
   11325             :  *
   11326             :  *  Note: this routine chooses dscale of the result.
   11327             :  */
   11328             : static void
   11329        1236 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   11330             :               NumericVar *result)
   11331             : {
   11332             :     double      f;
   11333             :     int         p;
   11334             :     int         i;
   11335             :     int         rscale;
   11336             :     int         sig_digits;
   11337             :     unsigned int mask;
   11338             :     bool        neg;
   11339             :     NumericVar  base_prod;
   11340             :     int         local_rscale;
   11341             : 
   11342             :     /*
   11343             :      * Choose the result scale.  For this we need an estimate of the decimal
   11344             :      * weight of the result, which we obtain by approximating using double
   11345             :      * precision arithmetic.
   11346             :      *
   11347             :      * We also perform crude overflow/underflow tests here so that we can exit
   11348             :      * early if the result is sure to overflow/underflow, and to guard against
   11349             :      * integer overflow when choosing the result scale.
   11350             :      */
   11351        1236 :     if (base->ndigits != 0)
   11352             :     {
   11353             :         /*----------
   11354             :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11355             :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11356             :          *----------
   11357             :          */
   11358        1206 :         f = base->digits[0];
   11359        1206 :         p = base->weight * DEC_DIGITS;
   11360             : 
   11361        1290 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11362             :         {
   11363          84 :             f = f * NBASE + base->digits[i];
   11364          84 :             p -= DEC_DIGITS;
   11365             :         }
   11366             : 
   11367        1206 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11368             :     }
   11369             :     else
   11370          30 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11371             : 
   11372             :     /* overflow/underflow tests with fuzz factors */
   11373        1236 :     if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
   11374          12 :         ereport(ERROR,
   11375             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11376             :                  errmsg("value overflows numeric format")));
   11377        1224 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11378             :     {
   11379          12 :         zero_var(result);
   11380          12 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11381         216 :         return;
   11382             :     }
   11383             : 
   11384             :     /*
   11385             :      * Choose the result scale in the same way as power_var(), so it has at
   11386             :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11387             :      * either input's display scale.
   11388             :      */
   11389        1212 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11390        1212 :     rscale = Max(rscale, base->dscale);
   11391        1212 :     rscale = Max(rscale, exp_dscale);
   11392        1212 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11393        1212 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11394             : 
   11395             :     /* Handle some common special cases, as well as corner cases */
   11396        1212 :     switch (exp)
   11397             :     {
   11398          72 :         case 0:
   11399             : 
   11400             :             /*
   11401             :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11402             :              * it as 1 because most programming languages do this. SQL:2003
   11403             :              * also requires a return value of 1.
   11404             :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11405             :              */
   11406          72 :             set_var_from_var(&const_one, result);
   11407          72 :             result->dscale = rscale; /* no need to round */
   11408          72 :             return;
   11409          48 :         case 1:
   11410          48 :             set_var_from_var(base, result);
   11411          48 :             round_var(result, rscale);
   11412          48 :             return;
   11413          30 :         case -1:
   11414          30 :             div_var(&const_one, base, result, rscale, true, true);
   11415          30 :             return;
   11416          54 :         case 2:
   11417          54 :             mul_var(base, base, result, rscale);
   11418          54 :             return;
   11419        1008 :         default:
   11420        1008 :             break;
   11421             :     }
   11422             : 
   11423             :     /* Handle the special case where the base is zero */
   11424        1008 :     if (base->ndigits == 0)
   11425             :     {
   11426           0 :         if (exp < 0)
   11427           0 :             ereport(ERROR,
   11428             :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11429             :                      errmsg("division by zero")));
   11430           0 :         zero_var(result);
   11431           0 :         result->dscale = rscale;
   11432           0 :         return;
   11433             :     }
   11434             : 
   11435             :     /*
   11436             :      * The general case repeatedly multiplies base according to the bit
   11437             :      * pattern of exp.
   11438             :      *
   11439             :      * The local rscale used for each multiplication is varied to keep a fixed
   11440             :      * number of significant digits, sufficient to give the required result
   11441             :      * scale.
   11442             :      */
   11443             : 
   11444             :     /*
   11445             :      * Approximate number of significant digits in the result.  Note that the
   11446             :      * underflow test above, together with the choice of rscale, ensures that
   11447             :      * this approximation is necessarily > 0.
   11448             :      */
   11449        1008 :     sig_digits = 1 + rscale + (int) f;
   11450             : 
   11451             :     /*
   11452             :      * The multiplications to produce the result may introduce an error of up
   11453             :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11454             :      * of precision (plus a few more for good measure).
   11455             :      */
   11456        1008 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11457             : 
   11458             :     /*
   11459             :      * Now we can proceed with the multiplications.
   11460             :      */
   11461        1008 :     neg = (exp < 0);
   11462        1008 :     mask = pg_abs_s32(exp);
   11463             : 
   11464        1008 :     init_var(&base_prod);
   11465        1008 :     set_var_from_var(base, &base_prod);
   11466             : 
   11467        1008 :     if (mask & 1)
   11468         498 :         set_var_from_var(base, result);
   11469             :     else
   11470         510 :         set_var_from_var(&const_one, result);
   11471             : 
   11472        5076 :     while ((mask >>= 1) > 0)
   11473             :     {
   11474             :         /*
   11475             :          * Do the multiplications using rscales large enough to hold the
   11476             :          * results to the required number of significant digits, but don't
   11477             :          * waste time by exceeding the scales of the numbers themselves.
   11478             :          */
   11479        4068 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11480        4068 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11481        4068 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11482             : 
   11483        4068 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11484             : 
   11485        4068 :         if (mask & 1)
   11486             :         {
   11487        2658 :             local_rscale = sig_digits -
   11488        2658 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11489        2658 :             local_rscale = Min(local_rscale,
   11490             :                                base_prod.dscale + result->dscale);
   11491        2658 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11492             : 
   11493        2658 :             mul_var(&base_prod, result, result, local_rscale);
   11494             :         }
   11495             : 
   11496             :         /*
   11497             :          * When abs(base) > 1, the number of digits to the left of the decimal
   11498             :          * point in base_prod doubles at each iteration, so if exp is large we
   11499             :          * could easily spend large amounts of time and memory space doing the
   11500             :          * multiplications.  But once the weight exceeds what will fit in
   11501             :          * int16, the final result is guaranteed to overflow (or underflow, if
   11502             :          * exp < 0), so we can give up before wasting too many cycles.
   11503             :          */
   11504        4068 :         if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
   11505        4068 :             result->weight > NUMERIC_WEIGHT_MAX)
   11506             :         {
   11507             :             /* overflow, unless neg, in which case result should be 0 */
   11508           0 :             if (!neg)
   11509           0 :                 ereport(ERROR,
   11510             :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11511             :                          errmsg("value overflows numeric format")));
   11512           0 :             zero_var(result);
   11513           0 :             neg = false;
   11514           0 :             break;
   11515             :         }
   11516             :     }
   11517             : 
   11518        1008 :     free_var(&base_prod);
   11519             : 
   11520             :     /* Compensate for input sign, and round to requested rscale */
   11521        1008 :     if (neg)
   11522         486 :         div_var(&const_one, result, result, rscale, true, false);
   11523             :     else
   11524         522 :         round_var(result, rscale);
   11525             : }
   11526             : 
   11527             : /*
   11528             :  * power_ten_int() -
   11529             :  *
   11530             :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11531             :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11532             :  */
   11533             : static void
   11534         228 : power_ten_int(int exp, NumericVar *result)
   11535             : {
   11536             :     /* Construct the result directly, starting from 10^0 = 1 */
   11537         228 :     set_var_from_var(&const_one, result);
   11538             : 
   11539             :     /* Scale needed to represent the result exactly */
   11540         228 :     result->dscale = exp < 0 ? -exp : 0;
   11541             : 
   11542             :     /* Base-NBASE weight of result and remaining exponent */
   11543         228 :     if (exp >= 0)
   11544         162 :         result->weight = exp / DEC_DIGITS;
   11545             :     else
   11546          66 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11547             : 
   11548         228 :     exp -= result->weight * DEC_DIGITS;
   11549             : 
   11550             :     /* Final adjustment of the result's single NBASE digit */
   11551         594 :     while (exp-- > 0)
   11552         366 :         result->digits[0] *= 10;
   11553         228 : }
   11554             : 
   11555             : /*
   11556             :  * random_var() - return a random value in the range [rmin, rmax].
   11557             :  */
   11558             : static void
   11559       33438 : random_var(pg_prng_state *state, const NumericVar *rmin,
   11560             :            const NumericVar *rmax, NumericVar *result)
   11561             : {
   11562             :     int         rscale;
   11563             :     NumericVar  rlen;
   11564             :     int         res_ndigits;
   11565             :     int         n;
   11566             :     int         pow10;
   11567             :     int         i;
   11568             :     uint64      rlen64;
   11569             :     int         rlen64_ndigits;
   11570             : 
   11571       33438 :     rscale = Max(rmin->dscale, rmax->dscale);
   11572             : 
   11573             :     /* Compute rlen = rmax - rmin and check the range bounds */
   11574       33438 :     init_var(&rlen);
   11575       33438 :     sub_var(rmax, rmin, &rlen);
   11576             : 
   11577       33438 :     if (rlen.sign == NUMERIC_NEG)
   11578           6 :         ereport(ERROR,
   11579             :                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
   11580             :                 errmsg("lower bound must be less than or equal to upper bound"));
   11581             : 
   11582             :     /* Special case for an empty range */
   11583       33432 :     if (rlen.ndigits == 0)
   11584             :     {
   11585          12 :         set_var_from_var(rmin, result);
   11586          12 :         result->dscale = rscale;
   11587          12 :         free_var(&rlen);
   11588          12 :         return;
   11589             :     }
   11590             : 
   11591             :     /*
   11592             :      * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
   11593             :      * and shift it to the required range by adding rmin.
   11594             :      */
   11595             : 
   11596             :     /* Required result digits */
   11597       33420 :     res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   11598             : 
   11599             :     /*
   11600             :      * To get the required rscale, the final result digit must be a multiple
   11601             :      * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
   11602             :      */
   11603       33420 :     n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
   11604       33420 :     pow10 = 1;
   11605       87900 :     for (i = 0; i < n; i++)
   11606       54480 :         pow10 *= 10;
   11607             : 
   11608             :     /*
   11609             :      * To choose a random value uniformly from the range [0, rlen], we choose
   11610             :      * from the slightly larger range [0, rlen2], where rlen2 is formed from
   11611             :      * rlen by copying the first 4 NBASE digits, and setting all remaining
   11612             :      * decimal digits to "9".
   11613             :      *
   11614             :      * Without loss of generality, we can ignore the weight of rlen2 and treat
   11615             :      * it as a pure integer for the purposes of this discussion.  The process
   11616             :      * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
   11617             :      * is a 64-bit integer formed from the first 4 NBASE digits copied from
   11618             :      * rlen.  Since this trivially factors into smaller pieces that fit in
   11619             :      * 64-bit integers, the task of choosing a random value uniformly from the
   11620             :      * rlen2 + 1 possible values in [0, rlen2] is much simpler.
   11621             :      *
   11622             :      * If the random value selected is too large, it is rejected, and we try
   11623             :      * again until we get a result <= rlen, ensuring that the overall result
   11624             :      * is uniform (no particular value is any more likely than any other).
   11625             :      *
   11626             :      * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
   11627             :      * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
   11628             :      * when DEC_DIGITS is 4). Therefore the probability of needing to reject
   11629             :      * the value chosen and retry is less than 1e-13.
   11630             :      */
   11631       33420 :     rlen64 = (uint64) rlen.digits[0];
   11632       33420 :     rlen64_ndigits = 1;
   11633       76212 :     while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
   11634             :     {
   11635       42792 :         rlen64 *= NBASE;
   11636       42792 :         if (rlen64_ndigits < rlen.ndigits)
   11637        6612 :             rlen64 += rlen.digits[rlen64_ndigits];
   11638       42792 :         rlen64_ndigits++;
   11639             :     }
   11640             : 
   11641             :     /* Loop until we get a result <= rlen */
   11642             :     do
   11643             :     {
   11644             :         NumericDigit *res_digits;
   11645             :         uint64      rand;
   11646             :         int         whole_ndigits;
   11647             : 
   11648       33420 :         alloc_var(result, res_ndigits);
   11649       33420 :         result->sign = NUMERIC_POS;
   11650       33420 :         result->weight = rlen.weight;
   11651       33420 :         result->dscale = rscale;
   11652       33420 :         res_digits = result->digits;
   11653             : 
   11654             :         /*
   11655             :          * Set the first rlen64_ndigits using a random value in [0, rlen64].
   11656             :          *
   11657             :          * If this is the whole result, and rscale is not a multiple of
   11658             :          * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
   11659             :          * multiple of pow10.
   11660             :          */
   11661       33420 :         if (rlen64_ndigits == res_ndigits && pow10 != 1)
   11662       21132 :             rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
   11663             :         else
   11664       12288 :             rand = pg_prng_uint64_range(state, 0, rlen64);
   11665             : 
   11666      109632 :         for (i = rlen64_ndigits - 1; i >= 0; i--)
   11667             :         {
   11668       76212 :             res_digits[i] = (NumericDigit) (rand % NBASE);
   11669       76212 :             rand = rand / NBASE;
   11670             :         }
   11671             : 
   11672             :         /*
   11673             :          * Set the remaining digits to random values in range [0, NBASE),
   11674             :          * noting that the last digit needs to be a multiple of pow10.
   11675             :          */
   11676       33420 :         whole_ndigits = res_ndigits;
   11677       33420 :         if (pow10 != 1)
   11678       33210 :             whole_ndigits--;
   11679             : 
   11680             :         /* Set whole digits in groups of 4 for best performance */
   11681       33420 :         i = rlen64_ndigits;
   11682       33480 :         while (i < whole_ndigits - 3)
   11683             :         {
   11684          60 :             rand = pg_prng_uint64_range(state, 0,
   11685             :                                         (uint64) NBASE * NBASE * NBASE * NBASE - 1);
   11686          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11687          60 :             rand = rand / NBASE;
   11688          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11689          60 :             rand = rand / NBASE;
   11690          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11691          60 :             rand = rand / NBASE;
   11692          60 :             res_digits[i++] = (NumericDigit) rand;
   11693             :         }
   11694             : 
   11695             :         /* Remaining whole digits */
   11696       33630 :         while (i < whole_ndigits)
   11697             :         {
   11698         210 :             rand = pg_prng_uint64_range(state, 0, NBASE - 1);
   11699         210 :             res_digits[i++] = (NumericDigit) rand;
   11700             :         }
   11701             : 
   11702             :         /* Final partial digit (multiple of pow10) */
   11703       33420 :         if (i < res_ndigits)
   11704             :         {
   11705       12078 :             rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
   11706       12078 :             res_digits[i] = (NumericDigit) rand;
   11707             :         }
   11708             : 
   11709             :         /* Remove leading/trailing zeroes */
   11710       33420 :         strip_var(result);
   11711             : 
   11712             :         /* If result > rlen, try again */
   11713             : 
   11714       33420 :     } while (cmp_var(result, &rlen) > 0);
   11715             : 
   11716             :     /* Offset the result to the required range */
   11717       33420 :     add_var(result, rmin, result);
   11718             : 
   11719       33420 :     free_var(&rlen);
   11720             : }
   11721             : 
   11722             : 
   11723             : /* ----------------------------------------------------------------------
   11724             :  *
   11725             :  * Following are the lowest level functions that operate unsigned
   11726             :  * on the variable level
   11727             :  *
   11728             :  * ----------------------------------------------------------------------
   11729             :  */
   11730             : 
   11731             : 
   11732             : /* ----------
   11733             :  * cmp_abs() -
   11734             :  *
   11735             :  *  Compare the absolute values of var1 and var2
   11736             :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11737             :  *              0  for ABS(var1) == ABS(var2)
   11738             :  *              1  for ABS(var1) > ABS(var2)
   11739             :  * ----------
   11740             :  */
   11741             : static int
   11742      358344 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11743             : {
   11744      716688 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11745      358344 :                           var2->digits, var2->ndigits, var2->weight);
   11746             : }
   11747             : 
   11748             : /* ----------
   11749             :  * cmp_abs_common() -
   11750             :  *
   11751             :  *  Main routine of cmp_abs(). This function can be used by both
   11752             :  *  NumericVar and Numeric.
   11753             :  * ----------
   11754             :  */
   11755             : static int
   11756     6224118 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11757             :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11758             : {
   11759     6224118 :     int         i1 = 0;
   11760     6224118 :     int         i2 = 0;
   11761             : 
   11762             :     /* Check any digits before the first common digit */
   11763             : 
   11764     6224118 :     while (var1weight > var2weight && i1 < var1ndigits)
   11765             :     {
   11766       29634 :         if (var1digits[i1++] != 0)
   11767       29634 :             return 1;
   11768           0 :         var1weight--;
   11769             :     }
   11770     6194484 :     while (var2weight > var1weight && i2 < var2ndigits)
   11771             :     {
   11772       31918 :         if (var2digits[i2++] != 0)
   11773       31918 :             return -1;
   11774           0 :         var2weight--;
   11775             :     }
   11776             : 
   11777             :     /* At this point, either w1 == w2 or we've run out of digits */
   11778             : 
   11779     6162566 :     if (var1weight == var2weight)
   11780             :     {
   11781    11592786 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11782             :         {
   11783     7851716 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11784             : 
   11785     7851716 :             if (stat)
   11786             :             {
   11787     2415122 :                 if (stat > 0)
   11788     1603194 :                     return 1;
   11789      811928 :                 return -1;
   11790             :             }
   11791             :         }
   11792             :     }
   11793             : 
   11794             :     /*
   11795             :      * At this point, we've run out of digits on one side or the other; so any
   11796             :      * remaining nonzero digits imply that side is larger
   11797             :      */
   11798     3747744 :     while (i1 < var1ndigits)
   11799             :     {
   11800        8258 :         if (var1digits[i1++] != 0)
   11801        7958 :             return 1;
   11802             :     }
   11803     3739666 :     while (i2 < var2ndigits)
   11804             :     {
   11805        1074 :         if (var2digits[i2++] != 0)
   11806         894 :             return -1;
   11807             :     }
   11808             : 
   11809     3738592 :     return 0;
   11810             : }
   11811             : 
   11812             : 
   11813             : /*
   11814             :  * add_abs() -
   11815             :  *
   11816             :  *  Add the absolute values of two variables into result.
   11817             :  *  result might point to one of the operands without danger.
   11818             :  */
   11819             : static void
   11820      330546 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11821             : {
   11822             :     NumericDigit *res_buf;
   11823             :     NumericDigit *res_digits;
   11824             :     int         res_ndigits;
   11825             :     int         res_weight;
   11826             :     int         res_rscale,
   11827             :                 rscale1,
   11828             :                 rscale2;
   11829             :     int         res_dscale;
   11830             :     int         i,
   11831             :                 i1,
   11832             :                 i2;
   11833      330546 :     int         carry = 0;
   11834             : 
   11835             :     /* copy these values into local vars for speed in inner loop */
   11836      330546 :     int         var1ndigits = var1->ndigits;
   11837      330546 :     int         var2ndigits = var2->ndigits;
   11838      330546 :     NumericDigit *var1digits = var1->digits;
   11839      330546 :     NumericDigit *var2digits = var2->digits;
   11840             : 
   11841      330546 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11842             : 
   11843      330546 :     res_dscale = Max(var1->dscale, var2->dscale);
   11844             : 
   11845             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11846      330546 :     rscale1 = var1->ndigits - var1->weight - 1;
   11847      330546 :     rscale2 = var2->ndigits - var2->weight - 1;
   11848      330546 :     res_rscale = Max(rscale1, rscale2);
   11849             : 
   11850      330546 :     res_ndigits = res_rscale + res_weight + 1;
   11851      330546 :     if (res_ndigits <= 0)
   11852           0 :         res_ndigits = 1;
   11853             : 
   11854      330546 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11855      330546 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11856      330546 :     res_digits = res_buf + 1;
   11857             : 
   11858      330546 :     i1 = res_rscale + var1->weight + 1;
   11859      330546 :     i2 = res_rscale + var2->weight + 1;
   11860     3366702 :     for (i = res_ndigits - 1; i >= 0; i--)
   11861             :     {
   11862     3036156 :         i1--;
   11863     3036156 :         i2--;
   11864     3036156 :         if (i1 >= 0 && i1 < var1ndigits)
   11865     1369246 :             carry += var1digits[i1];
   11866     3036156 :         if (i2 >= 0 && i2 < var2ndigits)
   11867     1037704 :             carry += var2digits[i2];
   11868             : 
   11869     3036156 :         if (carry >= NBASE)
   11870             :         {
   11871      234292 :             res_digits[i] = carry - NBASE;
   11872      234292 :             carry = 1;
   11873             :         }
   11874             :         else
   11875             :         {
   11876     2801864 :             res_digits[i] = carry;
   11877     2801864 :             carry = 0;
   11878             :         }
   11879             :     }
   11880             : 
   11881             :     Assert(carry == 0);         /* else we failed to allow for carry out */
   11882             : 
   11883      330546 :     digitbuf_free(result->buf);
   11884      330546 :     result->ndigits = res_ndigits;
   11885      330546 :     result->buf = res_buf;
   11886      330546 :     result->digits = res_digits;
   11887      330546 :     result->weight = res_weight;
   11888      330546 :     result->dscale = res_dscale;
   11889             : 
   11890             :     /* Remove leading/trailing zeroes */
   11891      330546 :     strip_var(result);
   11892      330546 : }
   11893             : 
   11894             : 
   11895             : /*
   11896             :  * sub_abs()
   11897             :  *
   11898             :  *  Subtract the absolute value of var2 from the absolute value of var1
   11899             :  *  and store in result. result might point to one of the operands
   11900             :  *  without danger.
   11901             :  *
   11902             :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   11903             :  */
   11904             : static void
   11905      324100 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11906             : {
   11907             :     NumericDigit *res_buf;
   11908             :     NumericDigit *res_digits;
   11909             :     int         res_ndigits;
   11910             :     int         res_weight;
   11911             :     int         res_rscale,
   11912             :                 rscale1,
   11913             :                 rscale2;
   11914             :     int         res_dscale;
   11915             :     int         i,
   11916             :                 i1,
   11917             :                 i2;
   11918      324100 :     int         borrow = 0;
   11919             : 
   11920             :     /* copy these values into local vars for speed in inner loop */
   11921      324100 :     int         var1ndigits = var1->ndigits;
   11922      324100 :     int         var2ndigits = var2->ndigits;
   11923      324100 :     NumericDigit *var1digits = var1->digits;
   11924      324100 :     NumericDigit *var2digits = var2->digits;
   11925             : 
   11926      324100 :     res_weight = var1->weight;
   11927             : 
   11928      324100 :     res_dscale = Max(var1->dscale, var2->dscale);
   11929             : 
   11930             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11931      324100 :     rscale1 = var1->ndigits - var1->weight - 1;
   11932      324100 :     rscale2 = var2->ndigits - var2->weight - 1;
   11933      324100 :     res_rscale = Max(rscale1, rscale2);
   11934             : 
   11935      324100 :     res_ndigits = res_rscale + res_weight + 1;
   11936      324100 :     if (res_ndigits <= 0)
   11937           0 :         res_ndigits = 1;
   11938             : 
   11939      324100 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11940      324100 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11941      324100 :     res_digits = res_buf + 1;
   11942             : 
   11943      324100 :     i1 = res_rscale + var1->weight + 1;
   11944      324100 :     i2 = res_rscale + var2->weight + 1;
   11945     4846764 :     for (i = res_ndigits - 1; i >= 0; i--)
   11946             :     {
   11947     4522664 :         i1--;
   11948     4522664 :         i2--;
   11949     4522664 :         if (i1 >= 0 && i1 < var1ndigits)
   11950     4096550 :             borrow += var1digits[i1];
   11951     4522664 :         if (i2 >= 0 && i2 < var2ndigits)
   11952     3842368 :             borrow -= var2digits[i2];
   11953             : 
   11954     4522664 :         if (borrow < 0)
   11955             :         {
   11956      473990 :             res_digits[i] = borrow + NBASE;
   11957      473990 :             borrow = -1;
   11958             :         }
   11959             :         else
   11960             :         {
   11961     4048674 :             res_digits[i] = borrow;
   11962     4048674 :             borrow = 0;
   11963             :         }
   11964             :     }
   11965             : 
   11966             :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   11967             : 
   11968      324100 :     digitbuf_free(result->buf);
   11969      324100 :     result->ndigits = res_ndigits;
   11970      324100 :     result->buf = res_buf;
   11971      324100 :     result->digits = res_digits;
   11972      324100 :     result->weight = res_weight;
   11973      324100 :     result->dscale = res_dscale;
   11974             : 
   11975             :     /* Remove leading/trailing zeroes */
   11976      324100 :     strip_var(result);
   11977      324100 : }
   11978             : 
   11979             : /*
   11980             :  * round_var
   11981             :  *
   11982             :  * Round the value of a variable to no more than rscale decimal digits
   11983             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11984             :  * rounding before the decimal point.
   11985             :  */
   11986             : static void
   11987      227270 : round_var(NumericVar *var, int rscale)
   11988             : {
   11989      227270 :     NumericDigit *digits = var->digits;
   11990             :     int         di;
   11991             :     int         ndigits;
   11992             :     int         carry;
   11993             : 
   11994      227270 :     var->dscale = rscale;
   11995             : 
   11996             :     /* decimal digits wanted */
   11997      227270 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11998             : 
   11999             :     /*
   12000             :      * If di = 0, the value loses all digits, but could round up to 1 if its
   12001             :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   12002             :      */
   12003      227270 :     if (di < 0)
   12004             :     {
   12005         104 :         var->ndigits = 0;
   12006         104 :         var->weight = 0;
   12007         104 :         var->sign = NUMERIC_POS;
   12008             :     }
   12009             :     else
   12010             :     {
   12011             :         /* NBASE digits wanted */
   12012      227166 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   12013             : 
   12014             :         /* 0, or number of decimal digits to keep in last NBASE digit */
   12015      227166 :         di %= DEC_DIGITS;
   12016             : 
   12017      227166 :         if (ndigits < var->ndigits ||
   12018       21368 :             (ndigits == var->ndigits && di > 0))
   12019             :         {
   12020      208990 :             var->ndigits = ndigits;
   12021             : 
   12022             : #if DEC_DIGITS == 1
   12023             :             /* di must be zero */
   12024             :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   12025             : #else
   12026      208990 :             if (di == 0)
   12027      167304 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   12028             :             else
   12029             :             {
   12030             :                 /* Must round within last NBASE digit */
   12031             :                 int         extra,
   12032             :                             pow10;
   12033             : 
   12034             : #if DEC_DIGITS == 4
   12035       41686 :                 pow10 = round_powers[di];
   12036             : #elif DEC_DIGITS == 2
   12037             :                 pow10 = 10;
   12038             : #else
   12039             : #error unsupported NBASE
   12040             : #endif
   12041       41686 :                 extra = digits[--ndigits] % pow10;
   12042       41686 :                 digits[ndigits] -= extra;
   12043       41686 :                 carry = 0;
   12044       41686 :                 if (extra >= pow10 / 2)
   12045             :                 {
   12046       19486 :                     pow10 += digits[ndigits];
   12047       19486 :                     if (pow10 >= NBASE)
   12048             :                     {
   12049         812 :                         pow10 -= NBASE;
   12050         812 :                         carry = 1;
   12051             :                     }
   12052       19486 :                     digits[ndigits] = pow10;
   12053             :                 }
   12054             :             }
   12055             : #endif
   12056             : 
   12057             :             /* Propagate carry if needed */
   12058      244228 :             while (carry)
   12059             :             {
   12060       35238 :                 carry += digits[--ndigits];
   12061       35238 :                 if (carry >= NBASE)
   12062             :                 {
   12063       24726 :                     digits[ndigits] = carry - NBASE;
   12064       24726 :                     carry = 1;
   12065             :                 }
   12066             :                 else
   12067             :                 {
   12068       10512 :                     digits[ndigits] = carry;
   12069       10512 :                     carry = 0;
   12070             :                 }
   12071             :             }
   12072             : 
   12073      208990 :             if (ndigits < 0)
   12074             :             {
   12075             :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   12076             :                 Assert(var->digits > var->buf);
   12077          96 :                 var->digits--;
   12078          96 :                 var->ndigits++;
   12079          96 :                 var->weight++;
   12080             :             }
   12081             :         }
   12082             :     }
   12083      227270 : }
   12084             : 
   12085             : /*
   12086             :  * trunc_var
   12087             :  *
   12088             :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   12089             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   12090             :  * truncation before the decimal point.
   12091             :  */
   12092             : static void
   12093       60832 : trunc_var(NumericVar *var, int rscale)
   12094             : {
   12095             :     int         di;
   12096             :     int         ndigits;
   12097             : 
   12098       60832 :     var->dscale = rscale;
   12099             : 
   12100             :     /* decimal digits wanted */
   12101       60832 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   12102             : 
   12103             :     /*
   12104             :      * If di <= 0, the value loses all digits.
   12105             :      */
   12106       60832 :     if (di <= 0)
   12107             :     {
   12108          90 :         var->ndigits = 0;
   12109          90 :         var->weight = 0;
   12110          90 :         var->sign = NUMERIC_POS;
   12111             :     }
   12112             :     else
   12113             :     {
   12114             :         /* NBASE digits wanted */
   12115       60742 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   12116             : 
   12117       60742 :         if (ndigits <= var->ndigits)
   12118             :         {
   12119       60472 :             var->ndigits = ndigits;
   12120             : 
   12121             : #if DEC_DIGITS == 1
   12122             :             /* no within-digit stuff to worry about */
   12123             : #else
   12124             :             /* 0, or number of decimal digits to keep in last NBASE digit */
   12125       60472 :             di %= DEC_DIGITS;
   12126             : 
   12127       60472 :             if (di > 0)
   12128             :             {
   12129             :                 /* Must truncate within last NBASE digit */
   12130         106 :                 NumericDigit *digits = var->digits;
   12131             :                 int         extra,
   12132             :                             pow10;
   12133             : 
   12134             : #if DEC_DIGITS == 4
   12135         106 :                 pow10 = round_powers[di];
   12136             : #elif DEC_DIGITS == 2
   12137             :                 pow10 = 10;
   12138             : #else
   12139             : #error unsupported NBASE
   12140             : #endif
   12141         106 :                 extra = digits[--ndigits] % pow10;
   12142         106 :                 digits[ndigits] -= extra;
   12143             :             }
   12144             : #endif
   12145             :         }
   12146             :     }
   12147       60832 : }
   12148             : 
   12149             : /*
   12150             :  * strip_var
   12151             :  *
   12152             :  * Strip any leading and trailing zeroes from a numeric variable
   12153             :  */
   12154             : static void
   12155     2066396 : strip_var(NumericVar *var)
   12156             : {
   12157     2066396 :     NumericDigit *digits = var->digits;
   12158     2066396 :     int         ndigits = var->ndigits;
   12159             : 
   12160             :     /* Strip leading zeroes */
   12161     4031974 :     while (ndigits > 0 && *digits == 0)
   12162             :     {
   12163     1965578 :         digits++;
   12164     1965578 :         var->weight--;
   12165     1965578 :         ndigits--;
   12166             :     }
   12167             : 
   12168             :     /* Strip trailing zeroes */
   12169     2738258 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   12170      671862 :         ndigits--;
   12171             : 
   12172             :     /* If it's zero, normalize the sign and weight */
   12173     2066396 :     if (ndigits == 0)
   12174             :     {
   12175       27352 :         var->sign = NUMERIC_POS;
   12176       27352 :         var->weight = 0;
   12177             :     }
   12178             : 
   12179     2066396 :     var->digits = digits;
   12180     2066396 :     var->ndigits = ndigits;
   12181     2066396 : }
   12182             : 
   12183             : 
   12184             : /* ----------------------------------------------------------------------
   12185             :  *
   12186             :  * Fast sum accumulator functions
   12187             :  *
   12188             :  * ----------------------------------------------------------------------
   12189             :  */
   12190             : 
   12191             : /*
   12192             :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   12193             :  * are not free'd.
   12194             :  */
   12195             : static void
   12196          18 : accum_sum_reset(NumericSumAccum *accum)
   12197             : {
   12198             :     int         i;
   12199             : 
   12200          18 :     accum->dscale = 0;
   12201          66 :     for (i = 0; i < accum->ndigits; i++)
   12202             :     {
   12203          48 :         accum->pos_digits[i] = 0;
   12204          48 :         accum->neg_digits[i] = 0;
   12205             :     }
   12206          18 : }
   12207             : 
   12208             : /*
   12209             :  * Accumulate a new value.
   12210             :  */
   12211             : static void
   12212     2355644 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   12213             : {
   12214             :     int32      *accum_digits;
   12215             :     int         i,
   12216             :                 val_i;
   12217             :     int         val_ndigits;
   12218             :     NumericDigit *val_digits;
   12219             : 
   12220             :     /*
   12221             :      * If we have accumulated too many values since the last carry
   12222             :      * propagation, do it now, to avoid overflowing.  (We could allow more
   12223             :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   12224             :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   12225             :      * seldom, that the performance difference is negligible.)
   12226             :      */
   12227     2355644 :     if (accum->num_uncarried == NBASE - 1)
   12228         174 :         accum_sum_carry(accum);
   12229             : 
   12230             :     /*
   12231             :      * Adjust the weight or scale of the old value, so that it can accommodate
   12232             :      * the new value.
   12233             :      */
   12234     2355644 :     accum_sum_rescale(accum, val);
   12235             : 
   12236             :     /* */
   12237     2355644 :     if (val->sign == NUMERIC_POS)
   12238     1754966 :         accum_digits = accum->pos_digits;
   12239             :     else
   12240      600678 :         accum_digits = accum->neg_digits;
   12241             : 
   12242             :     /* copy these values into local vars for speed in loop */
   12243     2355644 :     val_ndigits = val->ndigits;
   12244     2355644 :     val_digits = val->digits;
   12245             : 
   12246     2355644 :     i = accum->weight - val->weight;
   12247    11889758 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   12248             :     {
   12249     9534114 :         accum_digits[i] += (int32) val_digits[val_i];
   12250     9534114 :         i++;
   12251             :     }
   12252             : 
   12253     2355644 :     accum->num_uncarried++;
   12254     2355644 : }
   12255             : 
   12256             : /*
   12257             :  * Propagate carries.
   12258             :  */
   12259             : static void
   12260      172716 : accum_sum_carry(NumericSumAccum *accum)
   12261             : {
   12262             :     int         i;
   12263             :     int         ndigits;
   12264             :     int32      *dig;
   12265             :     int32       carry;
   12266      172716 :     int32       newdig = 0;
   12267             : 
   12268             :     /*
   12269             :      * If no new values have been added since last carry propagation, nothing
   12270             :      * to do.
   12271             :      */
   12272      172716 :     if (accum->num_uncarried == 0)
   12273          72 :         return;
   12274             : 
   12275             :     /*
   12276             :      * We maintain that the weight of the accumulator is always one larger
   12277             :      * than needed to hold the current value, before carrying, to make sure
   12278             :      * there is enough space for the possible extra digit when carry is
   12279             :      * propagated.  We cannot expand the buffer here, unless we require
   12280             :      * callers of accum_sum_final() to switch to the right memory context.
   12281             :      */
   12282             :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12283             : 
   12284      172644 :     ndigits = accum->ndigits;
   12285             : 
   12286             :     /* Propagate carry in the positive sum */
   12287      172644 :     dig = accum->pos_digits;
   12288      172644 :     carry = 0;
   12289     2605384 :     for (i = ndigits - 1; i >= 0; i--)
   12290             :     {
   12291     2432740 :         newdig = dig[i] + carry;
   12292     2432740 :         if (newdig >= NBASE)
   12293             :         {
   12294      110790 :             carry = newdig / NBASE;
   12295      110790 :             newdig -= carry * NBASE;
   12296             :         }
   12297             :         else
   12298     2321950 :             carry = 0;
   12299     2432740 :         dig[i] = newdig;
   12300             :     }
   12301             :     /* Did we use up the digit reserved for carry propagation? */
   12302      172644 :     if (newdig > 0)
   12303        2616 :         accum->have_carry_space = false;
   12304             : 
   12305             :     /* And the same for the negative sum */
   12306      172644 :     dig = accum->neg_digits;
   12307      172644 :     carry = 0;
   12308     2605384 :     for (i = ndigits - 1; i >= 0; i--)
   12309             :     {
   12310     2432740 :         newdig = dig[i] + carry;
   12311     2432740 :         if (newdig >= NBASE)
   12312             :         {
   12313         198 :             carry = newdig / NBASE;
   12314         198 :             newdig -= carry * NBASE;
   12315             :         }
   12316             :         else
   12317     2432542 :             carry = 0;
   12318     2432740 :         dig[i] = newdig;
   12319             :     }
   12320      172644 :     if (newdig > 0)
   12321          30 :         accum->have_carry_space = false;
   12322             : 
   12323      172644 :     accum->num_uncarried = 0;
   12324             : }
   12325             : 
   12326             : /*
   12327             :  * Re-scale accumulator to accommodate new value.
   12328             :  *
   12329             :  * If the new value has more digits than the current digit buffers in the
   12330             :  * accumulator, enlarge the buffers.
   12331             :  */
   12332             : static void
   12333     2355644 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   12334             : {
   12335     2355644 :     int         old_weight = accum->weight;
   12336     2355644 :     int         old_ndigits = accum->ndigits;
   12337             :     int         accum_ndigits;
   12338             :     int         accum_weight;
   12339             :     int         accum_rscale;
   12340             :     int         val_rscale;
   12341             : 
   12342     2355644 :     accum_weight = old_weight;
   12343     2355644 :     accum_ndigits = old_ndigits;
   12344             : 
   12345             :     /*
   12346             :      * Does the new value have a larger weight? If so, enlarge the buffers,
   12347             :      * and shift the existing value to the new weight, by adding leading
   12348             :      * zeros.
   12349             :      *
   12350             :      * We enforce that the accumulator always has a weight one larger than
   12351             :      * needed for the inputs, so that we have space for an extra digit at the
   12352             :      * final carry-propagation phase, if necessary.
   12353             :      */
   12354     2355644 :     if (val->weight >= accum_weight)
   12355             :     {
   12356      262176 :         accum_weight = val->weight + 1;
   12357      262176 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   12358             :     }
   12359             : 
   12360             :     /*
   12361             :      * Even though the new value is small, we might've used up the space
   12362             :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   12363             :      * so, enlarge to make room for another one.
   12364             :      */
   12365     2093468 :     else if (!accum->have_carry_space)
   12366             :     {
   12367          72 :         accum_weight++;
   12368          72 :         accum_ndigits++;
   12369             :     }
   12370             : 
   12371             :     /* Is the new value wider on the right side? */
   12372     2355644 :     accum_rscale = accum_ndigits - accum_weight - 1;
   12373     2355644 :     val_rscale = val->ndigits - val->weight - 1;
   12374     2355644 :     if (val_rscale > accum_rscale)
   12375      172186 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   12376             : 
   12377     2355644 :     if (accum_ndigits != old_ndigits ||
   12378             :         accum_weight != old_weight)
   12379             :     {
   12380             :         int32      *new_pos_digits;
   12381             :         int32      *new_neg_digits;
   12382             :         int         weightdiff;
   12383             : 
   12384      262512 :         weightdiff = accum_weight - old_weight;
   12385             : 
   12386      262512 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   12387      262512 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   12388             : 
   12389      262512 :         if (accum->pos_digits)
   12390             :         {
   12391       90396 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   12392             :                    old_ndigits * sizeof(int32));
   12393       90396 :             pfree(accum->pos_digits);
   12394             : 
   12395       90396 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   12396             :                    old_ndigits * sizeof(int32));
   12397       90396 :             pfree(accum->neg_digits);
   12398             :         }
   12399             : 
   12400      262512 :         accum->pos_digits = new_pos_digits;
   12401      262512 :         accum->neg_digits = new_neg_digits;
   12402             : 
   12403      262512 :         accum->weight = accum_weight;
   12404      262512 :         accum->ndigits = accum_ndigits;
   12405             : 
   12406             :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12407      262512 :         accum->have_carry_space = true;
   12408             :     }
   12409             : 
   12410     2355644 :     if (val->dscale > accum->dscale)
   12411         300 :         accum->dscale = val->dscale;
   12412     2355644 : }
   12413             : 
   12414             : /*
   12415             :  * Return the current value of the accumulator.  This perform final carry
   12416             :  * propagation, and adds together the positive and negative sums.
   12417             :  *
   12418             :  * Unlike all the other routines, the caller is not required to switch to
   12419             :  * the memory context that holds the accumulator.
   12420             :  */
   12421             : static void
   12422      172542 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   12423             : {
   12424             :     int         i;
   12425             :     NumericVar  pos_var;
   12426             :     NumericVar  neg_var;
   12427             : 
   12428      172542 :     if (accum->ndigits == 0)
   12429             :     {
   12430           0 :         set_var_from_var(&const_zero, result);
   12431           0 :         return;
   12432             :     }
   12433             : 
   12434             :     /* Perform final carry */
   12435      172542 :     accum_sum_carry(accum);
   12436             : 
   12437             :     /* Create NumericVars representing the positive and negative sums */
   12438      172542 :     init_var(&pos_var);
   12439      172542 :     init_var(&neg_var);
   12440             : 
   12441      172542 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   12442      172542 :     pos_var.weight = neg_var.weight = accum->weight;
   12443      172542 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   12444      172542 :     pos_var.sign = NUMERIC_POS;
   12445      172542 :     neg_var.sign = NUMERIC_NEG;
   12446             : 
   12447      172542 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   12448      172542 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   12449             : 
   12450     2604874 :     for (i = 0; i < accum->ndigits; i++)
   12451             :     {
   12452             :         Assert(accum->pos_digits[i] < NBASE);
   12453     2432332 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   12454             : 
   12455             :         Assert(accum->neg_digits[i] < NBASE);
   12456     2432332 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   12457             :     }
   12458             : 
   12459             :     /* And add them together */
   12460      172542 :     add_var(&pos_var, &neg_var, result);
   12461             : 
   12462             :     /* Remove leading/trailing zeroes */
   12463      172542 :     strip_var(result);
   12464             : }
   12465             : 
   12466             : /*
   12467             :  * Copy an accumulator's state.
   12468             :  *
   12469             :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   12470             :  * freeing old values.
   12471             :  */
   12472             : static void
   12473          42 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   12474             : {
   12475          42 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12476          42 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12477             : 
   12478          42 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12479          42 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12480          42 :     dst->num_uncarried = src->num_uncarried;
   12481          42 :     dst->ndigits = src->ndigits;
   12482          42 :     dst->weight = src->weight;
   12483          42 :     dst->dscale = src->dscale;
   12484          42 : }
   12485             : 
   12486             : /*
   12487             :  * Add the current value of 'accum2' into 'accum'.
   12488             :  */
   12489             : static void
   12490          18 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12491             : {
   12492             :     NumericVar  tmp_var;
   12493             : 
   12494          18 :     init_var(&tmp_var);
   12495             : 
   12496          18 :     accum_sum_final(accum2, &tmp_var);
   12497          18 :     accum_sum_add(accum, &tmp_var);
   12498             : 
   12499          18 :     free_var(&tmp_var);
   12500          18 : }

Generated by: LCOV version 1.14