LCOV - code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18beta1 Lines: 3826 4050 94.5 %
Date: 2025-06-27 16:18:35 Functions: 209 210 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-2025, 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 "optimizer/optimizer.h"
      38             : #include "utils/array.h"
      39             : #include "utils/builtins.h"
      40             : #include "utils/float.h"
      41             : #include "utils/guc.h"
      42             : #include "utils/numeric.h"
      43             : #include "utils/pg_lsn.h"
      44             : #include "utils/sortsupport.h"
      45             : 
      46             : /* ----------
      47             :  * Uncomment the following to enable compilation of dump_numeric()
      48             :  * and dump_var() and to get a dump of any result produced by make_result().
      49             :  * ----------
      50             : #define NUMERIC_DEBUG
      51             :  */
      52             : 
      53             : 
      54             : /* ----------
      55             :  * Local data types
      56             :  *
      57             :  * Numeric values are represented in a base-NBASE floating point format.
      58             :  * Each "digit" ranges from 0 to NBASE-1.  The type NumericDigit is signed
      59             :  * and wide enough to store a digit.  We assume that NBASE*NBASE can fit in
      60             :  * an int.  Although the purely calculational routines could handle any even
      61             :  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
      62             :  * in NBASE a power of ten, so that I/O conversions and decimal rounding
      63             :  * are easy.  Also, it's actually more efficient if NBASE is rather less than
      64             :  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var to
      65             :  * postpone processing carries.
      66             :  *
      67             :  * Values of NBASE other than 10000 are considered of historical interest only
      68             :  * and are no longer supported in any sense; no mechanism exists for the client
      69             :  * to discover the base, so every client supporting binary mode expects the
      70             :  * base-10000 format.  If you plan to change this, also note the numeric
      71             :  * abbreviation code, which assumes NBASE=10000.
      72             :  * ----------
      73             :  */
      74             : 
      75             : #if 0
      76             : #define NBASE       10
      77             : #define HALF_NBASE  5
      78             : #define DEC_DIGITS  1           /* decimal digits per NBASE digit */
      79             : #define MUL_GUARD_DIGITS    4   /* these are measured in NBASE digits */
      80             : #define DIV_GUARD_DIGITS    8
      81             : 
      82             : typedef signed char NumericDigit;
      83             : #endif
      84             : 
      85             : #if 0
      86             : #define NBASE       100
      87             : #define HALF_NBASE  50
      88             : #define DEC_DIGITS  2           /* decimal digits per NBASE digit */
      89             : #define MUL_GUARD_DIGITS    3   /* these are measured in NBASE digits */
      90             : #define DIV_GUARD_DIGITS    6
      91             : 
      92             : typedef signed char NumericDigit;
      93             : #endif
      94             : 
      95             : #if 1
      96             : #define NBASE       10000
      97             : #define HALF_NBASE  5000
      98             : #define DEC_DIGITS  4           /* decimal digits per NBASE digit */
      99             : #define MUL_GUARD_DIGITS    2   /* these are measured in NBASE digits */
     100             : #define DIV_GUARD_DIGITS    4
     101             : 
     102             : typedef int16 NumericDigit;
     103             : #endif
     104             : 
     105             : #define NBASE_SQR   (NBASE * NBASE)
     106             : 
     107             : /*
     108             :  * The Numeric type as stored on disk.
     109             :  *
     110             :  * If the high bits of the first word of a NumericChoice (n_header, or
     111             :  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
     112             :  * numeric follows the NumericShort format; if they are NUMERIC_POS or
     113             :  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
     114             :  * the value is a NaN or Infinity.  We currently always store SPECIAL values
     115             :  * using just two bytes (i.e. only n_header), but previous releases used only
     116             :  * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
     117             :  * on disk if a database has been migrated using pg_upgrade.  In either case,
     118             :  * the low-order bits of a special value's header are reserved and currently
     119             :  * should always be set to zero.
     120             :  *
     121             :  * In the NumericShort format, the remaining 14 bits of the header word
     122             :  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
     123             :  * negative), 6 for dynamic scale, and 7 for weight.  In practice, most
     124             :  * commonly-encountered values can be represented this way.
     125             :  *
     126             :  * In the NumericLong format, the remaining 14 bits of the header word
     127             :  * (n_long.n_sign_dscale) represent the display scale; and the weight is
     128             :  * stored separately in n_weight.
     129             :  *
     130             :  * NOTE: by convention, values in the packed form have been stripped of
     131             :  * all leading and trailing zero digits (where a "digit" is of base NBASE).
     132             :  * In particular, if the value is zero, there will be no digits at all!
     133             :  * The weight is arbitrary in that case, but we normally set it to zero.
     134             :  */
     135             : 
     136             : struct NumericShort
     137             : {
     138             :     uint16      n_header;       /* Sign + display scale + weight */
     139             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     140             : };
     141             : 
     142             : struct NumericLong
     143             : {
     144             :     uint16      n_sign_dscale;  /* Sign + display scale */
     145             :     int16       n_weight;       /* Weight of 1st digit  */
     146             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     147             : };
     148             : 
     149             : union NumericChoice
     150             : {
     151             :     uint16      n_header;       /* Header word */
     152             :     struct NumericLong n_long;  /* Long form (4-byte header) */
     153             :     struct NumericShort n_short;    /* Short form (2-byte header) */
     154             : };
     155             : 
     156             : struct NumericData
     157             : {
     158             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     159             :     union NumericChoice choice; /* choice of format */
     160             : };
     161             : 
     162             : 
     163             : /*
     164             :  * Interpretation of high bits.
     165             :  */
     166             : 
     167             : #define NUMERIC_SIGN_MASK   0xC000
     168             : #define NUMERIC_POS         0x0000
     169             : #define NUMERIC_NEG         0x4000
     170             : #define NUMERIC_SHORT       0x8000
     171             : #define NUMERIC_SPECIAL     0xC000
     172             : 
     173             : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
     174             : #define NUMERIC_IS_SHORT(n)     (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
     175             : #define NUMERIC_IS_SPECIAL(n)   (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
     176             : 
     177             : #define NUMERIC_HDRSZ   (VARHDRSZ + sizeof(uint16) + sizeof(int16))
     178             : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
     179             : 
     180             : /*
     181             :  * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
     182             :  * header; otherwise, we want the long one.  Instead of testing against each
     183             :  * value, we can just look at the high bit, for a slight efficiency gain.
     184             :  */
     185             : #define NUMERIC_HEADER_IS_SHORT(n)  (((n)->choice.n_header & 0x8000) != 0)
     186             : #define NUMERIC_HEADER_SIZE(n) \
     187             :     (VARHDRSZ + sizeof(uint16) + \
     188             :      (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
     189             : 
     190             : /*
     191             :  * Definitions for special values (NaN, positive infinity, negative infinity).
     192             :  *
     193             :  * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
     194             :  * infinity, 11 for negative infinity.  (This makes the sign bit match where
     195             :  * it is in a short-format value, though we make no use of that at present.)
     196             :  * We could mask off the remaining bits before testing the active bits, but
     197             :  * currently those bits must be zeroes, so masking would just add cycles.
     198             :  */
     199             : #define NUMERIC_EXT_SIGN_MASK   0xF000  /* high bits plus NaN/Inf flag bits */
     200             : #define NUMERIC_NAN             0xC000
     201             : #define NUMERIC_PINF            0xD000
     202             : #define NUMERIC_NINF            0xF000
     203             : #define NUMERIC_INF_SIGN_MASK   0x2000
     204             : 
     205             : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
     206             : #define NUMERIC_IS_NAN(n)       ((n)->choice.n_header == NUMERIC_NAN)
     207             : #define NUMERIC_IS_PINF(n)      ((n)->choice.n_header == NUMERIC_PINF)
     208             : #define NUMERIC_IS_NINF(n)      ((n)->choice.n_header == NUMERIC_NINF)
     209             : #define NUMERIC_IS_INF(n) \
     210             :     (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
     211             : 
     212             : /*
     213             :  * Short format definitions.
     214             :  */
     215             : 
     216             : #define NUMERIC_SHORT_SIGN_MASK         0x2000
     217             : #define NUMERIC_SHORT_DSCALE_MASK       0x1F80
     218             : #define NUMERIC_SHORT_DSCALE_SHIFT      7
     219             : #define NUMERIC_SHORT_DSCALE_MAX        \
     220             :     (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
     221             : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK  0x0040
     222             : #define NUMERIC_SHORT_WEIGHT_MASK       0x003F
     223             : #define NUMERIC_SHORT_WEIGHT_MAX        NUMERIC_SHORT_WEIGHT_MASK
     224             : #define NUMERIC_SHORT_WEIGHT_MIN        (-(NUMERIC_SHORT_WEIGHT_MASK+1))
     225             : 
     226             : /*
     227             :  * Extract sign, display scale, weight.  These macros extract field values
     228             :  * suitable for the NumericVar format from the Numeric (on-disk) format.
     229             :  *
     230             :  * Note that we don't trouble to ensure that dscale and weight read as zero
     231             :  * for an infinity; however, that doesn't matter since we never convert
     232             :  * "special" numerics to NumericVar form.  Only the constants defined below
     233             :  * (const_nan, etc) ever represent a non-finite value as a NumericVar.
     234             :  */
     235             : 
     236             : #define NUMERIC_DSCALE_MASK         0x3FFF
     237             : #define NUMERIC_DSCALE_MAX          NUMERIC_DSCALE_MASK
     238             : 
     239             : #define NUMERIC_SIGN(n) \
     240             :     (NUMERIC_IS_SHORT(n) ? \
     241             :         (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
     242             :          NUMERIC_NEG : NUMERIC_POS) : \
     243             :         (NUMERIC_IS_SPECIAL(n) ? \
     244             :          NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
     245             : #define NUMERIC_DSCALE(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     246             :     ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
     247             :         >> NUMERIC_SHORT_DSCALE_SHIFT \
     248             :     : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
     249             : #define NUMERIC_WEIGHT(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     250             :     (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
     251             :         ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
     252             :      | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
     253             :     : ((n)->choice.n_long.n_weight))
     254             : 
     255             : /*
     256             :  * Maximum weight of a stored Numeric value (based on the use of int16 for the
     257             :  * weight in NumericLong).  Note that intermediate values held in NumericVar
     258             :  * and NumericSumAccum variables may have much larger weights.
     259             :  */
     260             : #define NUMERIC_WEIGHT_MAX          PG_INT16_MAX
     261             : 
     262             : /* ----------
     263             :  * NumericVar is the format we use for arithmetic.  The digit-array part
     264             :  * is the same as the NumericData storage format, but the header is more
     265             :  * complex.
     266             :  *
     267             :  * The value represented by a NumericVar is determined by the sign, weight,
     268             :  * ndigits, and digits[] array.  If it is a "special" value (NaN or Inf)
     269             :  * then only the sign field matters; ndigits should be zero, and the weight
     270             :  * and dscale fields are ignored.
     271             :  *
     272             :  * Note: the first digit of a NumericVar's value is assumed to be multiplied
     273             :  * by NBASE ** weight.  Another way to say it is that there are weight+1
     274             :  * digits before the decimal point.  It is possible to have weight < 0.
     275             :  *
     276             :  * buf points at the physical start of the palloc'd digit buffer for the
     277             :  * NumericVar.  digits points at the first digit in actual use (the one
     278             :  * with the specified weight).  We normally leave an unused digit or two
     279             :  * (preset to zeroes) between buf and digits, so that there is room to store
     280             :  * a carry out of the top digit without reallocating space.  We just need to
     281             :  * decrement digits (and increment weight) to make room for the carry digit.
     282             :  * (There is no such extra space in a numeric value stored in the database,
     283             :  * only in a NumericVar in memory.)
     284             :  *
     285             :  * If buf is NULL then the digit buffer isn't actually palloc'd and should
     286             :  * not be freed --- see the constants below for an example.
     287             :  *
     288             :  * dscale, or display scale, is the nominal precision expressed as number
     289             :  * of digits after the decimal point (it must always be >= 0 at present).
     290             :  * dscale may be more than the number of physically stored fractional digits,
     291             :  * implying that we have suppressed storage of significant trailing zeroes.
     292             :  * It should never be less than the number of stored digits, since that would
     293             :  * imply hiding digits that are present.  NOTE that dscale is always expressed
     294             :  * in *decimal* digits, and so it may correspond to a fractional number of
     295             :  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
     296             :  *
     297             :  * rscale, or result scale, is the target precision for a computation.
     298             :  * Like dscale it is expressed as number of *decimal* digits after the decimal
     299             :  * point, and is always >= 0 at present.
     300             :  * Note that rscale is not stored in variables --- it's figured on-the-fly
     301             :  * from the dscales of the inputs.
     302             :  *
     303             :  * While we consistently use "weight" to refer to the base-NBASE weight of
     304             :  * a numeric value, it is convenient in some scale-related calculations to
     305             :  * make use of the base-10 weight (ie, the approximate log10 of the value).
     306             :  * To avoid confusion, such a decimal-units weight is called a "dweight".
     307             :  *
     308             :  * NB: All the variable-level functions are written in a style that makes it
     309             :  * possible to give one and the same variable as argument and destination.
     310             :  * This is feasible because the digit buffer is separate from the variable.
     311             :  * ----------
     312             :  */
     313             : typedef struct NumericVar
     314             : {
     315             :     int         ndigits;        /* # of digits in digits[] - can be 0! */
     316             :     int         weight;         /* weight of first digit */
     317             :     int         sign;           /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
     318             :     int         dscale;         /* display scale */
     319             :     NumericDigit *buf;          /* start of palloc'd space for digits[] */
     320             :     NumericDigit *digits;       /* base-NBASE digits */
     321             : } NumericVar;
     322             : 
     323             : 
     324             : /* ----------
     325             :  * Data for generate_series
     326             :  * ----------
     327             :  */
     328             : typedef struct
     329             : {
     330             :     NumericVar  current;
     331             :     NumericVar  stop;
     332             :     NumericVar  step;
     333             : } generate_series_numeric_fctx;
     334             : 
     335             : 
     336             : /* ----------
     337             :  * Sort support.
     338             :  * ----------
     339             :  */
     340             : typedef struct
     341             : {
     342             :     void       *buf;            /* buffer for short varlenas */
     343             :     int64       input_count;    /* number of non-null values seen */
     344             :     bool        estimating;     /* true if estimating cardinality */
     345             : 
     346             :     hyperLogLogState abbr_card; /* cardinality estimator */
     347             : } NumericSortSupport;
     348             : 
     349             : 
     350             : /* ----------
     351             :  * Fast sum accumulator.
     352             :  *
     353             :  * NumericSumAccum is used to implement SUM(), and other standard aggregates
     354             :  * that track the sum of input values.  It uses 32-bit integers to store the
     355             :  * digits, instead of the normal 16-bit integers (with NBASE=10000).  This
     356             :  * way, we can safely accumulate up to NBASE - 1 values without propagating
     357             :  * carry, before risking overflow of any of the digits.  'num_uncarried'
     358             :  * tracks how many values have been accumulated without propagating carry.
     359             :  *
     360             :  * Positive and negative values are accumulated separately, in 'pos_digits'
     361             :  * and 'neg_digits'.  This is simpler and faster than deciding whether to add
     362             :  * or subtract from the current value, for each new value (see sub_var() for
     363             :  * the logic we avoid by doing this).  Both buffers are of same size, and
     364             :  * have the same weight and scale.  In accum_sum_final(), the positive and
     365             :  * negative sums are added together to produce the final result.
     366             :  *
     367             :  * When a new value has a larger ndigits or weight than the accumulator
     368             :  * currently does, the accumulator is enlarged to accommodate the new value.
     369             :  * We normally have one zero digit reserved for carry propagation, and that
     370             :  * is indicated by the 'have_carry_space' flag.  When accum_sum_carry() uses
     371             :  * up the reserved digit, it clears the 'have_carry_space' flag.  The next
     372             :  * call to accum_sum_add() will enlarge the buffer, to make room for the
     373             :  * extra digit, and set the flag again.
     374             :  *
     375             :  * To initialize a new accumulator, simply reset all fields to zeros.
     376             :  *
     377             :  * The accumulator does not handle NaNs.
     378             :  * ----------
     379             :  */
     380             : typedef struct NumericSumAccum
     381             : {
     382             :     int         ndigits;
     383             :     int         weight;
     384             :     int         dscale;
     385             :     int         num_uncarried;
     386             :     bool        have_carry_space;
     387             :     int32      *pos_digits;
     388             :     int32      *neg_digits;
     389             : } NumericSumAccum;
     390             : 
     391             : 
     392             : /*
     393             :  * We define our own macros for packing and unpacking abbreviated-key
     394             :  * representations for numeric values in order to avoid depending on
     395             :  * USE_FLOAT8_BYVAL.  The type of abbreviation we use is based only on
     396             :  * the size of a datum, not the argument-passing convention for float8.
     397             :  *
     398             :  * The range of abbreviations for finite values is from +PG_INT64/32_MAX
     399             :  * to -PG_INT64/32_MAX.  NaN has the abbreviation PG_INT64/32_MIN, and we
     400             :  * define the sort ordering to make that work out properly (see further
     401             :  * comments below).  PINF and NINF share the abbreviations of the largest
     402             :  * and smallest finite abbreviation classes.
     403             :  */
     404             : #define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
     405             : #if SIZEOF_DATUM == 8
     406             : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     407             : #define DatumGetNumericAbbrev(X) ((int64) (X))
     408             : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT64_MIN)
     409             : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT64_MAX)
     410             : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT64_MAX)
     411             : #else
     412             : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     413             : #define DatumGetNumericAbbrev(X) ((int32) (X))
     414             : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT32_MIN)
     415             : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT32_MAX)
     416             : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT32_MAX)
     417             : #endif
     418             : 
     419             : 
     420             : /* ----------
     421             :  * Some preinitialized constants
     422             :  * ----------
     423             :  */
     424             : static const NumericDigit const_zero_data[1] = {0};
     425             : static const NumericVar const_zero =
     426             : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
     427             : 
     428             : static const NumericDigit const_one_data[1] = {1};
     429             : static const NumericVar const_one =
     430             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
     431             : 
     432             : static const NumericVar const_minus_one =
     433             : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
     434             : 
     435             : static const NumericDigit const_two_data[1] = {2};
     436             : static const NumericVar const_two =
     437             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
     438             : 
     439             : #if DEC_DIGITS == 4
     440             : static const NumericDigit const_zero_point_nine_data[1] = {9000};
     441             : #elif DEC_DIGITS == 2
     442             : static const NumericDigit const_zero_point_nine_data[1] = {90};
     443             : #elif DEC_DIGITS == 1
     444             : static const NumericDigit const_zero_point_nine_data[1] = {9};
     445             : #endif
     446             : static const NumericVar const_zero_point_nine =
     447             : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
     448             : 
     449             : #if DEC_DIGITS == 4
     450             : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
     451             : #elif DEC_DIGITS == 2
     452             : static const NumericDigit const_one_point_one_data[2] = {1, 10};
     453             : #elif DEC_DIGITS == 1
     454             : static const NumericDigit const_one_point_one_data[2] = {1, 1};
     455             : #endif
     456             : static const NumericVar const_one_point_one =
     457             : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
     458             : 
     459             : static const NumericVar const_nan =
     460             : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
     461             : 
     462             : static const NumericVar const_pinf =
     463             : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
     464             : 
     465             : static const NumericVar const_ninf =
     466             : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
     467             : 
     468             : #if DEC_DIGITS == 4
     469             : static const int round_powers[4] = {0, 1000, 100, 10};
     470             : #endif
     471             : 
     472             : 
     473             : /* ----------
     474             :  * Local functions
     475             :  * ----------
     476             :  */
     477             : 
     478             : #ifdef NUMERIC_DEBUG
     479             : static void dump_numeric(const char *str, Numeric num);
     480             : static void dump_var(const char *str, NumericVar *var);
     481             : #else
     482             : #define dump_numeric(s,n)
     483             : #define dump_var(s,v)
     484             : #endif
     485             : 
     486             : #define digitbuf_alloc(ndigits)  \
     487             :     ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
     488             : #define digitbuf_free(buf)  \
     489             :     do { \
     490             :          if ((buf) != NULL) \
     491             :              pfree(buf); \
     492             :     } while (0)
     493             : 
     494             : #define init_var(v)     memset(v, 0, sizeof(NumericVar))
     495             : 
     496             : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
     497             :     (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
     498             : #define NUMERIC_NDIGITS(num) \
     499             :     ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
     500             : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
     501             :     ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
     502             :     (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
     503             :     (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
     504             : 
     505             : static void alloc_var(NumericVar *var, int ndigits);
     506             : static void free_var(NumericVar *var);
     507             : static void zero_var(NumericVar *var);
     508             : 
     509             : static bool set_var_from_str(const char *str, const char *cp,
     510             :                              NumericVar *dest, const char **endptr,
     511             :                              Node *escontext);
     512             : static bool set_var_from_non_decimal_integer_str(const char *str,
     513             :                                                  const char *cp, int sign,
     514             :                                                  int base, NumericVar *dest,
     515             :                                                  const char **endptr,
     516             :                                                  Node *escontext);
     517             : static void set_var_from_num(Numeric num, NumericVar *dest);
     518             : static void init_var_from_num(Numeric num, NumericVar *dest);
     519             : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
     520             : static char *get_str_from_var(const NumericVar *var);
     521             : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
     522             : 
     523             : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
     524             : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
     525             : 
     526             : static Numeric duplicate_numeric(Numeric num);
     527             : static Numeric make_result(const NumericVar *var);
     528             : static Numeric make_result_opt_error(const NumericVar *var, bool *have_error);
     529             : 
     530             : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
     531             : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
     532             : 
     533             : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
     534             : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
     535             : static void int64_to_numericvar(int64 val, NumericVar *var);
     536             : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
     537             : #ifdef HAVE_INT128
     538             : static bool numericvar_to_int128(const NumericVar *var, int128 *result);
     539             : static void int128_to_numericvar(int128 val, NumericVar *var);
     540             : #endif
     541             : static double numericvar_to_double_no_overflow(const NumericVar *var);
     542             : 
     543             : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
     544             : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
     545             : static int  numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
     546             : static int  numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
     547             : 
     548             : static Datum numeric_abbrev_convert_var(const NumericVar *var,
     549             :                                         NumericSortSupport *nss);
     550             : 
     551             : static int  cmp_numerics(Numeric num1, Numeric num2);
     552             : static int  cmp_var(const NumericVar *var1, const NumericVar *var2);
     553             : static int  cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
     554             :                            int var1weight, int var1sign,
     555             :                            const NumericDigit *var2digits, int var2ndigits,
     556             :                            int var2weight, int var2sign);
     557             : static void add_var(const NumericVar *var1, const NumericVar *var2,
     558             :                     NumericVar *result);
     559             : static void sub_var(const NumericVar *var1, const NumericVar *var2,
     560             :                     NumericVar *result);
     561             : static void mul_var(const NumericVar *var1, const NumericVar *var2,
     562             :                     NumericVar *result,
     563             :                     int rscale);
     564             : static void mul_var_short(const NumericVar *var1, const NumericVar *var2,
     565             :                           NumericVar *result);
     566             : static void div_var(const NumericVar *var1, const NumericVar *var2,
     567             :                     NumericVar *result, int rscale, bool round, bool exact);
     568             : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
     569             :                         NumericVar *result, int rscale, bool round);
     570             : #ifdef HAVE_INT128
     571             : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
     572             :                           NumericVar *result, int rscale, bool round);
     573             : #endif
     574             : static int  select_div_scale(const NumericVar *var1, const NumericVar *var2);
     575             : static void mod_var(const NumericVar *var1, const NumericVar *var2,
     576             :                     NumericVar *result);
     577             : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
     578             :                         NumericVar *quot, NumericVar *rem);
     579             : static void ceil_var(const NumericVar *var, NumericVar *result);
     580             : static void floor_var(const NumericVar *var, NumericVar *result);
     581             : 
     582             : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
     583             :                     NumericVar *result);
     584             : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
     585             : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
     586             : static int  estimate_ln_dweight(const NumericVar *var);
     587             : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
     588             : static void log_var(const NumericVar *base, const NumericVar *num,
     589             :                     NumericVar *result);
     590             : static void power_var(const NumericVar *base, const NumericVar *exp,
     591             :                       NumericVar *result);
     592             : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
     593             :                           NumericVar *result);
     594             : static void power_ten_int(int exp, NumericVar *result);
     595             : static void random_var(pg_prng_state *state, const NumericVar *rmin,
     596             :                        const NumericVar *rmax, NumericVar *result);
     597             : 
     598             : static int  cmp_abs(const NumericVar *var1, const NumericVar *var2);
     599             : static int  cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
     600             :                            int var1weight,
     601             :                            const NumericDigit *var2digits, int var2ndigits,
     602             :                            int var2weight);
     603             : static void add_abs(const NumericVar *var1, const NumericVar *var2,
     604             :                     NumericVar *result);
     605             : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
     606             :                     NumericVar *result);
     607             : static void round_var(NumericVar *var, int rscale);
     608             : static void trunc_var(NumericVar *var, int rscale);
     609             : static void strip_var(NumericVar *var);
     610             : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
     611             :                            const NumericVar *count_var,
     612             :                            NumericVar *result_var);
     613             : 
     614             : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
     615             : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
     616             : static void accum_sum_carry(NumericSumAccum *accum);
     617             : static void accum_sum_reset(NumericSumAccum *accum);
     618             : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
     619             : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
     620             : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
     621             : 
     622             : 
     623             : /* ----------------------------------------------------------------------
     624             :  *
     625             :  * Input-, output- and rounding-functions
     626             :  *
     627             :  * ----------------------------------------------------------------------
     628             :  */
     629             : 
     630             : 
     631             : /*
     632             :  * numeric_in() -
     633             :  *
     634             :  *  Input function for numeric data type
     635             :  */
     636             : Datum
     637      213080 : numeric_in(PG_FUNCTION_ARGS)
     638             : {
     639      213080 :     char       *str = PG_GETARG_CSTRING(0);
     640             : #ifdef NOT_USED
     641             :     Oid         typelem = PG_GETARG_OID(1);
     642             : #endif
     643      213080 :     int32       typmod = PG_GETARG_INT32(2);
     644      213080 :     Node       *escontext = fcinfo->context;
     645             :     Numeric     res;
     646             :     const char *cp;
     647             :     const char *numstart;
     648             :     int         sign;
     649             : 
     650             :     /* Skip leading spaces */
     651      213080 :     cp = str;
     652      237500 :     while (*cp)
     653             :     {
     654      237482 :         if (!isspace((unsigned char) *cp))
     655      213062 :             break;
     656       24420 :         cp++;
     657             :     }
     658             : 
     659             :     /*
     660             :      * Process the number's sign. This duplicates logic in set_var_from_str(),
     661             :      * but it's worth doing here, since it simplifies the handling of
     662             :      * infinities and non-decimal integers.
     663             :      */
     664      213080 :     numstart = cp;
     665      213080 :     sign = NUMERIC_POS;
     666             : 
     667      213080 :     if (*cp == '+')
     668          48 :         cp++;
     669      213032 :     else if (*cp == '-')
     670             :     {
     671        4624 :         sign = NUMERIC_NEG;
     672        4624 :         cp++;
     673             :     }
     674             : 
     675             :     /*
     676             :      * Check for NaN and infinities.  We recognize the same strings allowed by
     677             :      * float8in().
     678             :      *
     679             :      * Since all other legal inputs have a digit or a decimal point after the
     680             :      * sign, we need only check for NaN/infinity if that's not the case.
     681             :      */
     682      213080 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
     683             :     {
     684             :         /*
     685             :          * The number must be NaN or infinity; anything else can only be a
     686             :          * syntax error. Note that NaN mustn't have a sign.
     687             :          */
     688        1868 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     689             :         {
     690         666 :             res = make_result(&const_nan);
     691         666 :             cp = numstart + 3;
     692             :         }
     693        1202 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     694             :         {
     695         504 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     696         504 :             cp += 8;
     697             :         }
     698         698 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
     699             :         {
     700         588 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     701         588 :             cp += 3;
     702             :         }
     703             :         else
     704         110 :             goto invalid_syntax;
     705             : 
     706             :         /*
     707             :          * Check for trailing junk; there should be nothing left but spaces.
     708             :          *
     709             :          * We intentionally do this check before applying the typmod because
     710             :          * we would like to throw any trailing-junk syntax error before any
     711             :          * semantic error resulting from apply_typmod_special().
     712             :          */
     713        1800 :         while (*cp)
     714             :         {
     715          42 :             if (!isspace((unsigned char) *cp))
     716           0 :                 goto invalid_syntax;
     717          42 :             cp++;
     718             :         }
     719             : 
     720        1758 :         if (!apply_typmod_special(res, typmod, escontext))
     721           0 :             PG_RETURN_NULL();
     722             :     }
     723             :     else
     724             :     {
     725             :         /*
     726             :          * We have a normal numeric value, which may be a non-decimal integer
     727             :          * or a regular decimal number.
     728             :          */
     729             :         NumericVar  value;
     730             :         int         base;
     731             :         bool        have_error;
     732             : 
     733      211212 :         init_var(&value);
     734             : 
     735             :         /*
     736             :          * Determine the number's base by looking for a non-decimal prefix
     737             :          * indicator ("0x", "0o", or "0b").
     738             :          */
     739      211212 :         if (cp[0] == '0')
     740             :         {
     741       85148 :             switch (cp[1])
     742             :             {
     743          72 :                 case 'x':
     744             :                 case 'X':
     745          72 :                     base = 16;
     746          72 :                     break;
     747          42 :                 case 'o':
     748             :                 case 'O':
     749          42 :                     base = 8;
     750          42 :                     break;
     751          42 :                 case 'b':
     752             :                 case 'B':
     753          42 :                     base = 2;
     754          42 :                     break;
     755       84992 :                 default:
     756       84992 :                     base = 10;
     757             :             }
     758             :         }
     759             :         else
     760      126064 :             base = 10;
     761             : 
     762             :         /* Parse the rest of the number and apply the sign */
     763      211212 :         if (base == 10)
     764             :         {
     765      211056 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     766          42 :                 PG_RETURN_NULL();
     767      211008 :             value.sign = sign;
     768             :         }
     769             :         else
     770             :         {
     771         156 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
     772             :                                                       &value, &cp, escontext))
     773           0 :                 PG_RETURN_NULL();
     774             :         }
     775             : 
     776             :         /*
     777             :          * Should be nothing left but spaces. As above, throw any typmod error
     778             :          * after finishing syntax check.
     779             :          */
     780      211224 :         while (*cp)
     781             :         {
     782         150 :             if (!isspace((unsigned char) *cp))
     783          72 :                 goto invalid_syntax;
     784          78 :             cp++;
     785             :         }
     786             : 
     787      211074 :         if (!apply_typmod(&value, typmod, escontext))
     788          24 :             PG_RETURN_NULL();
     789             : 
     790      211050 :         res = make_result_opt_error(&value, &have_error);
     791             : 
     792      211050 :         if (have_error)
     793          18 :             ereturn(escontext, (Datum) 0,
     794             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     795             :                      errmsg("value overflows numeric format")));
     796             : 
     797      211032 :         free_var(&value);
     798             :     }
     799             : 
     800      212790 :     PG_RETURN_NUMERIC(res);
     801             : 
     802         182 : invalid_syntax:
     803         182 :     ereturn(escontext, (Datum) 0,
     804             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     805             :              errmsg("invalid input syntax for type %s: \"%s\"",
     806             :                     "numeric", str)));
     807             : }
     808             : 
     809             : 
     810             : /*
     811             :  * numeric_out() -
     812             :  *
     813             :  *  Output function for numeric data type
     814             :  */
     815             : Datum
     816     1001938 : numeric_out(PG_FUNCTION_ARGS)
     817             : {
     818     1001938 :     Numeric     num = PG_GETARG_NUMERIC(0);
     819             :     NumericVar  x;
     820             :     char       *str;
     821             : 
     822             :     /*
     823             :      * Handle NaN and infinities
     824             :      */
     825     1001938 :     if (NUMERIC_IS_SPECIAL(num))
     826             :     {
     827        3846 :         if (NUMERIC_IS_PINF(num))
     828        1064 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     829        2782 :         else if (NUMERIC_IS_NINF(num))
     830         670 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     831             :         else
     832        2112 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     833             :     }
     834             : 
     835             :     /*
     836             :      * Get the number in the variable format.
     837             :      */
     838      998092 :     init_var_from_num(num, &x);
     839             : 
     840      998092 :     str = get_str_from_var(&x);
     841             : 
     842      998092 :     PG_RETURN_CSTRING(str);
     843             : }
     844             : 
     845             : /*
     846             :  * numeric_is_nan() -
     847             :  *
     848             :  *  Is Numeric value a NaN?
     849             :  */
     850             : bool
     851        7390 : numeric_is_nan(Numeric num)
     852             : {
     853        7390 :     return NUMERIC_IS_NAN(num);
     854             : }
     855             : 
     856             : /*
     857             :  * numeric_is_inf() -
     858             :  *
     859             :  *  Is Numeric value an infinity?
     860             :  */
     861             : bool
     862         312 : numeric_is_inf(Numeric num)
     863             : {
     864         312 :     return NUMERIC_IS_INF(num);
     865             : }
     866             : 
     867             : /*
     868             :  * numeric_is_integral() -
     869             :  *
     870             :  *  Is Numeric value integral?
     871             :  */
     872             : static bool
     873          66 : numeric_is_integral(Numeric num)
     874             : {
     875             :     NumericVar  arg;
     876             : 
     877             :     /* Reject NaN, but infinities are considered integral */
     878          66 :     if (NUMERIC_IS_SPECIAL(num))
     879             :     {
     880          30 :         if (NUMERIC_IS_NAN(num))
     881           0 :             return false;
     882          30 :         return true;
     883             :     }
     884             : 
     885             :     /* Integral if there are no digits to the right of the decimal point */
     886          36 :     init_var_from_num(num, &arg);
     887             : 
     888          36 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
     889             : }
     890             : 
     891             : /*
     892             :  * make_numeric_typmod() -
     893             :  *
     894             :  *  Pack numeric precision and scale values into a typmod.  The upper 16 bits
     895             :  *  are used for the precision (though actually not all these bits are needed,
     896             :  *  since the maximum allowed precision is 1000).  The lower 16 bits are for
     897             :  *  the scale, but since the scale is constrained to the range [-1000, 1000],
     898             :  *  we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
     899             :  *  unset, for possible future use.
     900             :  *
     901             :  *  For purely historical reasons VARHDRSZ is then added to the result, thus
     902             :  *  the unused space in the upper 16 bits is not all as freely available as it
     903             :  *  might seem.  (We can't let the result overflow to a negative int32, as
     904             :  *  other parts of the system would interpret that as not-a-valid-typmod.)
     905             :  */
     906             : static inline int32
     907        1980 : make_numeric_typmod(int precision, int scale)
     908             : {
     909        1980 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
     910             : }
     911             : 
     912             : /*
     913             :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
     914             :  */
     915             : static inline bool
     916      236370 : is_valid_numeric_typmod(int32 typmod)
     917             : {
     918      236370 :     return typmod >= (int32) VARHDRSZ;
     919             : }
     920             : 
     921             : /*
     922             :  * numeric_typmod_precision() -
     923             :  *
     924             :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
     925             :  */
     926             : static inline int
     927       49816 : numeric_typmod_precision(int32 typmod)
     928             : {
     929       49816 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
     930             : }
     931             : 
     932             : /*
     933             :  * numeric_typmod_scale() -
     934             :  *
     935             :  *  Extract the scale from a numeric typmod --- see make_numeric_typmod().
     936             :  *
     937             :  *  Note that the scale may be negative, so we must do sign extension when
     938             :  *  unpacking it.  We do this using the bit hack (x^1024)-1024, which sign
     939             :  *  extends an 11-bit two's complement number x.
     940             :  */
     941             : static inline int
     942       42620 : numeric_typmod_scale(int32 typmod)
     943             : {
     944       42620 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
     945             : }
     946             : 
     947             : /*
     948             :  * numeric_maximum_size() -
     949             :  *
     950             :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
     951             :  */
     952             : int32
     953        7196 : numeric_maximum_size(int32 typmod)
     954             : {
     955             :     int         precision;
     956             :     int         numeric_digits;
     957             : 
     958        7196 :     if (!is_valid_numeric_typmod(typmod))
     959           0 :         return -1;
     960             : 
     961             :     /* precision (ie, max # of digits) is in upper bits of typmod */
     962        7196 :     precision = numeric_typmod_precision(typmod);
     963             : 
     964             :     /*
     965             :      * This formula computes the maximum number of NumericDigits we could need
     966             :      * in order to store the specified number of decimal digits. Because the
     967             :      * weight is stored as a number of NumericDigits rather than a number of
     968             :      * decimal digits, it's possible that the first NumericDigit will contain
     969             :      * only a single decimal digit.  Thus, the first two decimal digits can
     970             :      * require two NumericDigits to store, but it isn't until we reach
     971             :      * DEC_DIGITS + 2 decimal digits that we potentially need a third
     972             :      * NumericDigit.
     973             :      */
     974        7196 :     numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
     975             : 
     976             :     /*
     977             :      * In most cases, the size of a numeric will be smaller than the value
     978             :      * computed below, because the varlena header will typically get toasted
     979             :      * down to a single byte before being stored on disk, and it may also be
     980             :      * possible to use a short numeric header.  But our job here is to compute
     981             :      * the worst case.
     982             :      */
     983        7196 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
     984             : }
     985             : 
     986             : /*
     987             :  * numeric_out_sci() -
     988             :  *
     989             :  *  Output function for numeric data type in scientific notation.
     990             :  */
     991             : char *
     992         246 : numeric_out_sci(Numeric num, int scale)
     993             : {
     994             :     NumericVar  x;
     995             :     char       *str;
     996             : 
     997             :     /*
     998             :      * Handle NaN and infinities
     999             :      */
    1000         246 :     if (NUMERIC_IS_SPECIAL(num))
    1001             :     {
    1002          18 :         if (NUMERIC_IS_PINF(num))
    1003           6 :             return pstrdup("Infinity");
    1004          12 :         else if (NUMERIC_IS_NINF(num))
    1005           6 :             return pstrdup("-Infinity");
    1006             :         else
    1007           6 :             return pstrdup("NaN");
    1008             :     }
    1009             : 
    1010         228 :     init_var_from_num(num, &x);
    1011             : 
    1012         228 :     str = get_str_from_var_sci(&x, scale);
    1013             : 
    1014         228 :     return str;
    1015             : }
    1016             : 
    1017             : /*
    1018             :  * numeric_normalize() -
    1019             :  *
    1020             :  *  Output function for numeric data type, suppressing insignificant trailing
    1021             :  *  zeroes and then any trailing decimal point.  The intent of this is to
    1022             :  *  produce strings that are equal if and only if the input numeric values
    1023             :  *  compare equal.
    1024             :  */
    1025             : char *
    1026       40478 : numeric_normalize(Numeric num)
    1027             : {
    1028             :     NumericVar  x;
    1029             :     char       *str;
    1030             :     int         last;
    1031             : 
    1032             :     /*
    1033             :      * Handle NaN and infinities
    1034             :      */
    1035       40478 :     if (NUMERIC_IS_SPECIAL(num))
    1036             :     {
    1037           0 :         if (NUMERIC_IS_PINF(num))
    1038           0 :             return pstrdup("Infinity");
    1039           0 :         else if (NUMERIC_IS_NINF(num))
    1040           0 :             return pstrdup("-Infinity");
    1041             :         else
    1042           0 :             return pstrdup("NaN");
    1043             :     }
    1044             : 
    1045       40478 :     init_var_from_num(num, &x);
    1046             : 
    1047       40478 :     str = get_str_from_var(&x);
    1048             : 
    1049             :     /* If there's no decimal point, there's certainly nothing to remove. */
    1050       40478 :     if (strchr(str, '.') != NULL)
    1051             :     {
    1052             :         /*
    1053             :          * Back up over trailing fractional zeroes.  Since there is a decimal
    1054             :          * point, this loop will terminate safely.
    1055             :          */
    1056          42 :         last = strlen(str) - 1;
    1057          84 :         while (str[last] == '0')
    1058          42 :             last--;
    1059             : 
    1060             :         /* We want to get rid of the decimal point too, if it's now last. */
    1061          42 :         if (str[last] == '.')
    1062          42 :             last--;
    1063             : 
    1064             :         /* Delete whatever we backed up over. */
    1065          42 :         str[last + 1] = '\0';
    1066             :     }
    1067             : 
    1068       40478 :     return str;
    1069             : }
    1070             : 
    1071             : /*
    1072             :  *      numeric_recv            - converts external binary format to numeric
    1073             :  *
    1074             :  * External format is a sequence of int16's:
    1075             :  * ndigits, weight, sign, dscale, NumericDigits.
    1076             :  */
    1077             : Datum
    1078         102 : numeric_recv(PG_FUNCTION_ARGS)
    1079             : {
    1080         102 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    1081             : 
    1082             : #ifdef NOT_USED
    1083             :     Oid         typelem = PG_GETARG_OID(1);
    1084             : #endif
    1085         102 :     int32       typmod = PG_GETARG_INT32(2);
    1086             :     NumericVar  value;
    1087             :     Numeric     res;
    1088             :     int         len,
    1089             :                 i;
    1090             : 
    1091         102 :     init_var(&value);
    1092             : 
    1093         102 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1094             : 
    1095         102 :     alloc_var(&value, len);
    1096             : 
    1097         102 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
    1098             :     /* we allow any int16 for weight --- OK? */
    1099             : 
    1100         102 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1101         102 :     if (!(value.sign == NUMERIC_POS ||
    1102           0 :           value.sign == NUMERIC_NEG ||
    1103           0 :           value.sign == NUMERIC_NAN ||
    1104           0 :           value.sign == NUMERIC_PINF ||
    1105           0 :           value.sign == NUMERIC_NINF))
    1106           0 :         ereport(ERROR,
    1107             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1108             :                  errmsg("invalid sign in external \"numeric\" value")));
    1109             : 
    1110         102 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1111         102 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
    1112           0 :         ereport(ERROR,
    1113             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1114             :                  errmsg("invalid scale in external \"numeric\" value")));
    1115             : 
    1116         274 :     for (i = 0; i < len; i++)
    1117             :     {
    1118         172 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
    1119             : 
    1120         172 :         if (d < 0 || d >= NBASE)
    1121           0 :             ereport(ERROR,
    1122             :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1123             :                      errmsg("invalid digit in external \"numeric\" value")));
    1124         172 :         value.digits[i] = d;
    1125             :     }
    1126             : 
    1127             :     /*
    1128             :      * If the given dscale would hide any digits, truncate those digits away.
    1129             :      * We could alternatively throw an error, but that would take a bunch of
    1130             :      * extra code (about as much as trunc_var involves), and it might cause
    1131             :      * client compatibility issues.  Be careful not to apply trunc_var to
    1132             :      * special values, as it could do the wrong thing; we don't need it
    1133             :      * anyway, since make_result will ignore all but the sign field.
    1134             :      *
    1135             :      * After doing that, be sure to check the typmod restriction.
    1136             :      */
    1137         102 :     if (value.sign == NUMERIC_POS ||
    1138           0 :         value.sign == NUMERIC_NEG)
    1139             :     {
    1140         102 :         trunc_var(&value, value.dscale);
    1141             : 
    1142         102 :         (void) apply_typmod(&value, typmod, NULL);
    1143             : 
    1144         102 :         res = make_result(&value);
    1145             :     }
    1146             :     else
    1147             :     {
    1148             :         /* apply_typmod_special wants us to make the Numeric first */
    1149           0 :         res = make_result(&value);
    1150             : 
    1151           0 :         (void) apply_typmod_special(res, typmod, NULL);
    1152             :     }
    1153             : 
    1154         102 :     free_var(&value);
    1155             : 
    1156         102 :     PG_RETURN_NUMERIC(res);
    1157             : }
    1158             : 
    1159             : /*
    1160             :  *      numeric_send            - converts numeric to binary format
    1161             :  */
    1162             : Datum
    1163          70 : numeric_send(PG_FUNCTION_ARGS)
    1164             : {
    1165          70 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1166             :     NumericVar  x;
    1167             :     StringInfoData buf;
    1168             :     int         i;
    1169             : 
    1170          70 :     init_var_from_num(num, &x);
    1171             : 
    1172          70 :     pq_begintypsend(&buf);
    1173             : 
    1174          70 :     pq_sendint16(&buf, x.ndigits);
    1175          70 :     pq_sendint16(&buf, x.weight);
    1176          70 :     pq_sendint16(&buf, x.sign);
    1177          70 :     pq_sendint16(&buf, x.dscale);
    1178         194 :     for (i = 0; i < x.ndigits; i++)
    1179         124 :         pq_sendint16(&buf, x.digits[i]);
    1180             : 
    1181          70 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    1182             : }
    1183             : 
    1184             : 
    1185             : /*
    1186             :  * numeric_support()
    1187             :  *
    1188             :  * Planner support function for the numeric() length coercion function.
    1189             :  *
    1190             :  * Flatten calls that solely represent increases in allowable precision.
    1191             :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
    1192             :  * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
    1193             :  * an unconstrained numeric to any constrained numeric is also unoptimizable.
    1194             :  */
    1195             : Datum
    1196         516 : numeric_support(PG_FUNCTION_ARGS)
    1197             : {
    1198         516 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1199         516 :     Node       *ret = NULL;
    1200             : 
    1201         516 :     if (IsA(rawreq, SupportRequestSimplify))
    1202             :     {
    1203         228 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
    1204         228 :         FuncExpr   *expr = req->fcall;
    1205             :         Node       *typmod;
    1206             : 
    1207             :         Assert(list_length(expr->args) >= 2);
    1208             : 
    1209         228 :         typmod = (Node *) lsecond(expr->args);
    1210             : 
    1211         228 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
    1212             :         {
    1213         228 :             Node       *source = (Node *) linitial(expr->args);
    1214         228 :             int32       old_typmod = exprTypmod(source);
    1215         228 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    1216         228 :             int32       old_scale = numeric_typmod_scale(old_typmod);
    1217         228 :             int32       new_scale = numeric_typmod_scale(new_typmod);
    1218         228 :             int32       old_precision = numeric_typmod_precision(old_typmod);
    1219         228 :             int32       new_precision = numeric_typmod_precision(new_typmod);
    1220             : 
    1221             :             /*
    1222             :              * If new_typmod is invalid, the destination is unconstrained;
    1223             :              * that's always OK.  If old_typmod is valid, the source is
    1224             :              * constrained, and we're OK if the scale is unchanged and the
    1225             :              * precision is not decreasing.  See further notes in function
    1226             :              * header comment.
    1227             :              */
    1228         456 :             if (!is_valid_numeric_typmod(new_typmod) ||
    1229         240 :                 (is_valid_numeric_typmod(old_typmod) &&
    1230           6 :                  new_scale == old_scale && new_precision >= old_precision))
    1231           6 :                 ret = relabel_to_typmod(source, new_typmod);
    1232             :         }
    1233             :     }
    1234             : 
    1235         516 :     PG_RETURN_POINTER(ret);
    1236             : }
    1237             : 
    1238             : /*
    1239             :  * numeric() -
    1240             :  *
    1241             :  *  This is a special function called by the Postgres database system
    1242             :  *  before a value is stored in a tuple's attribute. The precision and
    1243             :  *  scale of the attribute have to be applied on the value.
    1244             :  */
    1245             : Datum
    1246       11730 : numeric     (PG_FUNCTION_ARGS)
    1247             : {
    1248       11730 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1249       11730 :     int32       typmod = PG_GETARG_INT32(1);
    1250             :     Numeric     new;
    1251             :     int         precision;
    1252             :     int         scale;
    1253             :     int         ddigits;
    1254             :     int         maxdigits;
    1255             :     int         dscale;
    1256             :     NumericVar  var;
    1257             : 
    1258             :     /*
    1259             :      * Handle NaN and infinities: if apply_typmod_special doesn't complain,
    1260             :      * just return a copy of the input.
    1261             :      */
    1262       11730 :     if (NUMERIC_IS_SPECIAL(num))
    1263             :     {
    1264         210 :         (void) apply_typmod_special(num, typmod, NULL);
    1265         192 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1266             :     }
    1267             : 
    1268             :     /*
    1269             :      * If the value isn't a valid type modifier, simply return a copy of the
    1270             :      * input value
    1271             :      */
    1272       11520 :     if (!is_valid_numeric_typmod(typmod))
    1273           0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1274             : 
    1275             :     /*
    1276             :      * Get the precision and scale out of the typmod value
    1277             :      */
    1278       11520 :     precision = numeric_typmod_precision(typmod);
    1279       11520 :     scale = numeric_typmod_scale(typmod);
    1280       11520 :     maxdigits = precision - scale;
    1281             : 
    1282             :     /* The target display scale is non-negative */
    1283       11520 :     dscale = Max(scale, 0);
    1284             : 
    1285             :     /*
    1286             :      * If the number is certainly in bounds and due to the target scale no
    1287             :      * rounding could be necessary, just make a copy of the input and modify
    1288             :      * its scale fields, unless the larger scale forces us to abandon the
    1289             :      * short representation.  (Note we assume the existing dscale is
    1290             :      * honest...)
    1291             :      */
    1292       11520 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1293       11520 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
    1294        7134 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
    1295           0 :             || !NUMERIC_IS_SHORT(num)))
    1296             :     {
    1297        7134 :         new = duplicate_numeric(num);
    1298        7134 :         if (NUMERIC_IS_SHORT(num))
    1299        7134 :             new->choice.n_short.n_header =
    1300        7134 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
    1301        7134 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
    1302             :         else
    1303           0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
    1304           0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
    1305        7134 :         PG_RETURN_NUMERIC(new);
    1306             :     }
    1307             : 
    1308             :     /*
    1309             :      * We really need to fiddle with things - unpack the number into a
    1310             :      * variable and let apply_typmod() do it.
    1311             :      */
    1312        4386 :     init_var(&var);
    1313             : 
    1314        4386 :     set_var_from_num(num, &var);
    1315        4386 :     (void) apply_typmod(&var, typmod, NULL);
    1316        4326 :     new = make_result(&var);
    1317             : 
    1318        4326 :     free_var(&var);
    1319             : 
    1320        4326 :     PG_RETURN_NUMERIC(new);
    1321             : }
    1322             : 
    1323             : Datum
    1324        2022 : numerictypmodin(PG_FUNCTION_ARGS)
    1325             : {
    1326        2022 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1327             :     int32      *tl;
    1328             :     int         n;
    1329             :     int32       typmod;
    1330             : 
    1331        2022 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1332             : 
    1333        2022 :     if (n == 2)
    1334             :     {
    1335        2002 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1336          18 :             ereport(ERROR,
    1337             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1338             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1339             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1340        1984 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
    1341          12 :             ereport(ERROR,
    1342             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1343             :                      errmsg("NUMERIC scale %d must be between %d and %d",
    1344             :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
    1345        1972 :         typmod = make_numeric_typmod(tl[0], tl[1]);
    1346             :     }
    1347          20 :     else if (n == 1)
    1348             :     {
    1349           8 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1350           0 :             ereport(ERROR,
    1351             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1352             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1353             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1354             :         /* scale defaults to zero */
    1355           8 :         typmod = make_numeric_typmod(tl[0], 0);
    1356             :     }
    1357             :     else
    1358             :     {
    1359          12 :         ereport(ERROR,
    1360             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1361             :                  errmsg("invalid NUMERIC type modifier")));
    1362             :         typmod = 0;             /* keep compiler quiet */
    1363             :     }
    1364             : 
    1365        1980 :     PG_RETURN_INT32(typmod);
    1366             : }
    1367             : 
    1368             : Datum
    1369         526 : numerictypmodout(PG_FUNCTION_ARGS)
    1370             : {
    1371         526 :     int32       typmod = PG_GETARG_INT32(0);
    1372         526 :     char       *res = (char *) palloc(64);
    1373             : 
    1374         526 :     if (is_valid_numeric_typmod(typmod))
    1375         526 :         snprintf(res, 64, "(%d,%d)",
    1376             :                  numeric_typmod_precision(typmod),
    1377             :                  numeric_typmod_scale(typmod));
    1378             :     else
    1379           0 :         *res = '\0';
    1380             : 
    1381         526 :     PG_RETURN_CSTRING(res);
    1382             : }
    1383             : 
    1384             : 
    1385             : /* ----------------------------------------------------------------------
    1386             :  *
    1387             :  * Sign manipulation, rounding and the like
    1388             :  *
    1389             :  * ----------------------------------------------------------------------
    1390             :  */
    1391             : 
    1392             : Datum
    1393       19506 : numeric_abs(PG_FUNCTION_ARGS)
    1394             : {
    1395       19506 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1396             :     Numeric     res;
    1397             : 
    1398             :     /*
    1399             :      * Do it the easy way directly on the packed format
    1400             :      */
    1401       19506 :     res = duplicate_numeric(num);
    1402             : 
    1403       19506 :     if (NUMERIC_IS_SHORT(num))
    1404       19440 :         res->choice.n_short.n_header =
    1405       19440 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
    1406          66 :     else if (NUMERIC_IS_SPECIAL(num))
    1407             :     {
    1408             :         /* This changes -Inf to Inf, and doesn't affect NaN */
    1409          18 :         res->choice.n_short.n_header =
    1410          18 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
    1411             :     }
    1412             :     else
    1413          48 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
    1414             : 
    1415       19506 :     PG_RETURN_NUMERIC(res);
    1416             : }
    1417             : 
    1418             : 
    1419             : Datum
    1420         884 : numeric_uminus(PG_FUNCTION_ARGS)
    1421             : {
    1422         884 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1423             :     Numeric     res;
    1424             : 
    1425             :     /*
    1426             :      * Do it the easy way directly on the packed format
    1427             :      */
    1428         884 :     res = duplicate_numeric(num);
    1429             : 
    1430         884 :     if (NUMERIC_IS_SPECIAL(num))
    1431             :     {
    1432             :         /* Flip the sign, if it's Inf or -Inf */
    1433         126 :         if (!NUMERIC_IS_NAN(num))
    1434          84 :             res->choice.n_short.n_header =
    1435          84 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
    1436             :     }
    1437             : 
    1438             :     /*
    1439             :      * The packed format is known to be totally zero digit trimmed always. So
    1440             :      * once we've eliminated specials, we can identify a zero by the fact that
    1441             :      * there are no digits at all. Do nothing to a zero.
    1442             :      */
    1443         758 :     else if (NUMERIC_NDIGITS(num) != 0)
    1444             :     {
    1445             :         /* Else, flip the sign */
    1446         644 :         if (NUMERIC_IS_SHORT(num))
    1447         644 :             res->choice.n_short.n_header =
    1448         644 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
    1449           0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
    1450           0 :             res->choice.n_long.n_sign_dscale =
    1451           0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
    1452             :         else
    1453           0 :             res->choice.n_long.n_sign_dscale =
    1454           0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
    1455             :     }
    1456             : 
    1457         884 :     PG_RETURN_NUMERIC(res);
    1458             : }
    1459             : 
    1460             : 
    1461             : Datum
    1462         498 : numeric_uplus(PG_FUNCTION_ARGS)
    1463             : {
    1464         498 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1465             : 
    1466         498 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
    1467             : }
    1468             : 
    1469             : 
    1470             : /*
    1471             :  * numeric_sign_internal() -
    1472             :  *
    1473             :  * Returns -1 if the argument is less than 0, 0 if the argument is equal
    1474             :  * to 0, and 1 if the argument is greater than zero.  Caller must have
    1475             :  * taken care of the NaN case, but we can handle infinities here.
    1476             :  */
    1477             : static int
    1478        3570 : numeric_sign_internal(Numeric num)
    1479             : {
    1480        3570 :     if (NUMERIC_IS_SPECIAL(num))
    1481             :     {
    1482             :         Assert(!NUMERIC_IS_NAN(num));
    1483             :         /* Must be Inf or -Inf */
    1484         312 :         if (NUMERIC_IS_PINF(num))
    1485         186 :             return 1;
    1486             :         else
    1487         126 :             return -1;
    1488             :     }
    1489             : 
    1490             :     /*
    1491             :      * The packed format is known to be totally zero digit trimmed always. So
    1492             :      * once we've eliminated specials, we can identify a zero by the fact that
    1493             :      * there are no digits at all.
    1494             :      */
    1495        3258 :     else if (NUMERIC_NDIGITS(num) == 0)
    1496         228 :         return 0;
    1497        3030 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
    1498         732 :         return -1;
    1499             :     else
    1500        2298 :         return 1;
    1501             : }
    1502             : 
    1503             : /*
    1504             :  * numeric_sign() -
    1505             :  *
    1506             :  * returns -1 if the argument is less than 0, 0 if the argument is equal
    1507             :  * to 0, and 1 if the argument is greater than zero.
    1508             :  */
    1509             : Datum
    1510          48 : numeric_sign(PG_FUNCTION_ARGS)
    1511             : {
    1512          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1513             : 
    1514             :     /*
    1515             :      * Handle NaN (infinities can be handled normally)
    1516             :      */
    1517          48 :     if (NUMERIC_IS_NAN(num))
    1518           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    1519             : 
    1520          42 :     switch (numeric_sign_internal(num))
    1521             :     {
    1522           6 :         case 0:
    1523           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    1524          18 :         case 1:
    1525          18 :             PG_RETURN_NUMERIC(make_result(&const_one));
    1526          18 :         case -1:
    1527          18 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
    1528             :     }
    1529             : 
    1530             :     Assert(false);
    1531           0 :     return (Datum) 0;
    1532             : }
    1533             : 
    1534             : 
    1535             : /*
    1536             :  * numeric_round() -
    1537             :  *
    1538             :  *  Round a value to have 'scale' digits after the decimal point.
    1539             :  *  We allow negative 'scale', implying rounding before the decimal
    1540             :  *  point --- Oracle interprets rounding that way.
    1541             :  */
    1542             : Datum
    1543        7808 : numeric_round(PG_FUNCTION_ARGS)
    1544             : {
    1545        7808 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1546        7808 :     int32       scale = PG_GETARG_INT32(1);
    1547             :     Numeric     res;
    1548             :     NumericVar  arg;
    1549             : 
    1550             :     /*
    1551             :      * Handle NaN and infinities
    1552             :      */
    1553        7808 :     if (NUMERIC_IS_SPECIAL(num))
    1554          96 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1555             : 
    1556             :     /*
    1557             :      * Limit the scale value to avoid possible overflow in calculations.
    1558             :      *
    1559             :      * These limits are based on the maximum number of digits a Numeric value
    1560             :      * can have before and after the decimal point, but we must allow for one
    1561             :      * extra digit before the decimal point, in case the most significant
    1562             :      * digit rounds up; we must check if that causes Numeric overflow.
    1563             :      */
    1564        7712 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS - 1);
    1565        7712 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1566             : 
    1567             :     /*
    1568             :      * Unpack the argument and round it at the proper digit position
    1569             :      */
    1570        7712 :     init_var(&arg);
    1571        7712 :     set_var_from_num(num, &arg);
    1572             : 
    1573        7712 :     round_var(&arg, scale);
    1574             : 
    1575             :     /* We don't allow negative output dscale */
    1576        7712 :     if (scale < 0)
    1577         216 :         arg.dscale = 0;
    1578             : 
    1579             :     /*
    1580             :      * Return the rounded result
    1581             :      */
    1582        7712 :     res = make_result(&arg);
    1583             : 
    1584        7706 :     free_var(&arg);
    1585        7706 :     PG_RETURN_NUMERIC(res);
    1586             : }
    1587             : 
    1588             : 
    1589             : /*
    1590             :  * numeric_trunc() -
    1591             :  *
    1592             :  *  Truncate a value to have 'scale' digits after the decimal point.
    1593             :  *  We allow negative 'scale', implying a truncation before the decimal
    1594             :  *  point --- Oracle interprets truncation that way.
    1595             :  */
    1596             : Datum
    1597         626 : numeric_trunc(PG_FUNCTION_ARGS)
    1598             : {
    1599         626 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1600         626 :     int32       scale = PG_GETARG_INT32(1);
    1601             :     Numeric     res;
    1602             :     NumericVar  arg;
    1603             : 
    1604             :     /*
    1605             :      * Handle NaN and infinities
    1606             :      */
    1607         626 :     if (NUMERIC_IS_SPECIAL(num))
    1608          36 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1609             : 
    1610             :     /*
    1611             :      * Limit the scale value to avoid possible overflow in calculations.
    1612             :      *
    1613             :      * These limits are based on the maximum number of digits a Numeric value
    1614             :      * can have before and after the decimal point.
    1615             :      */
    1616         590 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS);
    1617         590 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1618             : 
    1619             :     /*
    1620             :      * Unpack the argument and truncate it at the proper digit position
    1621             :      */
    1622         590 :     init_var(&arg);
    1623         590 :     set_var_from_num(num, &arg);
    1624             : 
    1625         590 :     trunc_var(&arg, scale);
    1626             : 
    1627             :     /* We don't allow negative output dscale */
    1628         590 :     if (scale < 0)
    1629          24 :         arg.dscale = 0;
    1630             : 
    1631             :     /*
    1632             :      * Return the truncated result
    1633             :      */
    1634         590 :     res = make_result(&arg);
    1635             : 
    1636         590 :     free_var(&arg);
    1637         590 :     PG_RETURN_NUMERIC(res);
    1638             : }
    1639             : 
    1640             : 
    1641             : /*
    1642             :  * numeric_ceil() -
    1643             :  *
    1644             :  *  Return the smallest integer greater than or equal to the argument
    1645             :  */
    1646             : Datum
    1647         222 : numeric_ceil(PG_FUNCTION_ARGS)
    1648             : {
    1649         222 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1650             :     Numeric     res;
    1651             :     NumericVar  result;
    1652             : 
    1653             :     /*
    1654             :      * Handle NaN and infinities
    1655             :      */
    1656         222 :     if (NUMERIC_IS_SPECIAL(num))
    1657          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1658             : 
    1659         204 :     init_var_from_num(num, &result);
    1660         204 :     ceil_var(&result, &result);
    1661             : 
    1662         204 :     res = make_result(&result);
    1663         204 :     free_var(&result);
    1664             : 
    1665         204 :     PG_RETURN_NUMERIC(res);
    1666             : }
    1667             : 
    1668             : 
    1669             : /*
    1670             :  * numeric_floor() -
    1671             :  *
    1672             :  *  Return the largest integer equal to or less than the argument
    1673             :  */
    1674             : Datum
    1675         126 : numeric_floor(PG_FUNCTION_ARGS)
    1676             : {
    1677         126 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1678             :     Numeric     res;
    1679             :     NumericVar  result;
    1680             : 
    1681             :     /*
    1682             :      * Handle NaN and infinities
    1683             :      */
    1684         126 :     if (NUMERIC_IS_SPECIAL(num))
    1685          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1686             : 
    1687         108 :     init_var_from_num(num, &result);
    1688         108 :     floor_var(&result, &result);
    1689             : 
    1690         108 :     res = make_result(&result);
    1691         108 :     free_var(&result);
    1692             : 
    1693         108 :     PG_RETURN_NUMERIC(res);
    1694             : }
    1695             : 
    1696             : 
    1697             : /*
    1698             :  * generate_series_numeric() -
    1699             :  *
    1700             :  *  Generate series of numeric.
    1701             :  */
    1702             : Datum
    1703      120384 : generate_series_numeric(PG_FUNCTION_ARGS)
    1704             : {
    1705      120384 :     return generate_series_step_numeric(fcinfo);
    1706             : }
    1707             : 
    1708             : Datum
    1709      120834 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1710             : {
    1711             :     generate_series_numeric_fctx *fctx;
    1712             :     FuncCallContext *funcctx;
    1713             :     MemoryContext oldcontext;
    1714             : 
    1715      120834 :     if (SRF_IS_FIRSTCALL())
    1716             :     {
    1717         174 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1718         174 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1719         174 :         NumericVar  steploc = const_one;
    1720             : 
    1721             :         /* Reject NaN and infinities in start and stop values */
    1722         174 :         if (NUMERIC_IS_SPECIAL(start_num))
    1723             :         {
    1724          12 :             if (NUMERIC_IS_NAN(start_num))
    1725           6 :                 ereport(ERROR,
    1726             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1727             :                          errmsg("start value cannot be NaN")));
    1728             :             else
    1729           6 :                 ereport(ERROR,
    1730             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1731             :                          errmsg("start value cannot be infinity")));
    1732             :         }
    1733         162 :         if (NUMERIC_IS_SPECIAL(stop_num))
    1734             :         {
    1735          12 :             if (NUMERIC_IS_NAN(stop_num))
    1736           6 :                 ereport(ERROR,
    1737             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1738             :                          errmsg("stop value cannot be NaN")));
    1739             :             else
    1740           6 :                 ereport(ERROR,
    1741             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1742             :                          errmsg("stop value cannot be infinity")));
    1743             :         }
    1744             : 
    1745             :         /* see if we were given an explicit step size */
    1746         150 :         if (PG_NARGS() == 3)
    1747             :         {
    1748          72 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
    1749             : 
    1750          72 :             if (NUMERIC_IS_SPECIAL(step_num))
    1751             :             {
    1752          12 :                 if (NUMERIC_IS_NAN(step_num))
    1753           6 :                     ereport(ERROR,
    1754             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1755             :                              errmsg("step size cannot be NaN")));
    1756             :                 else
    1757           6 :                     ereport(ERROR,
    1758             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1759             :                              errmsg("step size cannot be infinity")));
    1760             :             }
    1761             : 
    1762          60 :             init_var_from_num(step_num, &steploc);
    1763             : 
    1764          60 :             if (cmp_var(&steploc, &const_zero) == 0)
    1765           6 :                 ereport(ERROR,
    1766             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1767             :                          errmsg("step size cannot equal zero")));
    1768             :         }
    1769             : 
    1770             :         /* create a function context for cross-call persistence */
    1771         132 :         funcctx = SRF_FIRSTCALL_INIT();
    1772             : 
    1773             :         /*
    1774             :          * Switch to memory context appropriate for multiple function calls.
    1775             :          */
    1776         132 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1777             : 
    1778             :         /* allocate memory for user context */
    1779             :         fctx = (generate_series_numeric_fctx *)
    1780         132 :             palloc(sizeof(generate_series_numeric_fctx));
    1781             : 
    1782             :         /*
    1783             :          * Use fctx to keep state from call to call. Seed current with the
    1784             :          * original start value. We must copy the start_num and stop_num
    1785             :          * values rather than pointing to them, since we may have detoasted
    1786             :          * them in the per-call context.
    1787             :          */
    1788         132 :         init_var(&fctx->current);
    1789         132 :         init_var(&fctx->stop);
    1790         132 :         init_var(&fctx->step);
    1791             : 
    1792         132 :         set_var_from_num(start_num, &fctx->current);
    1793         132 :         set_var_from_num(stop_num, &fctx->stop);
    1794         132 :         set_var_from_var(&steploc, &fctx->step);
    1795             : 
    1796         132 :         funcctx->user_fctx = fctx;
    1797         132 :         MemoryContextSwitchTo(oldcontext);
    1798             :     }
    1799             : 
    1800             :     /* stuff done on every call of the function */
    1801      120792 :     funcctx = SRF_PERCALL_SETUP();
    1802             : 
    1803             :     /*
    1804             :      * Get the saved state and use current state as the result of this
    1805             :      * iteration.
    1806             :      */
    1807      120792 :     fctx = funcctx->user_fctx;
    1808             : 
    1809      241404 :     if ((fctx->step.sign == NUMERIC_POS &&
    1810      120612 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1811         480 :         (fctx->step.sign == NUMERIC_NEG &&
    1812         180 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1813             :     {
    1814      120660 :         Numeric     result = make_result(&fctx->current);
    1815             : 
    1816             :         /* switch to memory context appropriate for iteration calculation */
    1817      120660 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1818             : 
    1819             :         /* increment current in preparation for next iteration */
    1820      120660 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1821      120660 :         MemoryContextSwitchTo(oldcontext);
    1822             : 
    1823             :         /* do when there is more left to send */
    1824      120660 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1825             :     }
    1826             :     else
    1827             :         /* do when there is no more left */
    1828         132 :         SRF_RETURN_DONE(funcctx);
    1829             : }
    1830             : 
    1831             : /*
    1832             :  * Planner support function for generate_series(numeric, numeric [, numeric])
    1833             :  */
    1834             : Datum
    1835         486 : generate_series_numeric_support(PG_FUNCTION_ARGS)
    1836             : {
    1837         486 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1838         486 :     Node       *ret = NULL;
    1839             : 
    1840         486 :     if (IsA(rawreq, SupportRequestRows))
    1841             :     {
    1842             :         /* Try to estimate the number of rows returned */
    1843         156 :         SupportRequestRows *req = (SupportRequestRows *) rawreq;
    1844             : 
    1845         156 :         if (is_funcclause(req->node))    /* be paranoid */
    1846             :         {
    1847         156 :             List       *args = ((FuncExpr *) req->node)->args;
    1848             :             Node       *arg1,
    1849             :                        *arg2,
    1850             :                        *arg3;
    1851             : 
    1852             :             /* We can use estimated argument values here */
    1853         156 :             arg1 = estimate_expression_value(req->root, linitial(args));
    1854         156 :             arg2 = estimate_expression_value(req->root, lsecond(args));
    1855         156 :             if (list_length(args) >= 3)
    1856         102 :                 arg3 = estimate_expression_value(req->root, lthird(args));
    1857             :             else
    1858          54 :                 arg3 = NULL;
    1859             : 
    1860             :             /*
    1861             :              * If any argument is constant NULL, we can safely assume that
    1862             :              * zero rows are returned.  Otherwise, if they're all non-NULL
    1863             :              * constants, we can calculate the number of rows that will be
    1864             :              * returned.
    1865             :              */
    1866         156 :             if ((IsA(arg1, Const) &&
    1867         150 :                  ((Const *) arg1)->constisnull) ||
    1868         156 :                 (IsA(arg2, Const) &&
    1869         156 :                  ((Const *) arg2)->constisnull) ||
    1870         102 :                 (arg3 != NULL && IsA(arg3, Const) &&
    1871          96 :                  ((Const *) arg3)->constisnull))
    1872             :             {
    1873           0 :                 req->rows = 0;
    1874           0 :                 ret = (Node *) req;
    1875             :             }
    1876         156 :             else if (IsA(arg1, Const) &&
    1877         150 :                      IsA(arg2, Const) &&
    1878         102 :                      (arg3 == NULL || IsA(arg3, Const)))
    1879             :             {
    1880             :                 Numeric     start_num;
    1881             :                 Numeric     stop_num;
    1882         138 :                 NumericVar  step = const_one;
    1883             : 
    1884             :                 /*
    1885             :                  * If any argument is NaN or infinity, generate_series() will
    1886             :                  * error out, so we needn't produce an estimate.
    1887             :                  */
    1888         138 :                 start_num = DatumGetNumeric(((Const *) arg1)->constvalue);
    1889         138 :                 stop_num = DatumGetNumeric(((Const *) arg2)->constvalue);
    1890             : 
    1891         138 :                 if (NUMERIC_IS_SPECIAL(start_num) ||
    1892         120 :                     NUMERIC_IS_SPECIAL(stop_num))
    1893          48 :                     PG_RETURN_POINTER(NULL);
    1894             : 
    1895         108 :                 if (arg3)
    1896             :                 {
    1897             :                     Numeric     step_num;
    1898             : 
    1899          66 :                     step_num = DatumGetNumeric(((Const *) arg3)->constvalue);
    1900             : 
    1901          66 :                     if (NUMERIC_IS_SPECIAL(step_num))
    1902          18 :                         PG_RETURN_POINTER(NULL);
    1903             : 
    1904          48 :                     init_var_from_num(step_num, &step);
    1905             :                 }
    1906             : 
    1907             :                 /*
    1908             :                  * The number of rows that will be returned is given by
    1909             :                  * floor((stop - start) / step) + 1, if the sign of step
    1910             :                  * matches the sign of stop - start.  Otherwise, no rows will
    1911             :                  * be returned.
    1912             :                  */
    1913          90 :                 if (cmp_var(&step, &const_zero) != 0)
    1914             :                 {
    1915             :                     NumericVar  start;
    1916             :                     NumericVar  stop;
    1917             :                     NumericVar  res;
    1918             : 
    1919          78 :                     init_var_from_num(start_num, &start);
    1920          78 :                     init_var_from_num(stop_num, &stop);
    1921             : 
    1922          78 :                     init_var(&res);
    1923          78 :                     sub_var(&stop, &start, &res);
    1924             : 
    1925          78 :                     if (step.sign != res.sign)
    1926             :                     {
    1927             :                         /* no rows will be returned */
    1928           6 :                         req->rows = 0;
    1929           6 :                         ret = (Node *) req;
    1930             :                     }
    1931             :                     else
    1932             :                     {
    1933          72 :                         if (arg3)
    1934          30 :                             div_var(&res, &step, &res, 0, false, false);
    1935             :                         else
    1936          42 :                             trunc_var(&res, 0); /* step = 1 */
    1937             : 
    1938          72 :                         req->rows = numericvar_to_double_no_overflow(&res) + 1;
    1939          72 :                         ret = (Node *) req;
    1940             :                     }
    1941             : 
    1942          78 :                     free_var(&res);
    1943             :                 }
    1944             :             }
    1945             :         }
    1946             :     }
    1947             : 
    1948         438 :     PG_RETURN_POINTER(ret);
    1949             : }
    1950             : 
    1951             : 
    1952             : /*
    1953             :  * Implements the numeric version of the width_bucket() function
    1954             :  * defined by SQL2003. See also width_bucket_float8().
    1955             :  *
    1956             :  * 'bound1' and 'bound2' are the lower and upper bounds of the
    1957             :  * histogram's range, respectively. 'count' is the number of buckets
    1958             :  * in the histogram. width_bucket() returns an integer indicating the
    1959             :  * bucket number that 'operand' belongs to in an equiwidth histogram
    1960             :  * with the specified characteristics. An operand smaller than the
    1961             :  * lower bound is assigned to bucket 0. An operand greater than or equal
    1962             :  * to the upper bound is assigned to an additional bucket (with number
    1963             :  * count+1). We don't allow "NaN" for any of the numeric inputs, and we
    1964             :  * don't allow either of the histogram bounds to be +/- infinity.
    1965             :  */
    1966             : Datum
    1967         780 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1968             : {
    1969         780 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1970         780 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1971         780 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1972         780 :     int32       count = PG_GETARG_INT32(3);
    1973             :     NumericVar  count_var;
    1974             :     NumericVar  result_var;
    1975             :     int32       result;
    1976             : 
    1977         780 :     if (count <= 0)
    1978          12 :         ereport(ERROR,
    1979             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1980             :                  errmsg("count must be greater than zero")));
    1981             : 
    1982         768 :     if (NUMERIC_IS_SPECIAL(operand) ||
    1983         750 :         NUMERIC_IS_SPECIAL(bound1) ||
    1984         744 :         NUMERIC_IS_SPECIAL(bound2))
    1985             :     {
    1986          36 :         if (NUMERIC_IS_NAN(operand) ||
    1987          30 :             NUMERIC_IS_NAN(bound1) ||
    1988          30 :             NUMERIC_IS_NAN(bound2))
    1989           6 :             ereport(ERROR,
    1990             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1991             :                      errmsg("operand, lower bound, and upper bound cannot be NaN")));
    1992             :         /* We allow "operand" to be infinite; cmp_numerics will cope */
    1993          30 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1994          18 :             ereport(ERROR,
    1995             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1996             :                      errmsg("lower and upper bounds must be finite")));
    1997             :     }
    1998             : 
    1999         744 :     init_var(&result_var);
    2000         744 :     init_var(&count_var);
    2001             : 
    2002             :     /* Convert 'count' to a numeric, for ease of use later */
    2003         744 :     int64_to_numericvar((int64) count, &count_var);
    2004             : 
    2005         744 :     switch (cmp_numerics(bound1, bound2))
    2006             :     {
    2007           6 :         case 0:
    2008           6 :             ereport(ERROR,
    2009             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    2010             :                      errmsg("lower bound cannot equal upper bound")));
    2011             :             break;
    2012             : 
    2013             :             /* bound1 < bound2 */
    2014         546 :         case -1:
    2015         546 :             if (cmp_numerics(operand, bound1) < 0)
    2016         114 :                 set_var_from_var(&const_zero, &result_var);
    2017         432 :             else if (cmp_numerics(operand, bound2) >= 0)
    2018         108 :                 add_var(&count_var, &const_one, &result_var);
    2019             :             else
    2020         324 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2021             :                                &result_var);
    2022         546 :             break;
    2023             : 
    2024             :             /* bound1 > bound2 */
    2025         192 :         case 1:
    2026         192 :             if (cmp_numerics(operand, bound1) > 0)
    2027          12 :                 set_var_from_var(&const_zero, &result_var);
    2028         180 :             else if (cmp_numerics(operand, bound2) <= 0)
    2029          24 :                 add_var(&count_var, &const_one, &result_var);
    2030             :             else
    2031         156 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2032             :                                &result_var);
    2033         192 :             break;
    2034             :     }
    2035             : 
    2036             :     /* if result exceeds the range of a legal int4, we ereport here */
    2037         738 :     if (!numericvar_to_int32(&result_var, &result))
    2038           0 :         ereport(ERROR,
    2039             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    2040             :                  errmsg("integer out of range")));
    2041             : 
    2042         738 :     free_var(&count_var);
    2043         738 :     free_var(&result_var);
    2044             : 
    2045         738 :     PG_RETURN_INT32(result);
    2046             : }
    2047             : 
    2048             : /*
    2049             :  * 'operand' is inside the bucket range, so determine the correct
    2050             :  * bucket for it to go in. The calculations performed by this function
    2051             :  * are derived directly from the SQL2003 spec. Note however that we
    2052             :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    2053             :  */
    2054             : static void
    2055         480 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    2056             :                const NumericVar *count_var, NumericVar *result_var)
    2057             : {
    2058             :     NumericVar  bound1_var;
    2059             :     NumericVar  bound2_var;
    2060             :     NumericVar  operand_var;
    2061             : 
    2062         480 :     init_var_from_num(bound1, &bound1_var);
    2063         480 :     init_var_from_num(bound2, &bound2_var);
    2064         480 :     init_var_from_num(operand, &operand_var);
    2065             : 
    2066             :     /*
    2067             :      * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
    2068             :      * bound1 <= operand < bound2 or bound1 >= operand > bound2.  Either way,
    2069             :      * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
    2070             :      * where the quotient is computed using floor division (i.e., division to
    2071             :      * zero decimal places with truncation), which guarantees that the result
    2072             :      * is in the range [1, count].  Reversing the bounds doesn't affect the
    2073             :      * computation, because the signs cancel out when dividing.
    2074             :      */
    2075         480 :     sub_var(&operand_var, &bound1_var, &operand_var);
    2076         480 :     sub_var(&bound2_var, &bound1_var, &bound2_var);
    2077             : 
    2078         480 :     mul_var(&operand_var, count_var, &operand_var,
    2079         480 :             operand_var.dscale + count_var->dscale);
    2080         480 :     div_var(&operand_var, &bound2_var, result_var, 0, false, true);
    2081         480 :     add_var(result_var, &const_one, result_var);
    2082             : 
    2083         480 :     free_var(&bound1_var);
    2084         480 :     free_var(&bound2_var);
    2085         480 :     free_var(&operand_var);
    2086         480 : }
    2087             : 
    2088             : /* ----------------------------------------------------------------------
    2089             :  *
    2090             :  * Comparison functions
    2091             :  *
    2092             :  * Note: btree indexes need these routines not to leak memory; therefore,
    2093             :  * be careful to free working copies of toasted datums.  Most places don't
    2094             :  * need to be so careful.
    2095             :  *
    2096             :  * Sort support:
    2097             :  *
    2098             :  * We implement the sortsupport strategy routine in order to get the benefit of
    2099             :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    2100             :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    2101             :  * while this could be worked on itself, the abbreviation strategy gives more
    2102             :  * speedup in many common cases.
    2103             :  *
    2104             :  * Two different representations are used for the abbreviated form, one in
    2105             :  * int32 and one in int64, whichever fits into a by-value Datum.  In both cases
    2106             :  * the representation is negated relative to the original value, because we use
    2107             :  * the largest negative value for NaN, which sorts higher than other values. We
    2108             :  * convert the absolute value of the numeric to a 31-bit or 63-bit positive
    2109             :  * value, and then negate it if the original number was positive.
    2110             :  *
    2111             :  * We abort the abbreviation process if the abbreviation cardinality is below
    2112             :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    2113             :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    2114             :  * very small penalty), but we don't want to build up too many abbreviated
    2115             :  * values before first testing for abort, so we take the slightly pessimistic
    2116             :  * number.  We make no attempt to estimate the cardinality of the real values,
    2117             :  * since it plays no part in the cost model here (if the abbreviation is equal,
    2118             :  * the cost of comparing equal and unequal underlying values is comparable).
    2119             :  * We discontinue even checking for abort (saving us the hashing overhead) if
    2120             :  * the estimated cardinality gets to 100k; that would be enough to support many
    2121             :  * billions of rows while doing no worse than breaking even.
    2122             :  *
    2123             :  * ----------------------------------------------------------------------
    2124             :  */
    2125             : 
    2126             : /*
    2127             :  * Sort support strategy routine.
    2128             :  */
    2129             : Datum
    2130        1124 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2131             : {
    2132        1124 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2133             : 
    2134        1124 :     ssup->comparator = numeric_fast_cmp;
    2135             : 
    2136        1124 :     if (ssup->abbreviate)
    2137             :     {
    2138             :         NumericSortSupport *nss;
    2139         268 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2140             : 
    2141         268 :         nss = palloc(sizeof(NumericSortSupport));
    2142             : 
    2143             :         /*
    2144             :          * palloc a buffer for handling unaligned packed values in addition to
    2145             :          * the support struct
    2146             :          */
    2147         268 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2148             : 
    2149         268 :         nss->input_count = 0;
    2150         268 :         nss->estimating = true;
    2151         268 :         initHyperLogLog(&nss->abbr_card, 10);
    2152             : 
    2153         268 :         ssup->ssup_extra = nss;
    2154             : 
    2155         268 :         ssup->abbrev_full_comparator = ssup->comparator;
    2156         268 :         ssup->comparator = numeric_cmp_abbrev;
    2157         268 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2158         268 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2159             : 
    2160         268 :         MemoryContextSwitchTo(oldcontext);
    2161             :     }
    2162             : 
    2163        1124 :     PG_RETURN_VOID();
    2164             : }
    2165             : 
    2166             : /*
    2167             :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2168             :  * (must not leak memory!)
    2169             :  */
    2170             : static Datum
    2171       19170 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2172             : {
    2173       19170 :     NumericSortSupport *nss = ssup->ssup_extra;
    2174       19170 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2175             :     Numeric     value;
    2176             :     Datum       result;
    2177             : 
    2178       19170 :     nss->input_count += 1;
    2179             : 
    2180             :     /*
    2181             :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2182             :      * we keep and reuse a buffer large enough to handle any short datum.
    2183             :      */
    2184       19170 :     if (VARATT_IS_SHORT(original_varatt))
    2185             :     {
    2186        1028 :         void       *buf = nss->buf;
    2187        1028 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2188             : 
    2189             :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2190             : 
    2191        1028 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2192        1028 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2193             : 
    2194        1028 :         value = (Numeric) buf;
    2195             :     }
    2196             :     else
    2197       18142 :         value = (Numeric) original_varatt;
    2198             : 
    2199       19170 :     if (NUMERIC_IS_SPECIAL(value))
    2200             :     {
    2201         150 :         if (NUMERIC_IS_PINF(value))
    2202          48 :             result = NUMERIC_ABBREV_PINF;
    2203         102 :         else if (NUMERIC_IS_NINF(value))
    2204          48 :             result = NUMERIC_ABBREV_NINF;
    2205             :         else
    2206          54 :             result = NUMERIC_ABBREV_NAN;
    2207             :     }
    2208             :     else
    2209             :     {
    2210             :         NumericVar  var;
    2211             : 
    2212       19020 :         init_var_from_num(value, &var);
    2213             : 
    2214       19020 :         result = numeric_abbrev_convert_var(&var, nss);
    2215             :     }
    2216             : 
    2217             :     /* should happen only for external/compressed toasts */
    2218       19170 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
    2219           0 :         pfree(original_varatt);
    2220             : 
    2221       19170 :     return result;
    2222             : }
    2223             : 
    2224             : /*
    2225             :  * Consider whether to abort abbreviation.
    2226             :  *
    2227             :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2228             :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2229             :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2230             :  * whether the underlying values are also equal.
    2231             :  */
    2232             : static bool
    2233         144 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2234             : {
    2235         144 :     NumericSortSupport *nss = ssup->ssup_extra;
    2236             :     double      abbr_card;
    2237             : 
    2238         144 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2239         144 :         return false;
    2240             : 
    2241           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2242             : 
    2243             :     /*
    2244             :      * If we have >100k distinct values, then even if we were sorting many
    2245             :      * billion rows we'd likely still break even, and the penalty of undoing
    2246             :      * that many rows of abbrevs would probably not be worth it. Stop even
    2247             :      * counting at that point.
    2248             :      */
    2249           0 :     if (abbr_card > 100000.0)
    2250             :     {
    2251           0 :         if (trace_sort)
    2252           0 :             elog(LOG,
    2253             :                  "numeric_abbrev: estimation ends at cardinality %f"
    2254             :                  " after " INT64_FORMAT " values (%d rows)",
    2255             :                  abbr_card, nss->input_count, memtupcount);
    2256           0 :         nss->estimating = false;
    2257           0 :         return false;
    2258             :     }
    2259             : 
    2260             :     /*
    2261             :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2262             :      * break even point is somewhere between one per 100k rows, where
    2263             :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2264             :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2265             :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2266             :      * abort earlier on genuinely pathological data where we've had exactly
    2267             :      * one abbreviated value in the first 10k (non-null) rows.
    2268             :      */
    2269           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2270             :     {
    2271           0 :         if (trace_sort)
    2272           0 :             elog(LOG,
    2273             :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2274             :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2275             :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2276             :                  nss->input_count, memtupcount);
    2277           0 :         return true;
    2278             :     }
    2279             : 
    2280           0 :     if (trace_sort)
    2281           0 :         elog(LOG,
    2282             :              "numeric_abbrev: cardinality %f"
    2283             :              " after " INT64_FORMAT " values (%d rows)",
    2284             :              abbr_card, nss->input_count, memtupcount);
    2285             : 
    2286           0 :     return false;
    2287             : }
    2288             : 
    2289             : /*
    2290             :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2291             :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2292             :  * are, but it is a required part of the sort support API when abbreviations
    2293             :  * are performed.
    2294             :  *
    2295             :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2296             :  * aligning short-varlena inputs, but this has not so far been considered to
    2297             :  * be worth the effort.
    2298             :  */
    2299             : static int
    2300    17835230 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2301             : {
    2302    17835230 :     Numeric     nx = DatumGetNumeric(x);
    2303    17835230 :     Numeric     ny = DatumGetNumeric(y);
    2304             :     int         result;
    2305             : 
    2306    17835230 :     result = cmp_numerics(nx, ny);
    2307             : 
    2308    17835230 :     if ((Pointer) nx != DatumGetPointer(x))
    2309     5713648 :         pfree(nx);
    2310    17835230 :     if ((Pointer) ny != DatumGetPointer(y))
    2311     5713642 :         pfree(ny);
    2312             : 
    2313    17835230 :     return result;
    2314             : }
    2315             : 
    2316             : /*
    2317             :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2318             :  * values differ, but if the abbreviations differ, they must reflect the
    2319             :  * ordering of the true values.)
    2320             :  */
    2321             : static int
    2322      188006 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2323             : {
    2324             :     /*
    2325             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2326             :      * negated relative to the original value, to handle NaN/infinity cases.
    2327             :      */
    2328      188006 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2329       95274 :         return 1;
    2330       92732 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2331       92508 :         return -1;
    2332         224 :     return 0;
    2333             : }
    2334             : 
    2335             : /*
    2336             :  * Abbreviate a NumericVar according to the available bit size.
    2337             :  *
    2338             :  * The 31-bit value is constructed as:
    2339             :  *
    2340             :  *  0 + 7bits digit weight + 24 bits digit value
    2341             :  *
    2342             :  * where the digit weight is in single decimal digits, not digit words, and
    2343             :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2344             :  * significant decimal digits of the value converted to binary. Values whose
    2345             :  * weights would fall outside the representable range are rounded off to zero
    2346             :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2347             :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2348             :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2349             :  * to be a serious limitation, or when values are of the same magnitude and
    2350             :  * equal in the first 7 decimal digits, which is considered to be an
    2351             :  * unavoidable limitation given the available bits. (Stealing three more bits
    2352             :  * to compare another digit would narrow the range of representable weights by
    2353             :  * a factor of 8, which starts to look like a real limiting factor.)
    2354             :  *
    2355             :  * (The value 44 for the excess is essentially arbitrary)
    2356             :  *
    2357             :  * The 63-bit value is constructed as:
    2358             :  *
    2359             :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2360             :  *
    2361             :  * The weight in this case is again stored in excess-44, but this time it is
    2362             :  * the original weight in digit words (i.e. powers of 10000). The first four
    2363             :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2364             :  * are packed into 14 bits each to form the rest of the value. Again,
    2365             :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2366             :  * representable range in this case is 10^-176 to 10^332, which is considered
    2367             :  * to be good enough for all practical purposes, and comparison of 4 words
    2368             :  * means that at least 13 decimal digits are compared, which is considered to
    2369             :  * be a reasonable compromise between effectiveness and efficiency in computing
    2370             :  * the abbreviation.
    2371             :  *
    2372             :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2373             :  * to match the value used in the 31-bit case)
    2374             :  *
    2375             :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2376             :  * and then treated as unsigned, so the smallest representable value is stored
    2377             :  * with all bits zero. This allows simple comparisons to work on the composite
    2378             :  * value.
    2379             :  */
    2380             : 
    2381             : #if NUMERIC_ABBREV_BITS == 64
    2382             : 
    2383             : static Datum
    2384       19020 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2385             : {
    2386       19020 :     int         ndigits = var->ndigits;
    2387       19020 :     int         weight = var->weight;
    2388             :     int64       result;
    2389             : 
    2390       19020 :     if (ndigits == 0 || weight < -44)
    2391             :     {
    2392          52 :         result = 0;
    2393             :     }
    2394       18968 :     else if (weight > 83)
    2395             :     {
    2396          12 :         result = PG_INT64_MAX;
    2397             :     }
    2398             :     else
    2399             :     {
    2400       18956 :         result = ((int64) (weight + 44) << 56);
    2401             : 
    2402       18956 :         switch (ndigits)
    2403             :         {
    2404           0 :             default:
    2405           0 :                 result |= ((int64) var->digits[3]);
    2406             :                 /* FALLTHROUGH */
    2407        6206 :             case 3:
    2408        6206 :                 result |= ((int64) var->digits[2]) << 14;
    2409             :                 /* FALLTHROUGH */
    2410       18312 :             case 2:
    2411       18312 :                 result |= ((int64) var->digits[1]) << 28;
    2412             :                 /* FALLTHROUGH */
    2413       18956 :             case 1:
    2414       18956 :                 result |= ((int64) var->digits[0]) << 42;
    2415       18956 :                 break;
    2416             :         }
    2417             :     }
    2418             : 
    2419             :     /* the abbrev is negated relative to the original */
    2420       19020 :     if (var->sign == NUMERIC_POS)
    2421       18922 :         result = -result;
    2422             : 
    2423       19020 :     if (nss->estimating)
    2424             :     {
    2425       19020 :         uint32      tmp = ((uint32) result
    2426       19020 :                            ^ (uint32) ((uint64) result >> 32));
    2427             : 
    2428       19020 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2429             :     }
    2430             : 
    2431       19020 :     return NumericAbbrevGetDatum(result);
    2432             : }
    2433             : 
    2434             : #endif                          /* NUMERIC_ABBREV_BITS == 64 */
    2435             : 
    2436             : #if NUMERIC_ABBREV_BITS == 32
    2437             : 
    2438             : static Datum
    2439             : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2440             : {
    2441             :     int         ndigits = var->ndigits;
    2442             :     int         weight = var->weight;
    2443             :     int32       result;
    2444             : 
    2445             :     if (ndigits == 0 || weight < -11)
    2446             :     {
    2447             :         result = 0;
    2448             :     }
    2449             :     else if (weight > 20)
    2450             :     {
    2451             :         result = PG_INT32_MAX;
    2452             :     }
    2453             :     else
    2454             :     {
    2455             :         NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
    2456             : 
    2457             :         weight = (weight + 11) * 4;
    2458             : 
    2459             :         result = var->digits[0];
    2460             : 
    2461             :         /*
    2462             :          * "result" now has 1 to 4 nonzero decimal digits. We pack in more
    2463             :          * digits to make 7 in total (largest we can fit in 24 bits)
    2464             :          */
    2465             : 
    2466             :         if (result > 999)
    2467             :         {
    2468             :             /* already have 4 digits, add 3 more */
    2469             :             result = (result * 1000) + (nxt1 / 10);
    2470             :             weight += 3;
    2471             :         }
    2472             :         else if (result > 99)
    2473             :         {
    2474             :             /* already have 3 digits, add 4 more */
    2475             :             result = (result * 10000) + nxt1;
    2476             :             weight += 2;
    2477             :         }
    2478             :         else if (result > 9)
    2479             :         {
    2480             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2481             : 
    2482             :             /* already have 2 digits, add 5 more */
    2483             :             result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
    2484             :             weight += 1;
    2485             :         }
    2486             :         else
    2487             :         {
    2488             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2489             : 
    2490             :             /* already have 1 digit, add 6 more */
    2491             :             result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
    2492             :         }
    2493             : 
    2494             :         result = result | (weight << 24);
    2495             :     }
    2496             : 
    2497             :     /* the abbrev is negated relative to the original */
    2498             :     if (var->sign == NUMERIC_POS)
    2499             :         result = -result;
    2500             : 
    2501             :     if (nss->estimating)
    2502             :     {
    2503             :         uint32      tmp = (uint32) result;
    2504             : 
    2505             :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2506             :     }
    2507             : 
    2508             :     return NumericAbbrevGetDatum(result);
    2509             : }
    2510             : 
    2511             : #endif                          /* NUMERIC_ABBREV_BITS == 32 */
    2512             : 
    2513             : /*
    2514             :  * Ordinary (non-sortsupport) comparisons follow.
    2515             :  */
    2516             : 
    2517             : Datum
    2518      750334 : numeric_cmp(PG_FUNCTION_ARGS)
    2519             : {
    2520      750334 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2521      750334 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2522             :     int         result;
    2523             : 
    2524      750334 :     result = cmp_numerics(num1, num2);
    2525             : 
    2526      750334 :     PG_FREE_IF_COPY(num1, 0);
    2527      750334 :     PG_FREE_IF_COPY(num2, 1);
    2528             : 
    2529      750334 :     PG_RETURN_INT32(result);
    2530             : }
    2531             : 
    2532             : 
    2533             : Datum
    2534      650794 : numeric_eq(PG_FUNCTION_ARGS)
    2535             : {
    2536      650794 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2537      650794 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2538             :     bool        result;
    2539             : 
    2540      650794 :     result = cmp_numerics(num1, num2) == 0;
    2541             : 
    2542      650794 :     PG_FREE_IF_COPY(num1, 0);
    2543      650794 :     PG_FREE_IF_COPY(num2, 1);
    2544             : 
    2545      650794 :     PG_RETURN_BOOL(result);
    2546             : }
    2547             : 
    2548             : Datum
    2549        5376 : numeric_ne(PG_FUNCTION_ARGS)
    2550             : {
    2551        5376 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2552        5376 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2553             :     bool        result;
    2554             : 
    2555        5376 :     result = cmp_numerics(num1, num2) != 0;
    2556             : 
    2557        5376 :     PG_FREE_IF_COPY(num1, 0);
    2558        5376 :     PG_FREE_IF_COPY(num2, 1);
    2559             : 
    2560        5376 :     PG_RETURN_BOOL(result);
    2561             : }
    2562             : 
    2563             : Datum
    2564       55626 : numeric_gt(PG_FUNCTION_ARGS)
    2565             : {
    2566       55626 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2567       55626 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2568             :     bool        result;
    2569             : 
    2570       55626 :     result = cmp_numerics(num1, num2) > 0;
    2571             : 
    2572       55626 :     PG_FREE_IF_COPY(num1, 0);
    2573       55626 :     PG_FREE_IF_COPY(num2, 1);
    2574             : 
    2575       55626 :     PG_RETURN_BOOL(result);
    2576             : }
    2577             : 
    2578             : Datum
    2579       15006 : numeric_ge(PG_FUNCTION_ARGS)
    2580             : {
    2581       15006 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2582       15006 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2583             :     bool        result;
    2584             : 
    2585       15006 :     result = cmp_numerics(num1, num2) >= 0;
    2586             : 
    2587       15006 :     PG_FREE_IF_COPY(num1, 0);
    2588       15006 :     PG_FREE_IF_COPY(num2, 1);
    2589             : 
    2590       15006 :     PG_RETURN_BOOL(result);
    2591             : }
    2592             : 
    2593             : Datum
    2594       59798 : numeric_lt(PG_FUNCTION_ARGS)
    2595             : {
    2596       59798 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2597       59798 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2598             :     bool        result;
    2599             : 
    2600       59798 :     result = cmp_numerics(num1, num2) < 0;
    2601             : 
    2602       59798 :     PG_FREE_IF_COPY(num1, 0);
    2603       59798 :     PG_FREE_IF_COPY(num2, 1);
    2604             : 
    2605       59798 :     PG_RETURN_BOOL(result);
    2606             : }
    2607             : 
    2608             : Datum
    2609       16888 : numeric_le(PG_FUNCTION_ARGS)
    2610             : {
    2611       16888 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2612       16888 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2613             :     bool        result;
    2614             : 
    2615       16888 :     result = cmp_numerics(num1, num2) <= 0;
    2616             : 
    2617       16888 :     PG_FREE_IF_COPY(num1, 0);
    2618       16888 :     PG_FREE_IF_COPY(num2, 1);
    2619             : 
    2620       16888 :     PG_RETURN_BOOL(result);
    2621             : }
    2622             : 
    2623             : static int
    2624    19410574 : cmp_numerics(Numeric num1, Numeric num2)
    2625             : {
    2626             :     int         result;
    2627             : 
    2628             :     /*
    2629             :      * We consider all NANs to be equal and larger than any non-NAN (including
    2630             :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2631             :      * a consistent sort order.
    2632             :      */
    2633    19410574 :     if (NUMERIC_IS_SPECIAL(num1))
    2634             :     {
    2635        5910 :         if (NUMERIC_IS_NAN(num1))
    2636             :         {
    2637        5820 :             if (NUMERIC_IS_NAN(num2))
    2638         584 :                 result = 0;     /* NAN = NAN */
    2639             :             else
    2640        5236 :                 result = 1;     /* NAN > non-NAN */
    2641             :         }
    2642          90 :         else if (NUMERIC_IS_PINF(num1))
    2643             :         {
    2644          72 :             if (NUMERIC_IS_NAN(num2))
    2645           0 :                 result = -1;    /* PINF < NAN */
    2646          72 :             else if (NUMERIC_IS_PINF(num2))
    2647           6 :                 result = 0;     /* PINF = PINF */
    2648             :             else
    2649          66 :                 result = 1;     /* PINF > anything else */
    2650             :         }
    2651             :         else                    /* num1 must be NINF */
    2652             :         {
    2653          18 :             if (NUMERIC_IS_NINF(num2))
    2654           6 :                 result = 0;     /* NINF = NINF */
    2655             :             else
    2656          12 :                 result = -1;    /* NINF < anything else */
    2657             :         }
    2658             :     }
    2659    19404664 :     else if (NUMERIC_IS_SPECIAL(num2))
    2660             :     {
    2661       11142 :         if (NUMERIC_IS_NINF(num2))
    2662          12 :             result = 1;         /* normal > NINF */
    2663             :         else
    2664       11130 :             result = -1;        /* normal < NAN or PINF */
    2665             :     }
    2666             :     else
    2667             :     {
    2668    38788072 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2669    19393824 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2670    19393522 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2671    19394248 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2672             :     }
    2673             : 
    2674    19410574 :     return result;
    2675             : }
    2676             : 
    2677             : /*
    2678             :  * in_range support function for numeric.
    2679             :  */
    2680             : Datum
    2681        1152 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2682             : {
    2683        1152 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2684        1152 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2685        1152 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2686        1152 :     bool        sub = PG_GETARG_BOOL(3);
    2687        1152 :     bool        less = PG_GETARG_BOOL(4);
    2688             :     bool        result;
    2689             : 
    2690             :     /*
    2691             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2692             :      * and NaN is because appropriate semantics for that seem non-obvious.
    2693             :      */
    2694        1152 :     if (NUMERIC_IS_NAN(offset) ||
    2695        1146 :         NUMERIC_IS_NINF(offset) ||
    2696        1146 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2697           6 :         ereport(ERROR,
    2698             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2699             :                  errmsg("invalid preceding or following size in window function")));
    2700             : 
    2701             :     /*
    2702             :      * Deal with cases where val and/or base is NaN, following the rule that
    2703             :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2704             :      * the conclusion.
    2705             :      */
    2706        1146 :     if (NUMERIC_IS_NAN(val))
    2707             :     {
    2708         186 :         if (NUMERIC_IS_NAN(base))
    2709          60 :             result = true;      /* NAN = NAN */
    2710             :         else
    2711         126 :             result = !less;     /* NAN > non-NAN */
    2712             :     }
    2713         960 :     else if (NUMERIC_IS_NAN(base))
    2714             :     {
    2715         126 :         result = less;          /* non-NAN < NAN */
    2716             :     }
    2717             : 
    2718             :     /*
    2719             :      * Deal with infinite offset (necessarily +Inf, at this point).
    2720             :      */
    2721         834 :     else if (NUMERIC_IS_SPECIAL(offset))
    2722             :     {
    2723             :         Assert(NUMERIC_IS_PINF(offset));
    2724         420 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2725             :         {
    2726             :             /*
    2727             :              * base +/- offset would produce NaN, so return true for any val
    2728             :              * (see in_range_float8_float8() for reasoning).
    2729             :              */
    2730         174 :             result = true;
    2731             :         }
    2732         246 :         else if (sub)
    2733             :         {
    2734             :             /* base - offset must be -inf */
    2735         150 :             if (less)
    2736          54 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2737             :             else
    2738          96 :                 result = true;  /* any val is >= sum */
    2739             :         }
    2740             :         else
    2741             :         {
    2742             :             /* base + offset must be +inf */
    2743          96 :             if (less)
    2744           0 :                 result = true;  /* any val is <= sum */
    2745             :             else
    2746          96 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2747             :         }
    2748             :     }
    2749             : 
    2750             :     /*
    2751             :      * Deal with cases where val and/or base is infinite.  The offset, being
    2752             :      * now known finite, cannot affect the conclusion.
    2753             :      */
    2754         414 :     else if (NUMERIC_IS_SPECIAL(val))
    2755             :     {
    2756          78 :         if (NUMERIC_IS_PINF(val))
    2757             :         {
    2758          36 :             if (NUMERIC_IS_PINF(base))
    2759          24 :                 result = true;  /* PINF = PINF */
    2760             :             else
    2761          12 :                 result = !less; /* PINF > any other non-NAN */
    2762             :         }
    2763             :         else                    /* val must be NINF */
    2764             :         {
    2765          42 :             if (NUMERIC_IS_NINF(base))
    2766          30 :                 result = true;  /* NINF = NINF */
    2767             :             else
    2768          12 :                 result = less;  /* NINF < anything else */
    2769             :         }
    2770             :     }
    2771         336 :     else if (NUMERIC_IS_SPECIAL(base))
    2772             :     {
    2773          24 :         if (NUMERIC_IS_NINF(base))
    2774          12 :             result = !less;     /* normal > NINF */
    2775             :         else
    2776          12 :             result = less;      /* normal < PINF */
    2777             :     }
    2778             :     else
    2779             :     {
    2780             :         /*
    2781             :          * Otherwise go ahead and compute base +/- offset.  While it's
    2782             :          * possible for this to overflow the numeric format, it's unlikely
    2783             :          * enough that we don't take measures to prevent it.
    2784             :          */
    2785             :         NumericVar  valv;
    2786             :         NumericVar  basev;
    2787             :         NumericVar  offsetv;
    2788             :         NumericVar  sum;
    2789             : 
    2790         312 :         init_var_from_num(val, &valv);
    2791         312 :         init_var_from_num(base, &basev);
    2792         312 :         init_var_from_num(offset, &offsetv);
    2793         312 :         init_var(&sum);
    2794             : 
    2795         312 :         if (sub)
    2796         156 :             sub_var(&basev, &offsetv, &sum);
    2797             :         else
    2798         156 :             add_var(&basev, &offsetv, &sum);
    2799             : 
    2800         312 :         if (less)
    2801         156 :             result = (cmp_var(&valv, &sum) <= 0);
    2802             :         else
    2803         156 :             result = (cmp_var(&valv, &sum) >= 0);
    2804             : 
    2805         312 :         free_var(&sum);
    2806             :     }
    2807             : 
    2808        1146 :     PG_FREE_IF_COPY(val, 0);
    2809        1146 :     PG_FREE_IF_COPY(base, 1);
    2810        1146 :     PG_FREE_IF_COPY(offset, 2);
    2811             : 
    2812        1146 :     PG_RETURN_BOOL(result);
    2813             : }
    2814             : 
    2815             : Datum
    2816      607746 : hash_numeric(PG_FUNCTION_ARGS)
    2817             : {
    2818      607746 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2819             :     Datum       digit_hash;
    2820             :     Datum       result;
    2821             :     int         weight;
    2822             :     int         start_offset;
    2823             :     int         end_offset;
    2824             :     int         i;
    2825             :     int         hash_len;
    2826             :     NumericDigit *digits;
    2827             : 
    2828             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2829      607746 :     if (NUMERIC_IS_SPECIAL(key))
    2830           0 :         PG_RETURN_UINT32(0);
    2831             : 
    2832      607746 :     weight = NUMERIC_WEIGHT(key);
    2833      607746 :     start_offset = 0;
    2834      607746 :     end_offset = 0;
    2835             : 
    2836             :     /*
    2837             :      * Omit any leading or trailing zeros from the input to the hash. The
    2838             :      * numeric implementation *should* guarantee that leading and trailing
    2839             :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2840             :      * starting and ending offsets in units of NumericDigits, not bytes.
    2841             :      */
    2842      607746 :     digits = NUMERIC_DIGITS(key);
    2843      607746 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2844             :     {
    2845      606080 :         if (digits[i] != (NumericDigit) 0)
    2846      606080 :             break;
    2847             : 
    2848           0 :         start_offset++;
    2849             : 
    2850             :         /*
    2851             :          * The weight is effectively the # of digits before the decimal point,
    2852             :          * so decrement it for each leading zero we skip.
    2853             :          */
    2854           0 :         weight--;
    2855             :     }
    2856             : 
    2857             :     /*
    2858             :      * If there are no non-zero digits, then the value of the number is zero,
    2859             :      * regardless of any other fields.
    2860             :      */
    2861      607746 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2862        1666 :         PG_RETURN_UINT32(-1);
    2863             : 
    2864      606080 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2865             :     {
    2866      606080 :         if (digits[i] != (NumericDigit) 0)
    2867      606080 :             break;
    2868             : 
    2869           0 :         end_offset++;
    2870             :     }
    2871             : 
    2872             :     /* If we get here, there should be at least one non-zero digit */
    2873             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2874             : 
    2875             :     /*
    2876             :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2877             :      * compare equal but have different scales. We also don't hash on the
    2878             :      * sign, although we could: since a sign difference implies inequality,
    2879             :      * this shouldn't affect correctness.
    2880             :      */
    2881      606080 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2882      606080 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2883             :                           hash_len * sizeof(NumericDigit));
    2884             : 
    2885             :     /* Mix in the weight, via XOR */
    2886      606080 :     result = digit_hash ^ weight;
    2887             : 
    2888      606080 :     PG_RETURN_DATUM(result);
    2889             : }
    2890             : 
    2891             : /*
    2892             :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2893             :  * Otherwise, similar to hash_numeric.
    2894             :  */
    2895             : Datum
    2896          84 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2897             : {
    2898          84 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2899          84 :     uint64      seed = PG_GETARG_INT64(1);
    2900             :     Datum       digit_hash;
    2901             :     Datum       result;
    2902             :     int         weight;
    2903             :     int         start_offset;
    2904             :     int         end_offset;
    2905             :     int         i;
    2906             :     int         hash_len;
    2907             :     NumericDigit *digits;
    2908             : 
    2909             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2910          84 :     if (NUMERIC_IS_SPECIAL(key))
    2911           0 :         PG_RETURN_UINT64(seed);
    2912             : 
    2913          84 :     weight = NUMERIC_WEIGHT(key);
    2914          84 :     start_offset = 0;
    2915          84 :     end_offset = 0;
    2916             : 
    2917          84 :     digits = NUMERIC_DIGITS(key);
    2918          84 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2919             :     {
    2920          72 :         if (digits[i] != (NumericDigit) 0)
    2921          72 :             break;
    2922             : 
    2923           0 :         start_offset++;
    2924             : 
    2925           0 :         weight--;
    2926             :     }
    2927             : 
    2928          84 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2929          12 :         PG_RETURN_UINT64(seed - 1);
    2930             : 
    2931          72 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2932             :     {
    2933          72 :         if (digits[i] != (NumericDigit) 0)
    2934          72 :             break;
    2935             : 
    2936           0 :         end_offset++;
    2937             :     }
    2938             : 
    2939             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2940             : 
    2941          72 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2942          72 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2943          72 :                                                       + start_offset),
    2944             :                                    hash_len * sizeof(NumericDigit),
    2945             :                                    seed);
    2946             : 
    2947          72 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2948             : 
    2949          72 :     PG_RETURN_DATUM(result);
    2950             : }
    2951             : 
    2952             : 
    2953             : /* ----------------------------------------------------------------------
    2954             :  *
    2955             :  * Basic arithmetic functions
    2956             :  *
    2957             :  * ----------------------------------------------------------------------
    2958             :  */
    2959             : 
    2960             : 
    2961             : /*
    2962             :  * numeric_add() -
    2963             :  *
    2964             :  *  Add two numerics
    2965             :  */
    2966             : Datum
    2967      252178 : numeric_add(PG_FUNCTION_ARGS)
    2968             : {
    2969      252178 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2970      252178 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2971             :     Numeric     res;
    2972             : 
    2973      252178 :     res = numeric_add_opt_error(num1, num2, NULL);
    2974             : 
    2975      252178 :     PG_RETURN_NUMERIC(res);
    2976             : }
    2977             : 
    2978             : /*
    2979             :  * numeric_add_opt_error() -
    2980             :  *
    2981             :  *  Internal version of numeric_add().  If "*have_error" flag is provided,
    2982             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2983             :  *  need to handle errors by itself.
    2984             :  */
    2985             : Numeric
    2986      253216 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2987             : {
    2988             :     NumericVar  arg1;
    2989             :     NumericVar  arg2;
    2990             :     NumericVar  result;
    2991             :     Numeric     res;
    2992             : 
    2993             :     /*
    2994             :      * Handle NaN and infinities
    2995             :      */
    2996      253216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2997             :     {
    2998         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2999          78 :             return make_result(&const_nan);
    3000         120 :         if (NUMERIC_IS_PINF(num1))
    3001             :         {
    3002          36 :             if (NUMERIC_IS_NINF(num2))
    3003           6 :                 return make_result(&const_nan); /* Inf + -Inf */
    3004             :             else
    3005          30 :                 return make_result(&const_pinf);
    3006             :         }
    3007          84 :         if (NUMERIC_IS_NINF(num1))
    3008             :         {
    3009          36 :             if (NUMERIC_IS_PINF(num2))
    3010           6 :                 return make_result(&const_nan); /* -Inf + Inf */
    3011             :             else
    3012          30 :                 return make_result(&const_ninf);
    3013             :         }
    3014             :         /* by here, num1 must be finite, so num2 is not */
    3015          48 :         if (NUMERIC_IS_PINF(num2))
    3016          24 :             return make_result(&const_pinf);
    3017             :         Assert(NUMERIC_IS_NINF(num2));
    3018          24 :         return make_result(&const_ninf);
    3019             :     }
    3020             : 
    3021             :     /*
    3022             :      * Unpack the values, let add_var() compute the result and return it.
    3023             :      */
    3024      253018 :     init_var_from_num(num1, &arg1);
    3025      253018 :     init_var_from_num(num2, &arg2);
    3026             : 
    3027      253018 :     init_var(&result);
    3028      253018 :     add_var(&arg1, &arg2, &result);
    3029             : 
    3030      253018 :     res = make_result_opt_error(&result, have_error);
    3031             : 
    3032      253018 :     free_var(&result);
    3033             : 
    3034      253018 :     return res;
    3035             : }
    3036             : 
    3037             : 
    3038             : /*
    3039             :  * numeric_sub() -
    3040             :  *
    3041             :  *  Subtract one numeric from another
    3042             :  */
    3043             : Datum
    3044       75390 : numeric_sub(PG_FUNCTION_ARGS)
    3045             : {
    3046       75390 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3047       75390 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3048             :     Numeric     res;
    3049             : 
    3050       75390 :     res = numeric_sub_opt_error(num1, num2, NULL);
    3051             : 
    3052       75390 :     PG_RETURN_NUMERIC(res);
    3053             : }
    3054             : 
    3055             : 
    3056             : /*
    3057             :  * numeric_sub_opt_error() -
    3058             :  *
    3059             :  *  Internal version of numeric_sub().  If "*have_error" flag is provided,
    3060             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3061             :  *  need to handle errors by itself.
    3062             :  */
    3063             : Numeric
    3064       75540 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3065             : {
    3066             :     NumericVar  arg1;
    3067             :     NumericVar  arg2;
    3068             :     NumericVar  result;
    3069             :     Numeric     res;
    3070             : 
    3071             :     /*
    3072             :      * Handle NaN and infinities
    3073             :      */
    3074       75540 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3075             :     {
    3076         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3077          78 :             return make_result(&const_nan);
    3078         120 :         if (NUMERIC_IS_PINF(num1))
    3079             :         {
    3080          36 :             if (NUMERIC_IS_PINF(num2))
    3081           6 :                 return make_result(&const_nan); /* Inf - Inf */
    3082             :             else
    3083          30 :                 return make_result(&const_pinf);
    3084             :         }
    3085          84 :         if (NUMERIC_IS_NINF(num1))
    3086             :         {
    3087          36 :             if (NUMERIC_IS_NINF(num2))
    3088           6 :                 return make_result(&const_nan); /* -Inf - -Inf */
    3089             :             else
    3090          30 :                 return make_result(&const_ninf);
    3091             :         }
    3092             :         /* by here, num1 must be finite, so num2 is not */
    3093          48 :         if (NUMERIC_IS_PINF(num2))
    3094          24 :             return make_result(&const_ninf);
    3095             :         Assert(NUMERIC_IS_NINF(num2));
    3096          24 :         return make_result(&const_pinf);
    3097             :     }
    3098             : 
    3099             :     /*
    3100             :      * Unpack the values, let sub_var() compute the result and return it.
    3101             :      */
    3102       75342 :     init_var_from_num(num1, &arg1);
    3103       75342 :     init_var_from_num(num2, &arg2);
    3104             : 
    3105       75342 :     init_var(&result);
    3106       75342 :     sub_var(&arg1, &arg2, &result);
    3107             : 
    3108       75342 :     res = make_result_opt_error(&result, have_error);
    3109             : 
    3110       75342 :     free_var(&result);
    3111             : 
    3112       75342 :     return res;
    3113             : }
    3114             : 
    3115             : 
    3116             : /*
    3117             :  * numeric_mul() -
    3118             :  *
    3119             :  *  Calculate the product of two numerics
    3120             :  */
    3121             : Datum
    3122      489704 : numeric_mul(PG_FUNCTION_ARGS)
    3123             : {
    3124      489704 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3125      489704 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3126             :     Numeric     res;
    3127             : 
    3128      489704 :     res = numeric_mul_opt_error(num1, num2, NULL);
    3129             : 
    3130      489704 :     PG_RETURN_NUMERIC(res);
    3131             : }
    3132             : 
    3133             : 
    3134             : /*
    3135             :  * numeric_mul_opt_error() -
    3136             :  *
    3137             :  *  Internal version of numeric_mul().  If "*have_error" flag is provided,
    3138             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3139             :  *  need to handle errors by itself.
    3140             :  */
    3141             : Numeric
    3142      489740 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3143             : {
    3144             :     NumericVar  arg1;
    3145             :     NumericVar  arg2;
    3146             :     NumericVar  result;
    3147             :     Numeric     res;
    3148             : 
    3149             :     /*
    3150             :      * Handle NaN and infinities
    3151             :      */
    3152      489740 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3153             :     {
    3154         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3155          78 :             return make_result(&const_nan);
    3156         120 :         if (NUMERIC_IS_PINF(num1))
    3157             :         {
    3158          36 :             switch (numeric_sign_internal(num2))
    3159             :             {
    3160           6 :                 case 0:
    3161           6 :                     return make_result(&const_nan); /* Inf * 0 */
    3162          18 :                 case 1:
    3163          18 :                     return make_result(&const_pinf);
    3164          12 :                 case -1:
    3165          12 :                     return make_result(&const_ninf);
    3166             :             }
    3167             :             Assert(false);
    3168             :         }
    3169          84 :         if (NUMERIC_IS_NINF(num1))
    3170             :         {
    3171          36 :             switch (numeric_sign_internal(num2))
    3172             :             {
    3173           6 :                 case 0:
    3174           6 :                     return make_result(&const_nan); /* -Inf * 0 */
    3175          18 :                 case 1:
    3176          18 :                     return make_result(&const_ninf);
    3177          12 :                 case -1:
    3178          12 :                     return make_result(&const_pinf);
    3179             :             }
    3180             :             Assert(false);
    3181             :         }
    3182             :         /* by here, num1 must be finite, so num2 is not */
    3183          48 :         if (NUMERIC_IS_PINF(num2))
    3184             :         {
    3185          24 :             switch (numeric_sign_internal(num1))
    3186             :             {
    3187           6 :                 case 0:
    3188           6 :                     return make_result(&const_nan); /* 0 * Inf */
    3189          12 :                 case 1:
    3190          12 :                     return make_result(&const_pinf);
    3191           6 :                 case -1:
    3192           6 :                     return make_result(&const_ninf);
    3193             :             }
    3194             :             Assert(false);
    3195             :         }
    3196             :         Assert(NUMERIC_IS_NINF(num2));
    3197          24 :         switch (numeric_sign_internal(num1))
    3198             :         {
    3199           6 :             case 0:
    3200           6 :                 return make_result(&const_nan); /* 0 * -Inf */
    3201          12 :             case 1:
    3202          12 :                 return make_result(&const_ninf);
    3203           6 :             case -1:
    3204           6 :                 return make_result(&const_pinf);
    3205             :         }
    3206             :         Assert(false);
    3207             :     }
    3208             : 
    3209             :     /*
    3210             :      * Unpack the values, let mul_var() compute the result and return it.
    3211             :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3212             :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3213             :      * we request exact representation for the product (rscale = sum(dscale of
    3214             :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3215             :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3216             :      * after computing the exact result ensures that the final result is
    3217             :      * correctly rounded (rounding in mul_var() using a truncated product
    3218             :      * would not guarantee this).
    3219             :      */
    3220      489542 :     init_var_from_num(num1, &arg1);
    3221      489542 :     init_var_from_num(num2, &arg2);
    3222             : 
    3223      489542 :     init_var(&result);
    3224      489542 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3225             : 
    3226      489542 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3227           6 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3228             : 
    3229      489542 :     res = make_result_opt_error(&result, have_error);
    3230             : 
    3231      489542 :     free_var(&result);
    3232             : 
    3233      489542 :     return res;
    3234             : }
    3235             : 
    3236             : 
    3237             : /*
    3238             :  * numeric_div() -
    3239             :  *
    3240             :  *  Divide one numeric into another
    3241             :  */
    3242             : Datum
    3243      148260 : numeric_div(PG_FUNCTION_ARGS)
    3244             : {
    3245      148260 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3246      148260 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3247             :     Numeric     res;
    3248             : 
    3249      148260 :     res = numeric_div_opt_error(num1, num2, NULL);
    3250             : 
    3251      148228 :     PG_RETURN_NUMERIC(res);
    3252             : }
    3253             : 
    3254             : 
    3255             : /*
    3256             :  * numeric_div_opt_error() -
    3257             :  *
    3258             :  *  Internal version of numeric_div().  If "*have_error" flag is provided,
    3259             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3260             :  *  need to handle errors by itself.
    3261             :  */
    3262             : Numeric
    3263      149100 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3264             : {
    3265             :     NumericVar  arg1;
    3266             :     NumericVar  arg2;
    3267             :     NumericVar  result;
    3268             :     Numeric     res;
    3269             :     int         rscale;
    3270             : 
    3271      149100 :     if (have_error)
    3272          48 :         *have_error = false;
    3273             : 
    3274             :     /*
    3275             :      * Handle NaN and infinities
    3276             :      */
    3277      149100 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3278             :     {
    3279         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3280          78 :             return make_result(&const_nan);
    3281         120 :         if (NUMERIC_IS_PINF(num1))
    3282             :         {
    3283          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3284          12 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3285          24 :             switch (numeric_sign_internal(num2))
    3286             :             {
    3287           6 :                 case 0:
    3288           6 :                     if (have_error)
    3289             :                     {
    3290           0 :                         *have_error = true;
    3291           0 :                         return NULL;
    3292             :                     }
    3293           6 :                     ereport(ERROR,
    3294             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3295             :                              errmsg("division by zero")));
    3296             :                     break;
    3297          12 :                 case 1:
    3298          12 :                     return make_result(&const_pinf);
    3299           6 :                 case -1:
    3300           6 :                     return make_result(&const_ninf);
    3301             :             }
    3302             :             Assert(false);
    3303             :         }
    3304          84 :         if (NUMERIC_IS_NINF(num1))
    3305             :         {
    3306          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3307          12 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
    3308          24 :             switch (numeric_sign_internal(num2))
    3309             :             {
    3310           6 :                 case 0:
    3311           6 :                     if (have_error)
    3312             :                     {
    3313           0 :                         *have_error = true;
    3314           0 :                         return NULL;
    3315             :                     }
    3316           6 :                     ereport(ERROR,
    3317             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3318             :                              errmsg("division by zero")));
    3319             :                     break;
    3320          12 :                 case 1:
    3321          12 :                     return make_result(&const_ninf);
    3322           6 :                 case -1:
    3323           6 :                     return make_result(&const_pinf);
    3324             :             }
    3325             :             Assert(false);
    3326             :         }
    3327             :         /* by here, num1 must be finite, so num2 is not */
    3328             : 
    3329             :         /*
    3330             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3331             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3332             :          * really do underflow, so let's just return zero.
    3333             :          */
    3334          48 :         return make_result(&const_zero);
    3335             :     }
    3336             : 
    3337             :     /*
    3338             :      * Unpack the arguments
    3339             :      */
    3340      148902 :     init_var_from_num(num1, &arg1);
    3341      148902 :     init_var_from_num(num2, &arg2);
    3342             : 
    3343      148902 :     init_var(&result);
    3344             : 
    3345             :     /*
    3346             :      * Select scale for division result
    3347             :      */
    3348      148902 :     rscale = select_div_scale(&arg1, &arg2);
    3349             : 
    3350             :     /*
    3351             :      * If "have_error" is provided, check for division by zero here
    3352             :      */
    3353      148902 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3354             :     {
    3355          12 :         *have_error = true;
    3356          12 :         return NULL;
    3357             :     }
    3358             : 
    3359             :     /*
    3360             :      * Do the divide and return the result
    3361             :      */
    3362      148890 :     div_var(&arg1, &arg2, &result, rscale, true, true);
    3363             : 
    3364      148852 :     res = make_result_opt_error(&result, have_error);
    3365             : 
    3366      148852 :     free_var(&result);
    3367             : 
    3368      148852 :     return res;
    3369             : }
    3370             : 
    3371             : 
    3372             : /*
    3373             :  * numeric_div_trunc() -
    3374             :  *
    3375             :  *  Divide one numeric into another, truncating the result to an integer
    3376             :  */
    3377             : Datum
    3378        1218 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3379             : {
    3380        1218 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3381        1218 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3382             :     NumericVar  arg1;
    3383             :     NumericVar  arg2;
    3384             :     NumericVar  result;
    3385             :     Numeric     res;
    3386             : 
    3387             :     /*
    3388             :      * Handle NaN and infinities
    3389             :      */
    3390        1218 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3391             :     {
    3392         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3393          78 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3394         120 :         if (NUMERIC_IS_PINF(num1))
    3395             :         {
    3396          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3397          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3398          24 :             switch (numeric_sign_internal(num2))
    3399             :             {
    3400           6 :                 case 0:
    3401           6 :                     ereport(ERROR,
    3402             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3403             :                              errmsg("division by zero")));
    3404             :                     break;
    3405          12 :                 case 1:
    3406          12 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3407           6 :                 case -1:
    3408           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3409             :             }
    3410             :             Assert(false);
    3411             :         }
    3412          84 :         if (NUMERIC_IS_NINF(num1))
    3413             :         {
    3414          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3415          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3416          24 :             switch (numeric_sign_internal(num2))
    3417             :             {
    3418           6 :                 case 0:
    3419           6 :                     ereport(ERROR,
    3420             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3421             :                              errmsg("division by zero")));
    3422             :                     break;
    3423          12 :                 case 1:
    3424          12 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3425           6 :                 case -1:
    3426           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3427             :             }
    3428             :             Assert(false);
    3429             :         }
    3430             :         /* by here, num1 must be finite, so num2 is not */
    3431             : 
    3432             :         /*
    3433             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3434             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3435             :          * really do underflow, so let's just return zero.
    3436             :          */
    3437          48 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3438             :     }
    3439             : 
    3440             :     /*
    3441             :      * Unpack the arguments
    3442             :      */
    3443        1020 :     init_var_from_num(num1, &arg1);
    3444        1020 :     init_var_from_num(num2, &arg2);
    3445             : 
    3446        1020 :     init_var(&result);
    3447             : 
    3448             :     /*
    3449             :      * Do the divide and return the result
    3450             :      */
    3451        1020 :     div_var(&arg1, &arg2, &result, 0, false, true);
    3452             : 
    3453        1014 :     res = make_result(&result);
    3454             : 
    3455        1014 :     free_var(&result);
    3456             : 
    3457        1014 :     PG_RETURN_NUMERIC(res);
    3458             : }
    3459             : 
    3460             : 
    3461             : /*
    3462             :  * numeric_mod() -
    3463             :  *
    3464             :  *  Calculate the modulo of two numerics
    3465             :  */
    3466             : Datum
    3467      413384 : numeric_mod(PG_FUNCTION_ARGS)
    3468             : {
    3469      413384 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3470      413384 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3471             :     Numeric     res;
    3472             : 
    3473      413384 :     res = numeric_mod_opt_error(num1, num2, NULL);
    3474             : 
    3475      413366 :     PG_RETURN_NUMERIC(res);
    3476             : }
    3477             : 
    3478             : 
    3479             : /*
    3480             :  * numeric_mod_opt_error() -
    3481             :  *
    3482             :  *  Internal version of numeric_mod().  If "*have_error" flag is provided,
    3483             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3484             :  *  need to handle errors by itself.
    3485             :  */
    3486             : Numeric
    3487      413396 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3488             : {
    3489             :     Numeric     res;
    3490             :     NumericVar  arg1;
    3491             :     NumericVar  arg2;
    3492             :     NumericVar  result;
    3493             : 
    3494      413396 :     if (have_error)
    3495           0 :         *have_error = false;
    3496             : 
    3497             :     /*
    3498             :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3499             :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3500             :      * returning NaN.  We choose to throw error only for y-is-zero.
    3501             :      */
    3502      413396 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3503             :     {
    3504         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3505          78 :             return make_result(&const_nan);
    3506         120 :         if (NUMERIC_IS_INF(num1))
    3507             :         {
    3508          72 :             if (numeric_sign_internal(num2) == 0)
    3509             :             {
    3510          12 :                 if (have_error)
    3511             :                 {
    3512           0 :                     *have_error = true;
    3513           0 :                     return NULL;
    3514             :                 }
    3515          12 :                 ereport(ERROR,
    3516             :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
    3517             :                          errmsg("division by zero")));
    3518             :             }
    3519             :             /* Inf % any nonzero = NaN */
    3520          60 :             return make_result(&const_nan);
    3521             :         }
    3522             :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3523          48 :         return duplicate_numeric(num1);
    3524             :     }
    3525             : 
    3526      413198 :     init_var_from_num(num1, &arg1);
    3527      413198 :     init_var_from_num(num2, &arg2);
    3528             : 
    3529      413198 :     init_var(&result);
    3530             : 
    3531             :     /*
    3532             :      * If "have_error" is provided, check for division by zero here
    3533             :      */
    3534      413198 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3535             :     {
    3536           0 :         *have_error = true;
    3537           0 :         return NULL;
    3538             :     }
    3539             : 
    3540      413198 :     mod_var(&arg1, &arg2, &result);
    3541             : 
    3542      413186 :     res = make_result_opt_error(&result, NULL);
    3543             : 
    3544      413186 :     free_var(&result);
    3545             : 
    3546      413186 :     return res;
    3547             : }
    3548             : 
    3549             : 
    3550             : /*
    3551             :  * numeric_inc() -
    3552             :  *
    3553             :  *  Increment a number by one
    3554             :  */
    3555             : Datum
    3556          48 : numeric_inc(PG_FUNCTION_ARGS)
    3557             : {
    3558          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3559             :     NumericVar  arg;
    3560             :     Numeric     res;
    3561             : 
    3562             :     /*
    3563             :      * Handle NaN and infinities
    3564             :      */
    3565          48 :     if (NUMERIC_IS_SPECIAL(num))
    3566          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3567             : 
    3568             :     /*
    3569             :      * Compute the result and return it
    3570             :      */
    3571          30 :     init_var_from_num(num, &arg);
    3572             : 
    3573          30 :     add_var(&arg, &const_one, &arg);
    3574             : 
    3575          30 :     res = make_result(&arg);
    3576             : 
    3577          30 :     free_var(&arg);
    3578             : 
    3579          30 :     PG_RETURN_NUMERIC(res);
    3580             : }
    3581             : 
    3582             : 
    3583             : /*
    3584             :  * numeric_smaller() -
    3585             :  *
    3586             :  *  Return the smaller of two numbers
    3587             :  */
    3588             : Datum
    3589         798 : numeric_smaller(PG_FUNCTION_ARGS)
    3590             : {
    3591         798 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3592         798 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3593             : 
    3594             :     /*
    3595             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3596             :      * particularly as regards comparisons involving NaN.
    3597             :      */
    3598         798 :     if (cmp_numerics(num1, num2) < 0)
    3599         642 :         PG_RETURN_NUMERIC(num1);
    3600             :     else
    3601         156 :         PG_RETURN_NUMERIC(num2);
    3602             : }
    3603             : 
    3604             : 
    3605             : /*
    3606             :  * numeric_larger() -
    3607             :  *
    3608             :  *  Return the larger of two numbers
    3609             :  */
    3610             : Datum
    3611       18630 : numeric_larger(PG_FUNCTION_ARGS)
    3612             : {
    3613       18630 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3614       18630 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3615             : 
    3616             :     /*
    3617             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3618             :      * particularly as regards comparisons involving NaN.
    3619             :      */
    3620       18630 :     if (cmp_numerics(num1, num2) > 0)
    3621       17868 :         PG_RETURN_NUMERIC(num1);
    3622             :     else
    3623         762 :         PG_RETURN_NUMERIC(num2);
    3624             : }
    3625             : 
    3626             : 
    3627             : /* ----------------------------------------------------------------------
    3628             :  *
    3629             :  * Advanced math functions
    3630             :  *
    3631             :  * ----------------------------------------------------------------------
    3632             :  */
    3633             : 
    3634             : /*
    3635             :  * numeric_gcd() -
    3636             :  *
    3637             :  *  Calculate the greatest common divisor of two numerics
    3638             :  */
    3639             : Datum
    3640         216 : numeric_gcd(PG_FUNCTION_ARGS)
    3641             : {
    3642         216 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3643         216 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3644             :     NumericVar  arg1;
    3645             :     NumericVar  arg2;
    3646             :     NumericVar  result;
    3647             :     Numeric     res;
    3648             : 
    3649             :     /*
    3650             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3651             :      * cases.
    3652             :      */
    3653         216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3654          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3655             : 
    3656             :     /*
    3657             :      * Unpack the arguments
    3658             :      */
    3659         120 :     init_var_from_num(num1, &arg1);
    3660         120 :     init_var_from_num(num2, &arg2);
    3661             : 
    3662         120 :     init_var(&result);
    3663             : 
    3664             :     /*
    3665             :      * Find the GCD and return the result
    3666             :      */
    3667         120 :     gcd_var(&arg1, &arg2, &result);
    3668             : 
    3669         120 :     res = make_result(&result);
    3670             : 
    3671         120 :     free_var(&result);
    3672             : 
    3673         120 :     PG_RETURN_NUMERIC(res);
    3674             : }
    3675             : 
    3676             : 
    3677             : /*
    3678             :  * numeric_lcm() -
    3679             :  *
    3680             :  *  Calculate the least common multiple of two numerics
    3681             :  */
    3682             : Datum
    3683         246 : numeric_lcm(PG_FUNCTION_ARGS)
    3684             : {
    3685         246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3686         246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3687             :     NumericVar  arg1;
    3688             :     NumericVar  arg2;
    3689             :     NumericVar  result;
    3690             :     Numeric     res;
    3691             : 
    3692             :     /*
    3693             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3694             :      * cases.
    3695             :      */
    3696         246 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3697          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3698             : 
    3699             :     /*
    3700             :      * Unpack the arguments
    3701             :      */
    3702         150 :     init_var_from_num(num1, &arg1);
    3703         150 :     init_var_from_num(num2, &arg2);
    3704             : 
    3705         150 :     init_var(&result);
    3706             : 
    3707             :     /*
    3708             :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3709             :      * zero if either input is zero.
    3710             :      *
    3711             :      * Note that the division is guaranteed to be exact, returning an integer
    3712             :      * result, so the LCM is an integral multiple of both x and y.  A display
    3713             :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3714             :      * but as with other numeric functions, we choose to return a result whose
    3715             :      * display scale is no smaller than either input.
    3716             :      */
    3717         150 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3718          48 :         set_var_from_var(&const_zero, &result);
    3719             :     else
    3720             :     {
    3721         102 :         gcd_var(&arg1, &arg2, &result);
    3722         102 :         div_var(&arg1, &result, &result, 0, false, true);
    3723         102 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3724         102 :         result.sign = NUMERIC_POS;
    3725             :     }
    3726             : 
    3727         150 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3728             : 
    3729         150 :     res = make_result(&result);
    3730             : 
    3731         144 :     free_var(&result);
    3732             : 
    3733         144 :     PG_RETURN_NUMERIC(res);
    3734             : }
    3735             : 
    3736             : 
    3737             : /*
    3738             :  * numeric_fac()
    3739             :  *
    3740             :  * Compute factorial
    3741             :  */
    3742             : Datum
    3743          42 : numeric_fac(PG_FUNCTION_ARGS)
    3744             : {
    3745          42 :     int64       num = PG_GETARG_INT64(0);
    3746             :     Numeric     res;
    3747             :     NumericVar  fact;
    3748             :     NumericVar  result;
    3749             : 
    3750          42 :     if (num < 0)
    3751           6 :         ereport(ERROR,
    3752             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3753             :                  errmsg("factorial of a negative number is undefined")));
    3754          36 :     if (num <= 1)
    3755             :     {
    3756           6 :         res = make_result(&const_one);
    3757           6 :         PG_RETURN_NUMERIC(res);
    3758             :     }
    3759             :     /* Fail immediately if the result would overflow */
    3760          30 :     if (num > 32177)
    3761           6 :         ereport(ERROR,
    3762             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3763             :                  errmsg("value overflows numeric format")));
    3764             : 
    3765          24 :     init_var(&fact);
    3766          24 :     init_var(&result);
    3767             : 
    3768          24 :     int64_to_numericvar(num, &result);
    3769             : 
    3770         294 :     for (num = num - 1; num > 1; num--)
    3771             :     {
    3772             :         /* this loop can take awhile, so allow it to be interrupted */
    3773         270 :         CHECK_FOR_INTERRUPTS();
    3774             : 
    3775         270 :         int64_to_numericvar(num, &fact);
    3776             : 
    3777         270 :         mul_var(&result, &fact, &result, 0);
    3778             :     }
    3779             : 
    3780          24 :     res = make_result(&result);
    3781             : 
    3782          24 :     free_var(&fact);
    3783          24 :     free_var(&result);
    3784             : 
    3785          24 :     PG_RETURN_NUMERIC(res);
    3786             : }
    3787             : 
    3788             : 
    3789             : /*
    3790             :  * numeric_sqrt() -
    3791             :  *
    3792             :  *  Compute the square root of a numeric.
    3793             :  */
    3794             : Datum
    3795         150 : numeric_sqrt(PG_FUNCTION_ARGS)
    3796             : {
    3797         150 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3798             :     Numeric     res;
    3799             :     NumericVar  arg;
    3800             :     NumericVar  result;
    3801             :     int         sweight;
    3802             :     int         rscale;
    3803             : 
    3804             :     /*
    3805             :      * Handle NaN and infinities
    3806             :      */
    3807         150 :     if (NUMERIC_IS_SPECIAL(num))
    3808             :     {
    3809             :         /* error should match that in sqrt_var() */
    3810          18 :         if (NUMERIC_IS_NINF(num))
    3811           6 :             ereport(ERROR,
    3812             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3813             :                      errmsg("cannot take square root of a negative number")));
    3814             :         /* For NAN or PINF, just duplicate the input */
    3815          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3816             :     }
    3817             : 
    3818             :     /*
    3819             :      * Unpack the argument and determine the result scale.  We choose a scale
    3820             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3821             :      * case not less than the input's dscale.
    3822             :      */
    3823         132 :     init_var_from_num(num, &arg);
    3824             : 
    3825         132 :     init_var(&result);
    3826             : 
    3827             :     /*
    3828             :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3829             :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3830             :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3831             :      * a few cycles, since the division is exact and there is no need to round
    3832             :      * towards negative infinity.
    3833             :      */
    3834             : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3835         132 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3836             : #else
    3837             :     if (arg.weight >= 0)
    3838             :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3839             :     else
    3840             :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3841             : #endif
    3842             : 
    3843         132 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3844         132 :     rscale = Max(rscale, arg.dscale);
    3845         132 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3846         132 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3847             : 
    3848             :     /*
    3849             :      * Let sqrt_var() do the calculation and return the result.
    3850             :      */
    3851         132 :     sqrt_var(&arg, &result, rscale);
    3852             : 
    3853         126 :     res = make_result(&result);
    3854             : 
    3855         126 :     free_var(&result);
    3856             : 
    3857         126 :     PG_RETURN_NUMERIC(res);
    3858             : }
    3859             : 
    3860             : 
    3861             : /*
    3862             :  * numeric_exp() -
    3863             :  *
    3864             :  *  Raise e to the power of x
    3865             :  */
    3866             : Datum
    3867          78 : numeric_exp(PG_FUNCTION_ARGS)
    3868             : {
    3869          78 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3870             :     Numeric     res;
    3871             :     NumericVar  arg;
    3872             :     NumericVar  result;
    3873             :     int         rscale;
    3874             :     double      val;
    3875             : 
    3876             :     /*
    3877             :      * Handle NaN and infinities
    3878             :      */
    3879          78 :     if (NUMERIC_IS_SPECIAL(num))
    3880             :     {
    3881             :         /* Per POSIX, exp(-Inf) is zero */
    3882          18 :         if (NUMERIC_IS_NINF(num))
    3883           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3884             :         /* For NAN or PINF, just duplicate the input */
    3885          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3886             :     }
    3887             : 
    3888             :     /*
    3889             :      * Unpack the argument and determine the result scale.  We choose a scale
    3890             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3891             :      * case not less than the input's dscale.
    3892             :      */
    3893          60 :     init_var_from_num(num, &arg);
    3894             : 
    3895          60 :     init_var(&result);
    3896             : 
    3897             :     /* convert input to float8, ignoring overflow */
    3898          60 :     val = numericvar_to_double_no_overflow(&arg);
    3899             : 
    3900             :     /*
    3901             :      * log10(result) = num * log10(e), so this is approximately the decimal
    3902             :      * weight of the result:
    3903             :      */
    3904          60 :     val *= 0.434294481903252;
    3905             : 
    3906             :     /* limit to something that won't cause integer overflow */
    3907          60 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3908          60 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3909             : 
    3910          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3911          60 :     rscale = Max(rscale, arg.dscale);
    3912          60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3913          60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3914             : 
    3915             :     /*
    3916             :      * Let exp_var() do the calculation and return the result.
    3917             :      */
    3918          60 :     exp_var(&arg, &result, rscale);
    3919             : 
    3920          60 :     res = make_result(&result);
    3921             : 
    3922          60 :     free_var(&result);
    3923             : 
    3924          60 :     PG_RETURN_NUMERIC(res);
    3925             : }
    3926             : 
    3927             : 
    3928             : /*
    3929             :  * numeric_ln() -
    3930             :  *
    3931             :  *  Compute the natural logarithm of x
    3932             :  */
    3933             : Datum
    3934         198 : numeric_ln(PG_FUNCTION_ARGS)
    3935             : {
    3936         198 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3937             :     Numeric     res;
    3938             :     NumericVar  arg;
    3939             :     NumericVar  result;
    3940             :     int         ln_dweight;
    3941             :     int         rscale;
    3942             : 
    3943             :     /*
    3944             :      * Handle NaN and infinities
    3945             :      */
    3946         198 :     if (NUMERIC_IS_SPECIAL(num))
    3947             :     {
    3948          18 :         if (NUMERIC_IS_NINF(num))
    3949           6 :             ereport(ERROR,
    3950             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3951             :                      errmsg("cannot take logarithm of a negative number")));
    3952             :         /* For NAN or PINF, just duplicate the input */
    3953          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3954             :     }
    3955             : 
    3956         180 :     init_var_from_num(num, &arg);
    3957         180 :     init_var(&result);
    3958             : 
    3959             :     /* Estimated dweight of logarithm */
    3960         180 :     ln_dweight = estimate_ln_dweight(&arg);
    3961             : 
    3962         180 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3963         180 :     rscale = Max(rscale, arg.dscale);
    3964         180 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3965         180 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3966             : 
    3967         180 :     ln_var(&arg, &result, rscale);
    3968             : 
    3969         156 :     res = make_result(&result);
    3970             : 
    3971         156 :     free_var(&result);
    3972             : 
    3973         156 :     PG_RETURN_NUMERIC(res);
    3974             : }
    3975             : 
    3976             : 
    3977             : /*
    3978             :  * numeric_log() -
    3979             :  *
    3980             :  *  Compute the logarithm of x in a given base
    3981             :  */
    3982             : Datum
    3983         342 : numeric_log(PG_FUNCTION_ARGS)
    3984             : {
    3985         342 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3986         342 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3987             :     Numeric     res;
    3988             :     NumericVar  arg1;
    3989             :     NumericVar  arg2;
    3990             :     NumericVar  result;
    3991             : 
    3992             :     /*
    3993             :      * Handle NaN and infinities
    3994             :      */
    3995         342 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3996             :     {
    3997             :         int         sign1,
    3998             :                     sign2;
    3999             : 
    4000         126 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    4001          54 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    4002             :         /* fail on negative inputs including -Inf, as log_var would */
    4003          72 :         sign1 = numeric_sign_internal(num1);
    4004          72 :         sign2 = numeric_sign_internal(num2);
    4005          72 :         if (sign1 < 0 || sign2 < 0)
    4006          24 :             ereport(ERROR,
    4007             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    4008             :                      errmsg("cannot take logarithm of a negative number")));
    4009             :         /* fail on zero inputs, as log_var would */
    4010          48 :         if (sign1 == 0 || sign2 == 0)
    4011           6 :             ereport(ERROR,
    4012             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    4013             :                      errmsg("cannot take logarithm of zero")));
    4014          42 :         if (NUMERIC_IS_PINF(num1))
    4015             :         {
    4016             :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    4017          18 :             if (NUMERIC_IS_PINF(num2))
    4018           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    4019             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    4020          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4021             :         }
    4022             :         Assert(NUMERIC_IS_PINF(num2));
    4023             :         /* log(finite-positive, Inf) is Inf */
    4024          24 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    4025             :     }
    4026             : 
    4027             :     /*
    4028             :      * Initialize things
    4029             :      */
    4030         216 :     init_var_from_num(num1, &arg1);
    4031         216 :     init_var_from_num(num2, &arg2);
    4032         216 :     init_var(&result);
    4033             : 
    4034             :     /*
    4035             :      * Call log_var() to compute and return the result; note it handles scale
    4036             :      * selection itself.
    4037             :      */
    4038         216 :     log_var(&arg1, &arg2, &result);
    4039             : 
    4040         156 :     res = make_result(&result);
    4041             : 
    4042         156 :     free_var(&result);
    4043             : 
    4044         156 :     PG_RETURN_NUMERIC(res);
    4045             : }
    4046             : 
    4047             : 
    4048             : /*
    4049             :  * numeric_power() -
    4050             :  *
    4051             :  *  Raise x to the power of y
    4052             :  */
    4053             : Datum
    4054        1644 : numeric_power(PG_FUNCTION_ARGS)
    4055             : {
    4056        1644 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    4057        1644 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    4058             :     Numeric     res;
    4059             :     NumericVar  arg1;
    4060             :     NumericVar  arg2;
    4061             :     NumericVar  result;
    4062             :     int         sign1,
    4063             :                 sign2;
    4064             : 
    4065             :     /*
    4066             :      * Handle NaN and infinities
    4067             :      */
    4068        1644 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    4069             :     {
    4070             :         /*
    4071             :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    4072             :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    4073             :          * (with no error).
    4074             :          */
    4075         234 :         if (NUMERIC_IS_NAN(num1))
    4076             :         {
    4077          54 :             if (!NUMERIC_IS_SPECIAL(num2))
    4078             :             {
    4079          36 :                 init_var_from_num(num2, &arg2);
    4080          36 :                 if (cmp_var(&arg2, &const_zero) == 0)
    4081          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4082             :             }
    4083          42 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    4084             :         }
    4085         180 :         if (NUMERIC_IS_NAN(num2))
    4086             :         {
    4087          42 :             if (!NUMERIC_IS_SPECIAL(num1))
    4088             :             {
    4089          36 :                 init_var_from_num(num1, &arg1);
    4090          36 :                 if (cmp_var(&arg1, &const_one) == 0)
    4091          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4092             :             }
    4093          30 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    4094             :         }
    4095             :         /* At least one input is infinite, but error rules still apply */
    4096         138 :         sign1 = numeric_sign_internal(num1);
    4097         138 :         sign2 = numeric_sign_internal(num2);
    4098         138 :         if (sign1 == 0 && sign2 < 0)
    4099           6 :             ereport(ERROR,
    4100             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4101             :                      errmsg("zero raised to a negative power is undefined")));
    4102         132 :         if (sign1 < 0 && !numeric_is_integral(num2))
    4103           6 :             ereport(ERROR,
    4104             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4105             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    4106             : 
    4107             :         /*
    4108             :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    4109             :          *
    4110             :          * For any value of y, if x is +1, 1.0 shall be returned.
    4111             :          */
    4112         126 :         if (!NUMERIC_IS_SPECIAL(num1))
    4113             :         {
    4114          42 :             init_var_from_num(num1, &arg1);
    4115          42 :             if (cmp_var(&arg1, &const_one) == 0)
    4116           6 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    4117             :         }
    4118             : 
    4119             :         /*
    4120             :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    4121             :          */
    4122         120 :         if (sign2 == 0)
    4123          12 :             PG_RETURN_NUMERIC(make_result(&const_one));
    4124             : 
    4125             :         /*
    4126             :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    4127             :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    4128             :          * be returned.  (Since we don't deal in minus zero, we need not
    4129             :          * distinguish these two cases.)
    4130             :          */
    4131         108 :         if (sign1 == 0 && sign2 > 0)
    4132           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4133             : 
    4134             :         /*
    4135             :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    4136             :          *
    4137             :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4138             :          *
    4139             :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4140             :          *
    4141             :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4142             :          *
    4143             :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4144             :          */
    4145         102 :         if (NUMERIC_IS_INF(num2))
    4146             :         {
    4147             :             bool        abs_x_gt_one;
    4148             : 
    4149          54 :             if (NUMERIC_IS_SPECIAL(num1))
    4150          24 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4151             :             else
    4152             :             {
    4153          30 :                 init_var_from_num(num1, &arg1);
    4154          30 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4155           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4156          24 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4157          24 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4158             :             }
    4159          48 :             if (abs_x_gt_one == (sign2 > 0))
    4160          30 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4161             :             else
    4162          18 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4163             :         }
    4164             : 
    4165             :         /*
    4166             :          * For y < 0, if x is +Inf, +0 shall be returned.
    4167             :          *
    4168             :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4169             :          */
    4170          48 :         if (NUMERIC_IS_PINF(num1))
    4171             :         {
    4172          24 :             if (sign2 > 0)
    4173          18 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4174             :             else
    4175           6 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4176             :         }
    4177             : 
    4178             :         Assert(NUMERIC_IS_NINF(num1));
    4179             : 
    4180             :         /*
    4181             :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4182             :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4183             :          * (Again, we need not distinguish these two cases.)
    4184             :          */
    4185          24 :         if (sign2 < 0)
    4186          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4187             : 
    4188             :         /*
    4189             :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4190             :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4191             :          */
    4192          12 :         init_var_from_num(num2, &arg2);
    4193          12 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4194          12 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4195           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4196             :         else
    4197           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4198             :     }
    4199             : 
    4200             :     /*
    4201             :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4202             :      * certain error conditions.  Specifically, we don't return a
    4203             :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4204             :      * non-integer power must produce the same error code, but that case is
    4205             :      * handled in power_var().
    4206             :      */
    4207        1410 :     sign1 = numeric_sign_internal(num1);
    4208        1410 :     sign2 = numeric_sign_internal(num2);
    4209             : 
    4210        1410 :     if (sign1 == 0 && sign2 < 0)
    4211          12 :         ereport(ERROR,
    4212             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4213             :                  errmsg("zero raised to a negative power is undefined")));
    4214             : 
    4215             :     /*
    4216             :      * Initialize things
    4217             :      */
    4218        1398 :     init_var(&result);
    4219        1398 :     init_var_from_num(num1, &arg1);
    4220        1398 :     init_var_from_num(num2, &arg2);
    4221             : 
    4222             :     /*
    4223             :      * Call power_var() to compute and return the result; note it handles
    4224             :      * scale selection itself.
    4225             :      */
    4226        1398 :     power_var(&arg1, &arg2, &result);
    4227             : 
    4228        1368 :     res = make_result(&result);
    4229             : 
    4230        1368 :     free_var(&result);
    4231             : 
    4232        1368 :     PG_RETURN_NUMERIC(res);
    4233             : }
    4234             : 
    4235             : /*
    4236             :  * numeric_scale() -
    4237             :  *
    4238             :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4239             :  */
    4240             : Datum
    4241         108 : numeric_scale(PG_FUNCTION_ARGS)
    4242             : {
    4243         108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4244             : 
    4245         108 :     if (NUMERIC_IS_SPECIAL(num))
    4246          18 :         PG_RETURN_NULL();
    4247             : 
    4248          90 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4249             : }
    4250             : 
    4251             : /*
    4252             :  * Calculate minimum scale for value.
    4253             :  */
    4254             : static int
    4255         372 : get_min_scale(NumericVar *var)
    4256             : {
    4257             :     int         min_scale;
    4258             :     int         last_digit_pos;
    4259             : 
    4260             :     /*
    4261             :      * Ordinarily, the input value will be "stripped" so that the last
    4262             :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4263             :      * loop if it isn't, so explicitly find the last nonzero digit.
    4264             :      */
    4265         372 :     last_digit_pos = var->ndigits - 1;
    4266         372 :     while (last_digit_pos >= 0 &&
    4267         342 :            var->digits[last_digit_pos] == 0)
    4268           0 :         last_digit_pos--;
    4269             : 
    4270         372 :     if (last_digit_pos >= 0)
    4271             :     {
    4272             :         /* compute min_scale assuming that last ndigit has no zeroes */
    4273         342 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4274             : 
    4275             :         /*
    4276             :          * We could get a negative result if there are no digits after the
    4277             :          * decimal point.  In this case the min_scale must be zero.
    4278             :          */
    4279         342 :         if (min_scale > 0)
    4280             :         {
    4281             :             /*
    4282             :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4283             :              * zero.
    4284             :              */
    4285         186 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4286             : 
    4287         498 :             while (last_digit % 10 == 0)
    4288             :             {
    4289         312 :                 min_scale--;
    4290         312 :                 last_digit /= 10;
    4291             :             }
    4292             :         }
    4293             :         else
    4294         156 :             min_scale = 0;
    4295             :     }
    4296             :     else
    4297          30 :         min_scale = 0;          /* result if input is zero */
    4298             : 
    4299         372 :     return min_scale;
    4300             : }
    4301             : 
    4302             : /*
    4303             :  * Returns minimum scale required to represent supplied value without loss.
    4304             :  */
    4305             : Datum
    4306          72 : numeric_min_scale(PG_FUNCTION_ARGS)
    4307             : {
    4308          72 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4309             :     NumericVar  arg;
    4310             :     int         min_scale;
    4311             : 
    4312          72 :     if (NUMERIC_IS_SPECIAL(num))
    4313          12 :         PG_RETURN_NULL();
    4314             : 
    4315          60 :     init_var_from_num(num, &arg);
    4316          60 :     min_scale = get_min_scale(&arg);
    4317          60 :     free_var(&arg);
    4318             : 
    4319          60 :     PG_RETURN_INT32(min_scale);
    4320             : }
    4321             : 
    4322             : /*
    4323             :  * Reduce scale of numeric value to represent supplied value without loss.
    4324             :  */
    4325             : Datum
    4326         324 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4327             : {
    4328         324 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4329             :     Numeric     res;
    4330             :     NumericVar  result;
    4331             : 
    4332         324 :     if (NUMERIC_IS_SPECIAL(num))
    4333          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4334             : 
    4335         312 :     init_var_from_num(num, &result);
    4336         312 :     result.dscale = get_min_scale(&result);
    4337         312 :     res = make_result(&result);
    4338         312 :     free_var(&result);
    4339             : 
    4340         312 :     PG_RETURN_NUMERIC(res);
    4341             : }
    4342             : 
    4343             : /*
    4344             :  * Return a random numeric value in the range [rmin, rmax].
    4345             :  */
    4346             : Numeric
    4347       33462 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
    4348             : {
    4349             :     NumericVar  rmin_var;
    4350             :     NumericVar  rmax_var;
    4351             :     NumericVar  result;
    4352             :     Numeric     res;
    4353             : 
    4354             :     /* Range bounds must not be NaN/infinity */
    4355       33462 :     if (NUMERIC_IS_SPECIAL(rmin))
    4356             :     {
    4357          12 :         if (NUMERIC_IS_NAN(rmin))
    4358           6 :             ereport(ERROR,
    4359             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4360             :                     errmsg("lower bound cannot be NaN"));
    4361             :         else
    4362           6 :             ereport(ERROR,
    4363             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4364             :                     errmsg("lower bound cannot be infinity"));
    4365             :     }
    4366       33450 :     if (NUMERIC_IS_SPECIAL(rmax))
    4367             :     {
    4368          12 :         if (NUMERIC_IS_NAN(rmax))
    4369           6 :             ereport(ERROR,
    4370             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4371             :                     errmsg("upper bound cannot be NaN"));
    4372             :         else
    4373           6 :             ereport(ERROR,
    4374             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4375             :                     errmsg("upper bound cannot be infinity"));
    4376             :     }
    4377             : 
    4378             :     /* Return a random value in the range [rmin, rmax] */
    4379       33438 :     init_var_from_num(rmin, &rmin_var);
    4380       33438 :     init_var_from_num(rmax, &rmax_var);
    4381             : 
    4382       33438 :     init_var(&result);
    4383             : 
    4384       33438 :     random_var(state, &rmin_var, &rmax_var, &result);
    4385             : 
    4386       33432 :     res = make_result(&result);
    4387             : 
    4388       33432 :     free_var(&result);
    4389             : 
    4390       33432 :     return res;
    4391             : }
    4392             : 
    4393             : 
    4394             : /* ----------------------------------------------------------------------
    4395             :  *
    4396             :  * Type conversion functions
    4397             :  *
    4398             :  * ----------------------------------------------------------------------
    4399             :  */
    4400             : 
    4401             : Numeric
    4402     1868360 : int64_to_numeric(int64 val)
    4403             : {
    4404             :     Numeric     res;
    4405             :     NumericVar  result;
    4406             : 
    4407     1868360 :     init_var(&result);
    4408             : 
    4409     1868360 :     int64_to_numericvar(val, &result);
    4410             : 
    4411     1868360 :     res = make_result(&result);
    4412             : 
    4413     1868360 :     free_var(&result);
    4414             : 
    4415     1868360 :     return res;
    4416             : }
    4417             : 
    4418             : /*
    4419             :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4420             :  * numeric division.
    4421             :  */
    4422             : Numeric
    4423       29384 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4424             : {
    4425             :     Numeric     res;
    4426             :     NumericVar  result;
    4427             :     int         rscale;
    4428             :     int         w;
    4429             :     int         m;
    4430             : 
    4431       29384 :     init_var(&result);
    4432             : 
    4433             :     /* result scale */
    4434       29384 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4435             : 
    4436             :     /* how much to decrease the weight by */
    4437       29384 :     w = log10val2 / DEC_DIGITS;
    4438             :     /* how much is left to divide by */
    4439       29384 :     m = log10val2 % DEC_DIGITS;
    4440       29384 :     if (m < 0)
    4441             :     {
    4442           0 :         m += DEC_DIGITS;
    4443           0 :         w--;
    4444             :     }
    4445             : 
    4446             :     /*
    4447             :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4448             :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4449             :      * one more.
    4450             :      */
    4451       29384 :     if (m > 0)
    4452             :     {
    4453             : #if DEC_DIGITS == 4
    4454             :         static const int pow10[] = {1, 10, 100, 1000};
    4455             : #elif DEC_DIGITS == 2
    4456             :         static const int pow10[] = {1, 10};
    4457             : #elif DEC_DIGITS == 1
    4458             :         static const int pow10[] = {1};
    4459             : #else
    4460             : #error unsupported NBASE
    4461             : #endif
    4462       29384 :         int64       factor = pow10[DEC_DIGITS - m];
    4463             :         int64       new_val1;
    4464             : 
    4465             :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4466             : 
    4467       29384 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4468             :         {
    4469             : #ifdef HAVE_INT128
    4470             :             /* do the multiplication using 128-bit integers */
    4471             :             int128      tmp;
    4472             : 
    4473          12 :             tmp = (int128) val1 * (int128) factor;
    4474             : 
    4475          12 :             int128_to_numericvar(tmp, &result);
    4476             : #else
    4477             :             /* do the multiplication using numerics */
    4478             :             NumericVar  tmp;
    4479             : 
    4480             :             init_var(&tmp);
    4481             : 
    4482             :             int64_to_numericvar(val1, &result);
    4483             :             int64_to_numericvar(factor, &tmp);
    4484             :             mul_var(&result, &tmp, &result, 0);
    4485             : 
    4486             :             free_var(&tmp);
    4487             : #endif
    4488             :         }
    4489             :         else
    4490       29372 :             int64_to_numericvar(new_val1, &result);
    4491             : 
    4492       29384 :         w++;
    4493             :     }
    4494             :     else
    4495           0 :         int64_to_numericvar(val1, &result);
    4496             : 
    4497       29384 :     result.weight -= w;
    4498       29384 :     result.dscale = rscale;
    4499             : 
    4500       29384 :     res = make_result(&result);
    4501             : 
    4502       29384 :     free_var(&result);
    4503             : 
    4504       29384 :     return res;
    4505             : }
    4506             : 
    4507             : Datum
    4508     1555012 : int4_numeric(PG_FUNCTION_ARGS)
    4509             : {
    4510     1555012 :     int32       val = PG_GETARG_INT32(0);
    4511             : 
    4512     1555012 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4513             : }
    4514             : 
    4515             : int32
    4516        7770 : numeric_int4_opt_error(Numeric num, bool *have_error)
    4517             : {
    4518             :     NumericVar  x;
    4519             :     int32       result;
    4520             : 
    4521        7770 :     if (have_error)
    4522        1584 :         *have_error = false;
    4523             : 
    4524        7770 :     if (NUMERIC_IS_SPECIAL(num))
    4525             :     {
    4526          18 :         if (have_error)
    4527             :         {
    4528           0 :             *have_error = true;
    4529           0 :             return 0;
    4530             :         }
    4531             :         else
    4532             :         {
    4533          18 :             if (NUMERIC_IS_NAN(num))
    4534           6 :                 ereport(ERROR,
    4535             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4536             :                          errmsg("cannot convert NaN to %s", "integer")));
    4537             :             else
    4538          12 :                 ereport(ERROR,
    4539             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4540             :                          errmsg("cannot convert infinity to %s", "integer")));
    4541             :         }
    4542             :     }
    4543             : 
    4544             :     /* Convert to variable format, then convert to int4 */
    4545        7752 :     init_var_from_num(num, &x);
    4546             : 
    4547        7752 :     if (!numericvar_to_int32(&x, &result))
    4548             :     {
    4549          90 :         if (have_error)
    4550             :         {
    4551          78 :             *have_error = true;
    4552          78 :             return 0;
    4553             :         }
    4554             :         else
    4555             :         {
    4556          12 :             ereport(ERROR,
    4557             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4558             :                      errmsg("integer out of range")));
    4559             :         }
    4560             :     }
    4561             : 
    4562        7662 :     return result;
    4563             : }
    4564             : 
    4565             : Datum
    4566        6186 : numeric_int4(PG_FUNCTION_ARGS)
    4567             : {
    4568        6186 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4569             : 
    4570        6186 :     PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
    4571             : }
    4572             : 
    4573             : /*
    4574             :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4575             :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4576             :  * The input NumericVar is *not* free'd.
    4577             :  */
    4578             : static bool
    4579        8490 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4580             : {
    4581             :     int64       val;
    4582             : 
    4583        8490 :     if (!numericvar_to_int64(var, &val))
    4584           6 :         return false;
    4585             : 
    4586        8484 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4587          84 :         return false;
    4588             : 
    4589             :     /* Down-convert to int4 */
    4590        8400 :     *result = (int32) val;
    4591             : 
    4592        8400 :     return true;
    4593             : }
    4594             : 
    4595             : Datum
    4596       36850 : int8_numeric(PG_FUNCTION_ARGS)
    4597             : {
    4598       36850 :     int64       val = PG_GETARG_INT64(0);
    4599             : 
    4600       36850 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4601             : }
    4602             : 
    4603             : int64
    4604         570 : numeric_int8_opt_error(Numeric num, bool *have_error)
    4605             : {
    4606             :     NumericVar  x;
    4607             :     int64       result;
    4608             : 
    4609         570 :     if (have_error)
    4610          48 :         *have_error = false;
    4611             : 
    4612         570 :     if (NUMERIC_IS_SPECIAL(num))
    4613             :     {
    4614          18 :         if (have_error)
    4615             :         {
    4616           0 :             *have_error = true;
    4617           0 :             return 0;
    4618             :         }
    4619             :         else
    4620             :         {
    4621          18 :             if (NUMERIC_IS_NAN(num))
    4622           6 :                 ereport(ERROR,
    4623             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4624             :                          errmsg("cannot convert NaN to %s", "bigint")));
    4625             :             else
    4626          12 :                 ereport(ERROR,
    4627             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4628             :                          errmsg("cannot convert infinity to %s", "bigint")));
    4629             :         }
    4630             :     }
    4631             : 
    4632             :     /* Convert to variable format, then convert to int8 */
    4633         552 :     init_var_from_num(num, &x);
    4634             : 
    4635         552 :     if (!numericvar_to_int64(&x, &result))
    4636             :     {
    4637          60 :         if (have_error)
    4638             :         {
    4639          12 :             *have_error = true;
    4640          12 :             return 0;
    4641             :         }
    4642             :         else
    4643             :         {
    4644          48 :             ereport(ERROR,
    4645             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4646             :                      errmsg("bigint out of range")));
    4647             :         }
    4648             :     }
    4649             : 
    4650         492 :     return result;
    4651             : }
    4652             : 
    4653             : Datum
    4654         522 : numeric_int8(PG_FUNCTION_ARGS)
    4655             : {
    4656         522 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4657             : 
    4658         522 :     PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
    4659             : }
    4660             : 
    4661             : 
    4662             : Datum
    4663           6 : int2_numeric(PG_FUNCTION_ARGS)
    4664             : {
    4665           6 :     int16       val = PG_GETARG_INT16(0);
    4666             : 
    4667           6 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4668             : }
    4669             : 
    4670             : 
    4671             : Datum
    4672         102 : numeric_int2(PG_FUNCTION_ARGS)
    4673             : {
    4674         102 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4675             :     NumericVar  x;
    4676             :     int64       val;
    4677             :     int16       result;
    4678             : 
    4679         102 :     if (NUMERIC_IS_SPECIAL(num))
    4680             :     {
    4681          18 :         if (NUMERIC_IS_NAN(num))
    4682           6 :             ereport(ERROR,
    4683             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4684             :                      errmsg("cannot convert NaN to %s", "smallint")));
    4685             :         else
    4686          12 :             ereport(ERROR,
    4687             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4688             :                      errmsg("cannot convert infinity to %s", "smallint")));
    4689             :     }
    4690             : 
    4691             :     /* Convert to variable format and thence to int8 */
    4692          84 :     init_var_from_num(num, &x);
    4693             : 
    4694          84 :     if (!numericvar_to_int64(&x, &val))
    4695           0 :         ereport(ERROR,
    4696             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4697             :                  errmsg("smallint out of range")));
    4698             : 
    4699          84 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4700          12 :         ereport(ERROR,
    4701             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4702             :                  errmsg("smallint out of range")));
    4703             : 
    4704             :     /* Down-convert to int2 */
    4705          72 :     result = (int16) val;
    4706             : 
    4707          72 :     PG_RETURN_INT16(result);
    4708             : }
    4709             : 
    4710             : 
    4711             : Datum
    4712        1074 : float8_numeric(PG_FUNCTION_ARGS)
    4713             : {
    4714        1074 :     float8      val = PG_GETARG_FLOAT8(0);
    4715             :     Numeric     res;
    4716             :     NumericVar  result;
    4717             :     char        buf[DBL_DIG + 100];
    4718             :     const char *endptr;
    4719             : 
    4720        1074 :     if (isnan(val))
    4721           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4722             : 
    4723        1068 :     if (isinf(val))
    4724             :     {
    4725          12 :         if (val < 0)
    4726           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4727             :         else
    4728           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4729             :     }
    4730             : 
    4731        1056 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4732             : 
    4733        1056 :     init_var(&result);
    4734             : 
    4735             :     /* Assume we need not worry about leading/trailing spaces */
    4736        1056 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4737             : 
    4738        1056 :     res = make_result(&result);
    4739             : 
    4740        1056 :     free_var(&result);
    4741             : 
    4742        1056 :     PG_RETURN_NUMERIC(res);
    4743             : }
    4744             : 
    4745             : 
    4746             : Datum
    4747      520072 : numeric_float8(PG_FUNCTION_ARGS)
    4748             : {
    4749      520072 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4750             :     char       *tmp;
    4751             :     Datum       result;
    4752             : 
    4753      520072 :     if (NUMERIC_IS_SPECIAL(num))
    4754             :     {
    4755          78 :         if (NUMERIC_IS_PINF(num))
    4756          24 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4757          54 :         else if (NUMERIC_IS_NINF(num))
    4758          24 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4759             :         else
    4760          30 :             PG_RETURN_FLOAT8(get_float8_nan());
    4761             :     }
    4762             : 
    4763      519994 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4764             :                                               NumericGetDatum(num)));
    4765             : 
    4766      519994 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
    4767             : 
    4768      519994 :     pfree(tmp);
    4769             : 
    4770      519994 :     PG_RETURN_DATUM(result);
    4771             : }
    4772             : 
    4773             : 
    4774             : /*
    4775             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4776             :  *
    4777             :  * (internal helper function, not directly callable from SQL)
    4778             :  */
    4779             : Datum
    4780          30 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4781             : {
    4782          30 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4783             :     double      val;
    4784             : 
    4785          30 :     if (NUMERIC_IS_SPECIAL(num))
    4786             :     {
    4787           0 :         if (NUMERIC_IS_PINF(num))
    4788           0 :             val = HUGE_VAL;
    4789           0 :         else if (NUMERIC_IS_NINF(num))
    4790           0 :             val = -HUGE_VAL;
    4791             :         else
    4792           0 :             val = get_float8_nan();
    4793             :     }
    4794             :     else
    4795             :     {
    4796             :         NumericVar  x;
    4797             : 
    4798          30 :         init_var_from_num(num, &x);
    4799          30 :         val = numericvar_to_double_no_overflow(&x);
    4800             :     }
    4801             : 
    4802          30 :     PG_RETURN_FLOAT8(val);
    4803             : }
    4804             : 
    4805             : Datum
    4806       22328 : float4_numeric(PG_FUNCTION_ARGS)
    4807             : {
    4808       22328 :     float4      val = PG_GETARG_FLOAT4(0);
    4809             :     Numeric     res;
    4810             :     NumericVar  result;
    4811             :     char        buf[FLT_DIG + 100];
    4812             :     const char *endptr;
    4813             : 
    4814       22328 :     if (isnan(val))
    4815           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4816             : 
    4817       22322 :     if (isinf(val))
    4818             :     {
    4819          12 :         if (val < 0)
    4820           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4821             :         else
    4822           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4823             :     }
    4824             : 
    4825       22310 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4826             : 
    4827       22310 :     init_var(&result);
    4828             : 
    4829             :     /* Assume we need not worry about leading/trailing spaces */
    4830       22310 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4831             : 
    4832       22310 :     res = make_result(&result);
    4833             : 
    4834       22310 :     free_var(&result);
    4835             : 
    4836       22310 :     PG_RETURN_NUMERIC(res);
    4837             : }
    4838             : 
    4839             : 
    4840             : Datum
    4841        2456 : numeric_float4(PG_FUNCTION_ARGS)
    4842             : {
    4843        2456 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4844             :     char       *tmp;
    4845             :     Datum       result;
    4846             : 
    4847        2456 :     if (NUMERIC_IS_SPECIAL(num))
    4848             :     {
    4849          78 :         if (NUMERIC_IS_PINF(num))
    4850          24 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4851          54 :         else if (NUMERIC_IS_NINF(num))
    4852          24 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4853             :         else
    4854          30 :             PG_RETURN_FLOAT4(get_float4_nan());
    4855             :     }
    4856             : 
    4857        2378 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4858             :                                               NumericGetDatum(num)));
    4859             : 
    4860        2378 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
    4861             : 
    4862        2378 :     pfree(tmp);
    4863             : 
    4864        2378 :     PG_RETURN_DATUM(result);
    4865             : }
    4866             : 
    4867             : 
    4868             : Datum
    4869         120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4870             : {
    4871         120 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4872             :     NumericVar  x;
    4873             :     XLogRecPtr  result;
    4874             : 
    4875         120 :     if (NUMERIC_IS_SPECIAL(num))
    4876             :     {
    4877           6 :         if (NUMERIC_IS_NAN(num))
    4878           6 :             ereport(ERROR,
    4879             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4880             :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4881             :         else
    4882           0 :             ereport(ERROR,
    4883             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4884             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4885             :     }
    4886             : 
    4887             :     /* Convert to variable format and thence to pg_lsn */
    4888         114 :     init_var_from_num(num, &x);
    4889             : 
    4890         114 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4891          24 :         ereport(ERROR,
    4892             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4893             :                  errmsg("pg_lsn out of range")));
    4894             : 
    4895          90 :     PG_RETURN_LSN(result);
    4896             : }
    4897             : 
    4898             : 
    4899             : /* ----------------------------------------------------------------------
    4900             :  *
    4901             :  * Aggregate functions
    4902             :  *
    4903             :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4904             :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4905             :  * context.  The digit buffers for the NumericVars will be there too.
    4906             :  *
    4907             :  * On platforms which support 128-bit integers some aggregates instead use a
    4908             :  * 128-bit integer based transition datatype to speed up calculations.
    4909             :  *
    4910             :  * ----------------------------------------------------------------------
    4911             :  */
    4912             : 
    4913             : typedef struct NumericAggState
    4914             : {
    4915             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4916             :     MemoryContext agg_context;  /* context we're calculating in */
    4917             :     int64       N;              /* count of processed numbers */
    4918             :     NumericSumAccum sumX;       /* sum of processed numbers */
    4919             :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4920             :     int         maxScale;       /* maximum scale seen so far */
    4921             :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4922             :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4923             :     int64       NaNcount;       /* count of NaN values */
    4924             :     int64       pInfcount;      /* count of +Inf values */
    4925             :     int64       nInfcount;      /* count of -Inf values */
    4926             : } NumericAggState;
    4927             : 
    4928             : #define NA_TOTAL_COUNT(na) \
    4929             :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4930             : 
    4931             : /*
    4932             :  * Prepare state data for a numeric aggregate function that needs to compute
    4933             :  * sum, count and optionally sum of squares of the input.
    4934             :  */
    4935             : static NumericAggState *
    4936      171160 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4937             : {
    4938             :     NumericAggState *state;
    4939             :     MemoryContext agg_context;
    4940             :     MemoryContext old_context;
    4941             : 
    4942      171160 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4943           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4944             : 
    4945      171160 :     old_context = MemoryContextSwitchTo(agg_context);
    4946             : 
    4947      171160 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4948      171160 :     state->calcSumX2 = calcSumX2;
    4949      171160 :     state->agg_context = agg_context;
    4950             : 
    4951      171160 :     MemoryContextSwitchTo(old_context);
    4952             : 
    4953      171160 :     return state;
    4954             : }
    4955             : 
    4956             : /*
    4957             :  * Like makeNumericAggState(), but allocate the state in the current memory
    4958             :  * context.
    4959             :  */
    4960             : static NumericAggState *
    4961          80 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4962             : {
    4963             :     NumericAggState *state;
    4964             : 
    4965          80 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4966          80 :     state->calcSumX2 = calcSumX2;
    4967          80 :     state->agg_context = CurrentMemoryContext;
    4968             : 
    4969          80 :     return state;
    4970             : }
    4971             : 
    4972             : /*
    4973             :  * Accumulate a new input value for numeric aggregate functions.
    4974             :  */
    4975             : static void
    4976     2113606 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4977             : {
    4978             :     NumericVar  X;
    4979             :     NumericVar  X2;
    4980             :     MemoryContext old_context;
    4981             : 
    4982             :     /* Count NaN/infinity inputs separately from all else */
    4983     2113606 :     if (NUMERIC_IS_SPECIAL(newval))
    4984             :     {
    4985         162 :         if (NUMERIC_IS_PINF(newval))
    4986          72 :             state->pInfcount++;
    4987          90 :         else if (NUMERIC_IS_NINF(newval))
    4988          36 :             state->nInfcount++;
    4989             :         else
    4990          54 :             state->NaNcount++;
    4991         162 :         return;
    4992             :     }
    4993             : 
    4994             :     /* load processed number in short-lived context */
    4995     2113444 :     init_var_from_num(newval, &X);
    4996             : 
    4997             :     /*
    4998             :      * Track the highest input dscale that we've seen, to support inverse
    4999             :      * transitions (see do_numeric_discard).
    5000             :      */
    5001     2113444 :     if (X.dscale > state->maxScale)
    5002             :     {
    5003         156 :         state->maxScale = X.dscale;
    5004         156 :         state->maxScaleCount = 1;
    5005             :     }
    5006     2113288 :     else if (X.dscale == state->maxScale)
    5007     2113252 :         state->maxScaleCount++;
    5008             : 
    5009             :     /* if we need X^2, calculate that in short-lived context */
    5010     2113444 :     if (state->calcSumX2)
    5011             :     {
    5012      240732 :         init_var(&X2);
    5013      240732 :         mul_var(&X, &X, &X2, X.dscale * 2);
    5014             :     }
    5015             : 
    5016             :     /* The rest of this needs to work in the aggregate context */
    5017     2113444 :     old_context = MemoryContextSwitchTo(state->agg_context);
    5018             : 
    5019     2113444 :     state->N++;
    5020             : 
    5021             :     /* Accumulate sums */
    5022     2113444 :     accum_sum_add(&(state->sumX), &X);
    5023             : 
    5024     2113444 :     if (state->calcSumX2)
    5025      240732 :         accum_sum_add(&(state->sumX2), &X2);
    5026             : 
    5027     2113444 :     MemoryContextSwitchTo(old_context);
    5028             : }
    5029             : 
    5030             : /*
    5031             :  * Attempt to remove an input value from the aggregated state.
    5032             :  *
    5033             :  * If the value cannot be removed then the function will return false; the
    5034             :  * possible reasons for failing are described below.
    5035             :  *
    5036             :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    5037             :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    5038             :  * won't be able to tell what the new aggregated value's dscale should be.
    5039             :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    5040             :  * have been zero if we'd really aggregated only 2.
    5041             :  *
    5042             :  * Note: alternatively, we could count the number of inputs with each possible
    5043             :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    5044             :  */
    5045             : static bool
    5046         342 : do_numeric_discard(NumericAggState *state, Numeric newval)
    5047             : {
    5048             :     NumericVar  X;
    5049             :     NumericVar  X2;
    5050             :     MemoryContext old_context;
    5051             : 
    5052             :     /* Count NaN/infinity inputs separately from all else */
    5053         342 :     if (NUMERIC_IS_SPECIAL(newval))
    5054             :     {
    5055           6 :         if (NUMERIC_IS_PINF(newval))
    5056           0 :             state->pInfcount--;
    5057           6 :         else if (NUMERIC_IS_NINF(newval))
    5058           0 :             state->nInfcount--;
    5059             :         else
    5060           6 :             state->NaNcount--;
    5061           6 :         return true;
    5062             :     }
    5063             : 
    5064             :     /* load processed number in short-lived context */
    5065         336 :     init_var_from_num(newval, &X);
    5066             : 
    5067             :     /*
    5068             :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    5069             :      * Removing the last input with that dscale would require us to recompute
    5070             :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    5071             :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    5072             :      * and force the aggregation to be redone from scratch.
    5073             :      */
    5074         336 :     if (X.dscale == state->maxScale)
    5075             :     {
    5076         336 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    5077             :         {
    5078             :             /*
    5079             :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    5080             :              * above zero anyway
    5081             :              */
    5082         318 :             state->maxScaleCount--;
    5083             :         }
    5084          18 :         else if (state->N == 1)
    5085             :         {
    5086             :             /* No remaining non-NaN inputs at all, so reset maxScale */
    5087          12 :             state->maxScale = 0;
    5088          12 :             state->maxScaleCount = 0;
    5089             :         }
    5090             :         else
    5091             :         {
    5092             :             /* Correct new maxScale is uncertain, must fail */
    5093           6 :             return false;
    5094             :         }
    5095             :     }
    5096             : 
    5097             :     /* if we need X^2, calculate that in short-lived context */
    5098         330 :     if (state->calcSumX2)
    5099             :     {
    5100         288 :         init_var(&X2);
    5101         288 :         mul_var(&X, &X, &X2, X.dscale * 2);
    5102             :     }
    5103             : 
    5104             :     /* The rest of this needs to work in the aggregate context */
    5105         330 :     old_context = MemoryContextSwitchTo(state->agg_context);
    5106             : 
    5107         330 :     if (state->N-- > 1)
    5108             :     {
    5109             :         /* Negate X, to subtract it from the sum */
    5110         312 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    5111         312 :         accum_sum_add(&(state->sumX), &X);
    5112             : 
    5113         312 :         if (state->calcSumX2)
    5114             :         {
    5115             :             /* Negate X^2. X^2 is always positive */
    5116         288 :             X2.sign = NUMERIC_NEG;
    5117         288 :             accum_sum_add(&(state->sumX2), &X2);
    5118             :         }
    5119             :     }
    5120             :     else
    5121             :     {
    5122             :         /* Zero the sums */
    5123             :         Assert(state->N == 0);
    5124             : 
    5125          18 :         accum_sum_reset(&state->sumX);
    5126          18 :         if (state->calcSumX2)
    5127           0 :             accum_sum_reset(&state->sumX2);
    5128             :     }
    5129             : 
    5130         330 :     MemoryContextSwitchTo(old_context);
    5131             : 
    5132         330 :     return true;
    5133             : }
    5134             : 
    5135             : /*
    5136             :  * Generic transition function for numeric aggregates that require sumX2.
    5137             :  */
    5138             : Datum
    5139         642 : numeric_accum(PG_FUNCTION_ARGS)
    5140             : {
    5141             :     NumericAggState *state;
    5142             : 
    5143         642 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5144             : 
    5145             :     /* Create the state data on the first call */
    5146         642 :     if (state == NULL)
    5147         174 :         state = makeNumericAggState(fcinfo, true);
    5148             : 
    5149         642 :     if (!PG_ARGISNULL(1))
    5150         624 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5151             : 
    5152         642 :     PG_RETURN_POINTER(state);
    5153             : }
    5154             : 
    5155             : /*
    5156             :  * Generic combine function for numeric aggregates which require sumX2
    5157             :  */
    5158             : Datum
    5159          34 : numeric_combine(PG_FUNCTION_ARGS)
    5160             : {
    5161             :     NumericAggState *state1;
    5162             :     NumericAggState *state2;
    5163             :     MemoryContext agg_context;
    5164             :     MemoryContext old_context;
    5165             : 
    5166          34 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5167           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5168             : 
    5169          34 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5170          34 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5171             : 
    5172          34 :     if (state2 == NULL)
    5173           0 :         PG_RETURN_POINTER(state1);
    5174             : 
    5175             :     /* manually copy all fields from state2 to state1 */
    5176          34 :     if (state1 == NULL)
    5177             :     {
    5178          18 :         old_context = MemoryContextSwitchTo(agg_context);
    5179             : 
    5180          18 :         state1 = makeNumericAggStateCurrentContext(true);
    5181          18 :         state1->N = state2->N;
    5182          18 :         state1->NaNcount = state2->NaNcount;
    5183          18 :         state1->pInfcount = state2->pInfcount;
    5184          18 :         state1->nInfcount = state2->nInfcount;
    5185          18 :         state1->maxScale = state2->maxScale;
    5186          18 :         state1->maxScaleCount = state2->maxScaleCount;
    5187             : 
    5188          18 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5189          18 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5190             : 
    5191          18 :         MemoryContextSwitchTo(old_context);
    5192             : 
    5193          18 :         PG_RETURN_POINTER(state1);
    5194             :     }
    5195             : 
    5196          16 :     state1->N += state2->N;
    5197          16 :     state1->NaNcount += state2->NaNcount;
    5198          16 :     state1->pInfcount += state2->pInfcount;
    5199          16 :     state1->nInfcount += state2->nInfcount;
    5200             : 
    5201          16 :     if (state2->N > 0)
    5202             :     {
    5203             :         /*
    5204             :          * These are currently only needed for moving aggregates, but let's do
    5205             :          * the right thing anyway...
    5206             :          */
    5207          16 :         if (state2->maxScale > state1->maxScale)
    5208             :         {
    5209           0 :             state1->maxScale = state2->maxScale;
    5210           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5211             :         }
    5212          16 :         else if (state2->maxScale == state1->maxScale)
    5213          16 :             state1->maxScaleCount += state2->maxScaleCount;
    5214             : 
    5215             :         /* The rest of this needs to work in the aggregate context */
    5216          16 :         old_context = MemoryContextSwitchTo(agg_context);
    5217             : 
    5218             :         /* Accumulate sums */
    5219          16 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5220          16 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5221             : 
    5222          16 :         MemoryContextSwitchTo(old_context);
    5223             :     }
    5224          16 :     PG_RETURN_POINTER(state1);
    5225             : }
    5226             : 
    5227             : /*
    5228             :  * Generic transition function for numeric aggregates that don't require sumX2.
    5229             :  */
    5230             : Datum
    5231     1872862 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5232             : {
    5233             :     NumericAggState *state;
    5234             : 
    5235     1872862 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5236             : 
    5237             :     /* Create the state data on the first call */
    5238     1872862 :     if (state == NULL)
    5239      170928 :         state = makeNumericAggState(fcinfo, false);
    5240             : 
    5241     1872862 :     if (!PG_ARGISNULL(1))
    5242     1872802 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5243             : 
    5244     1872862 :     PG_RETURN_POINTER(state);
    5245             : }
    5246             : 
    5247             : /*
    5248             :  * Combine function for numeric aggregates which don't require sumX2
    5249             :  */
    5250             : Datum
    5251          22 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5252             : {
    5253             :     NumericAggState *state1;
    5254             :     NumericAggState *state2;
    5255             :     MemoryContext agg_context;
    5256             :     MemoryContext old_context;
    5257             : 
    5258          22 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5259           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5260             : 
    5261          22 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5262          22 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5263             : 
    5264          22 :     if (state2 == NULL)
    5265           0 :         PG_RETURN_POINTER(state1);
    5266             : 
    5267             :     /* manually copy all fields from state2 to state1 */
    5268          22 :     if (state1 == NULL)
    5269             :     {
    5270           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5271             : 
    5272           6 :         state1 = makeNumericAggStateCurrentContext(false);
    5273           6 :         state1->N = state2->N;
    5274           6 :         state1->NaNcount = state2->NaNcount;
    5275           6 :         state1->pInfcount = state2->pInfcount;
    5276           6 :         state1->nInfcount = state2->nInfcount;
    5277           6 :         state1->maxScale = state2->maxScale;
    5278           6 :         state1->maxScaleCount = state2->maxScaleCount;
    5279             : 
    5280           6 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5281             : 
    5282           6 :         MemoryContextSwitchTo(old_context);
    5283             : 
    5284           6 :         PG_RETURN_POINTER(state1);
    5285             :     }
    5286             : 
    5287          16 :     state1->N += state2->N;
    5288          16 :     state1->NaNcount += state2->NaNcount;
    5289          16 :     state1->pInfcount += state2->pInfcount;
    5290          16 :     state1->nInfcount += state2->nInfcount;
    5291             : 
    5292          16 :     if (state2->N > 0)
    5293             :     {
    5294             :         /*
    5295             :          * These are currently only needed for moving aggregates, but let's do
    5296             :          * the right thing anyway...
    5297             :          */
    5298          16 :         if (state2->maxScale > state1->maxScale)
    5299             :         {
    5300           0 :             state1->maxScale = state2->maxScale;
    5301           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5302             :         }
    5303          16 :         else if (state2->maxScale == state1->maxScale)
    5304          16 :             state1->maxScaleCount += state2->maxScaleCount;
    5305             : 
    5306             :         /* The rest of this needs to work in the aggregate context */
    5307          16 :         old_context = MemoryContextSwitchTo(agg_context);
    5308             : 
    5309             :         /* Accumulate sums */
    5310          16 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5311             : 
    5312          16 :         MemoryContextSwitchTo(old_context);
    5313             :     }
    5314          16 :     PG_RETURN_POINTER(state1);
    5315             : }
    5316             : 
    5317             : /*
    5318             :  * numeric_avg_serialize
    5319             :  *      Serialize NumericAggState for numeric aggregates that don't require
    5320             :  *      sumX2.
    5321             :  */
    5322             : Datum
    5323          22 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5324             : {
    5325             :     NumericAggState *state;
    5326             :     StringInfoData buf;
    5327             :     bytea      *result;
    5328             :     NumericVar  tmp_var;
    5329             : 
    5330             :     /* Ensure we disallow calling when not in aggregate context */
    5331          22 :     if (!AggCheckCallContext(fcinfo, NULL))
    5332           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5333             : 
    5334          22 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5335             : 
    5336          22 :     init_var(&tmp_var);
    5337             : 
    5338          22 :     pq_begintypsend(&buf);
    5339             : 
    5340             :     /* N */
    5341          22 :     pq_sendint64(&buf, state->N);
    5342             : 
    5343             :     /* sumX */
    5344          22 :     accum_sum_final(&state->sumX, &tmp_var);
    5345          22 :     numericvar_serialize(&buf, &tmp_var);
    5346             : 
    5347             :     /* maxScale */
    5348          22 :     pq_sendint32(&buf, state->maxScale);
    5349             : 
    5350             :     /* maxScaleCount */
    5351          22 :     pq_sendint64(&buf, state->maxScaleCount);
    5352             : 
    5353             :     /* NaNcount */
    5354          22 :     pq_sendint64(&buf, state->NaNcount);
    5355             : 
    5356             :     /* pInfcount */
    5357          22 :     pq_sendint64(&buf, state->pInfcount);
    5358             : 
    5359             :     /* nInfcount */
    5360          22 :     pq_sendint64(&buf, state->nInfcount);
    5361             : 
    5362          22 :     result = pq_endtypsend(&buf);
    5363             : 
    5364          22 :     free_var(&tmp_var);
    5365             : 
    5366          22 :     PG_RETURN_BYTEA_P(result);
    5367             : }
    5368             : 
    5369             : /*
    5370             :  * numeric_avg_deserialize
    5371             :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5372             :  *      don't require sumX2.
    5373             :  */
    5374             : Datum
    5375          22 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5376             : {
    5377             :     bytea      *sstate;
    5378             :     NumericAggState *result;
    5379             :     StringInfoData buf;
    5380             :     NumericVar  tmp_var;
    5381             : 
    5382          22 :     if (!AggCheckCallContext(fcinfo, NULL))
    5383           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5384             : 
    5385          22 :     sstate = PG_GETARG_BYTEA_PP(0);
    5386             : 
    5387          22 :     init_var(&tmp_var);
    5388             : 
    5389             :     /*
    5390             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5391             :      * recv-function infrastructure.
    5392             :      */
    5393          22 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5394          22 :                            VARSIZE_ANY_EXHDR(sstate));
    5395             : 
    5396          22 :     result = makeNumericAggStateCurrentContext(false);
    5397             : 
    5398             :     /* N */
    5399          22 :     result->N = pq_getmsgint64(&buf);
    5400             : 
    5401             :     /* sumX */
    5402          22 :     numericvar_deserialize(&buf, &tmp_var);
    5403          22 :     accum_sum_add(&(result->sumX), &tmp_var);
    5404             : 
    5405             :     /* maxScale */
    5406          22 :     result->maxScale = pq_getmsgint(&buf, 4);
    5407             : 
    5408             :     /* maxScaleCount */
    5409          22 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5410             : 
    5411             :     /* NaNcount */
    5412          22 :     result->NaNcount = pq_getmsgint64(&buf);
    5413             : 
    5414             :     /* pInfcount */
    5415          22 :     result->pInfcount = pq_getmsgint64(&buf);
    5416             : 
    5417             :     /* nInfcount */
    5418          22 :     result->nInfcount = pq_getmsgint64(&buf);
    5419             : 
    5420          22 :     pq_getmsgend(&buf);
    5421             : 
    5422          22 :     free_var(&tmp_var);
    5423             : 
    5424          22 :     PG_RETURN_POINTER(result);
    5425             : }
    5426             : 
    5427             : /*
    5428             :  * numeric_serialize
    5429             :  *      Serialization function for NumericAggState for numeric aggregates that
    5430             :  *      require sumX2.
    5431             :  */
    5432             : Datum
    5433          34 : numeric_serialize(PG_FUNCTION_ARGS)
    5434             : {
    5435             :     NumericAggState *state;
    5436             :     StringInfoData buf;
    5437             :     bytea      *result;
    5438             :     NumericVar  tmp_var;
    5439             : 
    5440             :     /* Ensure we disallow calling when not in aggregate context */
    5441          34 :     if (!AggCheckCallContext(fcinfo, NULL))
    5442           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5443             : 
    5444          34 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5445             : 
    5446          34 :     init_var(&tmp_var);
    5447             : 
    5448          34 :     pq_begintypsend(&buf);
    5449             : 
    5450             :     /* N */
    5451          34 :     pq_sendint64(&buf, state->N);
    5452             : 
    5453             :     /* sumX */
    5454          34 :     accum_sum_final(&state->sumX, &tmp_var);
    5455          34 :     numericvar_serialize(&buf, &tmp_var);
    5456             : 
    5457             :     /* sumX2 */
    5458          34 :     accum_sum_final(&state->sumX2, &tmp_var);
    5459          34 :     numericvar_serialize(&buf, &tmp_var);
    5460             : 
    5461             :     /* maxScale */
    5462          34 :     pq_sendint32(&buf, state->maxScale);
    5463             : 
    5464             :     /* maxScaleCount */
    5465          34 :     pq_sendint64(&buf, state->maxScaleCount);
    5466             : 
    5467             :     /* NaNcount */
    5468          34 :     pq_sendint64(&buf, state->NaNcount);
    5469             : 
    5470             :     /* pInfcount */
    5471          34 :     pq_sendint64(&buf, state->pInfcount);
    5472             : 
    5473             :     /* nInfcount */
    5474          34 :     pq_sendint64(&buf, state->nInfcount);
    5475             : 
    5476          34 :     result = pq_endtypsend(&buf);
    5477             : 
    5478          34 :     free_var(&tmp_var);
    5479             : 
    5480          34 :     PG_RETURN_BYTEA_P(result);
    5481             : }
    5482             : 
    5483             : /*
    5484             :  * numeric_deserialize
    5485             :  *      Deserialization function for NumericAggState for numeric aggregates that
    5486             :  *      require sumX2.
    5487             :  */
    5488             : Datum
    5489          34 : numeric_deserialize(PG_FUNCTION_ARGS)
    5490             : {
    5491             :     bytea      *sstate;
    5492             :     NumericAggState *result;
    5493             :     StringInfoData buf;
    5494             :     NumericVar  tmp_var;
    5495             : 
    5496          34 :     if (!AggCheckCallContext(fcinfo, NULL))
    5497           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5498             : 
    5499          34 :     sstate = PG_GETARG_BYTEA_PP(0);
    5500             : 
    5501          34 :     init_var(&tmp_var);
    5502             : 
    5503             :     /*
    5504             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5505             :      * recv-function infrastructure.
    5506             :      */
    5507          34 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5508          34 :                            VARSIZE_ANY_EXHDR(sstate));
    5509             : 
    5510          34 :     result = makeNumericAggStateCurrentContext(false);
    5511             : 
    5512             :     /* N */
    5513          34 :     result->N = pq_getmsgint64(&buf);
    5514             : 
    5515             :     /* sumX */
    5516          34 :     numericvar_deserialize(&buf, &tmp_var);
    5517          34 :     accum_sum_add(&(result->sumX), &tmp_var);
    5518             : 
    5519             :     /* sumX2 */
    5520          34 :     numericvar_deserialize(&buf, &tmp_var);
    5521          34 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5522             : 
    5523             :     /* maxScale */
    5524          34 :     result->maxScale = pq_getmsgint(&buf, 4);
    5525             : 
    5526             :     /* maxScaleCount */
    5527          34 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5528             : 
    5529             :     /* NaNcount */
    5530          34 :     result->NaNcount = pq_getmsgint64(&buf);
    5531             : 
    5532             :     /* pInfcount */
    5533          34 :     result->pInfcount = pq_getmsgint64(&buf);
    5534             : 
    5535             :     /* nInfcount */
    5536          34 :     result->nInfcount = pq_getmsgint64(&buf);
    5537             : 
    5538          34 :     pq_getmsgend(&buf);
    5539             : 
    5540          34 :     free_var(&tmp_var);
    5541             : 
    5542          34 :     PG_RETURN_POINTER(result);
    5543             : }
    5544             : 
    5545             : /*
    5546             :  * Generic inverse transition function for numeric aggregates
    5547             :  * (with or without requirement for X^2).
    5548             :  */
    5549             : Datum
    5550         228 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5551             : {
    5552             :     NumericAggState *state;
    5553             : 
    5554         228 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5555             : 
    5556             :     /* Should not get here with no state */
    5557         228 :     if (state == NULL)
    5558           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5559             : 
    5560         228 :     if (!PG_ARGISNULL(1))
    5561             :     {
    5562             :         /* If we fail to perform the inverse transition, return NULL */
    5563         198 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5564           6 :             PG_RETURN_NULL();
    5565             :     }
    5566             : 
    5567         222 :     PG_RETURN_POINTER(state);
    5568             : }
    5569             : 
    5570             : 
    5571             : /*
    5572             :  * Integer data types in general use Numeric accumulators to share code
    5573             :  * and avoid risk of overflow.
    5574             :  *
    5575             :  * However for performance reasons optimized special-purpose accumulator
    5576             :  * routines are used when possible.
    5577             :  *
    5578             :  * On platforms with 128-bit integer support, the 128-bit routines will be
    5579             :  * used when sum(X) or sum(X*X) fit into 128-bit.
    5580             :  *
    5581             :  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
    5582             :  * accumulators will be used for SUM and AVG of these data types.
    5583             :  */
    5584             : 
    5585             : #ifdef HAVE_INT128
    5586             : typedef struct Int128AggState
    5587             : {
    5588             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5589             :     int64       N;              /* count of processed numbers */
    5590             :     int128      sumX;           /* sum of processed numbers */
    5591             :     int128      sumX2;          /* sum of squares of processed numbers */
    5592             : } Int128AggState;
    5593             : 
    5594             : /*
    5595             :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5596             :  * sum, count and optionally sum of squares of the input.
    5597             :  */
    5598             : static Int128AggState *
    5599         896 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5600             : {
    5601             :     Int128AggState *state;
    5602             :     MemoryContext agg_context;
    5603             :     MemoryContext old_context;
    5604             : 
    5605         896 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5606           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5607             : 
    5608         896 :     old_context = MemoryContextSwitchTo(agg_context);
    5609             : 
    5610         896 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5611         896 :     state->calcSumX2 = calcSumX2;
    5612             : 
    5613         896 :     MemoryContextSwitchTo(old_context);
    5614             : 
    5615         896 :     return state;
    5616             : }
    5617             : 
    5618             : /*
    5619             :  * Like makeInt128AggState(), but allocate the state in the current memory
    5620             :  * context.
    5621             :  */
    5622             : static Int128AggState *
    5623          42 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5624             : {
    5625             :     Int128AggState *state;
    5626             : 
    5627          42 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5628          42 :     state->calcSumX2 = calcSumX2;
    5629             : 
    5630          42 :     return state;
    5631             : }
    5632             : 
    5633             : /*
    5634             :  * Accumulate a new input value for 128-bit aggregate functions.
    5635             :  */
    5636             : static void
    5637      557178 : do_int128_accum(Int128AggState *state, int128 newval)
    5638             : {
    5639      557178 :     if (state->calcSumX2)
    5640      242360 :         state->sumX2 += newval * newval;
    5641             : 
    5642      557178 :     state->sumX += newval;
    5643      557178 :     state->N++;
    5644      557178 : }
    5645             : 
    5646             : /*
    5647             :  * Remove an input value from the aggregated state.
    5648             :  */
    5649             : static void
    5650         312 : do_int128_discard(Int128AggState *state, int128 newval)
    5651             : {
    5652         312 :     if (state->calcSumX2)
    5653         288 :         state->sumX2 -= newval * newval;
    5654             : 
    5655         312 :     state->sumX -= newval;
    5656         312 :     state->N--;
    5657         312 : }
    5658             : 
    5659             : typedef Int128AggState PolyNumAggState;
    5660             : #define makePolyNumAggState makeInt128AggState
    5661             : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
    5662             : #else
    5663             : typedef NumericAggState PolyNumAggState;
    5664             : #define makePolyNumAggState makeNumericAggState
    5665             : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
    5666             : #endif
    5667             : 
    5668             : Datum
    5669         198 : int2_accum(PG_FUNCTION_ARGS)
    5670             : {
    5671             :     PolyNumAggState *state;
    5672             : 
    5673         198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5674             : 
    5675             :     /* Create the state data on the first call */
    5676         198 :     if (state == NULL)
    5677          36 :         state = makePolyNumAggState(fcinfo, true);
    5678             : 
    5679         198 :     if (!PG_ARGISNULL(1))
    5680             :     {
    5681             : #ifdef HAVE_INT128
    5682         180 :         do_int128_accum(state, (int128) PG_GETARG_INT16(1));
    5683             : #else
    5684             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
    5685             : #endif
    5686             :     }
    5687             : 
    5688         198 :     PG_RETURN_POINTER(state);
    5689             : }
    5690             : 
    5691             : Datum
    5692      242198 : int4_accum(PG_FUNCTION_ARGS)
    5693             : {
    5694             :     PolyNumAggState *state;
    5695             : 
    5696      242198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5697             : 
    5698             :     /* Create the state data on the first call */
    5699      242198 :     if (state == NULL)
    5700          74 :         state = makePolyNumAggState(fcinfo, true);
    5701             : 
    5702      242198 :     if (!PG_ARGISNULL(1))
    5703             :     {
    5704             : #ifdef HAVE_INT128
    5705      242180 :         do_int128_accum(state, (int128) PG_GETARG_INT32(1));
    5706             : #else
    5707             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
    5708             : #endif
    5709             :     }
    5710             : 
    5711      242198 :     PG_RETURN_POINTER(state);
    5712             : }
    5713             : 
    5714             : Datum
    5715      240198 : int8_accum(PG_FUNCTION_ARGS)
    5716             : {
    5717             :     NumericAggState *state;
    5718             : 
    5719      240198 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5720             : 
    5721             :     /* Create the state data on the first call */
    5722      240198 :     if (state == NULL)
    5723          58 :         state = makeNumericAggState(fcinfo, true);
    5724             : 
    5725      240198 :     if (!PG_ARGISNULL(1))
    5726      240180 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5727             : 
    5728      240198 :     PG_RETURN_POINTER(state);
    5729             : }
    5730             : 
    5731             : /*
    5732             :  * Combine function for numeric aggregates which require sumX2
    5733             :  */
    5734             : Datum
    5735          18 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5736             : {
    5737             :     PolyNumAggState *state1;
    5738             :     PolyNumAggState *state2;
    5739             :     MemoryContext agg_context;
    5740             :     MemoryContext old_context;
    5741             : 
    5742          18 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5743           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5744             : 
    5745          18 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5746          18 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5747             : 
    5748          18 :     if (state2 == NULL)
    5749           0 :         PG_RETURN_POINTER(state1);
    5750             : 
    5751             :     /* manually copy all fields from state2 to state1 */
    5752          18 :     if (state1 == NULL)
    5753             :     {
    5754           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5755             : 
    5756           6 :         state1 = makePolyNumAggState(fcinfo, true);
    5757           6 :         state1->N = state2->N;
    5758             : 
    5759             : #ifdef HAVE_INT128
    5760           6 :         state1->sumX = state2->sumX;
    5761           6 :         state1->sumX2 = state2->sumX2;
    5762             : #else
    5763             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5764             :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5765             : #endif
    5766             : 
    5767           6 :         MemoryContextSwitchTo(old_context);
    5768             : 
    5769           6 :         PG_RETURN_POINTER(state1);
    5770             :     }
    5771             : 
    5772          12 :     if (state2->N > 0)
    5773             :     {
    5774          12 :         state1->N += state2->N;
    5775             : 
    5776             : #ifdef HAVE_INT128
    5777          12 :         state1->sumX += state2->sumX;
    5778          12 :         state1->sumX2 += state2->sumX2;
    5779             : #else
    5780             :         /* The rest of this needs to work in the aggregate context */
    5781             :         old_context = MemoryContextSwitchTo(agg_context);
    5782             : 
    5783             :         /* Accumulate sums */
    5784             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5785             :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5786             : 
    5787             :         MemoryContextSwitchTo(old_context);
    5788             : #endif
    5789             : 
    5790             :     }
    5791          12 :     PG_RETURN_POINTER(state1);
    5792             : }
    5793             : 
    5794             : /*
    5795             :  * numeric_poly_serialize
    5796             :  *      Serialize PolyNumAggState into bytea for aggregate functions which
    5797             :  *      require sumX2.
    5798             :  */
    5799             : Datum
    5800          18 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5801             : {
    5802             :     PolyNumAggState *state;
    5803             :     StringInfoData buf;
    5804             :     bytea      *result;
    5805             :     NumericVar  tmp_var;
    5806             : 
    5807             :     /* Ensure we disallow calling when not in aggregate context */
    5808          18 :     if (!AggCheckCallContext(fcinfo, NULL))
    5809           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5810             : 
    5811          18 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5812             : 
    5813             :     /*
    5814             :      * If the platform supports int128 then sumX and sumX2 will be a 128 bit
    5815             :      * integer type. Here we'll convert that into a numeric type so that the
    5816             :      * combine state is in the same format for both int128 enabled machines
    5817             :      * and machines which don't support that type. The logic here is that one
    5818             :      * day we might like to send these over to another server for further
    5819             :      * processing and we want a standard format to work with.
    5820             :      */
    5821             : 
    5822          18 :     init_var(&tmp_var);
    5823             : 
    5824          18 :     pq_begintypsend(&buf);
    5825             : 
    5826             :     /* N */
    5827          18 :     pq_sendint64(&buf, state->N);
    5828             : 
    5829             :     /* sumX */
    5830             : #ifdef HAVE_INT128
    5831          18 :     int128_to_numericvar(state->sumX, &tmp_var);
    5832             : #else
    5833             :     accum_sum_final(&state->sumX, &tmp_var);
    5834             : #endif
    5835          18 :     numericvar_serialize(&buf, &tmp_var);
    5836             : 
    5837             :     /* sumX2 */
    5838             : #ifdef HAVE_INT128
    5839          18 :     int128_to_numericvar(state->sumX2, &tmp_var);
    5840             : #else
    5841             :     accum_sum_final(&state->sumX2, &tmp_var);
    5842             : #endif
    5843          18 :     numericvar_serialize(&buf, &tmp_var);
    5844             : 
    5845          18 :     result = pq_endtypsend(&buf);
    5846             : 
    5847          18 :     free_var(&tmp_var);
    5848             : 
    5849          18 :     PG_RETURN_BYTEA_P(result);
    5850             : }
    5851             : 
    5852             : /*
    5853             :  * numeric_poly_deserialize
    5854             :  *      Deserialize PolyNumAggState from bytea for aggregate functions which
    5855             :  *      require sumX2.
    5856             :  */
    5857             : Datum
    5858          18 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5859             : {
    5860             :     bytea      *sstate;
    5861             :     PolyNumAggState *result;
    5862             :     StringInfoData buf;
    5863             :     NumericVar  tmp_var;
    5864             : 
    5865          18 :     if (!AggCheckCallContext(fcinfo, NULL))
    5866           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5867             : 
    5868          18 :     sstate = PG_GETARG_BYTEA_PP(0);
    5869             : 
    5870          18 :     init_var(&tmp_var);
    5871             : 
    5872             :     /*
    5873             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5874             :      * recv-function infrastructure.
    5875             :      */
    5876          18 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5877          18 :                            VARSIZE_ANY_EXHDR(sstate));
    5878             : 
    5879          18 :     result = makePolyNumAggStateCurrentContext(false);
    5880             : 
    5881             :     /* N */
    5882          18 :     result->N = pq_getmsgint64(&buf);
    5883             : 
    5884             :     /* sumX */
    5885          18 :     numericvar_deserialize(&buf, &tmp_var);
    5886             : #ifdef HAVE_INT128
    5887          18 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5888             : #else
    5889             :     accum_sum_add(&result->sumX, &tmp_var);
    5890             : #endif
    5891             : 
    5892             :     /* sumX2 */
    5893          18 :     numericvar_deserialize(&buf, &tmp_var);
    5894             : #ifdef HAVE_INT128
    5895          18 :     numericvar_to_int128(&tmp_var, &result->sumX2);
    5896             : #else
    5897             :     accum_sum_add(&result->sumX2, &tmp_var);
    5898             : #endif
    5899             : 
    5900          18 :     pq_getmsgend(&buf);
    5901             : 
    5902          18 :     free_var(&tmp_var);
    5903             : 
    5904          18 :     PG_RETURN_POINTER(result);
    5905             : }
    5906             : 
    5907             : /*
    5908             :  * Transition function for int8 input when we don't need sumX2.
    5909             :  */
    5910             : Datum
    5911      318616 : int8_avg_accum(PG_FUNCTION_ARGS)
    5912             : {
    5913             :     PolyNumAggState *state;
    5914             : 
    5915      318616 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5916             : 
    5917             :     /* Create the state data on the first call */
    5918      318616 :     if (state == NULL)
    5919         768 :         state = makePolyNumAggState(fcinfo, false);
    5920             : 
    5921      318616 :     if (!PG_ARGISNULL(1))
    5922             :     {
    5923             : #ifdef HAVE_INT128
    5924      314818 :         do_int128_accum(state, (int128) PG_GETARG_INT64(1));
    5925             : #else
    5926             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5927             : #endif
    5928             :     }
    5929             : 
    5930      318616 :     PG_RETURN_POINTER(state);
    5931             : }
    5932             : 
    5933             : /*
    5934             :  * Combine function for PolyNumAggState for aggregates which don't require
    5935             :  * sumX2
    5936             :  */
    5937             : Datum
    5938          24 : int8_avg_combine(PG_FUNCTION_ARGS)
    5939             : {
    5940             :     PolyNumAggState *state1;
    5941             :     PolyNumAggState *state2;
    5942             :     MemoryContext agg_context;
    5943             :     MemoryContext old_context;
    5944             : 
    5945          24 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5946           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5947             : 
    5948          24 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5949          24 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5950             : 
    5951          24 :     if (state2 == NULL)
    5952           0 :         PG_RETURN_POINTER(state1);
    5953             : 
    5954             :     /* manually copy all fields from state2 to state1 */
    5955          24 :     if (state1 == NULL)
    5956             :     {
    5957          12 :         old_context = MemoryContextSwitchTo(agg_context);
    5958             : 
    5959          12 :         state1 = makePolyNumAggState(fcinfo, false);
    5960          12 :         state1->N = state2->N;
    5961             : 
    5962             : #ifdef HAVE_INT128
    5963          12 :         state1->sumX = state2->sumX;
    5964             : #else
    5965             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5966             : #endif
    5967          12 :         MemoryContextSwitchTo(old_context);
    5968             : 
    5969          12 :         PG_RETURN_POINTER(state1);
    5970             :     }
    5971             : 
    5972          12 :     if (state2->N > 0)
    5973             :     {
    5974          12 :         state1->N += state2->N;
    5975             : 
    5976             : #ifdef HAVE_INT128
    5977          12 :         state1->sumX += state2->sumX;
    5978             : #else
    5979             :         /* The rest of this needs to work in the aggregate context */
    5980             :         old_context = MemoryContextSwitchTo(agg_context);
    5981             : 
    5982             :         /* Accumulate sums */
    5983             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5984             : 
    5985             :         MemoryContextSwitchTo(old_context);
    5986             : #endif
    5987             : 
    5988             :     }
    5989          12 :     PG_RETURN_POINTER(state1);
    5990             : }
    5991             : 
    5992             : /*
    5993             :  * int8_avg_serialize
    5994             :  *      Serialize PolyNumAggState into bytea using the standard
    5995             :  *      recv-function infrastructure.
    5996             :  */
    5997             : Datum
    5998          24 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5999             : {
    6000             :     PolyNumAggState *state;
    6001             :     StringInfoData buf;
    6002             :     bytea      *result;
    6003             :     NumericVar  tmp_var;
    6004             : 
    6005             :     /* Ensure we disallow calling when not in aggregate context */
    6006          24 :     if (!AggCheckCallContext(fcinfo, NULL))
    6007           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6008             : 
    6009          24 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    6010             : 
    6011             :     /*
    6012             :      * If the platform supports int128 then sumX will be a 128 integer type.
    6013             :      * Here we'll convert that into a numeric type so that the combine state
    6014             :      * is in the same format for both int128 enabled machines and machines
    6015             :      * which don't support that type. The logic here is that one day we might
    6016             :      * like to send these over to another server for further processing and we
    6017             :      * want a standard format to work with.
    6018             :      */
    6019             : 
    6020          24 :     init_var(&tmp_var);
    6021             : 
    6022          24 :     pq_begintypsend(&buf);
    6023             : 
    6024             :     /* N */
    6025          24 :     pq_sendint64(&buf, state->N);
    6026             : 
    6027             :     /* sumX */
    6028             : #ifdef HAVE_INT128
    6029          24 :     int128_to_numericvar(state->sumX, &tmp_var);
    6030             : #else
    6031             :     accum_sum_final(&state->sumX, &tmp_var);
    6032             : #endif
    6033          24 :     numericvar_serialize(&buf, &tmp_var);
    6034             : 
    6035          24 :     result = pq_endtypsend(&buf);
    6036             : 
    6037          24 :     free_var(&tmp_var);
    6038             : 
    6039          24 :     PG_RETURN_BYTEA_P(result);
    6040             : }
    6041             : 
    6042             : /*
    6043             :  * int8_avg_deserialize
    6044             :  *      Deserialize bytea back into PolyNumAggState.
    6045             :  */
    6046             : Datum
    6047          24 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    6048             : {
    6049             :     bytea      *sstate;
    6050             :     PolyNumAggState *result;
    6051             :     StringInfoData buf;
    6052             :     NumericVar  tmp_var;
    6053             : 
    6054          24 :     if (!AggCheckCallContext(fcinfo, NULL))
    6055           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6056             : 
    6057          24 :     sstate = PG_GETARG_BYTEA_PP(0);
    6058             : 
    6059          24 :     init_var(&tmp_var);
    6060             : 
    6061             :     /*
    6062             :      * Initialize a StringInfo so that we can "receive" it using the standard
    6063             :      * recv-function infrastructure.
    6064             :      */
    6065          24 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    6066          24 :                            VARSIZE_ANY_EXHDR(sstate));
    6067             : 
    6068          24 :     result = makePolyNumAggStateCurrentContext(false);
    6069             : 
    6070             :     /* N */
    6071          24 :     result->N = pq_getmsgint64(&buf);
    6072             : 
    6073             :     /* sumX */
    6074          24 :     numericvar_deserialize(&buf, &tmp_var);
    6075             : #ifdef HAVE_INT128
    6076          24 :     numericvar_to_int128(&tmp_var, &result->sumX);
    6077             : #else
    6078             :     accum_sum_add(&result->sumX, &tmp_var);
    6079             : #endif
    6080             : 
    6081          24 :     pq_getmsgend(&buf);
    6082             : 
    6083          24 :     free_var(&tmp_var);
    6084             : 
    6085          24 :     PG_RETURN_POINTER(result);
    6086             : }
    6087             : 
    6088             : /*
    6089             :  * Inverse transition functions to go with the above.
    6090             :  */
    6091             : 
    6092             : Datum
    6093         162 : int2_accum_inv(PG_FUNCTION_ARGS)
    6094             : {
    6095             :     PolyNumAggState *state;
    6096             : 
    6097         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6098             : 
    6099             :     /* Should not get here with no state */
    6100         162 :     if (state == NULL)
    6101           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    6102             : 
    6103         162 :     if (!PG_ARGISNULL(1))
    6104             :     {
    6105             : #ifdef HAVE_INT128
    6106         144 :         do_int128_discard(state, (int128) PG_GETARG_INT16(1));
    6107             : #else
    6108             :         /* Should never fail, all inputs have dscale 0 */
    6109             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
    6110             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6111             : #endif
    6112             :     }
    6113             : 
    6114         162 :     PG_RETURN_POINTER(state);
    6115             : }
    6116             : 
    6117             : Datum
    6118         162 : int4_accum_inv(PG_FUNCTION_ARGS)
    6119             : {
    6120             :     PolyNumAggState *state;
    6121             : 
    6122         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6123             : 
    6124             :     /* Should not get here with no state */
    6125         162 :     if (state == NULL)
    6126           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    6127             : 
    6128         162 :     if (!PG_ARGISNULL(1))
    6129             :     {
    6130             : #ifdef HAVE_INT128
    6131         144 :         do_int128_discard(state, (int128) PG_GETARG_INT32(1));
    6132             : #else
    6133             :         /* Should never fail, all inputs have dscale 0 */
    6134             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
    6135             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6136             : #endif
    6137             :     }
    6138             : 
    6139         162 :     PG_RETURN_POINTER(state);
    6140             : }
    6141             : 
    6142             : Datum
    6143         162 : int8_accum_inv(PG_FUNCTION_ARGS)
    6144             : {
    6145             :     NumericAggState *state;
    6146             : 
    6147         162 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6148             : 
    6149             :     /* Should not get here with no state */
    6150         162 :     if (state == NULL)
    6151           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    6152             : 
    6153         162 :     if (!PG_ARGISNULL(1))
    6154             :     {
    6155             :         /* Should never fail, all inputs have dscale 0 */
    6156         144 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6157           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6158             :     }
    6159             : 
    6160         162 :     PG_RETURN_POINTER(state);
    6161             : }
    6162             : 
    6163             : Datum
    6164          36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    6165             : {
    6166             :     PolyNumAggState *state;
    6167             : 
    6168          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6169             : 
    6170             :     /* Should not get here with no state */
    6171          36 :     if (state == NULL)
    6172           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    6173             : 
    6174          36 :     if (!PG_ARGISNULL(1))
    6175             :     {
    6176             : #ifdef HAVE_INT128
    6177          24 :         do_int128_discard(state, (int128) PG_GETARG_INT64(1));
    6178             : #else
    6179             :         /* Should never fail, all inputs have dscale 0 */
    6180             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6181             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6182             : #endif
    6183             :     }
    6184             : 
    6185          36 :     PG_RETURN_POINTER(state);
    6186             : }
    6187             : 
    6188             : Datum
    6189         990 : numeric_poly_sum(PG_FUNCTION_ARGS)
    6190             : {
    6191             : #ifdef HAVE_INT128
    6192             :     PolyNumAggState *state;
    6193             :     Numeric     res;
    6194             :     NumericVar  result;
    6195             : 
    6196         990 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6197             : 
    6198             :     /* If there were no non-null inputs, return NULL */
    6199         990 :     if (state == NULL || state->N == 0)
    6200          24 :         PG_RETURN_NULL();
    6201             : 
    6202         966 :     init_var(&result);
    6203             : 
    6204         966 :     int128_to_numericvar(state->sumX, &result);
    6205             : 
    6206         966 :     res = make_result(&result);
    6207             : 
    6208         966 :     free_var(&result);
    6209             : 
    6210         966 :     PG_RETURN_NUMERIC(res);
    6211             : #else
    6212             :     return numeric_sum(fcinfo);
    6213             : #endif
    6214             : }
    6215             : 
    6216             : Datum
    6217          36 : numeric_poly_avg(PG_FUNCTION_ARGS)
    6218             : {
    6219             : #ifdef HAVE_INT128
    6220             :     PolyNumAggState *state;
    6221             :     NumericVar  result;
    6222             :     Datum       countd,
    6223             :                 sumd;
    6224             : 
    6225          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6226             : 
    6227             :     /* If there were no non-null inputs, return NULL */
    6228          36 :     if (state == NULL || state->N == 0)
    6229          18 :         PG_RETURN_NULL();
    6230             : 
    6231          18 :     init_var(&result);
    6232             : 
    6233          18 :     int128_to_numericvar(state->sumX, &result);
    6234             : 
    6235          18 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    6236          18 :     sumd = NumericGetDatum(make_result(&result));
    6237             : 
    6238          18 :     free_var(&result);
    6239             : 
    6240          18 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6241             : #else
    6242             :     return numeric_avg(fcinfo);
    6243             : #endif
    6244             : }
    6245             : 
    6246             : Datum
    6247          78 : numeric_avg(PG_FUNCTION_ARGS)
    6248             : {
    6249             :     NumericAggState *state;
    6250             :     Datum       N_datum;
    6251             :     Datum       sumX_datum;
    6252             :     NumericVar  sumX_var;
    6253             : 
    6254          78 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6255             : 
    6256             :     /* If there were no non-null inputs, return NULL */
    6257          78 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6258          18 :         PG_RETURN_NULL();
    6259             : 
    6260          60 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6261           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6262             : 
    6263             :     /* adding plus and minus infinities gives NaN */
    6264          54 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6265           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6266          48 :     if (state->pInfcount > 0)
    6267          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6268          30 :     if (state->nInfcount > 0)
    6269           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6270             : 
    6271          24 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    6272             : 
    6273          24 :     init_var(&sumX_var);
    6274          24 :     accum_sum_final(&state->sumX, &sumX_var);
    6275          24 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    6276          24 :     free_var(&sumX_var);
    6277             : 
    6278          24 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    6279             : }
    6280             : 
    6281             : Datum
    6282      170930 : numeric_sum(PG_FUNCTION_ARGS)
    6283             : {
    6284             :     NumericAggState *state;
    6285             :     NumericVar  sumX_var;
    6286             :     Numeric     result;
    6287             : 
    6288      170930 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6289             : 
    6290             :     /* If there were no non-null inputs, return NULL */
    6291      170930 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6292          18 :         PG_RETURN_NULL();
    6293             : 
    6294      170912 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6295          18 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6296             : 
    6297             :     /* adding plus and minus infinities gives NaN */
    6298      170894 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6299           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6300      170888 :     if (state->pInfcount > 0)
    6301          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6302      170870 :     if (state->nInfcount > 0)
    6303           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6304             : 
    6305      170864 :     init_var(&sumX_var);
    6306      170864 :     accum_sum_final(&state->sumX, &sumX_var);
    6307      170864 :     result = make_result(&sumX_var);
    6308      170864 :     free_var(&sumX_var);
    6309             : 
    6310      170864 :     PG_RETURN_NUMERIC(result);
    6311             : }
    6312             : 
    6313             : /*
    6314             :  * Workhorse routine for the standard deviance and variance
    6315             :  * aggregates. 'state' is aggregate's transition state.
    6316             :  * 'variance' specifies whether we should calculate the
    6317             :  * variance or the standard deviation. 'sample' indicates whether the
    6318             :  * caller is interested in the sample or the population
    6319             :  * variance/stddev.
    6320             :  *
    6321             :  * If appropriate variance statistic is undefined for the input,
    6322             :  * *is_null is set to true and NULL is returned.
    6323             :  */
    6324             : static Numeric
    6325         986 : numeric_stddev_internal(NumericAggState *state,
    6326             :                         bool variance, bool sample,
    6327             :                         bool *is_null)
    6328             : {
    6329             :     Numeric     res;
    6330             :     NumericVar  vN,
    6331             :                 vsumX,
    6332             :                 vsumX2,
    6333             :                 vNminus1;
    6334             :     int64       totCount;
    6335             :     int         rscale;
    6336             : 
    6337             :     /*
    6338             :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6339             :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6340             :      * and infinities count as normal inputs for this purpose).
    6341             :      */
    6342         986 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6343             :     {
    6344           0 :         *is_null = true;
    6345           0 :         return NULL;
    6346             :     }
    6347             : 
    6348         986 :     if (sample && totCount <= 1)
    6349             :     {
    6350         132 :         *is_null = true;
    6351         132 :         return NULL;
    6352             :     }
    6353             : 
    6354         854 :     *is_null = false;
    6355             : 
    6356             :     /*
    6357             :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6358             :      * float8 functions, any infinity input produces NaN output.
    6359             :      */
    6360         854 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6361          54 :         return make_result(&const_nan);
    6362             : 
    6363             :     /* OK, normal calculation applies */
    6364         800 :     init_var(&vN);
    6365         800 :     init_var(&vsumX);
    6366         800 :     init_var(&vsumX2);
    6367             : 
    6368         800 :     int64_to_numericvar(state->N, &vN);
    6369         800 :     accum_sum_final(&(state->sumX), &vsumX);
    6370         800 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6371             : 
    6372         800 :     init_var(&vNminus1);
    6373         800 :     sub_var(&vN, &const_one, &vNminus1);
    6374             : 
    6375             :     /* compute rscale for mul_var calls */
    6376         800 :     rscale = vsumX.dscale * 2;
    6377             : 
    6378         800 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6379         800 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6380         800 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6381             : 
    6382         800 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6383             :     {
    6384             :         /* Watch out for roundoff error producing a negative numerator */
    6385          80 :         res = make_result(&const_zero);
    6386             :     }
    6387             :     else
    6388             :     {
    6389         720 :         if (sample)
    6390         492 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6391             :         else
    6392         228 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6393         720 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6394         720 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true);    /* variance */
    6395         720 :         if (!variance)
    6396         378 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6397             : 
    6398         720 :         res = make_result(&vsumX);
    6399             :     }
    6400             : 
    6401         800 :     free_var(&vNminus1);
    6402         800 :     free_var(&vsumX);
    6403         800 :     free_var(&vsumX2);
    6404             : 
    6405         800 :     return res;
    6406             : }
    6407             : 
    6408             : Datum
    6409         180 : numeric_var_samp(PG_FUNCTION_ARGS)
    6410             : {
    6411             :     NumericAggState *state;
    6412             :     Numeric     res;
    6413             :     bool        is_null;
    6414             : 
    6415         180 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6416             : 
    6417         180 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6418             : 
    6419         180 :     if (is_null)
    6420          42 :         PG_RETURN_NULL();
    6421             :     else
    6422         138 :         PG_RETURN_NUMERIC(res);
    6423             : }
    6424             : 
    6425             : Datum
    6426         174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6427             : {
    6428             :     NumericAggState *state;
    6429             :     Numeric     res;
    6430             :     bool        is_null;
    6431             : 
    6432         174 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6433             : 
    6434         174 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6435             : 
    6436         174 :     if (is_null)
    6437          42 :         PG_RETURN_NULL();
    6438             :     else
    6439         132 :         PG_RETURN_NUMERIC(res);
    6440             : }
    6441             : 
    6442             : Datum
    6443         114 : numeric_var_pop(PG_FUNCTION_ARGS)
    6444             : {
    6445             :     NumericAggState *state;
    6446             :     Numeric     res;
    6447             :     bool        is_null;
    6448             : 
    6449         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6450             : 
    6451         114 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6452             : 
    6453         114 :     if (is_null)
    6454           0 :         PG_RETURN_NULL();
    6455             :     else
    6456         114 :         PG_RETURN_NUMERIC(res);
    6457             : }
    6458             : 
    6459             : Datum
    6460          96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6461             : {
    6462             :     NumericAggState *state;
    6463             :     Numeric     res;
    6464             :     bool        is_null;
    6465             : 
    6466          96 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6467             : 
    6468          96 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6469             : 
    6470          96 :     if (is_null)
    6471           0 :         PG_RETURN_NULL();
    6472             :     else
    6473          96 :         PG_RETURN_NUMERIC(res);
    6474             : }
    6475             : 
    6476             : #ifdef HAVE_INT128
    6477             : static Numeric
    6478         422 : numeric_poly_stddev_internal(Int128AggState *state,
    6479             :                              bool variance, bool sample,
    6480             :                              bool *is_null)
    6481             : {
    6482             :     NumericAggState numstate;
    6483             :     Numeric     res;
    6484             : 
    6485             :     /* Initialize an empty agg state */
    6486         422 :     memset(&numstate, 0, sizeof(NumericAggState));
    6487             : 
    6488         422 :     if (state)
    6489             :     {
    6490             :         NumericVar  tmp_var;
    6491             : 
    6492         422 :         numstate.N = state->N;
    6493             : 
    6494         422 :         init_var(&tmp_var);
    6495             : 
    6496         422 :         int128_to_numericvar(state->sumX, &tmp_var);
    6497         422 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6498             : 
    6499         422 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6500         422 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6501             : 
    6502         422 :         free_var(&tmp_var);
    6503             :     }
    6504             : 
    6505         422 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6506             : 
    6507         422 :     if (numstate.sumX.ndigits > 0)
    6508             :     {
    6509         422 :         pfree(numstate.sumX.pos_digits);
    6510         422 :         pfree(numstate.sumX.neg_digits);
    6511             :     }
    6512         422 :     if (numstate.sumX2.ndigits > 0)
    6513             :     {
    6514         422 :         pfree(numstate.sumX2.pos_digits);
    6515         422 :         pfree(numstate.sumX2.neg_digits);
    6516             :     }
    6517             : 
    6518         422 :     return res;
    6519             : }
    6520             : #endif
    6521             : 
    6522             : Datum
    6523         126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6524             : {
    6525             : #ifdef HAVE_INT128
    6526             :     PolyNumAggState *state;
    6527             :     Numeric     res;
    6528             :     bool        is_null;
    6529             : 
    6530         126 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6531             : 
    6532         126 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6533             : 
    6534         126 :     if (is_null)
    6535          24 :         PG_RETURN_NULL();
    6536             :     else
    6537         102 :         PG_RETURN_NUMERIC(res);
    6538             : #else
    6539             :     return numeric_var_samp(fcinfo);
    6540             : #endif
    6541             : }
    6542             : 
    6543             : Datum
    6544         164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6545             : {
    6546             : #ifdef HAVE_INT128
    6547             :     PolyNumAggState *state;
    6548             :     Numeric     res;
    6549             :     bool        is_null;
    6550             : 
    6551         164 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6552             : 
    6553         164 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6554             : 
    6555         164 :     if (is_null)
    6556          24 :         PG_RETURN_NULL();
    6557             :     else
    6558         140 :         PG_RETURN_NUMERIC(res);
    6559             : #else
    6560             :     return numeric_stddev_samp(fcinfo);
    6561             : #endif
    6562             : }
    6563             : 
    6564             : Datum
    6565          60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6566             : {
    6567             : #ifdef HAVE_INT128
    6568             :     PolyNumAggState *state;
    6569             :     Numeric     res;
    6570             :     bool        is_null;
    6571             : 
    6572          60 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6573             : 
    6574          60 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6575             : 
    6576          60 :     if (is_null)
    6577           0 :         PG_RETURN_NULL();
    6578             :     else
    6579          60 :         PG_RETURN_NUMERIC(res);
    6580             : #else
    6581             :     return numeric_var_pop(fcinfo);
    6582             : #endif
    6583             : }
    6584             : 
    6585             : Datum
    6586          72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6587             : {
    6588             : #ifdef HAVE_INT128
    6589             :     PolyNumAggState *state;
    6590             :     Numeric     res;
    6591             :     bool        is_null;
    6592             : 
    6593          72 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6594             : 
    6595          72 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6596             : 
    6597          72 :     if (is_null)
    6598           0 :         PG_RETURN_NULL();
    6599             :     else
    6600          72 :         PG_RETURN_NUMERIC(res);
    6601             : #else
    6602             :     return numeric_stddev_pop(fcinfo);
    6603             : #endif
    6604             : }
    6605             : 
    6606             : /*
    6607             :  * SUM transition functions for integer datatypes.
    6608             :  *
    6609             :  * To avoid overflow, we use accumulators wider than the input datatype.
    6610             :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6611             :  * inputs, we use int8 accumulators which should be sufficient for practical
    6612             :  * purposes.  (The latter two therefore don't really belong in this file,
    6613             :  * but we keep them here anyway.)
    6614             :  *
    6615             :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6616             :  * the initial condition of the transition data value needs to be NULL. This
    6617             :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6618             :  * data value into the transition data: it doesn't know how to do the type
    6619             :  * conversion.  The upshot is that these routines have to be marked non-strict
    6620             :  * and handle substitution of the first non-null input themselves.
    6621             :  *
    6622             :  * Note: these functions are used only in plain aggregation mode.
    6623             :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6624             :  */
    6625             : 
    6626             : Datum
    6627          24 : int2_sum(PG_FUNCTION_ARGS)
    6628             : {
    6629             :     int64       newval;
    6630             : 
    6631          24 :     if (PG_ARGISNULL(0))
    6632             :     {
    6633             :         /* No non-null input seen so far... */
    6634           6 :         if (PG_ARGISNULL(1))
    6635           0 :             PG_RETURN_NULL();   /* still no non-null */
    6636             :         /* This is the first non-null input. */
    6637           6 :         newval = (int64) PG_GETARG_INT16(1);
    6638           6 :         PG_RETURN_INT64(newval);
    6639             :     }
    6640             : 
    6641             :     /*
    6642             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6643             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6644             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6645             :      * then of course this is useless as well as incorrect, so just ifdef it
    6646             :      * out.)
    6647             :      */
    6648             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6649             :     if (AggCheckCallContext(fcinfo, NULL))
    6650             :     {
    6651             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6652             : 
    6653             :         /* Leave the running sum unchanged in the new input is null */
    6654             :         if (!PG_ARGISNULL(1))
    6655             :             *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
    6656             : 
    6657             :         PG_RETURN_POINTER(oldsum);
    6658             :     }
    6659             :     else
    6660             : #endif
    6661             :     {
    6662          18 :         int64       oldsum = PG_GETARG_INT64(0);
    6663             : 
    6664             :         /* Leave sum unchanged if new input is null. */
    6665          18 :         if (PG_ARGISNULL(1))
    6666           0 :             PG_RETURN_INT64(oldsum);
    6667             : 
    6668             :         /* OK to do the addition. */
    6669          18 :         newval = oldsum + (int64) PG_GETARG_INT16(1);
    6670             : 
    6671          18 :         PG_RETURN_INT64(newval);
    6672             :     }
    6673             : }
    6674             : 
    6675             : Datum
    6676     3698156 : int4_sum(PG_FUNCTION_ARGS)
    6677             : {
    6678             :     int64       newval;
    6679             : 
    6680     3698156 :     if (PG_ARGISNULL(0))
    6681             :     {
    6682             :         /* No non-null input seen so far... */
    6683      207128 :         if (PG_ARGISNULL(1))
    6684         986 :             PG_RETURN_NULL();   /* still no non-null */
    6685             :         /* This is the first non-null input. */
    6686      206142 :         newval = (int64) PG_GETARG_INT32(1);
    6687      206142 :         PG_RETURN_INT64(newval);
    6688             :     }
    6689             : 
    6690             :     /*
    6691             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6692             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6693             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6694             :      * then of course this is useless as well as incorrect, so just ifdef it
    6695             :      * out.)
    6696             :      */
    6697             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6698             :     if (AggCheckCallContext(fcinfo, NULL))
    6699             :     {
    6700             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6701             : 
    6702             :         /* Leave the running sum unchanged in the new input is null */
    6703             :         if (!PG_ARGISNULL(1))
    6704             :             *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
    6705             : 
    6706             :         PG_RETURN_POINTER(oldsum);
    6707             :     }
    6708             :     else
    6709             : #endif
    6710             :     {
    6711     3491028 :         int64       oldsum = PG_GETARG_INT64(0);
    6712             : 
    6713             :         /* Leave sum unchanged if new input is null. */
    6714     3491028 :         if (PG_ARGISNULL(1))
    6715       30874 :             PG_RETURN_INT64(oldsum);
    6716             : 
    6717             :         /* OK to do the addition. */
    6718     3460154 :         newval = oldsum + (int64) PG_GETARG_INT32(1);
    6719             : 
    6720     3460154 :         PG_RETURN_INT64(newval);
    6721             :     }
    6722             : }
    6723             : 
    6724             : /*
    6725             :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6726             :  */
    6727             : Datum
    6728           0 : int8_sum(PG_FUNCTION_ARGS)
    6729             : {
    6730             :     Numeric     oldsum;
    6731             : 
    6732           0 :     if (PG_ARGISNULL(0))
    6733             :     {
    6734             :         /* No non-null input seen so far... */
    6735           0 :         if (PG_ARGISNULL(1))
    6736           0 :             PG_RETURN_NULL();   /* still no non-null */
    6737             :         /* This is the first non-null input. */
    6738           0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6739             :     }
    6740             : 
    6741             :     /*
    6742             :      * Note that we cannot special-case the aggregate case here, as we do for
    6743             :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6744             :      * our first parameter in-place.
    6745             :      */
    6746             : 
    6747           0 :     oldsum = PG_GETARG_NUMERIC(0);
    6748             : 
    6749             :     /* Leave sum unchanged if new input is null. */
    6750           0 :     if (PG_ARGISNULL(1))
    6751           0 :         PG_RETURN_NUMERIC(oldsum);
    6752             : 
    6753             :     /* OK to do the addition. */
    6754           0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6755             :                                         NumericGetDatum(oldsum),
    6756             :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6757             : }
    6758             : 
    6759             : 
    6760             : /*
    6761             :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6762             :  * is a two-element int8 array, holding count and sum.
    6763             :  *
    6764             :  * These functions are also used for sum(int2) and sum(int4) when
    6765             :  * operating in moving-aggregate mode, since for correct inverse transitions
    6766             :  * we need to count the inputs.
    6767             :  */
    6768             : 
    6769             : typedef struct Int8TransTypeData
    6770             : {
    6771             :     int64       count;
    6772             :     int64       sum;
    6773             : } Int8TransTypeData;
    6774             : 
    6775             : Datum
    6776          42 : int2_avg_accum(PG_FUNCTION_ARGS)
    6777             : {
    6778             :     ArrayType  *transarray;
    6779          42 :     int16       newval = PG_GETARG_INT16(1);
    6780             :     Int8TransTypeData *transdata;
    6781             : 
    6782             :     /*
    6783             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6784             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6785             :      * a copy of it before scribbling on it.
    6786             :      */
    6787          42 :     if (AggCheckCallContext(fcinfo, NULL))
    6788          42 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6789             :     else
    6790           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6791             : 
    6792          42 :     if (ARR_HASNULL(transarray) ||
    6793          42 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6794           0 :         elog(ERROR, "expected 2-element int8 array");
    6795             : 
    6796          42 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6797          42 :     transdata->count++;
    6798          42 :     transdata->sum += newval;
    6799             : 
    6800          42 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6801             : }
    6802             : 
    6803             : Datum
    6804     2620302 : int4_avg_accum(PG_FUNCTION_ARGS)
    6805             : {
    6806             :     ArrayType  *transarray;
    6807     2620302 :     int32       newval = PG_GETARG_INT32(1);
    6808             :     Int8TransTypeData *transdata;
    6809             : 
    6810             :     /*
    6811             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6812             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6813             :      * a copy of it before scribbling on it.
    6814             :      */
    6815     2620302 :     if (AggCheckCallContext(fcinfo, NULL))
    6816     2620302 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6817             :     else
    6818           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6819             : 
    6820     2620302 :     if (ARR_HASNULL(transarray) ||
    6821     2620302 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6822           0 :         elog(ERROR, "expected 2-element int8 array");
    6823             : 
    6824     2620302 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6825     2620302 :     transdata->count++;
    6826     2620302 :     transdata->sum += newval;
    6827             : 
    6828     2620302 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6829             : }
    6830             : 
    6831             : Datum
    6832        4032 : int4_avg_combine(PG_FUNCTION_ARGS)
    6833             : {
    6834             :     ArrayType  *transarray1;
    6835             :     ArrayType  *transarray2;
    6836             :     Int8TransTypeData *state1;
    6837             :     Int8TransTypeData *state2;
    6838             : 
    6839        4032 :     if (!AggCheckCallContext(fcinfo, NULL))
    6840           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6841             : 
    6842        4032 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6843        4032 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6844             : 
    6845        4032 :     if (ARR_HASNULL(transarray1) ||
    6846        4032 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6847           0 :         elog(ERROR, "expected 2-element int8 array");
    6848             : 
    6849        4032 :     if (ARR_HASNULL(transarray2) ||
    6850        4032 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6851           0 :         elog(ERROR, "expected 2-element int8 array");
    6852             : 
    6853        4032 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6854        4032 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6855             : 
    6856        4032 :     state1->count += state2->count;
    6857        4032 :     state1->sum += state2->sum;
    6858             : 
    6859        4032 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6860             : }
    6861             : 
    6862             : Datum
    6863          12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6864             : {
    6865             :     ArrayType  *transarray;
    6866          12 :     int16       newval = PG_GETARG_INT16(1);
    6867             :     Int8TransTypeData *transdata;
    6868             : 
    6869             :     /*
    6870             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6871             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6872             :      * a copy of it before scribbling on it.
    6873             :      */
    6874          12 :     if (AggCheckCallContext(fcinfo, NULL))
    6875          12 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6876             :     else
    6877           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6878             : 
    6879          12 :     if (ARR_HASNULL(transarray) ||
    6880          12 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6881           0 :         elog(ERROR, "expected 2-element int8 array");
    6882             : 
    6883          12 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6884          12 :     transdata->count--;
    6885          12 :     transdata->sum -= newval;
    6886             : 
    6887          12 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6888             : }
    6889             : 
    6890             : Datum
    6891        1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6892             : {
    6893             :     ArrayType  *transarray;
    6894        1452 :     int32       newval = PG_GETARG_INT32(1);
    6895             :     Int8TransTypeData *transdata;
    6896             : 
    6897             :     /*
    6898             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6899             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6900             :      * a copy of it before scribbling on it.
    6901             :      */
    6902        1452 :     if (AggCheckCallContext(fcinfo, NULL))
    6903        1452 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6904             :     else
    6905           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6906             : 
    6907        1452 :     if (ARR_HASNULL(transarray) ||
    6908        1452 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6909           0 :         elog(ERROR, "expected 2-element int8 array");
    6910             : 
    6911        1452 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6912        1452 :     transdata->count--;
    6913        1452 :     transdata->sum -= newval;
    6914             : 
    6915        1452 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6916             : }
    6917             : 
    6918             : Datum
    6919       10774 : int8_avg(PG_FUNCTION_ARGS)
    6920             : {
    6921       10774 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6922             :     Int8TransTypeData *transdata;
    6923             :     Datum       countd,
    6924             :                 sumd;
    6925             : 
    6926       10774 :     if (ARR_HASNULL(transarray) ||
    6927       10774 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6928           0 :         elog(ERROR, "expected 2-element int8 array");
    6929       10774 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6930             : 
    6931             :     /* SQL defines AVG of no values to be NULL */
    6932       10774 :     if (transdata->count == 0)
    6933         118 :         PG_RETURN_NULL();
    6934             : 
    6935       10656 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6936       10656 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6937             : 
    6938       10656 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6939             : }
    6940             : 
    6941             : /*
    6942             :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6943             :  * final function for both.
    6944             :  */
    6945             : Datum
    6946        3834 : int2int4_sum(PG_FUNCTION_ARGS)
    6947             : {
    6948        3834 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6949             :     Int8TransTypeData *transdata;
    6950             : 
    6951        3834 :     if (ARR_HASNULL(transarray) ||
    6952        3834 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6953           0 :         elog(ERROR, "expected 2-element int8 array");
    6954        3834 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6955             : 
    6956             :     /* SQL defines SUM of no values to be NULL */
    6957        3834 :     if (transdata->count == 0)
    6958         480 :         PG_RETURN_NULL();
    6959             : 
    6960        3354 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6961             : }
    6962             : 
    6963             : 
    6964             : /* ----------------------------------------------------------------------
    6965             :  *
    6966             :  * Debug support
    6967             :  *
    6968             :  * ----------------------------------------------------------------------
    6969             :  */
    6970             : 
    6971             : #ifdef NUMERIC_DEBUG
    6972             : 
    6973             : /*
    6974             :  * dump_numeric() - Dump a value in the db storage format for debugging
    6975             :  */
    6976             : static void
    6977             : dump_numeric(const char *str, Numeric num)
    6978             : {
    6979             :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6980             :     int         ndigits;
    6981             :     int         i;
    6982             : 
    6983             :     ndigits = NUMERIC_NDIGITS(num);
    6984             : 
    6985             :     printf("%s: NUMERIC w=%d d=%d ", str,
    6986             :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6987             :     switch (NUMERIC_SIGN(num))
    6988             :     {
    6989             :         case NUMERIC_POS:
    6990             :             printf("POS");
    6991             :             break;
    6992             :         case NUMERIC_NEG:
    6993             :             printf("NEG");
    6994             :             break;
    6995             :         case NUMERIC_NAN:
    6996             :             printf("NaN");
    6997             :             break;
    6998             :         case NUMERIC_PINF:
    6999             :             printf("Infinity");
    7000             :             break;
    7001             :         case NUMERIC_NINF:
    7002             :             printf("-Infinity");
    7003             :             break;
    7004             :         default:
    7005             :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    7006             :             break;
    7007             :     }
    7008             : 
    7009             :     for (i = 0; i < ndigits; i++)
    7010             :         printf(" %0*d", DEC_DIGITS, digits[i]);
    7011             :     printf("\n");
    7012             : }
    7013             : 
    7014             : 
    7015             : /*
    7016             :  * dump_var() - Dump a value in the variable format for debugging
    7017             :  */
    7018             : static void
    7019             : dump_var(const char *str, NumericVar *var)
    7020             : {
    7021             :     int         i;
    7022             : 
    7023             :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    7024             :     switch (var->sign)
    7025             :     {
    7026             :         case NUMERIC_POS:
    7027             :             printf("POS");
    7028             :             break;
    7029             :         case NUMERIC_NEG:
    7030             :             printf("NEG");
    7031             :             break;
    7032             :         case NUMERIC_NAN:
    7033             :             printf("NaN");
    7034             :             break;
    7035             :         case NUMERIC_PINF:
    7036             :             printf("Infinity");
    7037             :             break;
    7038             :         case NUMERIC_NINF:
    7039             :             printf("-Infinity");
    7040             :             break;
    7041             :         default:
    7042             :             printf("SIGN=0x%x", var->sign);
    7043             :             break;
    7044             :     }
    7045             : 
    7046             :     for (i = 0; i < var->ndigits; i++)
    7047             :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    7048             : 
    7049             :     printf("\n");
    7050             : }
    7051             : #endif                          /* NUMERIC_DEBUG */
    7052             : 
    7053             : 
    7054             : /* ----------------------------------------------------------------------
    7055             :  *
    7056             :  * Local functions follow
    7057             :  *
    7058             :  * In general, these do not support "special" (NaN or infinity) inputs;
    7059             :  * callers should handle those possibilities first.
    7060             :  * (There are one or two exceptions, noted in their header comments.)
    7061             :  *
    7062             :  * ----------------------------------------------------------------------
    7063             :  */
    7064             : 
    7065             : 
    7066             : /*
    7067             :  * alloc_var() -
    7068             :  *
    7069             :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    7070             :  */
    7071             : static void
    7072     2226700 : alloc_var(NumericVar *var, int ndigits)
    7073             : {
    7074     2226700 :     digitbuf_free(var->buf);
    7075     2226700 :     var->buf = digitbuf_alloc(ndigits + 1);
    7076     2226700 :     var->buf[0] = 0;         /* spare digit for rounding */
    7077     2226700 :     var->digits = var->buf + 1;
    7078     2226700 :     var->ndigits = ndigits;
    7079     2226700 : }
    7080             : 
    7081             : 
    7082             : /*
    7083             :  * free_var() -
    7084             :  *
    7085             :  *  Return the digit buffer of a variable to the free pool
    7086             :  */
    7087             : static void
    7088     4238342 : free_var(NumericVar *var)
    7089             : {
    7090     4238342 :     digitbuf_free(var->buf);
    7091     4238342 :     var->buf = NULL;
    7092     4238342 :     var->digits = NULL;
    7093     4238342 :     var->sign = NUMERIC_NAN;
    7094     4238342 : }
    7095             : 
    7096             : 
    7097             : /*
    7098             :  * zero_var() -
    7099             :  *
    7100             :  *  Set a variable to ZERO.
    7101             :  *  Note: its dscale is not touched.
    7102             :  */
    7103             : static void
    7104       60882 : zero_var(NumericVar *var)
    7105             : {
    7106       60882 :     digitbuf_free(var->buf);
    7107       60882 :     var->buf = NULL;
    7108       60882 :     var->digits = NULL;
    7109       60882 :     var->ndigits = 0;
    7110       60882 :     var->weight = 0;         /* by convention; doesn't really matter */
    7111       60882 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    7112       60882 : }
    7113             : 
    7114             : 
    7115             : /*
    7116             :  * set_var_from_str()
    7117             :  *
    7118             :  *  Parse a string and put the number into a variable
    7119             :  *
    7120             :  * This function does not handle leading or trailing spaces.  It returns
    7121             :  * the end+1 position parsed into *endptr, so that caller can check for
    7122             :  * trailing spaces/garbage if deemed necessary.
    7123             :  *
    7124             :  * cp is the place to actually start parsing; str is what to use in error
    7125             :  * reports.  (Typically cp would be the same except advanced over spaces.)
    7126             :  *
    7127             :  * Returns true on success, false on failure (if escontext points to an
    7128             :  * ErrorSaveContext; otherwise errors are thrown).
    7129             :  */
    7130             : static bool
    7131      234422 : set_var_from_str(const char *str, const char *cp,
    7132             :                  NumericVar *dest, const char **endptr,
    7133             :                  Node *escontext)
    7134             : {
    7135      234422 :     bool        have_dp = false;
    7136             :     int         i;
    7137             :     unsigned char *decdigits;
    7138      234422 :     int         sign = NUMERIC_POS;
    7139      234422 :     int         dweight = -1;
    7140             :     int         ddigits;
    7141      234422 :     int         dscale = 0;
    7142             :     int         weight;
    7143             :     int         ndigits;
    7144             :     int         offset;
    7145             :     NumericDigit *digits;
    7146             : 
    7147             :     /*
    7148             :      * We first parse the string to extract decimal digits and determine the
    7149             :      * correct decimal weight.  Then convert to NBASE representation.
    7150             :      */
    7151      234422 :     switch (*cp)
    7152             :     {
    7153           0 :         case '+':
    7154           0 :             sign = NUMERIC_POS;
    7155           0 :             cp++;
    7156           0 :             break;
    7157             : 
    7158         300 :         case '-':
    7159         300 :             sign = NUMERIC_NEG;
    7160         300 :             cp++;
    7161         300 :             break;
    7162             :     }
    7163             : 
    7164      234422 :     if (*cp == '.')
    7165             :     {
    7166         382 :         have_dp = true;
    7167         382 :         cp++;
    7168             :     }
    7169             : 
    7170      234422 :     if (!isdigit((unsigned char) *cp))
    7171           0 :         goto invalid_syntax;
    7172             : 
    7173      234422 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    7174             : 
    7175             :     /* leading padding for digit alignment later */
    7176      234422 :     memset(decdigits, 0, DEC_DIGITS);
    7177      234422 :     i = DEC_DIGITS;
    7178             : 
    7179     1573478 :     while (*cp)
    7180             :     {
    7181     1340400 :         if (isdigit((unsigned char) *cp))
    7182             :         {
    7183     1289386 :             decdigits[i++] = *cp++ - '0';
    7184     1289386 :             if (!have_dp)
    7185      576834 :                 dweight++;
    7186             :             else
    7187      712552 :                 dscale++;
    7188             :         }
    7189       51014 :         else if (*cp == '.')
    7190             :         {
    7191       49508 :             if (have_dp)
    7192           0 :                 goto invalid_syntax;
    7193       49508 :             have_dp = true;
    7194       49508 :             cp++;
    7195             :             /* decimal point must not be followed by underscore */
    7196       49508 :             if (*cp == '_')
    7197           6 :                 goto invalid_syntax;
    7198             :         }
    7199        1506 :         else if (*cp == '_')
    7200             :         {
    7201             :             /* underscore must be followed by more digits */
    7202         186 :             cp++;
    7203         186 :             if (!isdigit((unsigned char) *cp))
    7204          18 :                 goto invalid_syntax;
    7205             :         }
    7206             :         else
    7207        1320 :             break;
    7208             :     }
    7209             : 
    7210      234398 :     ddigits = i - DEC_DIGITS;
    7211             :     /* trailing padding for digit alignment later */
    7212      234398 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    7213             : 
    7214             :     /* Handle exponent, if any */
    7215      234398 :     if (*cp == 'e' || *cp == 'E')
    7216             :     {
    7217        1272 :         int64       exponent = 0;
    7218        1272 :         bool        neg = false;
    7219             : 
    7220             :         /*
    7221             :          * At this point, dweight and dscale can't be more than about
    7222             :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    7223             :          * constraining the exponent similarly should be enough to prevent
    7224             :          * integer overflow in this function.  If the value is too large to
    7225             :          * fit in storage format, make_result() will complain about it later;
    7226             :          * for consistency use the same ereport errcode/text as make_result().
    7227             :          */
    7228             : 
    7229             :         /* exponent sign */
    7230        1272 :         cp++;
    7231        1272 :         if (*cp == '+')
    7232         154 :             cp++;
    7233        1118 :         else if (*cp == '-')
    7234             :         {
    7235         470 :             neg = true;
    7236         470 :             cp++;
    7237             :         }
    7238             : 
    7239             :         /* exponent digits */
    7240        1272 :         if (!isdigit((unsigned char) *cp))
    7241           6 :             goto invalid_syntax;
    7242             : 
    7243        4464 :         while (*cp)
    7244             :         {
    7245        3216 :             if (isdigit((unsigned char) *cp))
    7246             :             {
    7247        3174 :                 exponent = exponent * 10 + (*cp++ - '0');
    7248        3174 :                 if (exponent > PG_INT32_MAX / 2)
    7249           6 :                     goto out_of_range;
    7250             :             }
    7251          42 :             else if (*cp == '_')
    7252             :             {
    7253             :                 /* underscore must be followed by more digits */
    7254          42 :                 cp++;
    7255          42 :                 if (!isdigit((unsigned char) *cp))
    7256          12 :                     goto invalid_syntax;
    7257             :             }
    7258             :             else
    7259           0 :                 break;
    7260             :         }
    7261             : 
    7262        1248 :         if (neg)
    7263         470 :             exponent = -exponent;
    7264             : 
    7265        1248 :         dweight += (int) exponent;
    7266        1248 :         dscale -= (int) exponent;
    7267        1248 :         if (dscale < 0)
    7268         574 :             dscale = 0;
    7269             :     }
    7270             : 
    7271             :     /*
    7272             :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    7273             :      * to determine the converted weight and ndigits.  offset is the number of
    7274             :      * decimal zeroes to insert before the first given digit to have a
    7275             :      * correctly aligned first NBASE digit.
    7276             :      */
    7277      234374 :     if (dweight >= 0)
    7278      233624 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    7279             :     else
    7280         750 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    7281      234374 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    7282      234374 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    7283             : 
    7284      234374 :     alloc_var(dest, ndigits);
    7285      234374 :     dest->sign = sign;
    7286      234374 :     dest->weight = weight;
    7287      234374 :     dest->dscale = dscale;
    7288             : 
    7289      234374 :     i = DEC_DIGITS - offset;
    7290      234374 :     digits = dest->digits;
    7291             : 
    7292      702264 :     while (ndigits-- > 0)
    7293             :     {
    7294             : #if DEC_DIGITS == 4
    7295      467890 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    7296      467890 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    7297             : #elif DEC_DIGITS == 2
    7298             :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    7299             : #elif DEC_DIGITS == 1
    7300             :         *digits++ = decdigits[i];
    7301             : #else
    7302             : #error unsupported NBASE
    7303             : #endif
    7304      467890 :         i += DEC_DIGITS;
    7305             :     }
    7306             : 
    7307      234374 :     pfree(decdigits);
    7308             : 
    7309             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    7310      234374 :     strip_var(dest);
    7311             : 
    7312             :     /* Return end+1 position for caller */
    7313      234374 :     *endptr = cp;
    7314             : 
    7315      234374 :     return true;
    7316             : 
    7317           6 : out_of_range:
    7318           6 :     ereturn(escontext, false,
    7319             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7320             :              errmsg("value overflows numeric format")));
    7321             : 
    7322          42 : invalid_syntax:
    7323          42 :     ereturn(escontext, false,
    7324             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7325             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7326             :                     "numeric", str)));
    7327             : }
    7328             : 
    7329             : 
    7330             : /*
    7331             :  * Return the numeric value of a single hex digit.
    7332             :  */
    7333             : static inline int
    7334         708 : xdigit_value(char dig)
    7335             : {
    7336         894 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    7337         294 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    7338         108 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    7339             : }
    7340             : 
    7341             : /*
    7342             :  * set_var_from_non_decimal_integer_str()
    7343             :  *
    7344             :  *  Parse a string containing a non-decimal integer
    7345             :  *
    7346             :  * This function does not handle leading or trailing spaces.  It returns
    7347             :  * the end+1 position parsed into *endptr, so that caller can check for
    7348             :  * trailing spaces/garbage if deemed necessary.
    7349             :  *
    7350             :  * cp is the place to actually start parsing; str is what to use in error
    7351             :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    7352             :  * assumed to have already been parsed, so cp should point to the number's
    7353             :  * first digit in the base specified.
    7354             :  *
    7355             :  * base is expected to be 2, 8 or 16.
    7356             :  *
    7357             :  * Returns true on success, false on failure (if escontext points to an
    7358             :  * ErrorSaveContext; otherwise errors are thrown).
    7359             :  */
    7360             : static bool
    7361         156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7362             :                                      int base, NumericVar *dest,
    7363             :                                      const char **endptr, Node *escontext)
    7364             : {
    7365         156 :     const char *firstdigit = cp;
    7366             :     int64       tmp;
    7367             :     int64       mul;
    7368             :     NumericVar  tmp_var;
    7369             : 
    7370         156 :     init_var(&tmp_var);
    7371             : 
    7372         156 :     zero_var(dest);
    7373             : 
    7374             :     /*
    7375             :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7376             :      * value of the digits in the group, and "mul" is base^n, where n is the
    7377             :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7378             :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7379             :      */
    7380         156 :     tmp = 0;
    7381         156 :     mul = 1;
    7382             : 
    7383         156 :     if (base == 16)
    7384             :     {
    7385         828 :         while (*cp)
    7386             :         {
    7387         798 :             if (isxdigit((unsigned char) *cp))
    7388             :             {
    7389         708 :                 if (mul > PG_INT64_MAX / 16)
    7390             :                 {
    7391             :                     /* Add the contribution from this group of digits */
    7392          30 :                     int64_to_numericvar(mul, &tmp_var);
    7393          30 :                     mul_var(dest, &tmp_var, dest, 0);
    7394          30 :                     int64_to_numericvar(tmp, &tmp_var);
    7395          30 :                     add_var(dest, &tmp_var, dest);
    7396             : 
    7397             :                     /* Result will overflow if weight overflows int16 */
    7398          30 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7399           0 :                         goto out_of_range;
    7400             : 
    7401             :                     /* Begin a new group */
    7402          30 :                     tmp = 0;
    7403          30 :                     mul = 1;
    7404             :                 }
    7405             : 
    7406         708 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7407         708 :                 mul = mul * 16;
    7408             :             }
    7409          90 :             else if (*cp == '_')
    7410             :             {
    7411             :                 /* Underscore must be followed by more digits */
    7412          66 :                 cp++;
    7413          66 :                 if (!isxdigit((unsigned char) *cp))
    7414          18 :                     goto invalid_syntax;
    7415             :             }
    7416             :             else
    7417          24 :                 break;
    7418             :         }
    7419             :     }
    7420          84 :     else if (base == 8)
    7421             :     {
    7422         636 :         while (*cp)
    7423             :         {
    7424         606 :             if (*cp >= '0' && *cp <= '7')
    7425             :             {
    7426         558 :                 if (mul > PG_INT64_MAX / 8)
    7427             :                 {
    7428             :                     /* Add the contribution from this group of digits */
    7429          18 :                     int64_to_numericvar(mul, &tmp_var);
    7430          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7431          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7432          18 :                     add_var(dest, &tmp_var, dest);
    7433             : 
    7434             :                     /* Result will overflow if weight overflows int16 */
    7435          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7436           0 :                         goto out_of_range;
    7437             : 
    7438             :                     /* Begin a new group */
    7439          18 :                     tmp = 0;
    7440          18 :                     mul = 1;
    7441             :                 }
    7442             : 
    7443         558 :                 tmp = tmp * 8 + (*cp++ - '0');
    7444         558 :                 mul = mul * 8;
    7445             :             }
    7446          48 :             else if (*cp == '_')
    7447             :             {
    7448             :                 /* Underscore must be followed by more digits */
    7449          36 :                 cp++;
    7450          36 :                 if (*cp < '0' || *cp > '7')
    7451           0 :                     goto invalid_syntax;
    7452             :             }
    7453             :             else
    7454          12 :                 break;
    7455             :         }
    7456             :     }
    7457          42 :     else if (base == 2)
    7458             :     {
    7459        1560 :         while (*cp)
    7460             :         {
    7461        1530 :             if (*cp >= '0' && *cp <= '1')
    7462             :             {
    7463        1416 :                 if (mul > PG_INT64_MAX / 2)
    7464             :                 {
    7465             :                     /* Add the contribution from this group of digits */
    7466          18 :                     int64_to_numericvar(mul, &tmp_var);
    7467          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7468          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7469          18 :                     add_var(dest, &tmp_var, dest);
    7470             : 
    7471             :                     /* Result will overflow if weight overflows int16 */
    7472          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7473           0 :                         goto out_of_range;
    7474             : 
    7475             :                     /* Begin a new group */
    7476          18 :                     tmp = 0;
    7477          18 :                     mul = 1;
    7478             :                 }
    7479             : 
    7480        1416 :                 tmp = tmp * 2 + (*cp++ - '0');
    7481        1416 :                 mul = mul * 2;
    7482             :             }
    7483         114 :             else if (*cp == '_')
    7484             :             {
    7485             :                 /* Underscore must be followed by more digits */
    7486         102 :                 cp++;
    7487         102 :                 if (*cp < '0' || *cp > '1')
    7488           0 :                     goto invalid_syntax;
    7489             :             }
    7490             :             else
    7491          12 :                 break;
    7492             :         }
    7493             :     }
    7494             :     else
    7495             :         /* Should never happen; treat as invalid input */
    7496           0 :         goto invalid_syntax;
    7497             : 
    7498             :     /* Check that we got at least one digit */
    7499         138 :     if (unlikely(cp == firstdigit))
    7500           0 :         goto invalid_syntax;
    7501             : 
    7502             :     /* Add the contribution from the final group of digits */
    7503         138 :     int64_to_numericvar(mul, &tmp_var);
    7504         138 :     mul_var(dest, &tmp_var, dest, 0);
    7505         138 :     int64_to_numericvar(tmp, &tmp_var);
    7506         138 :     add_var(dest, &tmp_var, dest);
    7507             : 
    7508         138 :     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7509           0 :         goto out_of_range;
    7510             : 
    7511         138 :     dest->sign = sign;
    7512             : 
    7513         138 :     free_var(&tmp_var);
    7514             : 
    7515             :     /* Return end+1 position for caller */
    7516         138 :     *endptr = cp;
    7517             : 
    7518         138 :     return true;
    7519             : 
    7520           0 : out_of_range:
    7521           0 :     ereturn(escontext, false,
    7522             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7523             :              errmsg("value overflows numeric format")));
    7524             : 
    7525          18 : invalid_syntax:
    7526          18 :     ereturn(escontext, false,
    7527             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7528             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7529             :                     "numeric", str)));
    7530             : }
    7531             : 
    7532             : 
    7533             : /*
    7534             :  * set_var_from_num() -
    7535             :  *
    7536             :  *  Convert the packed db format into a variable
    7537             :  */
    7538             : static void
    7539       12952 : set_var_from_num(Numeric num, NumericVar *dest)
    7540             : {
    7541             :     int         ndigits;
    7542             : 
    7543       12952 :     ndigits = NUMERIC_NDIGITS(num);
    7544             : 
    7545       12952 :     alloc_var(dest, ndigits);
    7546             : 
    7547       12952 :     dest->weight = NUMERIC_WEIGHT(num);
    7548       12952 :     dest->sign = NUMERIC_SIGN(num);
    7549       12952 :     dest->dscale = NUMERIC_DSCALE(num);
    7550             : 
    7551       12952 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7552       12952 : }
    7553             : 
    7554             : 
    7555             : /*
    7556             :  * init_var_from_num() -
    7557             :  *
    7558             :  *  Initialize a variable from packed db format. The digits array is not
    7559             :  *  copied, which saves some cycles when the resulting var is not modified.
    7560             :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7561             :  *  other value to it (with set_var_* functions, or by using the var as the
    7562             :  *  destination of a function like add_var())
    7563             :  *
    7564             :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7565             :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7566             :  *  propagate to the original Numeric! It's OK to use it as the destination
    7567             :  *  argument of one of the calculational functions, though.
    7568             :  */
    7569             : static void
    7570     6016806 : init_var_from_num(Numeric num, NumericVar *dest)
    7571             : {
    7572     6016806 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7573     6016806 :     dest->weight = NUMERIC_WEIGHT(num);
    7574     6016806 :     dest->sign = NUMERIC_SIGN(num);
    7575     6016806 :     dest->dscale = NUMERIC_DSCALE(num);
    7576     6016806 :     dest->digits = NUMERIC_DIGITS(num);
    7577     6016806 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7578     6016806 : }
    7579             : 
    7580             : 
    7581             : /*
    7582             :  * set_var_from_var() -
    7583             :  *
    7584             :  *  Copy one variable into another
    7585             :  */
    7586             : static void
    7587       35334 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7588             : {
    7589             :     NumericDigit *newbuf;
    7590             : 
    7591       35334 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7592       35334 :     newbuf[0] = 0;              /* spare digit for rounding */
    7593       35334 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7594       34388 :         memcpy(newbuf + 1, value->digits,
    7595       34388 :                value->ndigits * sizeof(NumericDigit));
    7596             : 
    7597       35334 :     digitbuf_free(dest->buf);
    7598             : 
    7599       35334 :     memmove(dest, value, sizeof(NumericVar));
    7600       35334 :     dest->buf = newbuf;
    7601       35334 :     dest->digits = newbuf + 1;
    7602       35334 : }
    7603             : 
    7604             : 
    7605             : /*
    7606             :  * get_str_from_var() -
    7607             :  *
    7608             :  *  Convert a var to text representation (guts of numeric_out).
    7609             :  *  The var is displayed to the number of digits indicated by its dscale.
    7610             :  *  Returns a palloc'd string.
    7611             :  */
    7612             : static char *
    7613     1039266 : get_str_from_var(const NumericVar *var)
    7614             : {
    7615             :     int         dscale;
    7616             :     char       *str;
    7617             :     char       *cp;
    7618             :     char       *endcp;
    7619             :     int         i;
    7620             :     int         d;
    7621             :     NumericDigit dig;
    7622             : 
    7623             : #if DEC_DIGITS > 1
    7624             :     NumericDigit d1;
    7625             : #endif
    7626             : 
    7627     1039266 :     dscale = var->dscale;
    7628             : 
    7629             :     /*
    7630             :      * Allocate space for the result.
    7631             :      *
    7632             :      * i is set to the # of decimal digits before decimal point. dscale is the
    7633             :      * # of decimal digits we will print after decimal point. We may generate
    7634             :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7635             :      * need room for sign, decimal point, null terminator.
    7636             :      */
    7637     1039266 :     i = (var->weight + 1) * DEC_DIGITS;
    7638     1039266 :     if (i <= 0)
    7639      226704 :         i = 1;
    7640             : 
    7641     1039266 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7642     1039266 :     cp = str;
    7643             : 
    7644             :     /*
    7645             :      * Output a dash for negative values
    7646             :      */
    7647     1039266 :     if (var->sign == NUMERIC_NEG)
    7648        8296 :         *cp++ = '-';
    7649             : 
    7650             :     /*
    7651             :      * Output all digits before the decimal point
    7652             :      */
    7653     1039266 :     if (var->weight < 0)
    7654             :     {
    7655      226704 :         d = var->weight + 1;
    7656      226704 :         *cp++ = '0';
    7657             :     }
    7658             :     else
    7659             :     {
    7660     1736942 :         for (d = 0; d <= var->weight; d++)
    7661             :         {
    7662      924380 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7663             :             /* In the first digit, suppress extra leading decimal zeroes */
    7664             : #if DEC_DIGITS == 4
    7665             :             {
    7666      924380 :                 bool        putit = (d > 0);
    7667             : 
    7668      924380 :                 d1 = dig / 1000;
    7669      924380 :                 dig -= d1 * 1000;
    7670      924380 :                 putit |= (d1 > 0);
    7671      924380 :                 if (putit)
    7672      175782 :                     *cp++ = d1 + '0';
    7673      924380 :                 d1 = dig / 100;
    7674      924380 :                 dig -= d1 * 100;
    7675      924380 :                 putit |= (d1 > 0);
    7676      924380 :                 if (putit)
    7677      592216 :                     *cp++ = d1 + '0';
    7678      924380 :                 d1 = dig / 10;
    7679      924380 :                 dig -= d1 * 10;
    7680      924380 :                 putit |= (d1 > 0);
    7681      924380 :                 if (putit)
    7682      748196 :                     *cp++ = d1 + '0';
    7683      924380 :                 *cp++ = dig + '0';
    7684             :             }
    7685             : #elif DEC_DIGITS == 2
    7686             :             d1 = dig / 10;
    7687             :             dig -= d1 * 10;
    7688             :             if (d1 > 0 || d > 0)
    7689             :                 *cp++ = d1 + '0';
    7690             :             *cp++ = dig + '0';
    7691             : #elif DEC_DIGITS == 1
    7692             :             *cp++ = dig + '0';
    7693             : #else
    7694             : #error unsupported NBASE
    7695             : #endif
    7696             :         }
    7697             :     }
    7698             : 
    7699             :     /*
    7700             :      * If requested, output a decimal point and all the digits that follow it.
    7701             :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7702             :      * needed.
    7703             :      */
    7704     1039266 :     if (dscale > 0)
    7705             :     {
    7706      739768 :         *cp++ = '.';
    7707      739768 :         endcp = cp + dscale;
    7708     2469520 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7709             :         {
    7710     1729752 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7711             : #if DEC_DIGITS == 4
    7712     1729752 :             d1 = dig / 1000;
    7713     1729752 :             dig -= d1 * 1000;
    7714     1729752 :             *cp++ = d1 + '0';
    7715     1729752 :             d1 = dig / 100;
    7716     1729752 :             dig -= d1 * 100;
    7717     1729752 :             *cp++ = d1 + '0';
    7718     1729752 :             d1 = dig / 10;
    7719     1729752 :             dig -= d1 * 10;
    7720     1729752 :             *cp++ = d1 + '0';
    7721     1729752 :             *cp++ = dig + '0';
    7722             : #elif DEC_DIGITS == 2
    7723             :             d1 = dig / 10;
    7724             :             dig -= d1 * 10;
    7725             :             *cp++ = d1 + '0';
    7726             :             *cp++ = dig + '0';
    7727             : #elif DEC_DIGITS == 1
    7728             :             *cp++ = dig + '0';
    7729             : #else
    7730             : #error unsupported NBASE
    7731             : #endif
    7732             :         }
    7733      739768 :         cp = endcp;
    7734             :     }
    7735             : 
    7736             :     /*
    7737             :      * terminate the string and return it
    7738             :      */
    7739     1039266 :     *cp = '\0';
    7740     1039266 :     return str;
    7741             : }
    7742             : 
    7743             : /*
    7744             :  * get_str_from_var_sci() -
    7745             :  *
    7746             :  *  Convert a var to a normalised scientific notation text representation.
    7747             :  *  This function does the heavy lifting for numeric_out_sci().
    7748             :  *
    7749             :  *  This notation has the general form a * 10^b, where a is known as the
    7750             :  *  "significand" and b is known as the "exponent".
    7751             :  *
    7752             :  *  Because we can't do superscript in ASCII (and because we want to copy
    7753             :  *  printf's behaviour) we display the exponent using E notation, with a
    7754             :  *  minimum of two exponent digits.
    7755             :  *
    7756             :  *  For example, the value 1234 could be output as 1.2e+03.
    7757             :  *
    7758             :  *  We assume that the exponent can fit into an int32.
    7759             :  *
    7760             :  *  rscale is the number of decimal digits desired after the decimal point in
    7761             :  *  the output, negative values will be treated as meaning zero.
    7762             :  *
    7763             :  *  Returns a palloc'd string.
    7764             :  */
    7765             : static char *
    7766         228 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7767             : {
    7768             :     int32       exponent;
    7769             :     NumericVar  tmp_var;
    7770             :     size_t      len;
    7771             :     char       *str;
    7772             :     char       *sig_out;
    7773             : 
    7774         228 :     if (rscale < 0)
    7775           0 :         rscale = 0;
    7776             : 
    7777             :     /*
    7778             :      * Determine the exponent of this number in normalised form.
    7779             :      *
    7780             :      * This is the exponent required to represent the number with only one
    7781             :      * significant digit before the decimal place.
    7782             :      */
    7783         228 :     if (var->ndigits > 0)
    7784             :     {
    7785         210 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7786             : 
    7787             :         /*
    7788             :          * Compensate for leading decimal zeroes in the first numeric digit by
    7789             :          * decrementing the exponent.
    7790             :          */
    7791         210 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7792             :     }
    7793             :     else
    7794             :     {
    7795             :         /*
    7796             :          * If var has no digits, then it must be zero.
    7797             :          *
    7798             :          * Zero doesn't technically have a meaningful exponent in normalised
    7799             :          * notation, but we just display the exponent as zero for consistency
    7800             :          * of output.
    7801             :          */
    7802          18 :         exponent = 0;
    7803             :     }
    7804             : 
    7805             :     /*
    7806             :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7807             :      * decimal digits in the process.
    7808             :      */
    7809         228 :     init_var(&tmp_var);
    7810             : 
    7811         228 :     power_ten_int(exponent, &tmp_var);
    7812         228 :     div_var(var, &tmp_var, &tmp_var, rscale, true, true);
    7813         228 :     sig_out = get_str_from_var(&tmp_var);
    7814             : 
    7815         228 :     free_var(&tmp_var);
    7816             : 
    7817             :     /*
    7818             :      * Allocate space for the result.
    7819             :      *
    7820             :      * In addition to the significand, we need room for the exponent
    7821             :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7822             :      * exponent itself, and of course the null terminator.
    7823             :      */
    7824         228 :     len = strlen(sig_out) + 13;
    7825         228 :     str = palloc(len);
    7826         228 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7827             : 
    7828         228 :     pfree(sig_out);
    7829             : 
    7830         228 :     return str;
    7831             : }
    7832             : 
    7833             : 
    7834             : /*
    7835             :  * numericvar_serialize - serialize NumericVar to binary format
    7836             :  *
    7837             :  * At variable level, no checks are performed on the weight or dscale, allowing
    7838             :  * us to pass around intermediate values with higher precision than supported
    7839             :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7840             :  * which use 16-bit integers for these fields.
    7841             :  */
    7842             : static void
    7843         150 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7844             : {
    7845             :     int         i;
    7846             : 
    7847         150 :     pq_sendint32(buf, var->ndigits);
    7848         150 :     pq_sendint32(buf, var->weight);
    7849         150 :     pq_sendint32(buf, var->sign);
    7850         150 :     pq_sendint32(buf, var->dscale);
    7851      637950 :     for (i = 0; i < var->ndigits; i++)
    7852      637800 :         pq_sendint16(buf, var->digits[i]);
    7853         150 : }
    7854             : 
    7855             : /*
    7856             :  * numericvar_deserialize - deserialize binary format to NumericVar
    7857             :  */
    7858             : static void
    7859         150 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7860             : {
    7861             :     int         len,
    7862             :                 i;
    7863             : 
    7864         150 :     len = pq_getmsgint(buf, sizeof(int32));
    7865             : 
    7866         150 :     alloc_var(var, len);        /* sets var->ndigits */
    7867             : 
    7868         150 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7869         150 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7870         150 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7871      637950 :     for (i = 0; i < len; i++)
    7872      637800 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7873         150 : }
    7874             : 
    7875             : 
    7876             : /*
    7877             :  * duplicate_numeric() - copy a packed-format Numeric
    7878             :  *
    7879             :  * This will handle NaN and Infinity cases.
    7880             :  */
    7881             : static Numeric
    7882       28496 : duplicate_numeric(Numeric num)
    7883             : {
    7884             :     Numeric     res;
    7885             : 
    7886       28496 :     res = (Numeric) palloc(VARSIZE(num));
    7887       28496 :     memcpy(res, num, VARSIZE(num));
    7888       28496 :     return res;
    7889             : }
    7890             : 
    7891             : /*
    7892             :  * make_result_opt_error() -
    7893             :  *
    7894             :  *  Create the packed db numeric format in palloc()'d memory from
    7895             :  *  a variable.  This will handle NaN and Infinity cases.
    7896             :  *
    7897             :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
    7898             :  *  NULL is returned.  This is helpful when caller needs to handle errors.
    7899             :  */
    7900             : static Numeric
    7901     3859028 : make_result_opt_error(const NumericVar *var, bool *have_error)
    7902             : {
    7903             :     Numeric     result;
    7904     3859028 :     NumericDigit *digits = var->digits;
    7905     3859028 :     int         weight = var->weight;
    7906     3859028 :     int         sign = var->sign;
    7907             :     int         n;
    7908             :     Size        len;
    7909             : 
    7910     3859028 :     if (have_error)
    7911      211458 :         *have_error = false;
    7912             : 
    7913     3859028 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7914             :     {
    7915             :         /*
    7916             :          * Verify valid special value.  This could be just an Assert, perhaps,
    7917             :          * but it seems worthwhile to expend a few cycles to ensure that we
    7918             :          * never write any nonzero reserved bits to disk.
    7919             :          */
    7920        3354 :         if (!(sign == NUMERIC_NAN ||
    7921             :               sign == NUMERIC_PINF ||
    7922             :               sign == NUMERIC_NINF))
    7923           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7924             : 
    7925        3354 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7926             : 
    7927        3354 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7928        3354 :         result->choice.n_header = sign;
    7929             :         /* the header word is all we need */
    7930             : 
    7931             :         dump_numeric("make_result()", result);
    7932        3354 :         return result;
    7933             :     }
    7934             : 
    7935     3855674 :     n = var->ndigits;
    7936             : 
    7937             :     /* truncate leading zeroes */
    7938     3855710 :     while (n > 0 && *digits == 0)
    7939             :     {
    7940          36 :         digits++;
    7941          36 :         weight--;
    7942          36 :         n--;
    7943             :     }
    7944             :     /* truncate trailing zeroes */
    7945     3941012 :     while (n > 0 && digits[n - 1] == 0)
    7946       85338 :         n--;
    7947             : 
    7948             :     /* If zero result, force to weight=0 and positive sign */
    7949     3855674 :     if (n == 0)
    7950             :     {
    7951      137668 :         weight = 0;
    7952      137668 :         sign = NUMERIC_POS;
    7953             :     }
    7954             : 
    7955             :     /* Build the result */
    7956     3855674 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7957             :     {
    7958     3853760 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7959     3853760 :         result = (Numeric) palloc(len);
    7960     3853760 :         SET_VARSIZE(result, len);
    7961     3853760 :         result->choice.n_short.n_header =
    7962             :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7963             :              : NUMERIC_SHORT)
    7964     3853760 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7965     3853760 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7966     3853760 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7967             :     }
    7968             :     else
    7969             :     {
    7970        1914 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7971        1914 :         result = (Numeric) palloc(len);
    7972        1914 :         SET_VARSIZE(result, len);
    7973        1914 :         result->choice.n_long.n_sign_dscale =
    7974        1914 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7975        1914 :         result->choice.n_long.n_weight = weight;
    7976             :     }
    7977             : 
    7978             :     Assert(NUMERIC_NDIGITS(result) == n);
    7979     3855674 :     if (n > 0)
    7980     3718006 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7981             : 
    7982             :     /* Check for overflow of int16 fields */
    7983     3855674 :     if (NUMERIC_WEIGHT(result) != weight ||
    7984     3855644 :         NUMERIC_DSCALE(result) != var->dscale)
    7985             :     {
    7986          30 :         if (have_error)
    7987             :         {
    7988          18 :             *have_error = true;
    7989          18 :             return NULL;
    7990             :         }
    7991             :         else
    7992             :         {
    7993          12 :             ereport(ERROR,
    7994             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7995             :                      errmsg("value overflows numeric format")));
    7996             :         }
    7997             :     }
    7998             : 
    7999             :     dump_numeric("make_result()", result);
    8000     3855644 :     return result;
    8001             : }
    8002             : 
    8003             : 
    8004             : /*
    8005             :  * make_result() -
    8006             :  *
    8007             :  *  An interface to make_result_opt_error() without "have_error" argument.
    8008             :  */
    8009             : static Numeric
    8010     2268038 : make_result(const NumericVar *var)
    8011             : {
    8012     2268038 :     return make_result_opt_error(var, NULL);
    8013             : }
    8014             : 
    8015             : 
    8016             : /*
    8017             :  * apply_typmod() -
    8018             :  *
    8019             :  *  Do bounds checking and rounding according to the specified typmod.
    8020             :  *  Note that this is only applied to normal finite values.
    8021             :  *
    8022             :  * Returns true on success, false on failure (if escontext points to an
    8023             :  * ErrorSaveContext; otherwise errors are thrown).
    8024             :  */
    8025             : static bool
    8026      215562 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    8027             : {
    8028             :     int         precision;
    8029             :     int         scale;
    8030             :     int         maxdigits;
    8031             :     int         ddigits;
    8032             :     int         i;
    8033             : 
    8034             :     /* Do nothing if we have an invalid typmod */
    8035      215562 :     if (!is_valid_numeric_typmod(typmod))
    8036      185462 :         return true;
    8037             : 
    8038       30100 :     precision = numeric_typmod_precision(typmod);
    8039       30100 :     scale = numeric_typmod_scale(typmod);
    8040       30100 :     maxdigits = precision - scale;
    8041             : 
    8042             :     /* Round to target scale (and set var->dscale) */
    8043       30100 :     round_var(var, scale);
    8044             : 
    8045             :     /* but don't allow var->dscale to be negative */
    8046       30100 :     if (var->dscale < 0)
    8047         158 :         var->dscale = 0;
    8048             : 
    8049             :     /*
    8050             :      * Check for overflow - note we can't do this before rounding, because
    8051             :      * rounding could raise the weight.  Also note that the var's weight could
    8052             :      * be inflated by leading zeroes, which will be stripped before storage
    8053             :      * but perhaps might not have been yet. In any case, we must recognize a
    8054             :      * true zero, whose weight doesn't mean anything.
    8055             :      */
    8056       30100 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    8057       30100 :     if (ddigits > maxdigits)
    8058             :     {
    8059             :         /* Determine true weight; and check for all-zero result */
    8060        6458 :         for (i = 0; i < var->ndigits; i++)
    8061             :         {
    8062        6436 :             NumericDigit dig = var->digits[i];
    8063             : 
    8064        6436 :             if (dig)
    8065             :             {
    8066             :                 /* Adjust for any high-order decimal zero digits */
    8067             : #if DEC_DIGITS == 4
    8068        6436 :                 if (dig < 10)
    8069         324 :                     ddigits -= 3;
    8070        6112 :                 else if (dig < 100)
    8071         632 :                     ddigits -= 2;
    8072        5480 :                 else if (dig < 1000)
    8073        5462 :                     ddigits -= 1;
    8074             : #elif DEC_DIGITS == 2
    8075             :                 if (dig < 10)
    8076             :                     ddigits -= 1;
    8077             : #elif DEC_DIGITS == 1
    8078             :                 /* no adjustment */
    8079             : #else
    8080             : #error unsupported NBASE
    8081             : #endif
    8082        6436 :                 if (ddigits > maxdigits)
    8083          84 :                     ereturn(escontext, false,
    8084             :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    8085             :                              errmsg("numeric field overflow"),
    8086             :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    8087             :                                        precision, scale,
    8088             :                     /* Display 10^0 as 1 */
    8089             :                                        maxdigits ? "10^" : "",
    8090             :                                        maxdigits ? maxdigits : 1
    8091             :                                        )));
    8092        6352 :                 break;
    8093             :             }
    8094           0 :             ddigits -= DEC_DIGITS;
    8095             :         }
    8096             :     }
    8097             : 
    8098       30016 :     return true;
    8099             : }
    8100             : 
    8101             : /*
    8102             :  * apply_typmod_special() -
    8103             :  *
    8104             :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    8105             :  *  For convenience of most callers, the value is presented in packed form.
    8106             :  *
    8107             :  * Returns true on success, false on failure (if escontext points to an
    8108             :  * ErrorSaveContext; otherwise errors are thrown).
    8109             :  */
    8110             : static bool
    8111        1968 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    8112             : {
    8113             :     int         precision;
    8114             :     int         scale;
    8115             : 
    8116             :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    8117             : 
    8118             :     /*
    8119             :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    8120             :      * but it's a longstanding behavior.  Inf is rejected if we have any
    8121             :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    8122             :      * any finite number of digits.
    8123             :      */
    8124        1968 :     if (NUMERIC_IS_NAN(num))
    8125         858 :         return true;
    8126             : 
    8127             :     /* Do nothing if we have a default typmod (-1) */
    8128        1110 :     if (!is_valid_numeric_typmod(typmod))
    8129        1092 :         return true;
    8130             : 
    8131          18 :     precision = numeric_typmod_precision(typmod);
    8132          18 :     scale = numeric_typmod_scale(typmod);
    8133             : 
    8134          18 :     ereturn(escontext, false,
    8135             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    8136             :              errmsg("numeric field overflow"),
    8137             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    8138             :                        precision, scale)));
    8139             : }
    8140             : 
    8141             : 
    8142             : /*
    8143             :  * Convert numeric to int8, rounding if needed.
    8144             :  *
    8145             :  * If overflow, return false (no error is raised).  Return true if okay.
    8146             :  */
    8147             : static bool
    8148       10398 : numericvar_to_int64(const NumericVar *var, int64 *result)
    8149             : {
    8150             :     NumericDigit *digits;
    8151             :     int         ndigits;
    8152             :     int         weight;
    8153             :     int         i;
    8154             :     int64       val;
    8155             :     bool        neg;
    8156             :     NumericVar  rounded;
    8157             : 
    8158             :     /* Round to nearest integer */
    8159       10398 :     init_var(&rounded);
    8160       10398 :     set_var_from_var(var, &rounded);
    8161       10398 :     round_var(&rounded, 0);
    8162             : 
    8163             :     /* Check for zero input */
    8164       10398 :     strip_var(&rounded);
    8165       10398 :     ndigits = rounded.ndigits;
    8166       10398 :     if (ndigits == 0)
    8167             :     {
    8168         478 :         *result = 0;
    8169         478 :         free_var(&rounded);
    8170         478 :         return true;
    8171             :     }
    8172             : 
    8173             :     /*
    8174             :      * For input like 10000000000, we must treat stripped digits as real. So
    8175             :      * the loop assumes there are weight+1 digits before the decimal point.
    8176             :      */
    8177        9920 :     weight = rounded.weight;
    8178             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8179             : 
    8180             :     /*
    8181             :      * Construct the result. To avoid issues with converting a value
    8182             :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    8183             :      * bit two's complement integer), accumulate value as a negative number.
    8184             :      */
    8185        9920 :     digits = rounded.digits;
    8186        9920 :     neg = (rounded.sign == NUMERIC_NEG);
    8187        9920 :     val = -digits[0];
    8188       14138 :     for (i = 1; i <= weight; i++)
    8189             :     {
    8190        4266 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    8191             :         {
    8192          30 :             free_var(&rounded);
    8193          30 :             return false;
    8194             :         }
    8195             : 
    8196        4236 :         if (i < ndigits)
    8197             :         {
    8198        3960 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    8199             :             {
    8200          18 :                 free_var(&rounded);
    8201          18 :                 return false;
    8202             :             }
    8203             :         }
    8204             :     }
    8205             : 
    8206        9872 :     free_var(&rounded);
    8207             : 
    8208        9872 :     if (!neg)
    8209             :     {
    8210        9080 :         if (unlikely(val == PG_INT64_MIN))
    8211          24 :             return false;
    8212        9056 :         val = -val;
    8213             :     }
    8214        9848 :     *result = val;
    8215             : 
    8216        9848 :     return true;
    8217             : }
    8218             : 
    8219             : /*
    8220             :  * Convert int8 value to numeric.
    8221             :  */
    8222             : static void
    8223     1899978 : int64_to_numericvar(int64 val, NumericVar *var)
    8224             : {
    8225             :     uint64      uval,
    8226             :                 newuval;
    8227             :     NumericDigit *ptr;
    8228             :     int         ndigits;
    8229             : 
    8230             :     /* int64 can require at most 19 decimal digits; add one for safety */
    8231     1899978 :     alloc_var(var, 20 / DEC_DIGITS);
    8232     1899978 :     if (val < 0)
    8233             :     {
    8234        1814 :         var->sign = NUMERIC_NEG;
    8235        1814 :         uval = pg_abs_s64(val);
    8236             :     }
    8237             :     else
    8238             :     {
    8239     1898164 :         var->sign = NUMERIC_POS;
    8240     1898164 :         uval = val;
    8241             :     }
    8242     1899978 :     var->dscale = 0;
    8243     1899978 :     if (val == 0)
    8244             :     {
    8245       30592 :         var->ndigits = 0;
    8246       30592 :         var->weight = 0;
    8247       30592 :         return;
    8248             :     }
    8249     1869386 :     ptr = var->digits + var->ndigits;
    8250     1869386 :     ndigits = 0;
    8251             :     do
    8252             :     {
    8253     2193182 :         ptr--;
    8254     2193182 :         ndigits++;
    8255     2193182 :         newuval = uval / NBASE;
    8256     2193182 :         *ptr = uval - newuval * NBASE;
    8257     2193182 :         uval = newuval;
    8258     2193182 :     } while (uval);
    8259     1869386 :     var->digits = ptr;
    8260     1869386 :     var->ndigits = ndigits;
    8261     1869386 :     var->weight = ndigits - 1;
    8262             : }
    8263             : 
    8264             : /*
    8265             :  * Convert numeric to uint64, rounding if needed.
    8266             :  *
    8267             :  * If overflow, return false (no error is raised).  Return true if okay.
    8268             :  */
    8269             : static bool
    8270         114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    8271             : {
    8272             :     NumericDigit *digits;
    8273             :     int         ndigits;
    8274             :     int         weight;
    8275             :     int         i;
    8276             :     uint64      val;
    8277             :     NumericVar  rounded;
    8278             : 
    8279             :     /* Round to nearest integer */
    8280         114 :     init_var(&rounded);
    8281         114 :     set_var_from_var(var, &rounded);
    8282         114 :     round_var(&rounded, 0);
    8283             : 
    8284             :     /* Check for zero input */
    8285         114 :     strip_var(&rounded);
    8286         114 :     ndigits = rounded.ndigits;
    8287         114 :     if (ndigits == 0)
    8288             :     {
    8289          18 :         *result = 0;
    8290          18 :         free_var(&rounded);
    8291          18 :         return true;
    8292             :     }
    8293             : 
    8294             :     /* Check for negative input */
    8295          96 :     if (rounded.sign == NUMERIC_NEG)
    8296             :     {
    8297          12 :         free_var(&rounded);
    8298          12 :         return false;
    8299             :     }
    8300             : 
    8301             :     /*
    8302             :      * For input like 10000000000, we must treat stripped digits as real. So
    8303             :      * the loop assumes there are weight+1 digits before the decimal point.
    8304             :      */
    8305          84 :     weight = rounded.weight;
    8306             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8307             : 
    8308             :     /* Construct the result */
    8309          84 :     digits = rounded.digits;
    8310          84 :     val = digits[0];
    8311         246 :     for (i = 1; i <= weight; i++)
    8312             :     {
    8313         174 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    8314             :         {
    8315           0 :             free_var(&rounded);
    8316           0 :             return false;
    8317             :         }
    8318             : 
    8319         174 :         if (i < ndigits)
    8320             :         {
    8321         174 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    8322             :             {
    8323          12 :                 free_var(&rounded);
    8324          12 :                 return false;
    8325             :             }
    8326             :         }
    8327             :     }
    8328             : 
    8329          72 :     free_var(&rounded);
    8330             : 
    8331          72 :     *result = val;
    8332             : 
    8333          72 :     return true;
    8334             : }
    8335             : 
    8336             : #ifdef HAVE_INT128
    8337             : /*
    8338             :  * Convert numeric to int128, rounding if needed.
    8339             :  *
    8340             :  * If overflow, return false (no error is raised).  Return true if okay.
    8341             :  */
    8342             : static bool
    8343          60 : numericvar_to_int128(const NumericVar *var, int128 *result)
    8344             : {
    8345             :     NumericDigit *digits;
    8346             :     int         ndigits;
    8347             :     int         weight;
    8348             :     int         i;
    8349             :     int128      val,
    8350             :                 oldval;
    8351             :     bool        neg;
    8352             :     NumericVar  rounded;
    8353             : 
    8354             :     /* Round to nearest integer */
    8355          60 :     init_var(&rounded);
    8356          60 :     set_var_from_var(var, &rounded);
    8357          60 :     round_var(&rounded, 0);
    8358             : 
    8359             :     /* Check for zero input */
    8360          60 :     strip_var(&rounded);
    8361          60 :     ndigits = rounded.ndigits;
    8362          60 :     if (ndigits == 0)
    8363             :     {
    8364           0 :         *result = 0;
    8365           0 :         free_var(&rounded);
    8366           0 :         return true;
    8367             :     }
    8368             : 
    8369             :     /*
    8370             :      * For input like 10000000000, we must treat stripped digits as real. So
    8371             :      * the loop assumes there are weight+1 digits before the decimal point.
    8372             :      */
    8373          60 :     weight = rounded.weight;
    8374             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8375             : 
    8376             :     /* Construct the result */
    8377          60 :     digits = rounded.digits;
    8378          60 :     neg = (rounded.sign == NUMERIC_NEG);
    8379          60 :     val = digits[0];
    8380         148 :     for (i = 1; i <= weight; i++)
    8381             :     {
    8382          88 :         oldval = val;
    8383          88 :         val *= NBASE;
    8384          88 :         if (i < ndigits)
    8385          88 :             val += digits[i];
    8386             : 
    8387             :         /*
    8388             :          * The overflow check is a bit tricky because we want to accept
    8389             :          * INT128_MIN, which will overflow the positive accumulator.  We can
    8390             :          * detect this case easily though because INT128_MIN is the only
    8391             :          * nonzero value for which -val == val (on a two's complement machine,
    8392             :          * anyway).
    8393             :          */
    8394          88 :         if ((val / NBASE) != oldval)    /* possible overflow? */
    8395             :         {
    8396           0 :             if (!neg || (-val) != val || val == 0 || oldval < 0)
    8397             :             {
    8398           0 :                 free_var(&rounded);
    8399           0 :                 return false;
    8400             :             }
    8401             :         }
    8402             :     }
    8403             : 
    8404          60 :     free_var(&rounded);
    8405             : 
    8406          60 :     *result = neg ? -val : val;
    8407          60 :     return true;
    8408             : }
    8409             : 
    8410             : /*
    8411             :  * Convert 128 bit integer to numeric.
    8412             :  */
    8413             : static void
    8414        8794 : int128_to_numericvar(int128 val, NumericVar *var)
    8415             : {
    8416             :     uint128     uval,
    8417             :                 newuval;
    8418             :     NumericDigit *ptr;
    8419             :     int         ndigits;
    8420             : 
    8421             :     /* int128 can require at most 39 decimal digits; add one for safety */
    8422        8794 :     alloc_var(var, 40 / DEC_DIGITS);
    8423        8794 :     if (val < 0)
    8424             :     {
    8425           0 :         var->sign = NUMERIC_NEG;
    8426           0 :         uval = -val;
    8427             :     }
    8428             :     else
    8429             :     {
    8430        8794 :         var->sign = NUMERIC_POS;
    8431        8794 :         uval = val;
    8432             :     }
    8433        8794 :     var->dscale = 0;
    8434        8794 :     if (val == 0)
    8435             :     {
    8436         212 :         var->ndigits = 0;
    8437         212 :         var->weight = 0;
    8438         212 :         return;
    8439             :     }
    8440        8582 :     ptr = var->digits + var->ndigits;
    8441        8582 :     ndigits = 0;
    8442             :     do
    8443             :     {
    8444       45110 :         ptr--;
    8445       45110 :         ndigits++;
    8446       45110 :         newuval = uval / NBASE;
    8447       45110 :         *ptr = uval - newuval * NBASE;
    8448       45110 :         uval = newuval;
    8449       45110 :     } while (uval);
    8450        8582 :     var->digits = ptr;
    8451        8582 :     var->ndigits = ndigits;
    8452        8582 :     var->weight = ndigits - 1;
    8453             : }
    8454             : #endif
    8455             : 
    8456             : /*
    8457             :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    8458             :  */
    8459             : static double
    8460         468 : numericvar_to_double_no_overflow(const NumericVar *var)
    8461             : {
    8462             :     char       *tmp;
    8463             :     double      val;
    8464             :     char       *endptr;
    8465             : 
    8466         468 :     tmp = get_str_from_var(var);
    8467             : 
    8468             :     /* unlike float8in, we ignore ERANGE from strtod */
    8469         468 :     val = strtod(tmp, &endptr);
    8470         468 :     if (*endptr != '\0')
    8471             :     {
    8472             :         /* shouldn't happen ... */
    8473           0 :         ereport(ERROR,
    8474             :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8475             :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8476             :                         "double precision", tmp)));
    8477             :     }
    8478             : 
    8479         468 :     pfree(tmp);
    8480             : 
    8481         468 :     return val;
    8482             : }
    8483             : 
    8484             : 
    8485             : /*
    8486             :  * cmp_var() -
    8487             :  *
    8488             :  *  Compare two values on variable level.  We assume zeroes have been
    8489             :  *  truncated to no digits.
    8490             :  */
    8491             : static int
    8492      170228 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8493             : {
    8494      340456 :     return cmp_var_common(var1->digits, var1->ndigits,
    8495      170228 :                           var1->weight, var1->sign,
    8496      170228 :                           var2->digits, var2->ndigits,
    8497      170228 :                           var2->weight, var2->sign);
    8498             : }
    8499             : 
    8500             : /*
    8501             :  * cmp_var_common() -
    8502             :  *
    8503             :  *  Main routine of cmp_var(). This function can be used by both
    8504             :  *  NumericVar and Numeric.
    8505             :  */
    8506             : static int
    8507    19563750 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8508             :                int var1weight, int var1sign,
    8509             :                const NumericDigit *var2digits, int var2ndigits,
    8510             :                int var2weight, int var2sign)
    8511             : {
    8512    19563750 :     if (var1ndigits == 0)
    8513             :     {
    8514      533916 :         if (var2ndigits == 0)
    8515      436464 :             return 0;
    8516       97452 :         if (var2sign == NUMERIC_NEG)
    8517        4122 :             return 1;
    8518       93330 :         return -1;
    8519             :     }
    8520    19029834 :     if (var2ndigits == 0)
    8521             :     {
    8522       71880 :         if (var1sign == NUMERIC_POS)
    8523       65206 :             return 1;
    8524        6674 :         return -1;
    8525             :     }
    8526             : 
    8527    18957954 :     if (var1sign == NUMERIC_POS)
    8528             :     {
    8529    18876972 :         if (var2sign == NUMERIC_NEG)
    8530       23046 :             return 1;
    8531    18853926 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8532             :                               var2digits, var2ndigits, var2weight);
    8533             :     }
    8534             : 
    8535       80982 :     if (var2sign == NUMERIC_POS)
    8536       23700 :         return -1;
    8537             : 
    8538       57282 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8539             :                           var1digits, var1ndigits, var1weight);
    8540             : }
    8541             : 
    8542             : 
    8543             : /*
    8544             :  * add_var() -
    8545             :  *
    8546             :  *  Full version of add functionality on variable level (handling signs).
    8547             :  *  result might point to one of the operands too without danger.
    8548             :  */
    8549             : static void
    8550      618112 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8551             : {
    8552             :     /*
    8553             :      * Decide on the signs of the two variables what to do
    8554             :      */
    8555      618112 :     if (var1->sign == NUMERIC_POS)
    8556             :     {
    8557      616546 :         if (var2->sign == NUMERIC_POS)
    8558             :         {
    8559             :             /*
    8560             :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8561             :              */
    8562      416158 :             add_abs(var1, var2, result);
    8563      416158 :             result->sign = NUMERIC_POS;
    8564             :         }
    8565             :         else
    8566             :         {
    8567             :             /*
    8568             :              * var1 is positive, var2 is negative Must compare absolute values
    8569             :              */
    8570      200388 :             switch (cmp_abs(var1, var2))
    8571             :             {
    8572         222 :                 case 0:
    8573             :                     /* ----------
    8574             :                      * ABS(var1) == ABS(var2)
    8575             :                      * result = ZERO
    8576             :                      * ----------
    8577             :                      */
    8578         222 :                     zero_var(result);
    8579         222 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8580         222 :                     break;
    8581             : 
    8582      186244 :                 case 1:
    8583             :                     /* ----------
    8584             :                      * ABS(var1) > ABS(var2)
    8585             :                      * result = +(ABS(var1) - ABS(var2))
    8586             :                      * ----------
    8587             :                      */
    8588      186244 :                     sub_abs(var1, var2, result);
    8589      186244 :                     result->sign = NUMERIC_POS;
    8590      186244 :                     break;
    8591             : 
    8592       13922 :                 case -1:
    8593             :                     /* ----------
    8594             :                      * ABS(var1) < ABS(var2)
    8595             :                      * result = -(ABS(var2) - ABS(var1))
    8596             :                      * ----------
    8597             :                      */
    8598       13922 :                     sub_abs(var2, var1, result);
    8599       13922 :                     result->sign = NUMERIC_NEG;
    8600       13922 :                     break;
    8601             :             }
    8602             :         }
    8603             :     }
    8604             :     else
    8605             :     {
    8606        1566 :         if (var2->sign == NUMERIC_POS)
    8607             :         {
    8608             :             /* ----------
    8609             :              * var1 is negative, var2 is positive
    8610             :              * Must compare absolute values
    8611             :              * ----------
    8612             :              */
    8613         468 :             switch (cmp_abs(var1, var2))
    8614             :             {
    8615          30 :                 case 0:
    8616             :                     /* ----------
    8617             :                      * ABS(var1) == ABS(var2)
    8618             :                      * result = ZERO
    8619             :                      * ----------
    8620             :                      */
    8621          30 :                     zero_var(result);
    8622          30 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8623          30 :                     break;
    8624             : 
    8625         294 :                 case 1:
    8626             :                     /* ----------
    8627             :                      * ABS(var1) > ABS(var2)
    8628             :                      * result = -(ABS(var1) - ABS(var2))
    8629             :                      * ----------
    8630             :                      */
    8631         294 :                     sub_abs(var1, var2, result);
    8632         294 :                     result->sign = NUMERIC_NEG;
    8633         294 :                     break;
    8634             : 
    8635         144 :                 case -1:
    8636             :                     /* ----------
    8637             :                      * ABS(var1) < ABS(var2)
    8638             :                      * result = +(ABS(var2) - ABS(var1))
    8639             :                      * ----------
    8640             :                      */
    8641         144 :                     sub_abs(var2, var1, result);
    8642         144 :                     result->sign = NUMERIC_POS;
    8643         144 :                     break;
    8644             :             }
    8645             :         }
    8646             :         else
    8647             :         {
    8648             :             /* ----------
    8649             :              * Both are negative
    8650             :              * result = -(ABS(var1) + ABS(var2))
    8651             :              * ----------
    8652             :              */
    8653        1098 :             add_abs(var1, var2, result);
    8654        1098 :             result->sign = NUMERIC_NEG;
    8655             :         }
    8656             :     }
    8657      618112 : }
    8658             : 
    8659             : 
    8660             : /*
    8661             :  * sub_var() -
    8662             :  *
    8663             :  *  Full version of sub functionality on variable level (handling signs).
    8664             :  *  result might point to one of the operands too without danger.
    8665             :  */
    8666             : static void
    8667      532692 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8668             : {
    8669             :     /*
    8670             :      * Decide on the signs of the two variables what to do
    8671             :      */
    8672      532692 :     if (var1->sign == NUMERIC_POS)
    8673             :     {
    8674      531782 :         if (var2->sign == NUMERIC_NEG)
    8675             :         {
    8676             :             /* ----------
    8677             :              * var1 is positive, var2 is negative
    8678             :              * result = +(ABS(var1) + ABS(var2))
    8679             :              * ----------
    8680             :              */
    8681       28746 :             add_abs(var1, var2, result);
    8682       28746 :             result->sign = NUMERIC_POS;
    8683             :         }
    8684             :         else
    8685             :         {
    8686             :             /* ----------
    8687             :              * Both are positive
    8688             :              * Must compare absolute values
    8689             :              * ----------
    8690             :              */
    8691      503036 :             switch (cmp_abs(var1, var2))
    8692             :             {
    8693       48916 :                 case 0:
    8694             :                     /* ----------
    8695             :                      * ABS(var1) == ABS(var2)
    8696             :                      * result = ZERO
    8697             :                      * ----------
    8698             :                      */
    8699       48916 :                     zero_var(result);
    8700       48916 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8701       48916 :                     break;
    8702             : 
    8703      444176 :                 case 1:
    8704             :                     /* ----------
    8705             :                      * ABS(var1) > ABS(var2)
    8706             :                      * result = +(ABS(var1) - ABS(var2))
    8707             :                      * ----------
    8708             :                      */
    8709      444176 :                     sub_abs(var1, var2, result);
    8710      444176 :                     result->sign = NUMERIC_POS;
    8711      444176 :                     break;
    8712             : 
    8713        9944 :                 case -1:
    8714             :                     /* ----------
    8715             :                      * ABS(var1) < ABS(var2)
    8716             :                      * result = -(ABS(var2) - ABS(var1))
    8717             :                      * ----------
    8718             :                      */
    8719        9944 :                     sub_abs(var2, var1, result);
    8720        9944 :                     result->sign = NUMERIC_NEG;
    8721        9944 :                     break;
    8722             :             }
    8723             :         }
    8724             :     }
    8725             :     else
    8726             :     {
    8727         910 :         if (var2->sign == NUMERIC_NEG)
    8728             :         {
    8729             :             /* ----------
    8730             :              * Both are negative
    8731             :              * Must compare absolute values
    8732             :              * ----------
    8733             :              */
    8734         454 :             switch (cmp_abs(var1, var2))
    8735             :             {
    8736         166 :                 case 0:
    8737             :                     /* ----------
    8738             :                      * ABS(var1) == ABS(var2)
    8739             :                      * result = ZERO
    8740             :                      * ----------
    8741             :                      */
    8742         166 :                     zero_var(result);
    8743         166 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8744         166 :                     break;
    8745             : 
    8746         240 :                 case 1:
    8747             :                     /* ----------
    8748             :                      * ABS(var1) > ABS(var2)
    8749             :                      * result = -(ABS(var1) - ABS(var2))
    8750             :                      * ----------
    8751             :                      */
    8752         240 :                     sub_abs(var1, var2, result);
    8753         240 :                     result->sign = NUMERIC_NEG;
    8754         240 :                     break;
    8755             : 
    8756          48 :                 case -1:
    8757             :                     /* ----------
    8758             :                      * ABS(var1) < ABS(var2)
    8759             :                      * result = +(ABS(var2) - ABS(var1))
    8760             :                      * ----------
    8761             :                      */
    8762          48 :                     sub_abs(var2, var1, result);
    8763          48 :                     result->sign = NUMERIC_POS;
    8764          48 :                     break;
    8765             :             }
    8766             :         }
    8767             :         else
    8768             :         {
    8769             :             /* ----------
    8770             :              * var1 is negative, var2 is positive
    8771             :              * result = -(ABS(var1) + ABS(var2))
    8772             :              * ----------
    8773             :              */
    8774         456 :             add_abs(var1, var2, result);
    8775         456 :             result->sign = NUMERIC_NEG;
    8776             :         }
    8777             :     }
    8778      532692 : }
    8779             : 
    8780             : 
    8781             : /*
    8782             :  * mul_var() -
    8783             :  *
    8784             :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8785             :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8786             :  */
    8787             : static void
    8788     1189802 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8789             :         int rscale)
    8790             : {
    8791             :     int         res_ndigits;
    8792             :     int         res_ndigitpairs;
    8793             :     int         res_sign;
    8794             :     int         res_weight;
    8795             :     int         pair_offset;
    8796             :     int         maxdigits;
    8797             :     int         maxdigitpairs;
    8798             :     uint64     *dig,
    8799             :                *dig_i1_off;
    8800             :     uint64      maxdig;
    8801             :     uint64      carry;
    8802             :     uint64      newdig;
    8803             :     int         var1ndigits;
    8804             :     int         var2ndigits;
    8805             :     int         var1ndigitpairs;
    8806             :     int         var2ndigitpairs;
    8807             :     NumericDigit *var1digits;
    8808             :     NumericDigit *var2digits;
    8809             :     uint32      var1digitpair;
    8810             :     uint32     *var2digitpairs;
    8811             :     NumericDigit *res_digits;
    8812             :     int         i,
    8813             :                 i1,
    8814             :                 i2,
    8815             :                 i2limit;
    8816             : 
    8817             :     /*
    8818             :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8819             :      * performance because the inner multiplication loop is much simpler than
    8820             :      * the outer loop, so it's better to have a smaller number of iterations
    8821             :      * of the outer loop.  This also reduces the number of times that the
    8822             :      * accumulator array needs to be normalized.
    8823             :      */
    8824     1189802 :     if (var1->ndigits > var2->ndigits)
    8825             :     {
    8826       15228 :         const NumericVar *tmp = var1;
    8827             : 
    8828       15228 :         var1 = var2;
    8829       15228 :         var2 = tmp;
    8830             :     }
    8831             : 
    8832             :     /* copy these values into local vars for speed in inner loop */
    8833     1189802 :     var1ndigits = var1->ndigits;
    8834     1189802 :     var2ndigits = var2->ndigits;
    8835     1189802 :     var1digits = var1->digits;
    8836     1189802 :     var2digits = var2->digits;
    8837             : 
    8838     1189802 :     if (var1ndigits == 0)
    8839             :     {
    8840             :         /* one or both inputs is zero; so is result */
    8841        2894 :         zero_var(result);
    8842        2894 :         result->dscale = rscale;
    8843        2894 :         return;
    8844             :     }
    8845             : 
    8846             :     /*
    8847             :      * If var1 has 1-6 digits and the exact result was requested, delegate to
    8848             :      * mul_var_short() which uses a faster direct multiplication algorithm.
    8849             :      */
    8850     1186908 :     if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
    8851             :     {
    8852     1158432 :         mul_var_short(var1, var2, result);
    8853     1158432 :         return;
    8854             :     }
    8855             : 
    8856             :     /* Determine result sign */
    8857       28476 :     if (var1->sign == var2->sign)
    8858       26994 :         res_sign = NUMERIC_POS;
    8859             :     else
    8860        1482 :         res_sign = NUMERIC_NEG;
    8861             : 
    8862             :     /*
    8863             :      * Determine the number of result digits to compute and the (maximum
    8864             :      * possible) result weight.  If the exact result would have more than
    8865             :      * rscale fractional digits, truncate the computation with
    8866             :      * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
    8867             :      * only contribute to the right of that.  (This will give the exact
    8868             :      * rounded-to-rscale answer unless carries out of the ignored positions
    8869             :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8870             :      *
    8871             :      * Note: an exact computation could not produce more than var1ndigits +
    8872             :      * var2ndigits digits, but we allocate at least one extra output digit in
    8873             :      * case rscale-driven rounding produces a carry out of the highest exact
    8874             :      * digit.
    8875             :      *
    8876             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    8877             :      * actually process the input digits in pairs, producing a base-NBASE^2
    8878             :      * intermediate result.  This significantly improves performance, since
    8879             :      * schoolbook multiplication is O(N^2) in the number of input digits, and
    8880             :      * working in base NBASE^2 effectively halves "N".
    8881             :      *
    8882             :      * Note: in a truncated computation, we must compute at least one extra
    8883             :      * output digit to ensure that all the guard digits are fully computed.
    8884             :      */
    8885             :     /* digit pairs in each input */
    8886       28476 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    8887       28476 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    8888             : 
    8889             :     /* digits in exact result */
    8890       28476 :     res_ndigits = var1ndigits + var2ndigits;
    8891             : 
    8892             :     /* digit pairs in exact result with at least one extra output digit */
    8893       28476 :     res_ndigitpairs = res_ndigits / 2 + 1;
    8894             : 
    8895             :     /* pair offset to align result to end of dig[] */
    8896       28476 :     pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
    8897             : 
    8898             :     /* maximum possible result weight (odd-length inputs shifted up below) */
    8899       28476 :     res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
    8900       28476 :         res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
    8901             : 
    8902             :     /* rscale-based truncation with at least one extra output digit */
    8903       28476 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8904             :         MUL_GUARD_DIGITS;
    8905       28476 :     maxdigitpairs = maxdigits / 2 + 1;
    8906             : 
    8907       28476 :     res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
    8908       28476 :     res_ndigits = 2 * res_ndigitpairs;
    8909             : 
    8910             :     /*
    8911             :      * In the computation below, digit pair i1 of var1 and digit pair i2 of
    8912             :      * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
    8913             :      * input digit pairs with index >= res_ndigitpairs - pair_offset don't
    8914             :      * contribute to the result, and can be ignored.
    8915             :      */
    8916       28476 :     if (res_ndigitpairs <= pair_offset)
    8917             :     {
    8918             :         /* All input digits will be ignored; so result is zero */
    8919          12 :         zero_var(result);
    8920          12 :         result->dscale = rscale;
    8921          12 :         return;
    8922             :     }
    8923       28464 :     var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
    8924       28464 :     var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
    8925             : 
    8926             :     /*
    8927             :      * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
    8928             :      * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
    8929             :      * headroom to avoid normalizing carries immediately.
    8930             :      *
    8931             :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8932             :      * threatens to exceed PG_UINT64_MAX, we take the time to propagate
    8933             :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    8934             :      * during the carry propagation passes either.  The carry values could be
    8935             :      * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
    8936             :      * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
    8937             :      *
    8938             :      * To avoid overflow in maxdig itself, it actually represents the maximum
    8939             :      * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
    8940             :      * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
    8941             :      *
    8942             :      * The conversion of var1 to base NBASE^2 is done on the fly, as each new
    8943             :      * digit is required.  The digits of var2 are converted upfront, and
    8944             :      * stored at the end of dig[].  To avoid loss of precision, the input
    8945             :      * digits are aligned with the start of digit pair array, effectively
    8946             :      * shifting them up (multiplying by NBASE) if the inputs have an odd
    8947             :      * number of NBASE digits.
    8948             :      */
    8949       28464 :     dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
    8950             :                             var2ndigitpairs * sizeof(uint32));
    8951             : 
    8952             :     /* convert var2 to base NBASE^2, shifting up if its length is odd */
    8953       28464 :     var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
    8954             : 
    8955     1547190 :     for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
    8956     1518726 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8957             : 
    8958       28464 :     if (2 * i2 + 1 < var2ndigits)
    8959       20448 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8960             :     else
    8961        8016 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
    8962             : 
    8963             :     /*
    8964             :      * Start by multiplying var2 by the least significant contributing digit
    8965             :      * pair from var1, storing the results at the end of dig[], and filling
    8966             :      * the leading digits with zeros.
    8967             :      *
    8968             :      * The loop here is the same as the inner loop below, except that we set
    8969             :      * the results in dig[], rather than adding to them.  This is the
    8970             :      * performance bottleneck for multiplication, so we want to keep it simple
    8971             :      * enough so that it can be auto-vectorized.  Accordingly, process the
    8972             :      * digits left-to-right even though schoolbook multiplication would
    8973             :      * suggest right-to-left.  Since we aren't propagating carries in this
    8974             :      * loop, the order does not matter.
    8975             :      */
    8976       28464 :     i1 = var1ndigitpairs - 1;
    8977       28464 :     if (2 * i1 + 1 < var1ndigits)
    8978       12720 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8979             :     else
    8980       15744 :         var1digitpair = var1digits[2 * i1] * NBASE;
    8981       28464 :     maxdig = var1digitpair;
    8982             : 
    8983       28464 :     i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8984       28464 :     dig_i1_off = &dig[i1 + pair_offset];
    8985             : 
    8986       28464 :     memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
    8987     1376622 :     for (i2 = 0; i2 < i2limit; i2++)
    8988     1348158 :         dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
    8989             : 
    8990             :     /*
    8991             :      * Next, multiply var2 by the remaining digit pairs from var1, adding the
    8992             :      * results to dig[] at the appropriate offsets, and normalizing whenever
    8993             :      * there is a risk of any dig[] entry overflowing.
    8994             :      */
    8995     1501710 :     for (i1 = i1 - 1; i1 >= 0; i1--)
    8996             :     {
    8997     1473246 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8998     1473246 :         if (var1digitpair == 0)
    8999     1179516 :             continue;
    9000             : 
    9001             :         /* Time to normalize? */
    9002      293730 :         maxdig += var1digitpair;
    9003      293730 :         if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
    9004             :         {
    9005             :             /* Yes, do it (to base NBASE^2) */
    9006          30 :             carry = 0;
    9007      119964 :             for (i = res_ndigitpairs - 1; i >= 0; i--)
    9008             :             {
    9009      119934 :                 newdig = dig[i] + carry;
    9010      119934 :                 if (newdig >= NBASE_SQR)
    9011             :                 {
    9012      115242 :                     carry = newdig / NBASE_SQR;
    9013      115242 :                     newdig -= carry * NBASE_SQR;
    9014             :                 }
    9015             :                 else
    9016        4692 :                     carry = 0;
    9017      119934 :                 dig[i] = newdig;
    9018             :             }
    9019             :             Assert(carry == 0);
    9020             :             /* Reset maxdig to indicate new worst-case */
    9021          30 :             maxdig = 1 + var1digitpair;
    9022             :         }
    9023             : 
    9024             :         /* Multiply and add */
    9025      293730 :         i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    9026      293730 :         dig_i1_off = &dig[i1 + pair_offset];
    9027             : 
    9028   124047846 :         for (i2 = 0; i2 < i2limit; i2++)
    9029   123754116 :             dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
    9030             :     }
    9031             : 
    9032             :     /*
    9033             :      * Now we do a final carry propagation pass to normalize back to base
    9034             :      * NBASE^2, and construct the base-NBASE result digits.  Note that this is
    9035             :      * still done at full precision w/guard digits.
    9036             :      */
    9037       28464 :     alloc_var(result, res_ndigits);
    9038       28464 :     res_digits = result->digits;
    9039       28464 :     carry = 0;
    9040     2882922 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9041             :     {
    9042     2854458 :         newdig = dig[i] + carry;
    9043     2854458 :         if (newdig >= NBASE_SQR)
    9044             :         {
    9045      406914 :             carry = newdig / NBASE_SQR;
    9046      406914 :             newdig -= carry * NBASE_SQR;
    9047             :         }
    9048             :         else
    9049     2447544 :             carry = 0;
    9050     2854458 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9051     2854458 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9052             :     }
    9053             :     Assert(carry == 0);
    9054             : 
    9055       28464 :     pfree(dig);
    9056             : 
    9057             :     /*
    9058             :      * Finally, round the result to the requested precision.
    9059             :      */
    9060       28464 :     result->weight = res_weight;
    9061       28464 :     result->sign = res_sign;
    9062             : 
    9063             :     /* Round to target rscale (and set result->dscale) */
    9064       28464 :     round_var(result, rscale);
    9065             : 
    9066             :     /* Strip leading and trailing zeroes */
    9067       28464 :     strip_var(result);
    9068             : }
    9069             : 
    9070             : 
    9071             : /*
    9072             :  * mul_var_short() -
    9073             :  *
    9074             :  *  Special-case multiplication function used when var1 has 1-6 digits, var2
    9075             :  *  has at least as many digits as var1, and the exact product var1 * var2 is
    9076             :  *  requested.
    9077             :  */
    9078             : static void
    9079     1158432 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
    9080             :               NumericVar *result)
    9081             : {
    9082     1158432 :     int         var1ndigits = var1->ndigits;
    9083     1158432 :     int         var2ndigits = var2->ndigits;
    9084     1158432 :     NumericDigit *var1digits = var1->digits;
    9085     1158432 :     NumericDigit *var2digits = var2->digits;
    9086             :     int         res_sign;
    9087             :     int         res_weight;
    9088             :     int         res_ndigits;
    9089             :     NumericDigit *res_buf;
    9090             :     NumericDigit *res_digits;
    9091     1158432 :     uint32      carry = 0;
    9092             :     uint32      term;
    9093             : 
    9094             :     /* Check preconditions */
    9095             :     Assert(var1ndigits >= 1);
    9096             :     Assert(var1ndigits <= 6);
    9097             :     Assert(var2ndigits >= var1ndigits);
    9098             : 
    9099             :     /*
    9100             :      * Determine the result sign, weight, and number of digits to calculate.
    9101             :      * The weight figured here is correct if the product has no leading zero
    9102             :      * digits; otherwise strip_var() will fix things up.  Note that, unlike
    9103             :      * mul_var(), we do not need to allocate an extra output digit, because we
    9104             :      * are not rounding here.
    9105             :      */
    9106     1158432 :     if (var1->sign == var2->sign)
    9107     1157240 :         res_sign = NUMERIC_POS;
    9108             :     else
    9109        1192 :         res_sign = NUMERIC_NEG;
    9110     1158432 :     res_weight = var1->weight + var2->weight + 1;
    9111     1158432 :     res_ndigits = var1ndigits + var2ndigits;
    9112             : 
    9113             :     /* Allocate result digit array */
    9114     1158432 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9115     1158432 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9116     1158432 :     res_digits = res_buf + 1;
    9117             : 
    9118             :     /*
    9119             :      * Compute the result digits in reverse, in one pass, propagating the
    9120             :      * carry up as we go.  The i'th result digit consists of the sum of the
    9121             :      * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
    9122             :      */
    9123             : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
    9124             : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
    9125             : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
    9126             : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
    9127             : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
    9128             : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
    9129             : 
    9130     1158432 :     switch (var1ndigits)
    9131             :     {
    9132     1152726 :         case 1:
    9133             :             /* ---------
    9134             :              * 1-digit case:
    9135             :              *      var1ndigits = 1
    9136             :              *      var2ndigits >= 1
    9137             :              *      res_ndigits = var2ndigits + 1
    9138             :              * ----------
    9139             :              */
    9140     3605246 :             for (int i = var2ndigits - 1; i >= 0; i--)
    9141             :             {
    9142     2452520 :                 term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
    9143     2452520 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9144     2452520 :                 carry = term / NBASE;
    9145             :             }
    9146     1152726 :             res_digits[0] = (NumericDigit) carry;
    9147     1152726 :             break;
    9148             : 
    9149         756 :         case 2:
    9150             :             /* ---------
    9151             :              * 2-digit case:
    9152             :              *      var1ndigits = 2
    9153             :              *      var2ndigits >= 2
    9154             :              *      res_ndigits = var2ndigits + 2
    9155             :              * ----------
    9156             :              */
    9157             :             /* last result digit and carry */
    9158         756 :             term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
    9159         756 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9160         756 :             carry = term / NBASE;
    9161             : 
    9162             :             /* remaining digits, except for the first two */
    9163        2304 :             for (int i = var2ndigits - 1; i >= 1; i--)
    9164             :             {
    9165        1548 :                 term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
    9166        1548 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9167        1548 :                 carry = term / NBASE;
    9168             :             }
    9169         756 :             break;
    9170             : 
    9171         204 :         case 3:
    9172             :             /* ---------
    9173             :              * 3-digit case:
    9174             :              *      var1ndigits = 3
    9175             :              *      var2ndigits >= 3
    9176             :              *      res_ndigits = var2ndigits + 3
    9177             :              * ----------
    9178             :              */
    9179             :             /* last two result digits */
    9180         204 :             term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
    9181         204 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9182         204 :             carry = term / NBASE;
    9183             : 
    9184         204 :             term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9185         204 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9186         204 :             carry = term / NBASE;
    9187             : 
    9188             :             /* remaining digits, except for the first three */
    9189         546 :             for (int i = var2ndigits - 1; i >= 2; i--)
    9190             :             {
    9191         342 :                 term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
    9192         342 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9193         342 :                 carry = term / NBASE;
    9194             :             }
    9195         204 :             break;
    9196             : 
    9197        4038 :         case 4:
    9198             :             /* ---------
    9199             :              * 4-digit case:
    9200             :              *      var1ndigits = 4
    9201             :              *      var2ndigits >= 4
    9202             :              *      res_ndigits = var2ndigits + 4
    9203             :              * ----------
    9204             :              */
    9205             :             /* last three result digits */
    9206        4038 :             term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
    9207        4038 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9208        4038 :             carry = term / NBASE;
    9209             : 
    9210        4038 :             term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9211        4038 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9212        4038 :             carry = term / NBASE;
    9213             : 
    9214        4038 :             term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9215        4038 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9216        4038 :             carry = term / NBASE;
    9217             : 
    9218             :             /* remaining digits, except for the first four */
    9219       11268 :             for (int i = var2ndigits - 1; i >= 3; i--)
    9220             :             {
    9221        7230 :                 term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
    9222        7230 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9223        7230 :                 carry = term / NBASE;
    9224             :             }
    9225        4038 :             break;
    9226             : 
    9227         114 :         case 5:
    9228             :             /* ---------
    9229             :              * 5-digit case:
    9230             :              *      var1ndigits = 5
    9231             :              *      var2ndigits >= 5
    9232             :              *      res_ndigits = var2ndigits + 5
    9233             :              * ----------
    9234             :              */
    9235             :             /* last four result digits */
    9236         114 :             term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
    9237         114 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9238         114 :             carry = term / NBASE;
    9239             : 
    9240         114 :             term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    9241         114 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9242         114 :             carry = term / NBASE;
    9243             : 
    9244         114 :             term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9245         114 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9246         114 :             carry = term / NBASE;
    9247             : 
    9248         114 :             term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9249         114 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    9250         114 :             carry = term / NBASE;
    9251             : 
    9252             :             /* remaining digits, except for the first five */
    9253         300 :             for (int i = var2ndigits - 1; i >= 4; i--)
    9254             :             {
    9255         186 :                 term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
    9256         186 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9257         186 :                 carry = term / NBASE;
    9258             :             }
    9259         114 :             break;
    9260             : 
    9261         594 :         case 6:
    9262             :             /* ---------
    9263             :              * 6-digit case:
    9264             :              *      var1ndigits = 6
    9265             :              *      var2ndigits >= 6
    9266             :              *      res_ndigits = var2ndigits + 6
    9267             :              * ----------
    9268             :              */
    9269             :             /* last five result digits */
    9270         594 :             term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
    9271         594 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9272         594 :             carry = term / NBASE;
    9273             : 
    9274         594 :             term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
    9275         594 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9276         594 :             carry = term / NBASE;
    9277             : 
    9278         594 :             term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    9279         594 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9280         594 :             carry = term / NBASE;
    9281             : 
    9282         594 :             term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9283         594 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    9284         594 :             carry = term / NBASE;
    9285             : 
    9286         594 :             term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9287         594 :             res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
    9288         594 :             carry = term / NBASE;
    9289             : 
    9290             :             /* remaining digits, except for the first six */
    9291        1656 :             for (int i = var2ndigits - 1; i >= 5; i--)
    9292             :             {
    9293        1062 :                 term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
    9294        1062 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9295        1062 :                 carry = term / NBASE;
    9296             :             }
    9297         594 :             break;
    9298             :     }
    9299             : 
    9300             :     /*
    9301             :      * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
    9302             :      * significant result digits.
    9303             :      */
    9304     1158432 :     switch (var1ndigits)
    9305             :     {
    9306         594 :         case 6:
    9307         594 :             term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
    9308         594 :             res_digits[5] = (NumericDigit) (term % NBASE);
    9309         594 :             carry = term / NBASE;
    9310             :             /* FALLTHROUGH */
    9311         708 :         case 5:
    9312         708 :             term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
    9313         708 :             res_digits[4] = (NumericDigit) (term % NBASE);
    9314         708 :             carry = term / NBASE;
    9315             :             /* FALLTHROUGH */
    9316        4746 :         case 4:
    9317        4746 :             term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
    9318        4746 :             res_digits[3] = (NumericDigit) (term % NBASE);
    9319        4746 :             carry = term / NBASE;
    9320             :             /* FALLTHROUGH */
    9321        4950 :         case 3:
    9322        4950 :             term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
    9323        4950 :             res_digits[2] = (NumericDigit) (term % NBASE);
    9324        4950 :             carry = term / NBASE;
    9325             :             /* FALLTHROUGH */
    9326        5706 :         case 2:
    9327        5706 :             term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
    9328        5706 :             res_digits[1] = (NumericDigit) (term % NBASE);
    9329        5706 :             res_digits[0] = (NumericDigit) (term / NBASE);
    9330        5706 :             break;
    9331             :     }
    9332             : 
    9333             :     /* Store the product in result */
    9334     1158432 :     digitbuf_free(result->buf);
    9335     1158432 :     result->ndigits = res_ndigits;
    9336     1158432 :     result->buf = res_buf;
    9337     1158432 :     result->digits = res_digits;
    9338     1158432 :     result->weight = res_weight;
    9339     1158432 :     result->sign = res_sign;
    9340     1158432 :     result->dscale = var1->dscale + var2->dscale;
    9341             : 
    9342             :     /* Strip leading and trailing zeroes */
    9343     1158432 :     strip_var(result);
    9344     1158432 : }
    9345             : 
    9346             : 
    9347             : /*
    9348             :  * div_var() -
    9349             :  *
    9350             :  *  Compute the quotient var1 / var2 to rscale fractional digits.
    9351             :  *
    9352             :  *  If "round" is true, the result is rounded at the rscale'th digit; if
    9353             :  *  false, it is truncated (towards zero) at that digit.
    9354             :  *
    9355             :  *  If "exact" is true, the exact result is computed to the specified rscale;
    9356             :  *  if false, successive quotient digits are approximated up to rscale plus
    9357             :  *  DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
    9358             :  *  the right of that, before rounding or truncating to the specified rscale.
    9359             :  *  This can be significantly faster, and usually gives the same result as the
    9360             :  *  exact computation, but it may occasionally be off by one in the final
    9361             :  *  digit, if contributions from the ignored digits would have propagated
    9362             :  *  through the guard digits.  This is good enough for the transcendental
    9363             :  *  functions, where small errors are acceptable.
    9364             :  */
    9365             : static void
    9366      571208 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    9367             :         int rscale, bool round, bool exact)
    9368             : {
    9369      571208 :     int         var1ndigits = var1->ndigits;
    9370      571208 :     int         var2ndigits = var2->ndigits;
    9371             :     int         res_sign;
    9372             :     int         res_weight;
    9373             :     int         res_ndigits;
    9374             :     int         var1ndigitpairs;
    9375             :     int         var2ndigitpairs;
    9376             :     int         res_ndigitpairs;
    9377             :     int         div_ndigitpairs;
    9378             :     int64      *dividend;
    9379             :     int32      *divisor;
    9380             :     double      fdivisor,
    9381             :                 fdivisorinverse,
    9382             :                 fdividend,
    9383             :                 fquotient;
    9384             :     int64       maxdiv;
    9385             :     int         qi;
    9386             :     int32       qdigit;
    9387             :     int64       carry;
    9388             :     int64       newdig;
    9389             :     int64      *remainder;
    9390             :     NumericDigit *res_digits;
    9391             :     int         i;
    9392             : 
    9393             :     /*
    9394             :      * First of all division by zero check; we must not be handed an
    9395             :      * unnormalized divisor.
    9396             :      */
    9397      571208 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    9398          62 :         ereport(ERROR,
    9399             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    9400             :                  errmsg("division by zero")));
    9401             : 
    9402             :     /*
    9403             :      * If the divisor has just one or two digits, delegate to div_var_int(),
    9404             :      * which uses fast short division.
    9405             :      *
    9406             :      * Similarly, on platforms with 128-bit integer support, delegate to
    9407             :      * div_var_int64() for divisors with three or four digits.
    9408             :      */
    9409      571146 :     if (var2ndigits <= 2)
    9410             :     {
    9411             :         int         idivisor;
    9412             :         int         idivisor_weight;
    9413             : 
    9414      565140 :         idivisor = var2->digits[0];
    9415      565140 :         idivisor_weight = var2->weight;
    9416      565140 :         if (var2ndigits == 2)
    9417             :         {
    9418        3920 :             idivisor = idivisor * NBASE + var2->digits[1];
    9419        3920 :             idivisor_weight--;
    9420             :         }
    9421      565140 :         if (var2->sign == NUMERIC_NEG)
    9422         654 :             idivisor = -idivisor;
    9423             : 
    9424      565140 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    9425      565140 :         return;
    9426             :     }
    9427             : #ifdef HAVE_INT128
    9428        6006 :     if (var2ndigits <= 4)
    9429             :     {
    9430             :         int64       idivisor;
    9431             :         int         idivisor_weight;
    9432             : 
    9433         528 :         idivisor = var2->digits[0];
    9434         528 :         idivisor_weight = var2->weight;
    9435        1968 :         for (i = 1; i < var2ndigits; i++)
    9436             :         {
    9437        1440 :             idivisor = idivisor * NBASE + var2->digits[i];
    9438        1440 :             idivisor_weight--;
    9439             :         }
    9440         528 :         if (var2->sign == NUMERIC_NEG)
    9441         120 :             idivisor = -idivisor;
    9442             : 
    9443         528 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    9444         528 :         return;
    9445             :     }
    9446             : #endif
    9447             : 
    9448             :     /*
    9449             :      * Otherwise, perform full long division.
    9450             :      */
    9451             : 
    9452             :     /* Result zero check */
    9453        5478 :     if (var1ndigits == 0)
    9454             :     {
    9455          36 :         zero_var(result);
    9456          36 :         result->dscale = rscale;
    9457          36 :         return;
    9458             :     }
    9459             : 
    9460             :     /*
    9461             :      * The approximate computation can be significantly faster than the exact
    9462             :      * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
    9463             :      * shorter below.  However, that comes with the tradeoff of computing
    9464             :      * DIV_GUARD_DIGITS extra base-NBASE result digits.  Ignoring all other
    9465             :      * overheads, that suggests that, in theory, the approximate computation
    9466             :      * will only be faster than the exact one when var2ndigits is greater than
    9467             :      * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
    9468             :      *
    9469             :      * Thus, we're better off doing an exact computation when var2 is shorter
    9470             :      * than this.  Empirically, it has been found that the exact threshold is
    9471             :      * a little higher, due to other overheads in the outer division loop.
    9472             :      */
    9473        5442 :     if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
    9474        3708 :         exact = true;
    9475             : 
    9476             :     /*
    9477             :      * Determine the result sign, weight and number of digits to calculate.
    9478             :      * The weight figured here is correct if the emitted quotient has no
    9479             :      * leading zero digits; otherwise strip_var() will fix things up.
    9480             :      */
    9481        5442 :     if (var1->sign == var2->sign)
    9482        5310 :         res_sign = NUMERIC_POS;
    9483             :     else
    9484         132 :         res_sign = NUMERIC_NEG;
    9485        5442 :     res_weight = var1->weight - var2->weight + 1;
    9486             :     /* The number of accurate result digits we need to produce: */
    9487        5442 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9488             :     /* ... but always at least 1 */
    9489        5442 :     res_ndigits = Max(res_ndigits, 1);
    9490             :     /* If rounding needed, figure one more digit to ensure correct result */
    9491        5442 :     if (round)
    9492         906 :         res_ndigits++;
    9493             :     /* Add guard digits for roundoff error when producing approx result */
    9494        5442 :     if (!exact)
    9495        1722 :         res_ndigits += DIV_GUARD_DIGITS;
    9496             : 
    9497             :     /*
    9498             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    9499             :      * actually process the input digits in pairs, producing a base-NBASE^2
    9500             :      * intermediate result.  This significantly improves performance, since
    9501             :      * the computation is O(N^2) in the number of input digits, and working in
    9502             :      * base NBASE^2 effectively halves "N".
    9503             :      */
    9504        5442 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    9505        5442 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    9506        5442 :     res_ndigitpairs = (res_ndigits + 1) / 2;
    9507        5442 :     res_ndigits = 2 * res_ndigitpairs;
    9508             : 
    9509             :     /*
    9510             :      * We do the arithmetic in an array "dividend[]" of signed 64-bit
    9511             :      * integers.  Since PG_INT64_MAX is much larger than NBASE^4, this gives
    9512             :      * us a lot of headroom to avoid normalizing carries immediately.
    9513             :      *
    9514             :      * When performing an exact computation, the working dividend requires
    9515             :      * res_ndigitpairs + var2ndigitpairs digits.  If var1 is larger than that,
    9516             :      * the extra digits do not contribute to the result, and are ignored.
    9517             :      *
    9518             :      * When performing an approximate computation, the working dividend only
    9519             :      * requires res_ndigitpairs digits (which includes the extra guard
    9520             :      * digits).  All input digits beyond that are ignored.
    9521             :      */
    9522        5442 :     if (exact)
    9523             :     {
    9524        3720 :         div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
    9525        3720 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9526             :     }
    9527             :     else
    9528             :     {
    9529        1722 :         div_ndigitpairs = res_ndigitpairs;
    9530        1722 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9531        1722 :         var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
    9532             :     }
    9533             : 
    9534             :     /*
    9535             :      * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
    9536             :      * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
    9537             :      *
    9538             :      * For convenience, we allocate one extra dividend digit, which is set to
    9539             :      * zero and not counted in div_ndigitpairs, so that the main loop below
    9540             :      * can safely read and write the (qi+1)'th digit in the approximate case.
    9541             :      */
    9542        5442 :     dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
    9543             :                                 var2ndigitpairs * sizeof(int32));
    9544        5442 :     divisor = (int32 *) (dividend + div_ndigitpairs + 1);
    9545             : 
    9546             :     /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
    9547       49458 :     for (i = 0; i < var1ndigitpairs - 1; i++)
    9548       44016 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9549             : 
    9550        5442 :     if (2 * i + 1 < var1ndigits)
    9551        3282 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9552             :     else
    9553        2160 :         dividend[i] = var1->digits[2 * i] * NBASE;
    9554             : 
    9555        5442 :     memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
    9556             : 
    9557             :     /* load var2 into divisor[0 .. var2ndigitpairs-1] */
    9558       39840 :     for (i = 0; i < var2ndigitpairs - 1; i++)
    9559       34398 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9560             : 
    9561        5442 :     if (2 * i + 1 < var2ndigits)
    9562        2922 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9563             :     else
    9564        2520 :         divisor[i] = var2->digits[2 * i] * NBASE;
    9565             : 
    9566             :     /*
    9567             :      * We estimate each quotient digit using floating-point arithmetic, taking
    9568             :      * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
    9569             :      * This must be float to avoid overflow.
    9570             :      *
    9571             :      * Since the floating-point dividend and divisor use 4 base-NBASE input
    9572             :      * digits, they include roughly 40-53 bits of information from their
    9573             :      * respective inputs (assuming NBASE is 10000), which fits well in IEEE
    9574             :      * double-precision variables.  The relative error in the floating-point
    9575             :      * quotient digit will then be less than around 2/NBASE^3, so the
    9576             :      * estimated base-NBASE^2 quotient digit will typically be correct, and
    9577             :      * should not be off by more than one from the correct value.
    9578             :      */
    9579        5442 :     fdivisor = (double) divisor[0] * NBASE_SQR;
    9580        5442 :     if (var2ndigitpairs > 1)
    9581        5442 :         fdivisor += (double) divisor[1];
    9582        5442 :     fdivisorinverse = 1.0 / fdivisor;
    9583             : 
    9584             :     /*
    9585             :      * maxdiv tracks the maximum possible absolute value of any dividend[]
    9586             :      * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
    9587             :      * propagate carries.  Furthermore, we need to ensure that overflow
    9588             :      * doesn't occur during the carry propagation passes either.  The carry
    9589             :      * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
    9590             :      * so really we must normalize when digits threaten to exceed PG_INT64_MAX
    9591             :      * - PG_INT64_MAX/NBASE^2 - 1.
    9592             :      *
    9593             :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9594             :      * value divided by NBASE^2-1, i.e., at the top of the loop it is known
    9595             :      * that no dividend[] entry has an absolute value exceeding maxdiv *
    9596             :      * (NBASE^2-1).
    9597             :      *
    9598             :      * Actually, though, that holds good only for dividend[] entries after
    9599             :      * dividend[qi]; the adjustment done at the bottom of the loop may cause
    9600             :      * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
    9601             :      * the next iteration is beyond the limit.  This does not cause problems,
    9602             :      * as explained below.
    9603             :      */
    9604        5442 :     maxdiv = 1;
    9605             : 
    9606             :     /*
    9607             :      * Outer loop computes next quotient digit, which goes in dividend[qi].
    9608             :      */
    9609       49542 :     for (qi = 0; qi < res_ndigitpairs; qi++)
    9610             :     {
    9611             :         /* Approximate the current dividend value */
    9612       44100 :         fdividend = (double) dividend[qi] * NBASE_SQR;
    9613       44100 :         fdividend += (double) dividend[qi + 1];
    9614             : 
    9615             :         /* Compute the (approximate) quotient digit */
    9616       44100 :         fquotient = fdividend * fdivisorinverse;
    9617       44100 :         qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9618           6 :             (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9619             : 
    9620       44100 :         if (qdigit != 0)
    9621             :         {
    9622             :             /* Do we need to normalize now? */
    9623       40506 :             maxdiv += i64abs(qdigit);
    9624       40506 :             if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
    9625             :             {
    9626             :                 /*
    9627             :                  * Yes, do it.  Note that if var2ndigitpairs is much smaller
    9628             :                  * than div_ndigitpairs, we can save a significant amount of
    9629             :                  * effort here by noting that we only need to normalise those
    9630             :                  * dividend[] entries touched where prior iterations
    9631             :                  * subtracted multiples of the divisor.
    9632             :                  */
    9633           6 :                 carry = 0;
    9634        6750 :                 for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
    9635             :                 {
    9636        6744 :                     newdig = dividend[i] + carry;
    9637        6744 :                     if (newdig < 0)
    9638             :                     {
    9639        6744 :                         carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9640        6744 :                         newdig -= carry * NBASE_SQR;
    9641             :                     }
    9642           0 :                     else if (newdig >= NBASE_SQR)
    9643             :                     {
    9644           0 :                         carry = newdig / NBASE_SQR;
    9645           0 :                         newdig -= carry * NBASE_SQR;
    9646             :                     }
    9647             :                     else
    9648           0 :                         carry = 0;
    9649        6744 :                     dividend[i] = newdig;
    9650             :                 }
    9651           6 :                 dividend[qi] += carry;
    9652             : 
    9653             :                 /*
    9654             :                  * All the dividend[] digits except possibly dividend[qi] are
    9655             :                  * now in the range 0..NBASE^2-1.  We do not need to consider
    9656             :                  * dividend[qi] in the maxdiv value anymore, so we can reset
    9657             :                  * maxdiv to 1.
    9658             :                  */
    9659           6 :                 maxdiv = 1;
    9660             : 
    9661             :                 /*
    9662             :                  * Recompute the quotient digit since new info may have
    9663             :                  * propagated into the top two dividend digits.
    9664             :                  */
    9665           6 :                 fdividend = (double) dividend[qi] * NBASE_SQR;
    9666           6 :                 fdividend += (double) dividend[qi + 1];
    9667           6 :                 fquotient = fdividend * fdivisorinverse;
    9668           6 :                 qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9669           0 :                     (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9670             : 
    9671           6 :                 maxdiv += i64abs(qdigit);
    9672             :             }
    9673             : 
    9674             :             /*
    9675             :              * Subtract off the appropriate multiple of the divisor.
    9676             :              *
    9677             :              * The digits beyond dividend[qi] cannot overflow, because we know
    9678             :              * they will fall within the maxdiv limit.  As for dividend[qi]
    9679             :              * itself, note that qdigit is approximately trunc(dividend[qi] /
    9680             :              * divisor[0]), which would make the new value simply dividend[qi]
    9681             :              * mod divisor[0].  The lower-order terms in qdigit can change
    9682             :              * this result by not more than about twice PG_INT64_MAX/NBASE^2,
    9683             :              * so overflow is impossible.
    9684             :              *
    9685             :              * This inner loop is the performance bottleneck for division, so
    9686             :              * code it in the same way as the inner loop of mul_var() so that
    9687             :              * it can be auto-vectorized.
    9688             :              */
    9689       40506 :             if (qdigit != 0)
    9690             :             {
    9691       40506 :                 int         istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
    9692       40506 :                 int64      *dividend_qi = &dividend[qi];
    9693             : 
    9694     7861254 :                 for (i = 0; i < istop; i++)
    9695     7820748 :                     dividend_qi[i] -= (int64) qdigit * divisor[i];
    9696             :             }
    9697             :         }
    9698             : 
    9699             :         /*
    9700             :          * The dividend digit we are about to replace might still be nonzero.
    9701             :          * Fold it into the next digit position.
    9702             :          *
    9703             :          * There is no risk of overflow here, although proving that requires
    9704             :          * some care.  Much as with the argument for dividend[qi] not
    9705             :          * overflowing, if we consider the first two terms in the numerator
    9706             :          * and denominator of qdigit, we can see that the final value of
    9707             :          * dividend[qi + 1] will be approximately a remainder mod
    9708             :          * (divisor[0]*NBASE^2 + divisor[1]).  Accounting for the lower-order
    9709             :          * terms is a bit complicated but ends up adding not much more than
    9710             :          * PG_INT64_MAX/NBASE^2 to the possible range.  Thus, dividend[qi + 1]
    9711             :          * cannot overflow here, and in its role as dividend[qi] in the next
    9712             :          * loop iteration, it can't be large enough to cause overflow in the
    9713             :          * carry propagation step (if any), either.
    9714             :          *
    9715             :          * But having said that: dividend[qi] can be more than
    9716             :          * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
    9717             :          * dividend[qi] * NBASE^2 *can* overflow.  When that happens, adding
    9718             :          * it to dividend[qi + 1] will always cause a canceling overflow so
    9719             :          * that the end result is correct.  We could avoid the intermediate
    9720             :          * overflow by doing the multiplication and addition using unsigned
    9721             :          * int64 arithmetic, which is modulo 2^64, but so far there appears no
    9722             :          * need.
    9723             :          */
    9724       44100 :         dividend[qi + 1] += dividend[qi] * NBASE_SQR;
    9725             : 
    9726       44100 :         dividend[qi] = qdigit;
    9727             :     }
    9728             : 
    9729             :     /*
    9730             :      * If an exact result was requested, use the remainder to correct the
    9731             :      * approximate quotient.  The remainder is in dividend[], immediately
    9732             :      * after the quotient digits.  Note, however, that although the remainder
    9733             :      * starts at dividend[qi = res_ndigitpairs], the first digit is the result
    9734             :      * of folding two remainder digits into one above, and the remainder
    9735             :      * currently only occupies var2ndigitpairs - 1 digits (the last digit of
    9736             :      * the working dividend was untouched by the computation above).  Thus we
    9737             :      * expand the remainder down by one base-NBASE^2 digit when we normalize
    9738             :      * it, so that it completely fills the last var2ndigitpairs digits of the
    9739             :      * dividend array.
    9740             :      */
    9741        5442 :     if (exact)
    9742             :     {
    9743             :         /* Normalize the remainder, expanding it down by one digit */
    9744        3720 :         remainder = &dividend[qi];
    9745        3720 :         carry = 0;
    9746       20214 :         for (i = var2ndigitpairs - 2; i >= 0; i--)
    9747             :         {
    9748       16494 :             newdig = remainder[i] + carry;
    9749       16494 :             if (newdig < 0)
    9750             :             {
    9751       12732 :                 carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9752       12732 :                 newdig -= carry * NBASE_SQR;
    9753             :             }
    9754        3762 :             else if (newdig >= NBASE_SQR)
    9755             :             {
    9756        3684 :                 carry = newdig / NBASE_SQR;
    9757        3684 :                 newdig -= carry * NBASE_SQR;
    9758             :             }
    9759             :             else
    9760          78 :                 carry = 0;
    9761       16494 :             remainder[i + 1] = newdig;
    9762             :         }
    9763        3720 :         remainder[0] = carry;
    9764             : 
    9765        3720 :         if (remainder[0] < 0)
    9766             :         {
    9767             :             /*
    9768             :              * The remainder is negative, so the approximate quotient is too
    9769             :              * large.  Correct by reducing the quotient by one and adding the
    9770             :              * divisor to the remainder until the remainder is positive.  We
    9771             :              * expect the quotient to be off by at most one, which has been
    9772             :              * borne out in all testing, but not conclusively proven, so we
    9773             :              * allow for larger corrections, just in case.
    9774             :              */
    9775             :             do
    9776             :             {
    9777             :                 /* Add the divisor to the remainder */
    9778           6 :                 carry = 0;
    9779          78 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9780             :                 {
    9781          72 :                     newdig = remainder[i] + divisor[i] + carry;
    9782          72 :                     if (newdig >= NBASE_SQR)
    9783             :                     {
    9784           0 :                         remainder[i] = newdig - NBASE_SQR;
    9785           0 :                         carry = 1;
    9786             :                     }
    9787             :                     else
    9788             :                     {
    9789          72 :                         remainder[i] = newdig;
    9790          72 :                         carry = 0;
    9791             :                     }
    9792             :                 }
    9793           6 :                 remainder[0] += divisor[0] + carry;
    9794             : 
    9795             :                 /* Subtract 1 from the quotient (propagating carries later) */
    9796           6 :                 dividend[qi - 1]--;
    9797             : 
    9798           6 :             } while (remainder[0] < 0);
    9799             :         }
    9800             :         else
    9801             :         {
    9802             :             /*
    9803             :              * The remainder is nonnegative.  If it's greater than or equal to
    9804             :              * the divisor, then the approximate quotient is too small and
    9805             :              * must be corrected.  As above, we don't expect to have to apply
    9806             :              * more than one correction, but allow for it just in case.
    9807             :              */
    9808             :             while (true)
    9809           6 :             {
    9810        3720 :                 bool        less = false;
    9811             : 
    9812             :                 /* Is remainder < divisor? */
    9813        3738 :                 for (i = 0; i < var2ndigitpairs; i++)
    9814             :                 {
    9815        3732 :                     if (remainder[i] < divisor[i])
    9816             :                     {
    9817        3714 :                         less = true;
    9818        3714 :                         break;
    9819             :                     }
    9820          18 :                     if (remainder[i] > divisor[i])
    9821           0 :                         break;  /* remainder > divisor */
    9822             :                 }
    9823        3720 :                 if (less)
    9824        3714 :                     break;      /* quotient is correct */
    9825             : 
    9826             :                 /* Subtract the divisor from the remainder */
    9827           6 :                 carry = 0;
    9828          18 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9829             :                 {
    9830          12 :                     newdig = remainder[i] - divisor[i] + carry;
    9831          12 :                     if (newdig < 0)
    9832             :                     {
    9833           0 :                         remainder[i] = newdig + NBASE_SQR;
    9834           0 :                         carry = -1;
    9835             :                     }
    9836             :                     else
    9837             :                     {
    9838          12 :                         remainder[i] = newdig;
    9839          12 :                         carry = 0;
    9840             :                     }
    9841             :                 }
    9842           6 :                 remainder[0] = remainder[0] - divisor[0] + carry;
    9843             : 
    9844             :                 /* Add 1 to the quotient (propagating carries later) */
    9845           6 :                 dividend[qi - 1]++;
    9846             :             }
    9847             :         }
    9848             :     }
    9849             : 
    9850             :     /*
    9851             :      * Because the quotient digits were estimates that might have been off by
    9852             :      * one (and we didn't bother propagating carries when adjusting the
    9853             :      * quotient above), some quotient digits might be out of range, so do a
    9854             :      * final carry propagation pass to normalize back to base NBASE^2, and
    9855             :      * construct the base-NBASE result digits.  Note that this is still done
    9856             :      * at full precision w/guard digits.
    9857             :      */
    9858        5442 :     alloc_var(result, res_ndigits);
    9859        5442 :     res_digits = result->digits;
    9860        5442 :     carry = 0;
    9861       49542 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9862             :     {
    9863       44100 :         newdig = dividend[i] + carry;
    9864       44100 :         if (newdig < 0)
    9865             :         {
    9866           6 :             carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9867           6 :             newdig -= carry * NBASE_SQR;
    9868             :         }
    9869       44094 :         else if (newdig >= NBASE_SQR)
    9870             :         {
    9871           0 :             carry = newdig / NBASE_SQR;
    9872           0 :             newdig -= carry * NBASE_SQR;
    9873             :         }
    9874             :         else
    9875       44094 :             carry = 0;
    9876       44100 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9877       44100 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9878             :     }
    9879             :     Assert(carry == 0);
    9880             : 
    9881        5442 :     pfree(dividend);
    9882             : 
    9883             :     /*
    9884             :      * Finally, round or truncate the result to the requested precision.
    9885             :      */
    9886        5442 :     result->weight = res_weight;
    9887        5442 :     result->sign = res_sign;
    9888             : 
    9889             :     /* Round or truncate to target rscale (and set result->dscale) */
    9890        5442 :     if (round)
    9891         906 :         round_var(result, rscale);
    9892             :     else
    9893        4536 :         trunc_var(result, rscale);
    9894             : 
    9895             :     /* Strip leading and trailing zeroes */
    9896        5442 :     strip_var(result);
    9897             : }
    9898             : 
    9899             : 
    9900             : /*
    9901             :  * div_var_int() -
    9902             :  *
    9903             :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9904             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9905             :  */
    9906             : static void
    9907      584298 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9908             :             NumericVar *result, int rscale, bool round)
    9909             : {
    9910      584298 :     NumericDigit *var_digits = var->digits;
    9911      584298 :     int         var_ndigits = var->ndigits;
    9912             :     int         res_sign;
    9913             :     int         res_weight;
    9914             :     int         res_ndigits;
    9915             :     NumericDigit *res_buf;
    9916             :     NumericDigit *res_digits;
    9917             :     uint32      divisor;
    9918             :     int         i;
    9919             : 
    9920             :     /* Guard against division by zero */
    9921      584298 :     if (ival == 0)
    9922           0 :         ereport(ERROR,
    9923             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9924             :                 errmsg("division by zero"));
    9925             : 
    9926             :     /* Result zero check */
    9927      584298 :     if (var_ndigits == 0)
    9928             :     {
    9929        2300 :         zero_var(result);
    9930        2300 :         result->dscale = rscale;
    9931        2300 :         return;
    9932             :     }
    9933             : 
    9934             :     /*
    9935             :      * Determine the result sign, weight and number of digits to calculate.
    9936             :      * The weight figured here is correct if the emitted quotient has no
    9937             :      * leading zero digits; otherwise strip_var() will fix things up.
    9938             :      */
    9939      581998 :     if (var->sign == NUMERIC_POS)
    9940      579010 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9941             :     else
    9942        2988 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9943      581998 :     res_weight = var->weight - ival_weight;
    9944             :     /* The number of accurate result digits we need to produce: */
    9945      581998 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9946             :     /* ... but always at least 1 */
    9947      581998 :     res_ndigits = Max(res_ndigits, 1);
    9948             :     /* If rounding needed, figure one more digit to ensure correct result */
    9949      581998 :     if (round)
    9950      166688 :         res_ndigits++;
    9951             : 
    9952      581998 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9953      581998 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9954      581998 :     res_digits = res_buf + 1;
    9955             : 
    9956             :     /*
    9957             :      * Now compute the quotient digits.  This is the short division algorithm
    9958             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9959             :      * allow the divisor to exceed the internal base.
    9960             :      *
    9961             :      * In this algorithm, the carry from one digit to the next is at most
    9962             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9963             :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9964             :      * integer if this exceeds UINT_MAX.
    9965             :      */
    9966      581998 :     divisor = abs(ival);
    9967             : 
    9968      581998 :     if (divisor <= UINT_MAX / NBASE)
    9969             :     {
    9970             :         /* carry cannot overflow 32 bits */
    9971      578678 :         uint32      carry = 0;
    9972             : 
    9973     2844906 :         for (i = 0; i < res_ndigits; i++)
    9974             :         {
    9975     2266228 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9976     2266228 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9977     2266228 :             carry = carry % divisor;
    9978             :         }
    9979             :     }
    9980             :     else
    9981             :     {
    9982             :         /* carry may exceed 32 bits */
    9983        3320 :         uint64      carry = 0;
    9984             : 
    9985       10626 :         for (i = 0; i < res_ndigits; i++)
    9986             :         {
    9987        7306 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9988        7306 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9989        7306 :             carry = carry % divisor;
    9990             :         }
    9991             :     }
    9992             : 
    9993             :     /* Store the quotient in result */
    9994      581998 :     digitbuf_free(result->buf);
    9995      581998 :     result->ndigits = res_ndigits;
    9996      581998 :     result->buf = res_buf;
    9997      581998 :     result->digits = res_digits;
    9998      581998 :     result->weight = res_weight;
    9999      581998 :     result->sign = res_sign;
   10000             : 
   10001             :     /* Round or truncate to target rscale (and set result->dscale) */
   10002      581998 :     if (round)
   10003      166688 :         round_var(result, rscale);
   10004             :     else
   10005      415310 :         trunc_var(result, rscale);
   10006             : 
   10007             :     /* Strip leading/trailing zeroes */
   10008      581998 :     strip_var(result);
   10009             : }
   10010             : 
   10011             : 
   10012             : #ifdef HAVE_INT128
   10013             : /*
   10014             :  * div_var_int64() -
   10015             :  *
   10016             :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
   10017             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
   10018             :  *
   10019             :  *  This duplicates the logic in div_var_int(), so any changes made there
   10020             :  *  should be made here too.
   10021             :  */
   10022             : static void
   10023         528 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
   10024             :               NumericVar *result, int rscale, bool round)
   10025             : {
   10026         528 :     NumericDigit *var_digits = var->digits;
   10027         528 :     int         var_ndigits = var->ndigits;
   10028             :     int         res_sign;
   10029             :     int         res_weight;
   10030             :     int         res_ndigits;
   10031             :     NumericDigit *res_buf;
   10032             :     NumericDigit *res_digits;
   10033             :     uint64      divisor;
   10034             :     int         i;
   10035             : 
   10036             :     /* Guard against division by zero */
   10037         528 :     if (ival == 0)
   10038           0 :         ereport(ERROR,
   10039             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
   10040             :                 errmsg("division by zero"));
   10041             : 
   10042             :     /* Result zero check */
   10043         528 :     if (var_ndigits == 0)
   10044             :     {
   10045          96 :         zero_var(result);
   10046          96 :         result->dscale = rscale;
   10047          96 :         return;
   10048             :     }
   10049             : 
   10050             :     /*
   10051             :      * Determine the result sign, weight and number of digits to calculate.
   10052             :      * The weight figured here is correct if the emitted quotient has no
   10053             :      * leading zero digits; otherwise strip_var() will fix things up.
   10054             :      */
   10055         432 :     if (var->sign == NUMERIC_POS)
   10056         258 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
   10057             :     else
   10058         174 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
   10059         432 :     res_weight = var->weight - ival_weight;
   10060             :     /* The number of accurate result digits we need to produce: */
   10061         432 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   10062             :     /* ... but always at least 1 */
   10063         432 :     res_ndigits = Max(res_ndigits, 1);
   10064             :     /* If rounding needed, figure one more digit to ensure correct result */
   10065         432 :     if (round)
   10066         426 :         res_ndigits++;
   10067             : 
   10068         432 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   10069         432 :     res_buf[0] = 0;             /* spare digit for later rounding */
   10070         432 :     res_digits = res_buf + 1;
   10071             : 
   10072             :     /*
   10073             :      * Now compute the quotient digits.  This is the short division algorithm
   10074             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
   10075             :      * allow the divisor to exceed the internal base.
   10076             :      *
   10077             :      * In this algorithm, the carry from one digit to the next is at most
   10078             :      * divisor - 1.  Therefore, while processing the next digit, carry may
   10079             :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
   10080             :      * integer if this exceeds PG_UINT64_MAX.
   10081             :      */
   10082         432 :     divisor = i64abs(ival);
   10083             : 
   10084         432 :     if (divisor <= PG_UINT64_MAX / NBASE)
   10085             :     {
   10086             :         /* carry cannot overflow 64 bits */
   10087         336 :         uint64      carry = 0;
   10088             : 
   10089        3414 :         for (i = 0; i < res_ndigits; i++)
   10090             :         {
   10091        3078 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
   10092        3078 :             res_digits[i] = (NumericDigit) (carry / divisor);
   10093        3078 :             carry = carry % divisor;
   10094             :         }
   10095             :     }
   10096             :     else
   10097             :     {
   10098             :         /* carry may exceed 64 bits */
   10099          96 :         uint128     carry = 0;
   10100             : 
   10101        1032 :         for (i = 0; i < res_ndigits; i++)
   10102             :         {
   10103         936 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
   10104         936 :             res_digits[i] = (NumericDigit) (carry / divisor);
   10105         936 :             carry = carry % divisor;
   10106             :         }
   10107             :     }
   10108             : 
   10109             :     /* Store the quotient in result */
   10110         432 :     digitbuf_free(result->buf);
   10111         432 :     result->ndigits = res_ndigits;
   10112         432 :     result->buf = res_buf;
   10113         432 :     result->digits = res_digits;
   10114         432 :     result->weight = res_weight;
   10115         432 :     result->sign = res_sign;
   10116             : 
   10117             :     /* Round or truncate to target rscale (and set result->dscale) */
   10118         432 :     if (round)
   10119         426 :         round_var(result, rscale);
   10120             :     else
   10121           6 :         trunc_var(result, rscale);
   10122             : 
   10123             :     /* Strip leading/trailing zeroes */
   10124         432 :     strip_var(result);
   10125             : }
   10126             : #endif
   10127             : 
   10128             : 
   10129             : /*
   10130             :  * Default scale selection for division
   10131             :  *
   10132             :  * Returns the appropriate result scale for the division result.
   10133             :  */
   10134             : static int
   10135      149622 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
   10136             : {
   10137             :     int         weight1,
   10138             :                 weight2,
   10139             :                 qweight,
   10140             :                 i;
   10141             :     NumericDigit firstdigit1,
   10142             :                 firstdigit2;
   10143             :     int         rscale;
   10144             : 
   10145             :     /*
   10146             :      * The result scale of a division isn't specified in any SQL standard. For
   10147             :      * PostgreSQL we select a result scale that will give at least
   10148             :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
   10149             :      * result no less accurate than float8; but use a scale not less than
   10150             :      * either input's display scale.
   10151             :      */
   10152             : 
   10153             :     /* Get the actual (normalized) weight and first digit of each input */
   10154             : 
   10155      149622 :     weight1 = 0;                /* values to use if var1 is zero */
   10156      149622 :     firstdigit1 = 0;
   10157      149622 :     for (i = 0; i < var1->ndigits; i++)
   10158             :     {
   10159      147922 :         firstdigit1 = var1->digits[i];
   10160      147922 :         if (firstdigit1 != 0)
   10161             :         {
   10162      147922 :             weight1 = var1->weight - i;
   10163      147922 :             break;
   10164             :         }
   10165             :     }
   10166             : 
   10167      149622 :     weight2 = 0;                /* values to use if var2 is zero */
   10168      149622 :     firstdigit2 = 0;
   10169      149622 :     for (i = 0; i < var2->ndigits; i++)
   10170             :     {
   10171      149572 :         firstdigit2 = var2->digits[i];
   10172      149572 :         if (firstdigit2 != 0)
   10173             :         {
   10174      149572 :             weight2 = var2->weight - i;
   10175      149572 :             break;
   10176             :         }
   10177             :     }
   10178             : 
   10179             :     /*
   10180             :      * Estimate weight of quotient.  If the two first digits are equal, we
   10181             :      * can't be sure, but assume that var1 is less than var2.
   10182             :      */
   10183      149622 :     qweight = weight1 - weight2;
   10184      149622 :     if (firstdigit1 <= firstdigit2)
   10185      132774 :         qweight--;
   10186             : 
   10187             :     /* Select result scale */
   10188      149622 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
   10189      149622 :     rscale = Max(rscale, var1->dscale);
   10190      149622 :     rscale = Max(rscale, var2->dscale);
   10191      149622 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10192      149622 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10193             : 
   10194      149622 :     return rscale;
   10195             : }
   10196             : 
   10197             : 
   10198             : /*
   10199             :  * mod_var() -
   10200             :  *
   10201             :  *  Calculate the modulo of two numerics at variable level
   10202             :  */
   10203             : static void
   10204      413786 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   10205             : {
   10206             :     NumericVar  tmp;
   10207             : 
   10208      413786 :     init_var(&tmp);
   10209             : 
   10210             :     /* ---------
   10211             :      * We do this using the equation
   10212             :      *      mod(x,y) = x - trunc(x/y)*y
   10213             :      * div_var can be persuaded to give us trunc(x/y) directly.
   10214             :      * ----------
   10215             :      */
   10216      413786 :     div_var(var1, var2, &tmp, 0, false, true);
   10217             : 
   10218      413774 :     mul_var(var2, &tmp, &tmp, var2->dscale);
   10219             : 
   10220      413774 :     sub_var(var1, &tmp, result);
   10221             : 
   10222      413774 :     free_var(&tmp);
   10223      413774 : }
   10224             : 
   10225             : 
   10226             : /*
   10227             :  * div_mod_var() -
   10228             :  *
   10229             :  *  Calculate the truncated integer quotient and numeric remainder of two
   10230             :  *  numeric variables.  The remainder is precise to var2's dscale.
   10231             :  */
   10232             : static void
   10233        4518 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
   10234             :             NumericVar *quot, NumericVar *rem)
   10235             : {
   10236             :     NumericVar  q;
   10237             :     NumericVar  r;
   10238             : 
   10239        4518 :     init_var(&q);
   10240        4518 :     init_var(&r);
   10241             : 
   10242             :     /*
   10243             :      * Use div_var() with exact = false to get an initial estimate for the
   10244             :      * integer quotient (truncated towards zero).  This might be slightly
   10245             :      * inaccurate, but we correct it below.
   10246             :      */
   10247        4518 :     div_var(var1, var2, &q, 0, false, false);
   10248             : 
   10249             :     /* Compute initial estimate of remainder using the quotient estimate. */
   10250        4518 :     mul_var(var2, &q, &r, var2->dscale);
   10251        4518 :     sub_var(var1, &r, &r);
   10252             : 
   10253             :     /*
   10254             :      * Adjust the results if necessary --- the remainder should have the same
   10255             :      * sign as var1, and its absolute value should be less than the absolute
   10256             :      * value of var2.
   10257             :      */
   10258        4518 :     while (r.ndigits != 0 && r.sign != var1->sign)
   10259             :     {
   10260             :         /* The absolute value of the quotient is too large */
   10261           0 :         if (var1->sign == var2->sign)
   10262             :         {
   10263           0 :             sub_var(&q, &const_one, &q);
   10264           0 :             add_var(&r, var2, &r);
   10265             :         }
   10266             :         else
   10267             :         {
   10268           0 :             add_var(&q, &const_one, &q);
   10269           0 :             sub_var(&r, var2, &r);
   10270             :         }
   10271             :     }
   10272             : 
   10273        4518 :     while (cmp_abs(&r, var2) >= 0)
   10274             :     {
   10275             :         /* The absolute value of the quotient is too small */
   10276           0 :         if (var1->sign == var2->sign)
   10277             :         {
   10278           0 :             add_var(&q, &const_one, &q);
   10279           0 :             sub_var(&r, var2, &r);
   10280             :         }
   10281             :         else
   10282             :         {
   10283           0 :             sub_var(&q, &const_one, &q);
   10284           0 :             add_var(&r, var2, &r);
   10285             :         }
   10286             :     }
   10287             : 
   10288        4518 :     set_var_from_var(&q, quot);
   10289        4518 :     set_var_from_var(&r, rem);
   10290             : 
   10291        4518 :     free_var(&q);
   10292        4518 :     free_var(&r);
   10293        4518 : }
   10294             : 
   10295             : 
   10296             : /*
   10297             :  * ceil_var() -
   10298             :  *
   10299             :  *  Return the smallest integer greater than or equal to the argument
   10300             :  *  on variable level
   10301             :  */
   10302             : static void
   10303         204 : ceil_var(const NumericVar *var, NumericVar *result)
   10304             : {
   10305             :     NumericVar  tmp;
   10306             : 
   10307         204 :     init_var(&tmp);
   10308         204 :     set_var_from_var(var, &tmp);
   10309             : 
   10310         204 :     trunc_var(&tmp, 0);
   10311             : 
   10312         204 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
   10313          60 :         add_var(&tmp, &const_one, &tmp);
   10314             : 
   10315         204 :     set_var_from_var(&tmp, result);
   10316         204 :     free_var(&tmp);
   10317         204 : }
   10318             : 
   10319             : 
   10320             : /*
   10321             :  * floor_var() -
   10322             :  *
   10323             :  *  Return the largest integer equal to or less than the argument
   10324             :  *  on variable level
   10325             :  */
   10326             : static void
   10327         108 : floor_var(const NumericVar *var, NumericVar *result)
   10328             : {
   10329             :     NumericVar  tmp;
   10330             : 
   10331         108 :     init_var(&tmp);
   10332         108 :     set_var_from_var(var, &tmp);
   10333             : 
   10334         108 :     trunc_var(&tmp, 0);
   10335             : 
   10336         108 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
   10337          30 :         sub_var(&tmp, &const_one, &tmp);
   10338             : 
   10339         108 :     set_var_from_var(&tmp, result);
   10340         108 :     free_var(&tmp);
   10341         108 : }
   10342             : 
   10343             : 
   10344             : /*
   10345             :  * gcd_var() -
   10346             :  *
   10347             :  *  Calculate the greatest common divisor of two numerics at variable level
   10348             :  */
   10349             : static void
   10350         222 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   10351             : {
   10352             :     int         res_dscale;
   10353             :     int         cmp;
   10354             :     NumericVar  tmp_arg;
   10355             :     NumericVar  mod;
   10356             : 
   10357         222 :     res_dscale = Max(var1->dscale, var2->dscale);
   10358             : 
   10359             :     /*
   10360             :      * Arrange for var1 to be the number with the greater absolute value.
   10361             :      *
   10362             :      * This would happen automatically in the loop below, but avoids an
   10363             :      * expensive modulo operation.
   10364             :      */
   10365         222 :     cmp = cmp_abs(var1, var2);
   10366         222 :     if (cmp < 0)
   10367             :     {
   10368          84 :         const NumericVar *tmp = var1;
   10369             : 
   10370          84 :         var1 = var2;
   10371          84 :         var2 = tmp;
   10372             :     }
   10373             : 
   10374             :     /*
   10375             :      * Also avoid the taking the modulo if the inputs have the same absolute
   10376             :      * value, or if the smaller input is zero.
   10377             :      */
   10378         222 :     if (cmp == 0 || var2->ndigits == 0)
   10379             :     {
   10380          72 :         set_var_from_var(var1, result);
   10381          72 :         result->sign = NUMERIC_POS;
   10382          72 :         result->dscale = res_dscale;
   10383          72 :         return;
   10384             :     }
   10385             : 
   10386         150 :     init_var(&tmp_arg);
   10387         150 :     init_var(&mod);
   10388             : 
   10389             :     /* Use the Euclidean algorithm to find the GCD */
   10390         150 :     set_var_from_var(var1, &tmp_arg);
   10391         150 :     set_var_from_var(var2, result);
   10392             : 
   10393             :     for (;;)
   10394             :     {
   10395             :         /* this loop can take a while, so allow it to be interrupted */
   10396         588 :         CHECK_FOR_INTERRUPTS();
   10397             : 
   10398         588 :         mod_var(&tmp_arg, result, &mod);
   10399         588 :         if (mod.ndigits == 0)
   10400         150 :             break;
   10401         438 :         set_var_from_var(result, &tmp_arg);
   10402         438 :         set_var_from_var(&mod, result);
   10403             :     }
   10404         150 :     result->sign = NUMERIC_POS;
   10405         150 :     result->dscale = res_dscale;
   10406             : 
   10407         150 :     free_var(&tmp_arg);
   10408         150 :     free_var(&mod);
   10409             : }
   10410             : 
   10411             : 
   10412             : /*
   10413             :  * sqrt_var() -
   10414             :  *
   10415             :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
   10416             :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
   10417             :  *  point.
   10418             :  */
   10419             : static void
   10420        4194 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
   10421             : {
   10422             :     int         stat;
   10423             :     int         res_weight;
   10424             :     int         res_ndigits;
   10425             :     int         src_ndigits;
   10426             :     int         step;
   10427             :     int         ndigits[32];
   10428             :     int         blen;
   10429             :     int64       arg_int64;
   10430             :     int         src_idx;
   10431             :     int64       s_int64;
   10432             :     int64       r_int64;
   10433             :     NumericVar  s_var;
   10434             :     NumericVar  r_var;
   10435             :     NumericVar  a0_var;
   10436             :     NumericVar  a1_var;
   10437             :     NumericVar  q_var;
   10438             :     NumericVar  u_var;
   10439             : 
   10440        4194 :     stat = cmp_var(arg, &const_zero);
   10441        4194 :     if (stat == 0)
   10442             :     {
   10443          18 :         zero_var(result);
   10444          18 :         result->dscale = rscale;
   10445          18 :         return;
   10446             :     }
   10447             : 
   10448             :     /*
   10449             :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
   10450             :      * SQLSTATE error code if the operand is negative.
   10451             :      */
   10452        4176 :     if (stat < 0)
   10453           6 :         ereport(ERROR,
   10454             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10455             :                  errmsg("cannot take square root of a negative number")));
   10456             : 
   10457        4170 :     init_var(&s_var);
   10458        4170 :     init_var(&r_var);
   10459        4170 :     init_var(&a0_var);
   10460        4170 :     init_var(&a1_var);
   10461        4170 :     init_var(&q_var);
   10462        4170 :     init_var(&u_var);
   10463             : 
   10464             :     /*
   10465             :      * The result weight is half the input weight, rounded towards minus
   10466             :      * infinity --- res_weight = floor(arg->weight / 2).
   10467             :      */
   10468        4170 :     if (arg->weight >= 0)
   10469        3858 :         res_weight = arg->weight / 2;
   10470             :     else
   10471         312 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10472             : 
   10473             :     /*
   10474             :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10475             :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10476             :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10477             :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10478             :      */
   10479        4170 :     if (rscale + 1 >= 0)
   10480        4170 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10481             :     else
   10482           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10483        4170 :     res_ndigits = Max(res_ndigits, 1);
   10484             : 
   10485             :     /*
   10486             :      * Number of source NBASE digits logically required to produce a result
   10487             :      * with this precision --- every digit before the decimal point, plus 2
   10488             :      * for each result digit after the decimal point (or minus 2 for each
   10489             :      * result digit we round before the decimal point).
   10490             :      */
   10491        4170 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10492        4170 :     src_ndigits = Max(src_ndigits, 1);
   10493             : 
   10494             :     /* ----------
   10495             :      * From this point on, we treat the input and the result as integers and
   10496             :      * compute the integer square root and remainder using the Karatsuba
   10497             :      * Square Root algorithm, which may be written recursively as follows:
   10498             :      *
   10499             :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10500             :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10501             :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10502             :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10503             :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10504             :      *      Let s = s*b + q
   10505             :      *      Let r = u*b + a0 - q^2
   10506             :      *      If r < 0 Then
   10507             :      *          Let r = r + s
   10508             :      *          Let s = s - 1
   10509             :      *          Let r = r + s
   10510             :      *      Return (s,r)
   10511             :      *
   10512             :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10513             :      * RR-3805, November 1999.  At the time of writing this was available
   10514             :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10515             :      *
   10516             :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10517             :      * "choose a base b such that n requires at least four base-b digits to
   10518             :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10519             :      * than b".  For optimal performance, b should have approximately a
   10520             :      * quarter the number of digits in the input, so that the outer square
   10521             :      * root computes roughly twice as many digits as the inner one.  For
   10522             :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10523             :      *
   10524             :      * We implement the algorithm iteratively rather than recursively, to
   10525             :      * allow the working variables to be reused.  With this approach, each
   10526             :      * digit of the input is read precisely once --- src_idx tracks the number
   10527             :      * of input digits used so far.
   10528             :      *
   10529             :      * The array ndigits[] holds the number of NBASE digits of the input that
   10530             :      * will have been used at the end of each iteration, which roughly doubles
   10531             :      * each time.  Note that the array elements are stored in reverse order,
   10532             :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10533             :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10534             :      * the square root of the 3 most significant NBASE digits.
   10535             :      *
   10536             :      * In each iteration, we choose blen to be the largest integer for which
   10537             :      * the input number has a3 >= b/4, when written in the form above.  In
   10538             :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10539             :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10540             :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10541             :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10542             :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10543             :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10544             :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10545             :      * the first input digit.
   10546             :      *
   10547             :      * Additionally, we can put an upper bound on the number of steps required
   10548             :      * as follows --- suppose that the number of source digits is an n-bit
   10549             :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10550             :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10551             :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10552             :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10553             :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10554             :      * This pattern repeats, and in the worst case the array ndigits[] will
   10555             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10556             :      * will require n steps.  Therefore, since all digit array sizes are
   10557             :      * signed 32-bit integers, the number of steps required is guaranteed to
   10558             :      * be less than 32.
   10559             :      * ----------
   10560             :      */
   10561        4170 :     step = 0;
   10562       19962 :     while ((ndigits[step] = src_ndigits) > 4)
   10563             :     {
   10564             :         /* Choose b so that a3 >= b/4, as described above */
   10565       15792 :         blen = src_ndigits / 4;
   10566       15792 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10567         324 :             blen--;
   10568             : 
   10569             :         /* Number of digits in the next step (inner square root) */
   10570       15792 :         src_ndigits -= 2 * blen;
   10571       15792 :         step++;
   10572             :     }
   10573             : 
   10574             :     /*
   10575             :      * First iteration (innermost square root and remainder):
   10576             :      *
   10577             :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10578             :      * has at most 9 decimal digits, so estimate it using double precision
   10579             :      * arithmetic, which will in fact almost certainly return the correct
   10580             :      * result with no further correction required.
   10581             :      */
   10582        4170 :     arg_int64 = arg->digits[0];
   10583       13314 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10584             :     {
   10585        9144 :         arg_int64 *= NBASE;
   10586        9144 :         if (src_idx < arg->ndigits)
   10587        7686 :             arg_int64 += arg->digits[src_idx];
   10588             :     }
   10589             : 
   10590        4170 :     s_int64 = (int64) sqrt((double) arg_int64);
   10591        4170 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10592             : 
   10593             :     /*
   10594             :      * Use Newton's method to correct the result, if necessary.
   10595             :      *
   10596             :      * This uses integer division with truncation to compute the truncated
   10597             :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10598             :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10599             :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10600             :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10601             :      * checking the remainder.
   10602             :      */
   10603        4170 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10604             :     {
   10605           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10606           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10607             :     }
   10608             : 
   10609             :     /*
   10610             :      * Iterations with src_ndigits <= 8:
   10611             :      *
   10612             :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10613             :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10614             :      * input no longer does) and we can continue to compute using int64
   10615             :      * variables to avoid more expensive numeric computations.
   10616             :      *
   10617             :      * It is fairly easy to see that there is no risk of the intermediate
   10618             :      * values below overflowing 64-bit integers.  In the worst case, the
   10619             :      * previous iteration will have computed a 3-digit square root (of a
   10620             :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10621             :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10622             :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10623             :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10624             :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10625             :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10626             :      * in 64-bit integers.
   10627             :      */
   10628        4170 :     step--;
   10629       10566 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10630             :     {
   10631             :         int         b;
   10632             :         int         a0;
   10633             :         int         a1;
   10634             :         int         i;
   10635             :         int64       numer;
   10636             :         int64       denom;
   10637             :         int64       q;
   10638             :         int64       u;
   10639             : 
   10640        6396 :         blen = (src_ndigits - src_idx) / 2;
   10641             : 
   10642             :         /* Extract a1 and a0, and compute b */
   10643        6396 :         a0 = 0;
   10644        6396 :         a1 = 0;
   10645        6396 :         b = 1;
   10646             : 
   10647       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10648             :         {
   10649        6540 :             b *= NBASE;
   10650        6540 :             a1 *= NBASE;
   10651        6540 :             if (src_idx < arg->ndigits)
   10652        4800 :                 a1 += arg->digits[src_idx];
   10653             :         }
   10654             : 
   10655       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10656             :         {
   10657        6540 :             a0 *= NBASE;
   10658        6540 :             if (src_idx < arg->ndigits)
   10659        4644 :                 a0 += arg->digits[src_idx];
   10660             :         }
   10661             : 
   10662             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10663        6396 :         numer = r_int64 * b + a1;
   10664        6396 :         denom = 2 * s_int64;
   10665        6396 :         q = numer / denom;
   10666        6396 :         u = numer - q * denom;
   10667             : 
   10668             :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10669        6396 :         s_int64 = s_int64 * b + q;
   10670        6396 :         r_int64 = u * b + a0 - q * q;
   10671             : 
   10672        6396 :         if (r_int64 < 0)
   10673             :         {
   10674             :             /* s is too large by 1; set r += s, s--, r += s */
   10675         210 :             r_int64 += s_int64;
   10676         210 :             s_int64--;
   10677         210 :             r_int64 += s_int64;
   10678             :         }
   10679             : 
   10680             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10681        6396 :         step--;
   10682             :     }
   10683             : 
   10684             :     /*
   10685             :      * On platforms with 128-bit integer support, we can further delay the
   10686             :      * need to use numeric variables.
   10687             :      */
   10688             : #ifdef HAVE_INT128
   10689        4170 :     if (step >= 0)
   10690             :     {
   10691             :         int128      s_int128;
   10692             :         int128      r_int128;
   10693             : 
   10694        4170 :         s_int128 = s_int64;
   10695        4170 :         r_int128 = r_int64;
   10696             : 
   10697             :         /*
   10698             :          * Iterations with src_ndigits <= 16:
   10699             :          *
   10700             :          * The result fits in an int128 (even though the input doesn't) so we
   10701             :          * use int128 variables to avoid more expensive numeric computations.
   10702             :          */
   10703        9048 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10704             :         {
   10705             :             int64       b;
   10706             :             int64       a0;
   10707             :             int64       a1;
   10708             :             int64       i;
   10709             :             int128      numer;
   10710             :             int128      denom;
   10711             :             int128      q;
   10712             :             int128      u;
   10713             : 
   10714        4878 :             blen = (src_ndigits - src_idx) / 2;
   10715             : 
   10716             :             /* Extract a1 and a0, and compute b */
   10717        4878 :             a0 = 0;
   10718        4878 :             a1 = 0;
   10719        4878 :             b = 1;
   10720             : 
   10721       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10722             :             {
   10723       11202 :                 b *= NBASE;
   10724       11202 :                 a1 *= NBASE;
   10725       11202 :                 if (src_idx < arg->ndigits)
   10726        6606 :                     a1 += arg->digits[src_idx];
   10727             :             }
   10728             : 
   10729       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10730             :             {
   10731       11202 :                 a0 *= NBASE;
   10732       11202 :                 if (src_idx < arg->ndigits)
   10733        4470 :                     a0 += arg->digits[src_idx];
   10734             :             }
   10735             : 
   10736             :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10737        4878 :             numer = r_int128 * b + a1;
   10738        4878 :             denom = 2 * s_int128;
   10739        4878 :             q = numer / denom;
   10740        4878 :             u = numer - q * denom;
   10741             : 
   10742             :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10743        4878 :             s_int128 = s_int128 * b + q;
   10744        4878 :             r_int128 = u * b + a0 - q * q;
   10745             : 
   10746        4878 :             if (r_int128 < 0)
   10747             :             {
   10748             :                 /* s is too large by 1; set r += s, s--, r += s */
   10749         192 :                 r_int128 += s_int128;
   10750         192 :                 s_int128--;
   10751         192 :                 r_int128 += s_int128;
   10752             :             }
   10753             : 
   10754             :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10755        4878 :             step--;
   10756             :         }
   10757             : 
   10758             :         /*
   10759             :          * All remaining iterations require numeric variables.  Convert the
   10760             :          * integer values to NumericVar and continue.  Note that in the final
   10761             :          * iteration we don't need the remainder, so we can save a few cycles
   10762             :          * there by not fully computing it.
   10763             :          */
   10764        4170 :         int128_to_numericvar(s_int128, &s_var);
   10765        4170 :         if (step >= 0)
   10766        2724 :             int128_to_numericvar(r_int128, &r_var);
   10767             :     }
   10768             :     else
   10769             :     {
   10770           0 :         int64_to_numericvar(s_int64, &s_var);
   10771             :         /* step < 0, so we certainly don't need r */
   10772             :     }
   10773             : #else                           /* !HAVE_INT128 */
   10774             :     int64_to_numericvar(s_int64, &s_var);
   10775             :     if (step >= 0)
   10776             :         int64_to_numericvar(r_int64, &r_var);
   10777             : #endif                          /* HAVE_INT128 */
   10778             : 
   10779             :     /*
   10780             :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10781             :      * use numeric variables.
   10782             :      */
   10783        8688 :     while (step >= 0)
   10784             :     {
   10785             :         int         tmp_len;
   10786             : 
   10787        4518 :         src_ndigits = ndigits[step];
   10788        4518 :         blen = (src_ndigits - src_idx) / 2;
   10789             : 
   10790             :         /* Extract a1 and a0 */
   10791        4518 :         if (src_idx < arg->ndigits)
   10792             :         {
   10793        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10794        1512 :             alloc_var(&a1_var, tmp_len);
   10795        1512 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10796             :                    tmp_len * sizeof(NumericDigit));
   10797        1512 :             a1_var.weight = blen - 1;
   10798        1512 :             a1_var.sign = NUMERIC_POS;
   10799        1512 :             a1_var.dscale = 0;
   10800        1512 :             strip_var(&a1_var);
   10801             :         }
   10802             :         else
   10803             :         {
   10804        3006 :             zero_var(&a1_var);
   10805        3006 :             a1_var.dscale = 0;
   10806             :         }
   10807        4518 :         src_idx += blen;
   10808             : 
   10809        4518 :         if (src_idx < arg->ndigits)
   10810             :         {
   10811        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10812        1512 :             alloc_var(&a0_var, tmp_len);
   10813        1512 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10814             :                    tmp_len * sizeof(NumericDigit));
   10815        1512 :             a0_var.weight = blen - 1;
   10816        1512 :             a0_var.sign = NUMERIC_POS;
   10817        1512 :             a0_var.dscale = 0;
   10818        1512 :             strip_var(&a0_var);
   10819             :         }
   10820             :         else
   10821             :         {
   10822        3006 :             zero_var(&a0_var);
   10823        3006 :             a0_var.dscale = 0;
   10824             :         }
   10825        4518 :         src_idx += blen;
   10826             : 
   10827             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10828        4518 :         set_var_from_var(&r_var, &q_var);
   10829        4518 :         q_var.weight += blen;
   10830        4518 :         add_var(&q_var, &a1_var, &q_var);
   10831        4518 :         add_var(&s_var, &s_var, &u_var);
   10832        4518 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10833             : 
   10834             :         /* Compute s = s*b + q */
   10835        4518 :         s_var.weight += blen;
   10836        4518 :         add_var(&s_var, &q_var, &s_var);
   10837             : 
   10838             :         /*
   10839             :          * Compute r = u*b + a0 - q^2.
   10840             :          *
   10841             :          * In the final iteration, we don't actually need r; we just need to
   10842             :          * know whether it is negative, so that we know whether to adjust s.
   10843             :          * So instead of the final subtraction we can just compare.
   10844             :          */
   10845        4518 :         u_var.weight += blen;
   10846        4518 :         add_var(&u_var, &a0_var, &u_var);
   10847        4518 :         mul_var(&q_var, &q_var, &q_var, 0);
   10848             : 
   10849        4518 :         if (step > 0)
   10850             :         {
   10851             :             /* Need r for later iterations */
   10852        1794 :             sub_var(&u_var, &q_var, &r_var);
   10853        1794 :             if (r_var.sign == NUMERIC_NEG)
   10854             :             {
   10855             :                 /* s is too large by 1; set r += s, s--, r += s */
   10856         120 :                 add_var(&r_var, &s_var, &r_var);
   10857         120 :                 sub_var(&s_var, &const_one, &s_var);
   10858         120 :                 add_var(&r_var, &s_var, &r_var);
   10859             :             }
   10860             :         }
   10861             :         else
   10862             :         {
   10863             :             /* Don't need r anymore, except to test if s is too large by 1 */
   10864        2724 :             if (cmp_var(&u_var, &q_var) < 0)
   10865          36 :                 sub_var(&s_var, &const_one, &s_var);
   10866             :         }
   10867             : 
   10868             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10869        4518 :         step--;
   10870             :     }
   10871             : 
   10872             :     /*
   10873             :      * Construct the final result, rounding it to the requested precision.
   10874             :      */
   10875        4170 :     set_var_from_var(&s_var, result);
   10876        4170 :     result->weight = res_weight;
   10877        4170 :     result->sign = NUMERIC_POS;
   10878             : 
   10879             :     /* Round to target rscale (and set result->dscale) */
   10880        4170 :     round_var(result, rscale);
   10881             : 
   10882             :     /* Strip leading and trailing zeroes */
   10883        4170 :     strip_var(result);
   10884             : 
   10885        4170 :     free_var(&s_var);
   10886        4170 :     free_var(&r_var);
   10887        4170 :     free_var(&a0_var);
   10888        4170 :     free_var(&a1_var);
   10889        4170 :     free_var(&q_var);
   10890        4170 :     free_var(&u_var);
   10891             : }
   10892             : 
   10893             : 
   10894             : /*
   10895             :  * exp_var() -
   10896             :  *
   10897             :  *  Raise e to the power of x, computed to rscale fractional digits
   10898             :  */
   10899             : static void
   10900         180 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10901             : {
   10902             :     NumericVar  x;
   10903             :     NumericVar  elem;
   10904             :     int         ni;
   10905             :     double      val;
   10906             :     int         dweight;
   10907             :     int         ndiv2;
   10908             :     int         sig_digits;
   10909             :     int         local_rscale;
   10910             : 
   10911         180 :     init_var(&x);
   10912         180 :     init_var(&elem);
   10913             : 
   10914         180 :     set_var_from_var(arg, &x);
   10915             : 
   10916             :     /*
   10917             :      * Estimate the dweight of the result using floating point arithmetic, so
   10918             :      * that we can choose an appropriate local rscale for the calculation.
   10919             :      */
   10920         180 :     val = numericvar_to_double_no_overflow(&x);
   10921             : 
   10922             :     /* Guard against overflow/underflow */
   10923             :     /* If you change this limit, see also power_var()'s limit */
   10924         180 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10925             :     {
   10926           6 :         if (val > 0)
   10927           0 :             ereport(ERROR,
   10928             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10929             :                      errmsg("value overflows numeric format")));
   10930           6 :         zero_var(result);
   10931           6 :         result->dscale = rscale;
   10932           6 :         return;
   10933             :     }
   10934             : 
   10935             :     /* decimal weight = log10(e^x) = x * log10(e) */
   10936         174 :     dweight = (int) (val * 0.434294481903252);
   10937             : 
   10938             :     /*
   10939             :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10940             :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10941             :      *
   10942             :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10943             :      * means that ndiv2 <= 20 here.
   10944             :      */
   10945         174 :     if (fabs(val) > 0.01)
   10946             :     {
   10947         144 :         ndiv2 = 1;
   10948         144 :         val /= 2;
   10949             : 
   10950        1818 :         while (fabs(val) > 0.01)
   10951             :         {
   10952        1674 :             ndiv2++;
   10953        1674 :             val /= 2;
   10954             :         }
   10955             : 
   10956         144 :         local_rscale = x.dscale + ndiv2;
   10957         144 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10958             :     }
   10959             :     else
   10960          30 :         ndiv2 = 0;
   10961             : 
   10962             :     /*
   10963             :      * Set the scale for the Taylor series expansion.  The final result has
   10964             :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10965             :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10966             :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10967             :      * extra digits of precision (plus a few more for good measure).
   10968             :      */
   10969         174 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10970         174 :     sig_digits = Max(sig_digits, 0) + 8;
   10971             : 
   10972         174 :     local_rscale = sig_digits - 1;
   10973             : 
   10974             :     /*
   10975             :      * Use the Taylor series
   10976             :      *
   10977             :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10978             :      *
   10979             :      * Given the limited range of x, this should converge reasonably quickly.
   10980             :      * We run the series until the terms fall below the local_rscale limit.
   10981             :      */
   10982         174 :     add_var(&const_one, &x, result);
   10983             : 
   10984         174 :     mul_var(&x, &x, &elem, local_rscale);
   10985         174 :     ni = 2;
   10986         174 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10987             : 
   10988        4992 :     while (elem.ndigits != 0)
   10989             :     {
   10990        4818 :         add_var(result, &elem, result);
   10991             : 
   10992        4818 :         mul_var(&elem, &x, &elem, local_rscale);
   10993        4818 :         ni++;
   10994        4818 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10995             :     }
   10996             : 
   10997             :     /*
   10998             :      * Compensate for the argument range reduction.  Since the weight of the
   10999             :      * result doubles with each multiplication, we can reduce the local rscale
   11000             :      * as we proceed.
   11001             :      */
   11002        1992 :     while (ndiv2-- > 0)
   11003             :     {
   11004        1818 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   11005        1818 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11006        1818 :         mul_var(result, result, result, local_rscale);
   11007             :     }
   11008             : 
   11009             :     /* Round to requested rscale */
   11010         174 :     round_var(result, rscale);
   11011             : 
   11012         174 :     free_var(&x);
   11013         174 :     free_var(&elem);
   11014             : }
   11015             : 
   11016             : 
   11017             : /*
   11018             :  * Estimate the dweight of the most significant decimal digit of the natural
   11019             :  * logarithm of a number.
   11020             :  *
   11021             :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   11022             :  * determine the appropriate rscale when computing natural logarithms.
   11023             :  *
   11024             :  * Note: many callers call this before range-checking the input.  Therefore,
   11025             :  * we must be robust against values that are invalid to apply ln() to.
   11026             :  * We don't wish to throw an error here, so just return zero in such cases.
   11027             :  */
   11028             : static int
   11029         738 : estimate_ln_dweight(const NumericVar *var)
   11030             : {
   11031             :     int         ln_dweight;
   11032             : 
   11033             :     /* Caller should fail on ln(negative), but for the moment return zero */
   11034         738 :     if (var->sign != NUMERIC_POS)
   11035          42 :         return 0;
   11036             : 
   11037        1314 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   11038         618 :         cmp_var(var, &const_one_point_one) <= 0)
   11039          90 :     {
   11040             :         /*
   11041             :          * 0.9 <= var <= 1.1
   11042             :          *
   11043             :          * ln(var) has a negative weight (possibly very large).  To get a
   11044             :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   11045             :          */
   11046             :         NumericVar  x;
   11047             : 
   11048          90 :         init_var(&x);
   11049          90 :         sub_var(var, &const_one, &x);
   11050             : 
   11051          90 :         if (x.ndigits > 0)
   11052             :         {
   11053             :             /* Use weight of most significant decimal digit of x */
   11054          42 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   11055             :         }
   11056             :         else
   11057             :         {
   11058             :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   11059          48 :             ln_dweight = 0;
   11060             :         }
   11061             : 
   11062          90 :         free_var(&x);
   11063             :     }
   11064             :     else
   11065             :     {
   11066             :         /*
   11067             :          * Estimate the logarithm using the first couple of digits from the
   11068             :          * input number.  This will give an accurate result whenever the input
   11069             :          * is not too close to 1.
   11070             :          */
   11071         606 :         if (var->ndigits > 0)
   11072             :         {
   11073             :             int         digits;
   11074             :             int         dweight;
   11075             :             double      ln_var;
   11076             : 
   11077         564 :             digits = var->digits[0];
   11078         564 :             dweight = var->weight * DEC_DIGITS;
   11079             : 
   11080         564 :             if (var->ndigits > 1)
   11081             :             {
   11082         342 :                 digits = digits * NBASE + var->digits[1];
   11083         342 :                 dweight -= DEC_DIGITS;
   11084             :             }
   11085             : 
   11086             :             /*----------
   11087             :              * We have var ~= digits * 10^dweight
   11088             :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   11089             :              *----------
   11090             :              */
   11091         564 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   11092         564 :             ln_dweight = (int) log10(fabs(ln_var));
   11093             :         }
   11094             :         else
   11095             :         {
   11096             :             /* Caller should fail on ln(0), but for the moment return zero */
   11097          42 :             ln_dweight = 0;
   11098             :         }
   11099             :     }
   11100             : 
   11101         696 :     return ln_dweight;
   11102             : }
   11103             : 
   11104             : 
   11105             : /*
   11106             :  * ln_var() -
   11107             :  *
   11108             :  *  Compute the natural log of x
   11109             :  */
   11110             : static void
   11111         834 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   11112             : {
   11113             :     NumericVar  x;
   11114             :     NumericVar  xx;
   11115             :     int         ni;
   11116             :     NumericVar  elem;
   11117             :     NumericVar  fact;
   11118             :     int         nsqrt;
   11119             :     int         local_rscale;
   11120             :     int         cmp;
   11121             : 
   11122         834 :     cmp = cmp_var(arg, &const_zero);
   11123         834 :     if (cmp == 0)
   11124          42 :         ereport(ERROR,
   11125             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   11126             :                  errmsg("cannot take logarithm of zero")));
   11127         792 :     else if (cmp < 0)
   11128          36 :         ereport(ERROR,
   11129             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   11130             :                  errmsg("cannot take logarithm of a negative number")));
   11131             : 
   11132         756 :     init_var(&x);
   11133         756 :     init_var(&xx);
   11134         756 :     init_var(&elem);
   11135         756 :     init_var(&fact);
   11136             : 
   11137         756 :     set_var_from_var(arg, &x);
   11138         756 :     set_var_from_var(&const_two, &fact);
   11139             : 
   11140             :     /*
   11141             :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   11142             :      *
   11143             :      * The final logarithm will have up to around rscale+6 significant digits.
   11144             :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   11145             :      * rscale as we work so that we keep this many significant digits at each
   11146             :      * step (plus a few more for good measure).
   11147             :      *
   11148             :      * Note that we allow local_rscale < 0 during this input reduction
   11149             :      * process, which implies rounding before the decimal point.  sqrt_var()
   11150             :      * explicitly supports this, and it significantly reduces the work
   11151             :      * required to reduce very large inputs to the required range.  Once the
   11152             :      * input reduction is complete, x.weight will be 0 and its display scale
   11153             :      * will be non-negative again.
   11154             :      */
   11155         756 :     nsqrt = 0;
   11156        1068 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   11157             :     {
   11158         312 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   11159         312 :         sqrt_var(&x, &x, local_rscale);
   11160         312 :         mul_var(&fact, &const_two, &fact, 0);
   11161         312 :         nsqrt++;
   11162             :     }
   11163        4128 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   11164             :     {
   11165        3372 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   11166        3372 :         sqrt_var(&x, &x, local_rscale);
   11167        3372 :         mul_var(&fact, &const_two, &fact, 0);
   11168        3372 :         nsqrt++;
   11169             :     }
   11170             : 
   11171             :     /*
   11172             :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   11173             :      *
   11174             :      * z + z^3/3 + z^5/5 + ...
   11175             :      *
   11176             :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   11177             :      * due to the above range-reduction of x.
   11178             :      *
   11179             :      * The convergence of this is not as fast as one would like, but is
   11180             :      * tolerable given that z is small.
   11181             :      *
   11182             :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   11183             :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   11184             :      * digits of precision (plus a few more for good measure).
   11185             :      */
   11186         756 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   11187             : 
   11188         756 :     sub_var(&x, &const_one, result);
   11189         756 :     add_var(&x, &const_one, &elem);
   11190         756 :     div_var(result, &elem, result, local_rscale, true, false);
   11191         756 :     set_var_from_var(result, &xx);
   11192         756 :     mul_var(result, result, &x, local_rscale);
   11193             : 
   11194         756 :     ni = 1;
   11195             : 
   11196             :     for (;;)
   11197             :     {
   11198       14022 :         ni += 2;
   11199       14022 :         mul_var(&xx, &x, &xx, local_rscale);
   11200       14022 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   11201             : 
   11202       14022 :         if (elem.ndigits == 0)
   11203         756 :             break;
   11204             : 
   11205       13266 :         add_var(result, &elem, result);
   11206             : 
   11207       13266 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   11208           0 :             break;
   11209             :     }
   11210             : 
   11211             :     /* Compensate for argument range reduction, round to requested rscale */
   11212         756 :     mul_var(result, &fact, result, rscale);
   11213             : 
   11214         756 :     free_var(&x);
   11215         756 :     free_var(&xx);
   11216         756 :     free_var(&elem);
   11217         756 :     free_var(&fact);
   11218         756 : }
   11219             : 
   11220             : 
   11221             : /*
   11222             :  * log_var() -
   11223             :  *
   11224             :  *  Compute the logarithm of num in a given base.
   11225             :  *
   11226             :  *  Note: this routine chooses dscale of the result.
   11227             :  */
   11228             : static void
   11229         216 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   11230             : {
   11231             :     NumericVar  ln_base;
   11232             :     NumericVar  ln_num;
   11233             :     int         ln_base_dweight;
   11234             :     int         ln_num_dweight;
   11235             :     int         result_dweight;
   11236             :     int         rscale;
   11237             :     int         ln_base_rscale;
   11238             :     int         ln_num_rscale;
   11239             : 
   11240         216 :     init_var(&ln_base);
   11241         216 :     init_var(&ln_num);
   11242             : 
   11243             :     /* Estimated dweights of ln(base), ln(num) and the final result */
   11244         216 :     ln_base_dweight = estimate_ln_dweight(base);
   11245         216 :     ln_num_dweight = estimate_ln_dweight(num);
   11246         216 :     result_dweight = ln_num_dweight - ln_base_dweight;
   11247             : 
   11248             :     /*
   11249             :      * Select the scale of the result so that it will have at least
   11250             :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   11251             :      * input's display scale.
   11252             :      */
   11253         216 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   11254         216 :     rscale = Max(rscale, base->dscale);
   11255         216 :     rscale = Max(rscale, num->dscale);
   11256         216 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11257         216 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11258             : 
   11259             :     /*
   11260             :      * Set the scales for ln(base) and ln(num) so that they each have more
   11261             :      * significant digits than the final result.
   11262             :      */
   11263         216 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   11264         216 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11265             : 
   11266         216 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   11267         216 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11268             : 
   11269             :     /* Form natural logarithms */
   11270         216 :     ln_var(base, &ln_base, ln_base_rscale);
   11271         192 :     ln_var(num, &ln_num, ln_num_rscale);
   11272             : 
   11273             :     /* Divide and round to the required scale */
   11274         162 :     div_var(&ln_num, &ln_base, result, rscale, true, false);
   11275             : 
   11276         156 :     free_var(&ln_num);
   11277         156 :     free_var(&ln_base);
   11278         156 : }
   11279             : 
   11280             : 
   11281             : /*
   11282             :  * power_var() -
   11283             :  *
   11284             :  *  Raise base to the power of exp
   11285             :  *
   11286             :  *  Note: this routine chooses dscale of the result.
   11287             :  */
   11288             : static void
   11289        1398 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   11290             : {
   11291             :     int         res_sign;
   11292             :     NumericVar  abs_base;
   11293             :     NumericVar  ln_base;
   11294             :     NumericVar  ln_num;
   11295             :     int         ln_dweight;
   11296             :     int         rscale;
   11297             :     int         sig_digits;
   11298             :     int         local_rscale;
   11299             :     double      val;
   11300             : 
   11301             :     /* If exp can be represented as an integer, use power_var_int */
   11302        1398 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   11303             :     {
   11304             :         /* exact integer, but does it fit in int? */
   11305             :         int64       expval64;
   11306             : 
   11307        1272 :         if (numericvar_to_int64(exp, &expval64))
   11308             :         {
   11309        1266 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   11310             :             {
   11311             :                 /* Okay, use power_var_int */
   11312        1236 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   11313        1224 :                 return;
   11314             :             }
   11315             :         }
   11316             :     }
   11317             : 
   11318             :     /*
   11319             :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   11320             :      * handled by power_var_int().
   11321             :      */
   11322         162 :     if (cmp_var(base, &const_zero) == 0)
   11323             :     {
   11324          18 :         set_var_from_var(&const_zero, result);
   11325          18 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   11326          18 :         return;
   11327             :     }
   11328             : 
   11329         144 :     init_var(&abs_base);
   11330         144 :     init_var(&ln_base);
   11331         144 :     init_var(&ln_num);
   11332             : 
   11333             :     /*
   11334             :      * If base is negative, insist that exp be an integer.  The result is then
   11335             :      * positive if exp is even and negative if exp is odd.
   11336             :      */
   11337         144 :     if (base->sign == NUMERIC_NEG)
   11338             :     {
   11339             :         /*
   11340             :          * Check that exp is an integer.  This error code is defined by the
   11341             :          * SQL standard, and matches other errors in numeric_power().
   11342             :          */
   11343          36 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   11344          18 :             ereport(ERROR,
   11345             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   11346             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   11347             : 
   11348             :         /* Test if exp is odd or even */
   11349          18 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   11350          12 :             (exp->digits[exp->ndigits - 1] & 1))
   11351           6 :             res_sign = NUMERIC_NEG;
   11352             :         else
   11353          12 :             res_sign = NUMERIC_POS;
   11354             : 
   11355             :         /* Then work with abs(base) below */
   11356          18 :         set_var_from_var(base, &abs_base);
   11357          18 :         abs_base.sign = NUMERIC_POS;
   11358          18 :         base = &abs_base;
   11359             :     }
   11360             :     else
   11361         108 :         res_sign = NUMERIC_POS;
   11362             : 
   11363             :     /*----------
   11364             :      * Decide on the scale for the ln() calculation.  For this we need an
   11365             :      * estimate of the weight of the result, which we obtain by doing an
   11366             :      * initial low-precision calculation of exp * ln(base).
   11367             :      *
   11368             :      * We want result = e ^ (exp * ln(base))
   11369             :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   11370             :      *
   11371             :      * We also perform a crude overflow test here so that we can exit early if
   11372             :      * the full-precision result is sure to overflow, and to guard against
   11373             :      * integer overflow when determining the scale for the real calculation.
   11374             :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   11375             :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   11376             :      * Since the values here are only approximations, we apply a small fuzz
   11377             :      * factor to this overflow test and let exp_var() determine the exact
   11378             :      * overflow threshold so that it is consistent for all inputs.
   11379             :      *----------
   11380             :      */
   11381         126 :     ln_dweight = estimate_ln_dweight(base);
   11382             : 
   11383             :     /*
   11384             :      * Set the scale for the low-precision calculation, computing ln(base) to
   11385             :      * around 8 significant digits.  Note that ln_dweight may be as small as
   11386             :      * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
   11387             :      * here.
   11388             :      */
   11389         126 :     local_rscale = 8 - ln_dweight;
   11390         126 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11391             : 
   11392         126 :     ln_var(base, &ln_base, local_rscale);
   11393             : 
   11394         126 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11395             : 
   11396         126 :     val = numericvar_to_double_no_overflow(&ln_num);
   11397             : 
   11398             :     /* initial overflow/underflow test with fuzz factor */
   11399         126 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   11400             :     {
   11401           6 :         if (val > 0)
   11402           0 :             ereport(ERROR,
   11403             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11404             :                      errmsg("value overflows numeric format")));
   11405           6 :         zero_var(result);
   11406           6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11407           6 :         return;
   11408             :     }
   11409             : 
   11410         120 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   11411             : 
   11412             :     /* choose the result scale */
   11413         120 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   11414         120 :     rscale = Max(rscale, base->dscale);
   11415         120 :     rscale = Max(rscale, exp->dscale);
   11416         120 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11417         120 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11418             : 
   11419             :     /* significant digits required in the result */
   11420         120 :     sig_digits = rscale + (int) val;
   11421         120 :     sig_digits = Max(sig_digits, 0);
   11422             : 
   11423             :     /* set the scale for the real exp * ln(base) calculation */
   11424         120 :     local_rscale = sig_digits - ln_dweight + 8;
   11425         120 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11426             : 
   11427             :     /* and do the real calculation */
   11428             : 
   11429         120 :     ln_var(base, &ln_base, local_rscale);
   11430             : 
   11431         120 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11432             : 
   11433         120 :     exp_var(&ln_num, result, rscale);
   11434             : 
   11435         120 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   11436           6 :         result->sign = NUMERIC_NEG;
   11437             : 
   11438         120 :     free_var(&ln_num);
   11439         120 :     free_var(&ln_base);
   11440         120 :     free_var(&abs_base);
   11441             : }
   11442             : 
   11443             : /*
   11444             :  * power_var_int() -
   11445             :  *
   11446             :  *  Raise base to the power of exp, where exp is an integer.
   11447             :  *
   11448             :  *  Note: this routine chooses dscale of the result.
   11449             :  */
   11450             : static void
   11451        1236 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   11452             :               NumericVar *result)
   11453             : {
   11454             :     double      f;
   11455             :     int         p;
   11456             :     int         i;
   11457             :     int         rscale;
   11458             :     int         sig_digits;
   11459             :     unsigned int mask;
   11460             :     bool        neg;
   11461             :     NumericVar  base_prod;
   11462             :     int         local_rscale;
   11463             : 
   11464             :     /*
   11465             :      * Choose the result scale.  For this we need an estimate of the decimal
   11466             :      * weight of the result, which we obtain by approximating using double
   11467             :      * precision arithmetic.
   11468             :      *
   11469             :      * We also perform crude overflow/underflow tests here so that we can exit
   11470             :      * early if the result is sure to overflow/underflow, and to guard against
   11471             :      * integer overflow when choosing the result scale.
   11472             :      */
   11473        1236 :     if (base->ndigits != 0)
   11474             :     {
   11475             :         /*----------
   11476             :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11477             :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11478             :          *----------
   11479             :          */
   11480        1206 :         f = base->digits[0];
   11481        1206 :         p = base->weight * DEC_DIGITS;
   11482             : 
   11483        1290 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11484             :         {
   11485          84 :             f = f * NBASE + base->digits[i];
   11486          84 :             p -= DEC_DIGITS;
   11487             :         }
   11488             : 
   11489        1206 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11490             :     }
   11491             :     else
   11492          30 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11493             : 
   11494             :     /* overflow/underflow tests with fuzz factors */
   11495        1236 :     if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
   11496          12 :         ereport(ERROR,
   11497             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11498             :                  errmsg("value overflows numeric format")));
   11499        1224 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11500             :     {
   11501          12 :         zero_var(result);
   11502          12 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11503         216 :         return;
   11504             :     }
   11505             : 
   11506             :     /*
   11507             :      * Choose the result scale in the same way as power_var(), so it has at
   11508             :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11509             :      * either input's display scale.
   11510             :      */
   11511        1212 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11512        1212 :     rscale = Max(rscale, base->dscale);
   11513        1212 :     rscale = Max(rscale, exp_dscale);
   11514        1212 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11515        1212 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11516             : 
   11517             :     /* Handle some common special cases, as well as corner cases */
   11518        1212 :     switch (exp)
   11519             :     {
   11520          72 :         case 0:
   11521             : 
   11522             :             /*
   11523             :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11524             :              * it as 1 because most programming languages do this. SQL:2003
   11525             :              * also requires a return value of 1.
   11526             :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11527             :              */
   11528          72 :             set_var_from_var(&const_one, result);
   11529          72 :             result->dscale = rscale; /* no need to round */
   11530          72 :             return;
   11531          48 :         case 1:
   11532          48 :             set_var_from_var(base, result);
   11533          48 :             round_var(result, rscale);
   11534          48 :             return;
   11535          30 :         case -1:
   11536          30 :             div_var(&const_one, base, result, rscale, true, true);
   11537          30 :             return;
   11538          54 :         case 2:
   11539          54 :             mul_var(base, base, result, rscale);
   11540          54 :             return;
   11541        1008 :         default:
   11542        1008 :             break;
   11543             :     }
   11544             : 
   11545             :     /* Handle the special case where the base is zero */
   11546        1008 :     if (base->ndigits == 0)
   11547             :     {
   11548           0 :         if (exp < 0)
   11549           0 :             ereport(ERROR,
   11550             :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11551             :                      errmsg("division by zero")));
   11552           0 :         zero_var(result);
   11553           0 :         result->dscale = rscale;
   11554           0 :         return;
   11555             :     }
   11556             : 
   11557             :     /*
   11558             :      * The general case repeatedly multiplies base according to the bit
   11559             :      * pattern of exp.
   11560             :      *
   11561             :      * The local rscale used for each multiplication is varied to keep a fixed
   11562             :      * number of significant digits, sufficient to give the required result
   11563             :      * scale.
   11564             :      */
   11565             : 
   11566             :     /*
   11567             :      * Approximate number of significant digits in the result.  Note that the
   11568             :      * underflow test above, together with the choice of rscale, ensures that
   11569             :      * this approximation is necessarily > 0.
   11570             :      */
   11571        1008 :     sig_digits = 1 + rscale + (int) f;
   11572             : 
   11573             :     /*
   11574             :      * The multiplications to produce the result may introduce an error of up
   11575             :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11576             :      * of precision (plus a few more for good measure).
   11577             :      */
   11578        1008 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11579             : 
   11580             :     /*
   11581             :      * Now we can proceed with the multiplications.
   11582             :      */
   11583        1008 :     neg = (exp < 0);
   11584        1008 :     mask = pg_abs_s32(exp);
   11585             : 
   11586        1008 :     init_var(&base_prod);
   11587        1008 :     set_var_from_var(base, &base_prod);
   11588             : 
   11589        1008 :     if (mask & 1)
   11590         498 :         set_var_from_var(base, result);
   11591             :     else
   11592         510 :         set_var_from_var(&const_one, result);
   11593             : 
   11594        5076 :     while ((mask >>= 1) > 0)
   11595             :     {
   11596             :         /*
   11597             :          * Do the multiplications using rscales large enough to hold the
   11598             :          * results to the required number of significant digits, but don't
   11599             :          * waste time by exceeding the scales of the numbers themselves.
   11600             :          */
   11601        4068 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11602        4068 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11603        4068 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11604             : 
   11605        4068 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11606             : 
   11607        4068 :         if (mask & 1)
   11608             :         {
   11609        2658 :             local_rscale = sig_digits -
   11610        2658 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11611        2658 :             local_rscale = Min(local_rscale,
   11612             :                                base_prod.dscale + result->dscale);
   11613        2658 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11614             : 
   11615        2658 :             mul_var(&base_prod, result, result, local_rscale);
   11616             :         }
   11617             : 
   11618             :         /*
   11619             :          * When abs(base) > 1, the number of digits to the left of the decimal
   11620             :          * point in base_prod doubles at each iteration, so if exp is large we
   11621             :          * could easily spend large amounts of time and memory space doing the
   11622             :          * multiplications.  But once the weight exceeds what will fit in
   11623             :          * int16, the final result is guaranteed to overflow (or underflow, if
   11624             :          * exp < 0), so we can give up before wasting too many cycles.
   11625             :          */
   11626        4068 :         if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
   11627        4068 :             result->weight > NUMERIC_WEIGHT_MAX)
   11628             :         {
   11629             :             /* overflow, unless neg, in which case result should be 0 */
   11630           0 :             if (!neg)
   11631           0 :                 ereport(ERROR,
   11632             :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11633             :                          errmsg("value overflows numeric format")));
   11634           0 :             zero_var(result);
   11635           0 :             neg = false;
   11636           0 :             break;
   11637             :         }
   11638             :     }
   11639             : 
   11640        1008 :     free_var(&base_prod);
   11641             : 
   11642             :     /* Compensate for input sign, and round to requested rscale */
   11643        1008 :     if (neg)
   11644         486 :         div_var(&const_one, result, result, rscale, true, false);
   11645             :     else
   11646         522 :         round_var(result, rscale);
   11647             : }
   11648             : 
   11649             : /*
   11650             :  * power_ten_int() -
   11651             :  *
   11652             :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11653             :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11654             :  */
   11655             : static void
   11656         228 : power_ten_int(int exp, NumericVar *result)
   11657             : {
   11658             :     /* Construct the result directly, starting from 10^0 = 1 */
   11659         228 :     set_var_from_var(&const_one, result);
   11660             : 
   11661             :     /* Scale needed to represent the result exactly */
   11662         228 :     result->dscale = exp < 0 ? -exp : 0;
   11663             : 
   11664             :     /* Base-NBASE weight of result and remaining exponent */
   11665         228 :     if (exp >= 0)
   11666         162 :         result->weight = exp / DEC_DIGITS;
   11667             :     else
   11668          66 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11669             : 
   11670         228 :     exp -= result->weight * DEC_DIGITS;
   11671             : 
   11672             :     /* Final adjustment of the result's single NBASE digit */
   11673         594 :     while (exp-- > 0)
   11674         366 :         result->digits[0] *= 10;
   11675         228 : }
   11676             : 
   11677             : /*
   11678             :  * random_var() - return a random value in the range [rmin, rmax].
   11679             :  */
   11680             : static void
   11681       33438 : random_var(pg_prng_state *state, const NumericVar *rmin,
   11682             :            const NumericVar *rmax, NumericVar *result)
   11683             : {
   11684             :     int         rscale;
   11685             :     NumericVar  rlen;
   11686             :     int         res_ndigits;
   11687             :     int         n;
   11688             :     int         pow10;
   11689             :     int         i;
   11690             :     uint64      rlen64;
   11691             :     int         rlen64_ndigits;
   11692             : 
   11693       33438 :     rscale = Max(rmin->dscale, rmax->dscale);
   11694             : 
   11695             :     /* Compute rlen = rmax - rmin and check the range bounds */
   11696       33438 :     init_var(&rlen);
   11697       33438 :     sub_var(rmax, rmin, &rlen);
   11698             : 
   11699       33438 :     if (rlen.sign == NUMERIC_NEG)
   11700           6 :         ereport(ERROR,
   11701             :                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
   11702             :                 errmsg("lower bound must be less than or equal to upper bound"));
   11703             : 
   11704             :     /* Special case for an empty range */
   11705       33432 :     if (rlen.ndigits == 0)
   11706             :     {
   11707          12 :         set_var_from_var(rmin, result);
   11708          12 :         result->dscale = rscale;
   11709          12 :         free_var(&rlen);
   11710          12 :         return;
   11711             :     }
   11712             : 
   11713             :     /*
   11714             :      * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
   11715             :      * and shift it to the required range by adding rmin.
   11716             :      */
   11717             : 
   11718             :     /* Required result digits */
   11719       33420 :     res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   11720             : 
   11721             :     /*
   11722             :      * To get the required rscale, the final result digit must be a multiple
   11723             :      * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
   11724             :      */
   11725       33420 :     n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
   11726       33420 :     pow10 = 1;
   11727       87900 :     for (i = 0; i < n; i++)
   11728       54480 :         pow10 *= 10;
   11729             : 
   11730             :     /*
   11731             :      * To choose a random value uniformly from the range [0, rlen], we choose
   11732             :      * from the slightly larger range [0, rlen2], where rlen2 is formed from
   11733             :      * rlen by copying the first 4 NBASE digits, and setting all remaining
   11734             :      * decimal digits to "9".
   11735             :      *
   11736             :      * Without loss of generality, we can ignore the weight of rlen2 and treat
   11737             :      * it as a pure integer for the purposes of this discussion.  The process
   11738             :      * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
   11739             :      * is a 64-bit integer formed from the first 4 NBASE digits copied from
   11740             :      * rlen.  Since this trivially factors into smaller pieces that fit in
   11741             :      * 64-bit integers, the task of choosing a random value uniformly from the
   11742             :      * rlen2 + 1 possible values in [0, rlen2] is much simpler.
   11743             :      *
   11744             :      * If the random value selected is too large, it is rejected, and we try
   11745             :      * again until we get a result <= rlen, ensuring that the overall result
   11746             :      * is uniform (no particular value is any more likely than any other).
   11747             :      *
   11748             :      * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
   11749             :      * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
   11750             :      * when DEC_DIGITS is 4). Therefore the probability of needing to reject
   11751             :      * the value chosen and retry is less than 1e-13.
   11752             :      */
   11753       33420 :     rlen64 = (uint64) rlen.digits[0];
   11754       33420 :     rlen64_ndigits = 1;
   11755       76212 :     while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
   11756             :     {
   11757       42792 :         rlen64 *= NBASE;
   11758       42792 :         if (rlen64_ndigits < rlen.ndigits)
   11759        6612 :             rlen64 += rlen.digits[rlen64_ndigits];
   11760       42792 :         rlen64_ndigits++;
   11761             :     }
   11762             : 
   11763             :     /* Loop until we get a result <= rlen */
   11764             :     do
   11765             :     {
   11766             :         NumericDigit *res_digits;
   11767             :         uint64      rand;
   11768             :         int         whole_ndigits;
   11769             : 
   11770       33420 :         alloc_var(result, res_ndigits);
   11771       33420 :         result->sign = NUMERIC_POS;
   11772       33420 :         result->weight = rlen.weight;
   11773       33420 :         result->dscale = rscale;
   11774       33420 :         res_digits = result->digits;
   11775             : 
   11776             :         /*
   11777             :          * Set the first rlen64_ndigits using a random value in [0, rlen64].
   11778             :          *
   11779             :          * If this is the whole result, and rscale is not a multiple of
   11780             :          * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
   11781             :          * multiple of pow10.
   11782             :          */
   11783       33420 :         if (rlen64_ndigits == res_ndigits && pow10 != 1)
   11784       21132 :             rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
   11785             :         else
   11786       12288 :             rand = pg_prng_uint64_range(state, 0, rlen64);
   11787             : 
   11788      109632 :         for (i = rlen64_ndigits - 1; i >= 0; i--)
   11789             :         {
   11790       76212 :             res_digits[i] = (NumericDigit) (rand % NBASE);
   11791       76212 :             rand = rand / NBASE;
   11792             :         }
   11793             : 
   11794             :         /*
   11795             :          * Set the remaining digits to random values in range [0, NBASE),
   11796             :          * noting that the last digit needs to be a multiple of pow10.
   11797             :          */
   11798       33420 :         whole_ndigits = res_ndigits;
   11799       33420 :         if (pow10 != 1)
   11800       33210 :             whole_ndigits--;
   11801             : 
   11802             :         /* Set whole digits in groups of 4 for best performance */
   11803       33420 :         i = rlen64_ndigits;
   11804       33480 :         while (i < whole_ndigits - 3)
   11805             :         {
   11806          60 :             rand = pg_prng_uint64_range(state, 0,
   11807             :                                         (uint64) NBASE * NBASE * NBASE * NBASE - 1);
   11808          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11809          60 :             rand = rand / NBASE;
   11810          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11811          60 :             rand = rand / NBASE;
   11812          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11813          60 :             rand = rand / NBASE;
   11814          60 :             res_digits[i++] = (NumericDigit) rand;
   11815             :         }
   11816             : 
   11817             :         /* Remaining whole digits */
   11818       33630 :         while (i < whole_ndigits)
   11819             :         {
   11820         210 :             rand = pg_prng_uint64_range(state, 0, NBASE - 1);
   11821         210 :             res_digits[i++] = (NumericDigit) rand;
   11822             :         }
   11823             : 
   11824             :         /* Final partial digit (multiple of pow10) */
   11825       33420 :         if (i < res_ndigits)
   11826             :         {
   11827       12078 :             rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
   11828       12078 :             res_digits[i] = (NumericDigit) rand;
   11829             :         }
   11830             : 
   11831             :         /* Remove leading/trailing zeroes */
   11832       33420 :         strip_var(result);
   11833             : 
   11834             :         /* If result > rlen, try again */
   11835             : 
   11836       33420 :     } while (cmp_var(result, &rlen) > 0);
   11837             : 
   11838             :     /* Offset the result to the required range */
   11839       33420 :     add_var(result, rmin, result);
   11840             : 
   11841       33420 :     free_var(&rlen);
   11842             : }
   11843             : 
   11844             : 
   11845             : /* ----------------------------------------------------------------------
   11846             :  *
   11847             :  * Following are the lowest level functions that operate unsigned
   11848             :  * on the variable level
   11849             :  *
   11850             :  * ----------------------------------------------------------------------
   11851             :  */
   11852             : 
   11853             : 
   11854             : /* ----------
   11855             :  * cmp_abs() -
   11856             :  *
   11857             :  *  Compare the absolute values of var1 and var2
   11858             :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11859             :  *              0  for ABS(var1) == ABS(var2)
   11860             :  *              1  for ABS(var1) > ABS(var2)
   11861             :  * ----------
   11862             :  */
   11863             : static int
   11864      709086 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11865             : {
   11866     1418172 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11867      709086 :                           var2->digits, var2->ndigits, var2->weight);
   11868             : }
   11869             : 
   11870             : /* ----------
   11871             :  * cmp_abs_common() -
   11872             :  *
   11873             :  *  Main routine of cmp_abs(). This function can be used by both
   11874             :  *  NumericVar and Numeric.
   11875             :  * ----------
   11876             :  */
   11877             : static int
   11878    19620294 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11879             :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11880             : {
   11881    19620294 :     int         i1 = 0;
   11882    19620294 :     int         i2 = 0;
   11883             : 
   11884             :     /* Check any digits before the first common digit */
   11885             : 
   11886    19620294 :     while (var1weight > var2weight && i1 < var1ndigits)
   11887             :     {
   11888       26066 :         if (var1digits[i1++] != 0)
   11889       26066 :             return 1;
   11890           0 :         var1weight--;
   11891             :     }
   11892    19594228 :     while (var2weight > var1weight && i2 < var2ndigits)
   11893             :     {
   11894      150342 :         if (var2digits[i2++] != 0)
   11895      150342 :             return -1;
   11896           0 :         var2weight--;
   11897             :     }
   11898             : 
   11899             :     /* At this point, either w1 == w2 or we've run out of digits */
   11900             : 
   11901    19443886 :     if (var1weight == var2weight)
   11902             :     {
   11903    31634690 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11904             :         {
   11905    21008102 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11906             : 
   11907    21008102 :             if (stat)
   11908             :             {
   11909     8810946 :                 if (stat > 0)
   11910     5292034 :                     return 1;
   11911     3518912 :                 return -1;
   11912             :             }
   11913             :         }
   11914             :     }
   11915             : 
   11916             :     /*
   11917             :      * At this point, we've run out of digits on one side or the other; so any
   11918             :      * remaining nonzero digits imply that side is larger
   11919             :      */
   11920    10633276 :     while (i1 < var1ndigits)
   11921             :     {
   11922        9504 :         if (var1digits[i1++] != 0)
   11923        9168 :             return 1;
   11924             :     }
   11925    10624096 :     while (i2 < var2ndigits)
   11926             :     {
   11927        1206 :         if (var2digits[i2++] != 0)
   11928         882 :             return -1;
   11929             :     }
   11930             : 
   11931    10622890 :     return 0;
   11932             : }
   11933             : 
   11934             : 
   11935             : /*
   11936             :  * add_abs() -
   11937             :  *
   11938             :  *  Add the absolute values of two variables into result.
   11939             :  *  result might point to one of the operands without danger.
   11940             :  */
   11941             : static void
   11942      446458 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11943             : {
   11944             :     NumericDigit *res_buf;
   11945             :     NumericDigit *res_digits;
   11946             :     int         res_ndigits;
   11947             :     int         res_weight;
   11948             :     int         res_rscale,
   11949             :                 rscale1,
   11950             :                 rscale2;
   11951             :     int         res_dscale;
   11952             :     int         i,
   11953             :                 i1,
   11954             :                 i2;
   11955      446458 :     int         carry = 0;
   11956             : 
   11957             :     /* copy these values into local vars for speed in inner loop */
   11958      446458 :     int         var1ndigits = var1->ndigits;
   11959      446458 :     int         var2ndigits = var2->ndigits;
   11960      446458 :     NumericDigit *var1digits = var1->digits;
   11961      446458 :     NumericDigit *var2digits = var2->digits;
   11962             : 
   11963      446458 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11964             : 
   11965      446458 :     res_dscale = Max(var1->dscale, var2->dscale);
   11966             : 
   11967             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11968      446458 :     rscale1 = var1->ndigits - var1->weight - 1;
   11969      446458 :     rscale2 = var2->ndigits - var2->weight - 1;
   11970      446458 :     res_rscale = Max(rscale1, rscale2);
   11971             : 
   11972      446458 :     res_ndigits = res_rscale + res_weight + 1;
   11973      446458 :     if (res_ndigits <= 0)
   11974           0 :         res_ndigits = 1;
   11975             : 
   11976      446458 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11977      446458 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11978      446458 :     res_digits = res_buf + 1;
   11979             : 
   11980      446458 :     i1 = res_rscale + var1->weight + 1;
   11981      446458 :     i2 = res_rscale + var2->weight + 1;
   11982     3639694 :     for (i = res_ndigits - 1; i >= 0; i--)
   11983             :     {
   11984     3193236 :         i1--;
   11985     3193236 :         i2--;
   11986     3193236 :         if (i1 >= 0 && i1 < var1ndigits)
   11987     1417206 :             carry += var1digits[i1];
   11988     3193236 :         if (i2 >= 0 && i2 < var2ndigits)
   11989     1136714 :             carry += var2digits[i2];
   11990             : 
   11991     3193236 :         if (carry >= NBASE)
   11992             :         {
   11993      226228 :             res_digits[i] = carry - NBASE;
   11994      226228 :             carry = 1;
   11995             :         }
   11996             :         else
   11997             :         {
   11998     2967008 :             res_digits[i] = carry;
   11999     2967008 :             carry = 0;
   12000             :         }
   12001             :     }
   12002             : 
   12003             :     Assert(carry == 0);         /* else we failed to allow for carry out */
   12004             : 
   12005      446458 :     digitbuf_free(result->buf);
   12006      446458 :     result->ndigits = res_ndigits;
   12007      446458 :     result->buf = res_buf;
   12008      446458 :     result->digits = res_digits;
   12009      446458 :     result->weight = res_weight;
   12010      446458 :     result->dscale = res_dscale;
   12011             : 
   12012             :     /* Remove leading/trailing zeroes */
   12013      446458 :     strip_var(result);
   12014      446458 : }
   12015             : 
   12016             : 
   12017             : /*
   12018             :  * sub_abs()
   12019             :  *
   12020             :  *  Subtract the absolute value of var2 from the absolute value of var1
   12021             :  *  and store in result. result might point to one of the operands
   12022             :  *  without danger.
   12023             :  *
   12024             :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   12025             :  */
   12026             : static void
   12027      655012 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   12028             : {
   12029             :     NumericDigit *res_buf;
   12030             :     NumericDigit *res_digits;
   12031             :     int         res_ndigits;
   12032             :     int         res_weight;
   12033             :     int         res_rscale,
   12034             :                 rscale1,
   12035             :                 rscale2;
   12036             :     int         res_dscale;
   12037             :     int         i,
   12038             :                 i1,
   12039             :                 i2;
   12040      655012 :     int         borrow = 0;
   12041             : 
   12042             :     /* copy these values into local vars for speed in inner loop */
   12043      655012 :     int         var1ndigits = var1->ndigits;
   12044      655012 :     int         var2ndigits = var2->ndigits;
   12045      655012 :     NumericDigit *var1digits = var1->digits;
   12046      655012 :     NumericDigit *var2digits = var2->digits;
   12047             : 
   12048      655012 :     res_weight = var1->weight;
   12049             : 
   12050      655012 :     res_dscale = Max(var1->dscale, var2->dscale);
   12051             : 
   12052             :     /* Note: here we are figuring rscale in base-NBASE digits */
   12053      655012 :     rscale1 = var1->ndigits - var1->weight - 1;
   12054      655012 :     rscale2 = var2->ndigits - var2->weight - 1;
   12055      655012 :     res_rscale = Max(rscale1, rscale2);
   12056             : 
   12057      655012 :     res_ndigits = res_rscale + res_weight + 1;
   12058      655012 :     if (res_ndigits <= 0)
   12059           0 :         res_ndigits = 1;
   12060             : 
   12061      655012 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   12062      655012 :     res_buf[0] = 0;             /* spare digit for later rounding */
   12063      655012 :     res_digits = res_buf + 1;
   12064             : 
   12065      655012 :     i1 = res_rscale + var1->weight + 1;
   12066      655012 :     i2 = res_rscale + var2->weight + 1;
   12067     5188668 :     for (i = res_ndigits - 1; i >= 0; i--)
   12068             :     {
   12069     4533656 :         i1--;
   12070     4533656 :         i2--;
   12071     4533656 :         if (i1 >= 0 && i1 < var1ndigits)
   12072     4111040 :             borrow += var1digits[i1];
   12073     4533656 :         if (i2 >= 0 && i2 < var2ndigits)
   12074     4033450 :             borrow -= var2digits[i2];
   12075             : 
   12076     4533656 :         if (borrow < 0)
   12077             :         {
   12078      456038 :             res_digits[i] = borrow + NBASE;
   12079      456038 :             borrow = -1;
   12080             :         }
   12081             :         else
   12082             :         {
   12083     4077618 :             res_digits[i] = borrow;
   12084     4077618 :             borrow = 0;
   12085             :         }
   12086             :     }
   12087             : 
   12088             :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   12089             : 
   12090      655012 :     digitbuf_free(result->buf);
   12091      655012 :     result->ndigits = res_ndigits;
   12092      655012 :     result->buf = res_buf;
   12093      655012 :     result->digits = res_digits;
   12094      655012 :     result->weight = res_weight;
   12095      655012 :     result->dscale = res_dscale;
   12096             : 
   12097             :     /* Remove leading/trailing zeroes */
   12098      655012 :     strip_var(result);
   12099      655012 : }
   12100             : 
   12101             : /*
   12102             :  * round_var
   12103             :  *
   12104             :  * Round the value of a variable to no more than rscale decimal digits
   12105             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   12106             :  * rounding before the decimal point.
   12107             :  */
   12108             : static void
   12109      249788 : round_var(NumericVar *var, int rscale)
   12110             : {
   12111      249788 :     NumericDigit *digits = var->digits;
   12112             :     int         di;
   12113             :     int         ndigits;
   12114             :     int         carry;
   12115             : 
   12116      249788 :     var->dscale = rscale;
   12117             : 
   12118             :     /* decimal digits wanted */
   12119      249788 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   12120             : 
   12121             :     /*
   12122             :      * If di = 0, the value loses all digits, but could round up to 1 if its
   12123             :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   12124             :      */
   12125      249788 :     if (di < 0)
   12126             :     {
   12127         106 :         var->ndigits = 0;
   12128         106 :         var->weight = 0;
   12129         106 :         var->sign = NUMERIC_POS;
   12130             :     }
   12131             :     else
   12132             :     {
   12133             :         /* NBASE digits wanted */
   12134      249682 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   12135             : 
   12136             :         /* 0, or number of decimal digits to keep in last NBASE digit */
   12137      249682 :         di %= DEC_DIGITS;
   12138             : 
   12139      249682 :         if (ndigits < var->ndigits ||
   12140       46888 :             (ndigits == var->ndigits && di > 0))
   12141             :         {
   12142      206636 :             var->ndigits = ndigits;
   12143             : 
   12144             : #if DEC_DIGITS == 1
   12145             :             /* di must be zero */
   12146             :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   12147             : #else
   12148      206636 :             if (di == 0)
   12149      164372 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   12150             :             else
   12151             :             {
   12152             :                 /* Must round within last NBASE digit */
   12153             :                 int         extra,
   12154             :                             pow10;
   12155             : 
   12156             : #if DEC_DIGITS == 4
   12157       42264 :                 pow10 = round_powers[di];
   12158             : #elif DEC_DIGITS == 2
   12159             :                 pow10 = 10;
   12160             : #else
   12161             : #error unsupported NBASE
   12162             : #endif
   12163       42264 :                 extra = digits[--ndigits] % pow10;
   12164       42264 :                 digits[ndigits] -= extra;
   12165       42264 :                 carry = 0;
   12166       42264 :                 if (extra >= pow10 / 2)
   12167             :                 {
   12168       19448 :                     pow10 += digits[ndigits];
   12169       19448 :                     if (pow10 >= NBASE)
   12170             :                     {
   12171         812 :                         pow10 -= NBASE;
   12172         812 :                         carry = 1;
   12173             :                     }
   12174       19448 :                     digits[ndigits] = pow10;
   12175             :                 }
   12176             :             }
   12177             : #endif
   12178             : 
   12179             :             /* Propagate carry if needed */
   12180      240258 :             while (carry)
   12181             :             {
   12182       33622 :                 carry += digits[--ndigits];
   12183       33622 :                 if (carry >= NBASE)
   12184             :                 {
   12185       24626 :                     digits[ndigits] = carry - NBASE;
   12186       24626 :                     carry = 1;
   12187             :                 }
   12188             :                 else
   12189             :                 {
   12190        8996 :                     digits[ndigits] = carry;
   12191        8996 :                     carry = 0;
   12192             :                 }
   12193             :             }
   12194             : 
   12195      206636 :             if (ndigits < 0)
   12196             :             {
   12197             :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   12198             :                 Assert(var->digits > var->buf);
   12199          96 :                 var->digits--;
   12200          96 :                 var->ndigits++;
   12201          96 :                 var->weight++;
   12202             :             }
   12203             :         }
   12204             :     }
   12205      249788 : }
   12206             : 
   12207             : /*
   12208             :  * trunc_var
   12209             :  *
   12210             :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   12211             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   12212             :  * truncation before the decimal point.
   12213             :  */
   12214             : static void
   12215      420898 : trunc_var(NumericVar *var, int rscale)
   12216             : {
   12217             :     int         di;
   12218             :     int         ndigits;
   12219             : 
   12220      420898 :     var->dscale = rscale;
   12221             : 
   12222             :     /* decimal digits wanted */
   12223      420898 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   12224             : 
   12225             :     /*
   12226             :      * If di <= 0, the value loses all digits.
   12227             :      */
   12228      420898 :     if (di <= 0)
   12229             :     {
   12230          90 :         var->ndigits = 0;
   12231          90 :         var->weight = 0;
   12232          90 :         var->sign = NUMERIC_POS;
   12233             :     }
   12234             :     else
   12235             :     {
   12236             :         /* NBASE digits wanted */
   12237      420808 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   12238             : 
   12239      420808 :         if (ndigits <= var->ndigits)
   12240             :         {
   12241      420538 :             var->ndigits = ndigits;
   12242             : 
   12243             : #if DEC_DIGITS == 1
   12244             :             /* no within-digit stuff to worry about */
   12245             : #else
   12246             :             /* 0, or number of decimal digits to keep in last NBASE digit */
   12247      420538 :             di %= DEC_DIGITS;
   12248             : 
   12249      420538 :             if (di > 0)
   12250             :             {
   12251             :                 /* Must truncate within last NBASE digit */
   12252         106 :                 NumericDigit *digits = var->digits;
   12253             :                 int         extra,
   12254             :                             pow10;
   12255             : 
   12256             : #if DEC_DIGITS == 4
   12257         106 :                 pow10 = round_powers[di];
   12258             : #elif DEC_DIGITS == 2
   12259             :                 pow10 = 10;
   12260             : #else
   12261             : #error unsupported NBASE
   12262             : #endif
   12263         106 :                 extra = digits[--ndigits] % pow10;
   12264         106 :                 digits[ndigits] -= extra;
   12265             :             }
   12266             : #endif
   12267             :         }
   12268             :     }
   12269      420898 : }
   12270             : 
   12271             : /*
   12272             :  * strip_var
   12273             :  *
   12274             :  * Strip any leading and trailing zeroes from a numeric variable
   12275             :  */
   12276             : static void
   12277     3334424 : strip_var(NumericVar *var)
   12278             : {
   12279     3334424 :     NumericDigit *digits = var->digits;
   12280     3334424 :     int         ndigits = var->ndigits;
   12281             : 
   12282             :     /* Strip leading zeroes */
   12283     5718882 :     while (ndigits > 0 && *digits == 0)
   12284             :     {
   12285     2384458 :         digits++;
   12286     2384458 :         var->weight--;
   12287     2384458 :         ndigits--;
   12288             :     }
   12289             : 
   12290             :     /* Strip trailing zeroes */
   12291     4128816 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   12292      794392 :         ndigits--;
   12293             : 
   12294             :     /* If it's zero, normalize the sign and weight */
   12295     3334424 :     if (ndigits == 0)
   12296             :     {
   12297       56408 :         var->sign = NUMERIC_POS;
   12298       56408 :         var->weight = 0;
   12299             :     }
   12300             : 
   12301     3334424 :     var->digits = digits;
   12302     3334424 :     var->ndigits = ndigits;
   12303     3334424 : }
   12304             : 
   12305             : 
   12306             : /* ----------------------------------------------------------------------
   12307             :  *
   12308             :  * Fast sum accumulator functions
   12309             :  *
   12310             :  * ----------------------------------------------------------------------
   12311             :  */
   12312             : 
   12313             : /*
   12314             :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   12315             :  * are not free'd.
   12316             :  */
   12317             : static void
   12318          18 : accum_sum_reset(NumericSumAccum *accum)
   12319             : {
   12320             :     int         i;
   12321             : 
   12322          18 :     accum->dscale = 0;
   12323          66 :     for (i = 0; i < accum->ndigits; i++)
   12324             :     {
   12325          48 :         accum->pos_digits[i] = 0;
   12326          48 :         accum->neg_digits[i] = 0;
   12327             :     }
   12328          18 : }
   12329             : 
   12330             : /*
   12331             :  * Accumulate a new value.
   12332             :  */
   12333             : static void
   12334     2355758 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   12335             : {
   12336             :     int32      *accum_digits;
   12337             :     int         i,
   12338             :                 val_i;
   12339             :     int         val_ndigits;
   12340             :     NumericDigit *val_digits;
   12341             : 
   12342             :     /*
   12343             :      * If we have accumulated too many values since the last carry
   12344             :      * propagation, do it now, to avoid overflowing.  (We could allow more
   12345             :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   12346             :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   12347             :      * seldom, that the performance difference is negligible.)
   12348             :      */
   12349     2355758 :     if (accum->num_uncarried == NBASE - 1)
   12350         150 :         accum_sum_carry(accum);
   12351             : 
   12352             :     /*
   12353             :      * Adjust the weight or scale of the old value, so that it can accommodate
   12354             :      * the new value.
   12355             :      */
   12356     2355758 :     accum_sum_rescale(accum, val);
   12357             : 
   12358             :     /* */
   12359     2355758 :     if (val->sign == NUMERIC_POS)
   12360     1755080 :         accum_digits = accum->pos_digits;
   12361             :     else
   12362      600678 :         accum_digits = accum->neg_digits;
   12363             : 
   12364             :     /* copy these values into local vars for speed in loop */
   12365     2355758 :     val_ndigits = val->ndigits;
   12366     2355758 :     val_digits = val->digits;
   12367             : 
   12368     2355758 :     i = accum->weight - val->weight;
   12369    11890050 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   12370             :     {
   12371     9534292 :         accum_digits[i] += (int32) val_digits[val_i];
   12372     9534292 :         i++;
   12373             :     }
   12374             : 
   12375     2355758 :     accum->num_uncarried++;
   12376     2355758 : }
   12377             : 
   12378             : /*
   12379             :  * Propagate carries.
   12380             :  */
   12381             : static void
   12382      172776 : accum_sum_carry(NumericSumAccum *accum)
   12383             : {
   12384             :     int         i;
   12385             :     int         ndigits;
   12386             :     int32      *dig;
   12387             :     int32       carry;
   12388      172776 :     int32       newdig = 0;
   12389             : 
   12390             :     /*
   12391             :      * If no new values have been added since last carry propagation, nothing
   12392             :      * to do.
   12393             :      */
   12394      172776 :     if (accum->num_uncarried == 0)
   12395          72 :         return;
   12396             : 
   12397             :     /*
   12398             :      * We maintain that the weight of the accumulator is always one larger
   12399             :      * than needed to hold the current value, before carrying, to make sure
   12400             :      * there is enough space for the possible extra digit when carry is
   12401             :      * propagated.  We cannot expand the buffer here, unless we require
   12402             :      * callers of accum_sum_final() to switch to the right memory context.
   12403             :      */
   12404             :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12405             : 
   12406      172704 :     ndigits = accum->ndigits;
   12407             : 
   12408             :     /* Propagate carry in the positive sum */
   12409      172704 :     dig = accum->pos_digits;
   12410      172704 :     carry = 0;
   12411     2605574 :     for (i = ndigits - 1; i >= 0; i--)
   12412             :     {
   12413     2432870 :         newdig = dig[i] + carry;
   12414     2432870 :         if (newdig >= NBASE)
   12415             :         {
   12416      110798 :             carry = newdig / NBASE;
   12417      110798 :             newdig -= carry * NBASE;
   12418             :         }
   12419             :         else
   12420     2322072 :             carry = 0;
   12421     2432870 :         dig[i] = newdig;
   12422             :     }
   12423             :     /* Did we use up the digit reserved for carry propagation? */
   12424      172704 :     if (newdig > 0)
   12425        2638 :         accum->have_carry_space = false;
   12426             : 
   12427             :     /* And the same for the negative sum */
   12428      172704 :     dig = accum->neg_digits;
   12429      172704 :     carry = 0;
   12430     2605574 :     for (i = ndigits - 1; i >= 0; i--)
   12431             :     {
   12432     2432870 :         newdig = dig[i] + carry;
   12433     2432870 :         if (newdig >= NBASE)
   12434             :         {
   12435         198 :             carry = newdig / NBASE;
   12436         198 :             newdig -= carry * NBASE;
   12437             :         }
   12438             :         else
   12439     2432672 :             carry = 0;
   12440     2432870 :         dig[i] = newdig;
   12441             :     }
   12442      172704 :     if (newdig > 0)
   12443          30 :         accum->have_carry_space = false;
   12444             : 
   12445      172704 :     accum->num_uncarried = 0;
   12446             : }
   12447             : 
   12448             : /*
   12449             :  * Re-scale accumulator to accommodate new value.
   12450             :  *
   12451             :  * If the new value has more digits than the current digit buffers in the
   12452             :  * accumulator, enlarge the buffers.
   12453             :  */
   12454             : static void
   12455     2355758 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   12456             : {
   12457     2355758 :     int         old_weight = accum->weight;
   12458     2355758 :     int         old_ndigits = accum->ndigits;
   12459             :     int         accum_ndigits;
   12460             :     int         accum_weight;
   12461             :     int         accum_rscale;
   12462             :     int         val_rscale;
   12463             : 
   12464     2355758 :     accum_weight = old_weight;
   12465     2355758 :     accum_ndigits = old_ndigits;
   12466             : 
   12467             :     /*
   12468             :      * Does the new value have a larger weight? If so, enlarge the buffers,
   12469             :      * and shift the existing value to the new weight, by adding leading
   12470             :      * zeros.
   12471             :      *
   12472             :      * We enforce that the accumulator always has a weight one larger than
   12473             :      * needed for the inputs, so that we have space for an extra digit at the
   12474             :      * final carry-propagation phase, if necessary.
   12475             :      */
   12476     2355758 :     if (val->weight >= accum_weight)
   12477             :     {
   12478      262248 :         accum_weight = val->weight + 1;
   12479      262248 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   12480             :     }
   12481             : 
   12482             :     /*
   12483             :      * Even though the new value is small, we might've used up the space
   12484             :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   12485             :      * so, enlarge to make room for another one.
   12486             :      */
   12487     2093510 :     else if (!accum->have_carry_space)
   12488             :     {
   12489          72 :         accum_weight++;
   12490          72 :         accum_ndigits++;
   12491             :     }
   12492             : 
   12493             :     /* Is the new value wider on the right side? */
   12494     2355758 :     accum_rscale = accum_ndigits - accum_weight - 1;
   12495     2355758 :     val_rscale = val->ndigits - val->weight - 1;
   12496     2355758 :     if (val_rscale > accum_rscale)
   12497      172270 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   12498             : 
   12499     2355758 :     if (accum_ndigits != old_ndigits ||
   12500             :         accum_weight != old_weight)
   12501             :     {
   12502             :         int32      *new_pos_digits;
   12503             :         int32      *new_neg_digits;
   12504             :         int         weightdiff;
   12505             : 
   12506      262588 :         weightdiff = accum_weight - old_weight;
   12507             : 
   12508      262588 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   12509      262588 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   12510             : 
   12511      262588 :         if (accum->pos_digits)
   12512             :         {
   12513       90388 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   12514             :                    old_ndigits * sizeof(int32));
   12515       90388 :             pfree(accum->pos_digits);
   12516             : 
   12517       90388 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   12518             :                    old_ndigits * sizeof(int32));
   12519       90388 :             pfree(accum->neg_digits);
   12520             :         }
   12521             : 
   12522      262588 :         accum->pos_digits = new_pos_digits;
   12523      262588 :         accum->neg_digits = new_neg_digits;
   12524             : 
   12525      262588 :         accum->weight = accum_weight;
   12526      262588 :         accum->ndigits = accum_ndigits;
   12527             : 
   12528             :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12529      262588 :         accum->have_carry_space = true;
   12530             :     }
   12531             : 
   12532     2355758 :     if (val->dscale > accum->dscale)
   12533         300 :         accum->dscale = val->dscale;
   12534     2355758 : }
   12535             : 
   12536             : /*
   12537             :  * Return the current value of the accumulator.  This perform final carry
   12538             :  * propagation, and adds together the positive and negative sums.
   12539             :  *
   12540             :  * Unlike all the other routines, the caller is not required to switch to
   12541             :  * the memory context that holds the accumulator.
   12542             :  */
   12543             : static void
   12544      172626 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   12545             : {
   12546             :     int         i;
   12547             :     NumericVar  pos_var;
   12548             :     NumericVar  neg_var;
   12549             : 
   12550      172626 :     if (accum->ndigits == 0)
   12551             :     {
   12552           0 :         set_var_from_var(&const_zero, result);
   12553           0 :         return;
   12554             :     }
   12555             : 
   12556             :     /* Perform final carry */
   12557      172626 :     accum_sum_carry(accum);
   12558             : 
   12559             :     /* Create NumericVars representing the positive and negative sums */
   12560      172626 :     init_var(&pos_var);
   12561      172626 :     init_var(&neg_var);
   12562             : 
   12563      172626 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   12564      172626 :     pos_var.weight = neg_var.weight = accum->weight;
   12565      172626 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   12566      172626 :     pos_var.sign = NUMERIC_POS;
   12567      172626 :     neg_var.sign = NUMERIC_NEG;
   12568             : 
   12569      172626 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   12570      172626 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   12571             : 
   12572     2605156 :     for (i = 0; i < accum->ndigits; i++)
   12573             :     {
   12574             :         Assert(accum->pos_digits[i] < NBASE);
   12575     2432530 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   12576             : 
   12577             :         Assert(accum->neg_digits[i] < NBASE);
   12578     2432530 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   12579             :     }
   12580             : 
   12581             :     /* And add them together */
   12582      172626 :     add_var(&pos_var, &neg_var, result);
   12583             : 
   12584             :     /* Remove leading/trailing zeroes */
   12585      172626 :     strip_var(result);
   12586             : }
   12587             : 
   12588             : /*
   12589             :  * Copy an accumulator's state.
   12590             :  *
   12591             :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   12592             :  * freeing old values.
   12593             :  */
   12594             : static void
   12595          42 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   12596             : {
   12597          42 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12598          42 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12599             : 
   12600          42 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12601          42 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12602          42 :     dst->num_uncarried = src->num_uncarried;
   12603          42 :     dst->ndigits = src->ndigits;
   12604          42 :     dst->weight = src->weight;
   12605          42 :     dst->dscale = src->dscale;
   12606          42 : }
   12607             : 
   12608             : /*
   12609             :  * Add the current value of 'accum2' into 'accum'.
   12610             :  */
   12611             : static void
   12612          48 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12613             : {
   12614             :     NumericVar  tmp_var;
   12615             : 
   12616          48 :     init_var(&tmp_var);
   12617             : 
   12618          48 :     accum_sum_final(accum2, &tmp_var);
   12619          48 :     accum_sum_add(accum, &tmp_var);
   12620             : 
   12621          48 :     free_var(&tmp_var);
   12622          48 : }

Generated by: LCOV version 1.16