LCOV - code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 3834 4056 94.5 %
Date: 2025-01-18 04:15:08 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      119884 : numeric_in(PG_FUNCTION_ARGS)
     638             : {
     639      119884 :     char       *str = PG_GETARG_CSTRING(0);
     640             : #ifdef NOT_USED
     641             :     Oid         typelem = PG_GETARG_OID(1);
     642             : #endif
     643      119884 :     int32       typmod = PG_GETARG_INT32(2);
     644      119884 :     Node       *escontext = fcinfo->context;
     645             :     Numeric     res;
     646             :     const char *cp;
     647             :     const char *numstart;
     648             :     int         sign;
     649             : 
     650             :     /* Skip leading spaces */
     651      119884 :     cp = str;
     652      120274 :     while (*cp)
     653             :     {
     654      120262 :         if (!isspace((unsigned char) *cp))
     655      119872 :             break;
     656         390 :         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      119884 :     numstart = cp;
     665      119884 :     sign = NUMERIC_POS;
     666             : 
     667      119884 :     if (*cp == '+')
     668          48 :         cp++;
     669      119836 :     else if (*cp == '-')
     670             :     {
     671        3744 :         sign = NUMERIC_NEG;
     672        3744 :         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      119884 :     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        1776 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     689             :         {
     690         592 :             res = make_result(&const_nan);
     691         592 :             cp = numstart + 3;
     692             :         }
     693        1184 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     694             :         {
     695         492 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     696         492 :             cp += 8;
     697             :         }
     698         692 :         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         104 :             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        1714 :         while (*cp)
     714             :         {
     715          42 :             if (!isspace((unsigned char) *cp))
     716           0 :                 goto invalid_syntax;
     717          42 :             cp++;
     718             :         }
     719             : 
     720        1672 :         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      118108 :         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      118108 :         if (cp[0] == '0')
     740             :         {
     741       36380 :             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       36224 :                 default:
     756       36224 :                     base = 10;
     757             :             }
     758             :         }
     759             :         else
     760       81728 :             base = 10;
     761             : 
     762             :         /* Parse the rest of the number and apply the sign */
     763      118108 :         if (base == 10)
     764             :         {
     765      117952 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     766          42 :                 PG_RETURN_NULL();
     767      117904 :             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      118120 :         while (*cp)
     781             :         {
     782         150 :             if (!isspace((unsigned char) *cp))
     783          72 :                 goto invalid_syntax;
     784          78 :             cp++;
     785             :         }
     786             : 
     787      117970 :         if (!apply_typmod(&value, typmod, escontext))
     788          24 :             PG_RETURN_NULL();
     789             : 
     790      117946 :         res = make_result_opt_error(&value, &have_error);
     791             : 
     792      117946 :         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      117928 :         free_var(&value);
     798             :     }
     799             : 
     800      119600 :     PG_RETURN_NUMERIC(res);
     801             : 
     802         176 : invalid_syntax:
     803         176 :     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      789298 : numeric_out(PG_FUNCTION_ARGS)
     817             : {
     818      789298 :     Numeric     num = PG_GETARG_NUMERIC(0);
     819             :     NumericVar  x;
     820             :     char       *str;
     821             : 
     822             :     /*
     823             :      * Handle NaN and infinities
     824             :      */
     825      789298 :     if (NUMERIC_IS_SPECIAL(num))
     826             :     {
     827        3604 :         if (NUMERIC_IS_PINF(num))
     828        1040 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     829        2564 :         else if (NUMERIC_IS_NINF(num))
     830         658 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     831             :         else
     832        1906 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     833             :     }
     834             : 
     835             :     /*
     836             :      * Get the number in the variable format.
     837             :      */
     838      785694 :     init_var_from_num(num, &x);
     839             : 
     840      785694 :     str = get_str_from_var(&x);
     841             : 
     842      785694 :     PG_RETURN_CSTRING(str);
     843             : }
     844             : 
     845             : /*
     846             :  * numeric_is_nan() -
     847             :  *
     848             :  *  Is Numeric value a NaN?
     849             :  */
     850             : bool
     851       13670 : numeric_is_nan(Numeric num)
     852             : {
     853       13670 :     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        1890 : make_numeric_typmod(int precision, int scale)
     908             : {
     909        1890 :     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      143192 : is_valid_numeric_typmod(int32 typmod)
     917             : {
     918      143192 :     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       24292 : numeric_typmod_precision(int32 typmod)
     928             : {
     929       24292 :     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       17128 : numeric_typmod_scale(int32 typmod)
     943             : {
     944       17128 :     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        7164 : numeric_maximum_size(int32 typmod)
     954             : {
     955             :     int         precision;
     956             :     int         numeric_digits;
     957             : 
     958        7164 :     if (!is_valid_numeric_typmod(typmod))
     959           0 :         return -1;
     960             : 
     961             :     /* precision (ie, max # of digits) is in upper bits of typmod */
     962        7164 :     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        7164 :     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        7164 :     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       12966 : numeric_normalize(Numeric num)
    1027             : {
    1028             :     NumericVar  x;
    1029             :     char       *str;
    1030             :     int         last;
    1031             : 
    1032             :     /*
    1033             :      * Handle NaN and infinities
    1034             :      */
    1035       12966 :     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       12966 :     init_var_from_num(num, &x);
    1046             : 
    1047       12966 :     str = get_str_from_var(&x);
    1048             : 
    1049             :     /* If there's no decimal point, there's certainly nothing to remove. */
    1050       12966 :     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       12966 :     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       11790 : numeric     (PG_FUNCTION_ARGS)
    1247             : {
    1248       11790 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1249       11790 :     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       11790 :     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       11580 :     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       11580 :     precision = numeric_typmod_precision(typmod);
    1279       11580 :     scale = numeric_typmod_scale(typmod);
    1280       11580 :     maxdigits = precision - scale;
    1281             : 
    1282             :     /* The target display scale is non-negative */
    1283       11580 :     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       11580 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1293       11580 :     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        4446 :     init_var(&var);
    1313             : 
    1314        4446 :     set_var_from_num(num, &var);
    1315        4446 :     (void) apply_typmod(&var, typmod, NULL);
    1316        4386 :     new = make_result(&var);
    1317             : 
    1318        4386 :     free_var(&var);
    1319             : 
    1320        4386 :     PG_RETURN_NUMERIC(new);
    1321             : }
    1322             : 
    1323             : Datum
    1324        1932 : numerictypmodin(PG_FUNCTION_ARGS)
    1325             : {
    1326        1932 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1327             :     int32      *tl;
    1328             :     int         n;
    1329             :     int32       typmod;
    1330             : 
    1331        1932 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1332             : 
    1333        1932 :     if (n == 2)
    1334             :     {
    1335        1912 :         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        1894 :         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        1882 :         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        1890 :     PG_RETURN_INT32(typmod);
    1366             : }
    1367             : 
    1368             : Datum
    1369         376 : numerictypmodout(PG_FUNCTION_ARGS)
    1370             : {
    1371         376 :     int32       typmod = PG_GETARG_INT32(0);
    1372         376 :     char       *res = (char *) palloc(64);
    1373             : 
    1374         376 :     if (is_valid_numeric_typmod(typmod))
    1375         376 :         snprintf(res, 64, "(%d,%d)",
    1376             :                  numeric_typmod_precision(typmod),
    1377             :                  numeric_typmod_scale(typmod));
    1378             :     else
    1379           0 :         *res = '\0';
    1380             : 
    1381         376 :     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         372 : generate_series_numeric(PG_FUNCTION_ARGS)
    1704             : {
    1705         372 :     return generate_series_step_numeric(fcinfo);
    1706             : }
    1707             : 
    1708             : Datum
    1709         822 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1710             : {
    1711             :     generate_series_numeric_fctx *fctx;
    1712             :     FuncCallContext *funcctx;
    1713             :     MemoryContext oldcontext;
    1714             : 
    1715         822 :     if (SRF_IS_FIRSTCALL())
    1716             :     {
    1717         162 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1718         162 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1719         162 :         NumericVar  steploc = const_one;
    1720             : 
    1721             :         /* Reject NaN and infinities in start and stop values */
    1722         162 :         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         150 :         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         138 :         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         120 :         funcctx = SRF_FIRSTCALL_INIT();
    1772             : 
    1773             :         /*
    1774             :          * Switch to memory context appropriate for multiple function calls.
    1775             :          */
    1776         120 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1777             : 
    1778             :         /* allocate memory for user context */
    1779             :         fctx = (generate_series_numeric_fctx *)
    1780         120 :             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         120 :         init_var(&fctx->current);
    1789         120 :         init_var(&fctx->stop);
    1790         120 :         init_var(&fctx->step);
    1791             : 
    1792         120 :         set_var_from_num(start_num, &fctx->current);
    1793         120 :         set_var_from_num(stop_num, &fctx->stop);
    1794         120 :         set_var_from_var(&steploc, &fctx->step);
    1795             : 
    1796         120 :         funcctx->user_fctx = fctx;
    1797         120 :         MemoryContextSwitchTo(oldcontext);
    1798             :     }
    1799             : 
    1800             :     /* stuff done on every call of the function */
    1801         780 :     funcctx = SRF_PERCALL_SETUP();
    1802             : 
    1803             :     /*
    1804             :      * Get the saved state and use current state as the result of this
    1805             :      * iteration.
    1806             :      */
    1807         780 :     fctx = funcctx->user_fctx;
    1808             : 
    1809        1380 :     if ((fctx->step.sign == NUMERIC_POS &&
    1810         600 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1811         468 :         (fctx->step.sign == NUMERIC_NEG &&
    1812         180 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1813             :     {
    1814         660 :         Numeric     result = make_result(&fctx->current);
    1815             : 
    1816             :         /* switch to memory context appropriate for iteration calculation */
    1817         660 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1818             : 
    1819             :         /* increment current in preparation for next iteration */
    1820         660 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1821         660 :         MemoryContextSwitchTo(oldcontext);
    1822             : 
    1823             :         /* do when there is more left to send */
    1824         660 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1825             :     }
    1826             :     else
    1827             :         /* do when there is no more left */
    1828         120 :         SRF_RETURN_DONE(funcctx);
    1829             : }
    1830             : 
    1831             : /*
    1832             :  * Planner support function for generate_series(numeric, numeric [, numeric])
    1833             :  */
    1834             : Datum
    1835         450 : generate_series_numeric_support(PG_FUNCTION_ARGS)
    1836             : {
    1837         450 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1838         450 :     Node       *ret = NULL;
    1839             : 
    1840         450 :     if (IsA(rawreq, SupportRequestRows))
    1841             :     {
    1842             :         /* Try to estimate the number of rows returned */
    1843         144 :         SupportRequestRows *req = (SupportRequestRows *) rawreq;
    1844             : 
    1845         144 :         if (is_funcclause(req->node))    /* be paranoid */
    1846             :         {
    1847         144 :             List       *args = ((FuncExpr *) req->node)->args;
    1848             :             Node       *arg1,
    1849             :                        *arg2,
    1850             :                        *arg3;
    1851             : 
    1852             :             /* We can use estimated argument values here */
    1853         144 :             arg1 = estimate_expression_value(req->root, linitial(args));
    1854         144 :             arg2 = estimate_expression_value(req->root, lsecond(args));
    1855         144 :             if (list_length(args) >= 3)
    1856         102 :                 arg3 = estimate_expression_value(req->root, lthird(args));
    1857             :             else
    1858          42 :                 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         144 :             if ((IsA(arg1, Const) &&
    1867         138 :                  ((Const *) arg1)->constisnull) ||
    1868         144 :                 (IsA(arg2, Const) &&
    1869         144 :                  ((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         144 :             else if (IsA(arg1, Const) &&
    1877         138 :                      IsA(arg2, Const) &&
    1878         102 :                      (arg3 == NULL || IsA(arg3, Const)))
    1879             :             {
    1880             :                 Numeric     start_num;
    1881             :                 Numeric     stop_num;
    1882         126 :                 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         126 :                 start_num = DatumGetNumeric(((Const *) arg1)->constvalue);
    1889         126 :                 stop_num = DatumGetNumeric(((Const *) arg2)->constvalue);
    1890             : 
    1891         126 :                 if (NUMERIC_IS_SPECIAL(start_num) ||
    1892         108 :                     NUMERIC_IS_SPECIAL(stop_num))
    1893          48 :                     PG_RETURN_POINTER(NULL);
    1894             : 
    1895          96 :                 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          78 :                 if (cmp_var(&step, &const_zero) != 0)
    1914             :                 {
    1915             :                     NumericVar  start;
    1916             :                     NumericVar  stop;
    1917             :                     NumericVar  res;
    1918             : 
    1919          66 :                     init_var_from_num(start_num, &start);
    1920          66 :                     init_var_from_num(stop_num, &stop);
    1921             : 
    1922          66 :                     init_var(&res);
    1923          66 :                     sub_var(&stop, &start, &res);
    1924             : 
    1925          66 :                     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          60 :                         if (arg3)
    1934          30 :                             div_var(&res, &step, &res, 0, false, false);
    1935             :                         else
    1936          30 :                             trunc_var(&res, 0); /* step = 1 */
    1937             : 
    1938          60 :                         req->rows = numericvar_to_double_no_overflow(&res) + 1;
    1939          60 :                         ret = (Node *) req;
    1940             :                     }
    1941             : 
    1942          66 :                     free_var(&res);
    1943             :                 }
    1944             :             }
    1945             :         }
    1946             :     }
    1947             : 
    1948         402 :     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 the
    1962             :  * upper bound is assigned to an additional bucket (with number
    1963             :  * count+1). We don't allow "NaN" for any of the numeric arguments.
    1964             :  */
    1965             : Datum
    1966         780 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1967             : {
    1968         780 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1969         780 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1970         780 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1971         780 :     int32       count = PG_GETARG_INT32(3);
    1972             :     NumericVar  count_var;
    1973             :     NumericVar  result_var;
    1974             :     int32       result;
    1975             : 
    1976         780 :     if (count <= 0)
    1977          12 :         ereport(ERROR,
    1978             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1979             :                  errmsg("count must be greater than zero")));
    1980             : 
    1981         768 :     if (NUMERIC_IS_SPECIAL(operand) ||
    1982         750 :         NUMERIC_IS_SPECIAL(bound1) ||
    1983         744 :         NUMERIC_IS_SPECIAL(bound2))
    1984             :     {
    1985          36 :         if (NUMERIC_IS_NAN(operand) ||
    1986          30 :             NUMERIC_IS_NAN(bound1) ||
    1987          30 :             NUMERIC_IS_NAN(bound2))
    1988           6 :             ereport(ERROR,
    1989             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1990             :                      errmsg("operand, lower bound, and upper bound cannot be NaN")));
    1991             :         /* We allow "operand" to be infinite; cmp_numerics will cope */
    1992          30 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1993          18 :             ereport(ERROR,
    1994             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1995             :                      errmsg("lower and upper bounds must be finite")));
    1996             :     }
    1997             : 
    1998         744 :     init_var(&result_var);
    1999         744 :     init_var(&count_var);
    2000             : 
    2001             :     /* Convert 'count' to a numeric, for ease of use later */
    2002         744 :     int64_to_numericvar((int64) count, &count_var);
    2003             : 
    2004         744 :     switch (cmp_numerics(bound1, bound2))
    2005             :     {
    2006           6 :         case 0:
    2007           6 :             ereport(ERROR,
    2008             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    2009             :                      errmsg("lower bound cannot equal upper bound")));
    2010             :             break;
    2011             : 
    2012             :             /* bound1 < bound2 */
    2013         546 :         case -1:
    2014         546 :             if (cmp_numerics(operand, bound1) < 0)
    2015         114 :                 set_var_from_var(&const_zero, &result_var);
    2016         432 :             else if (cmp_numerics(operand, bound2) >= 0)
    2017         108 :                 add_var(&count_var, &const_one, &result_var);
    2018             :             else
    2019         324 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2020             :                                &result_var);
    2021         546 :             break;
    2022             : 
    2023             :             /* bound1 > bound2 */
    2024         192 :         case 1:
    2025         192 :             if (cmp_numerics(operand, bound1) > 0)
    2026          12 :                 set_var_from_var(&const_zero, &result_var);
    2027         180 :             else if (cmp_numerics(operand, bound2) <= 0)
    2028          24 :                 add_var(&count_var, &const_one, &result_var);
    2029             :             else
    2030         156 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2031             :                                &result_var);
    2032         192 :             break;
    2033             :     }
    2034             : 
    2035             :     /* if result exceeds the range of a legal int4, we ereport here */
    2036         738 :     if (!numericvar_to_int32(&result_var, &result))
    2037           0 :         ereport(ERROR,
    2038             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    2039             :                  errmsg("integer out of range")));
    2040             : 
    2041         738 :     free_var(&count_var);
    2042         738 :     free_var(&result_var);
    2043             : 
    2044         738 :     PG_RETURN_INT32(result);
    2045             : }
    2046             : 
    2047             : /*
    2048             :  * 'operand' is inside the bucket range, so determine the correct
    2049             :  * bucket for it to go in. The calculations performed by this function
    2050             :  * are derived directly from the SQL2003 spec. Note however that we
    2051             :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    2052             :  */
    2053             : static void
    2054         480 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    2055             :                const NumericVar *count_var, NumericVar *result_var)
    2056             : {
    2057             :     NumericVar  bound1_var;
    2058             :     NumericVar  bound2_var;
    2059             :     NumericVar  operand_var;
    2060             : 
    2061         480 :     init_var_from_num(bound1, &bound1_var);
    2062         480 :     init_var_from_num(bound2, &bound2_var);
    2063         480 :     init_var_from_num(operand, &operand_var);
    2064             : 
    2065             :     /*
    2066             :      * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
    2067             :      * bound1 <= operand < bound2 or bound1 >= operand > bound2.  Either way,
    2068             :      * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
    2069             :      * where the quotient is computed using floor division (i.e., division to
    2070             :      * zero decimal places with truncation), which guarantees that the result
    2071             :      * is in the range [1, count].  Reversing the bounds doesn't affect the
    2072             :      * computation, because the signs cancel out when dividing.
    2073             :      */
    2074         480 :     sub_var(&operand_var, &bound1_var, &operand_var);
    2075         480 :     sub_var(&bound2_var, &bound1_var, &bound2_var);
    2076             : 
    2077         480 :     mul_var(&operand_var, count_var, &operand_var,
    2078         480 :             operand_var.dscale + count_var->dscale);
    2079         480 :     div_var(&operand_var, &bound2_var, result_var, 0, false, true);
    2080         480 :     add_var(result_var, &const_one, result_var);
    2081             : 
    2082         480 :     free_var(&bound1_var);
    2083         480 :     free_var(&bound2_var);
    2084         480 :     free_var(&operand_var);
    2085         480 : }
    2086             : 
    2087             : /* ----------------------------------------------------------------------
    2088             :  *
    2089             :  * Comparison functions
    2090             :  *
    2091             :  * Note: btree indexes need these routines not to leak memory; therefore,
    2092             :  * be careful to free working copies of toasted datums.  Most places don't
    2093             :  * need to be so careful.
    2094             :  *
    2095             :  * Sort support:
    2096             :  *
    2097             :  * We implement the sortsupport strategy routine in order to get the benefit of
    2098             :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    2099             :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    2100             :  * while this could be worked on itself, the abbreviation strategy gives more
    2101             :  * speedup in many common cases.
    2102             :  *
    2103             :  * Two different representations are used for the abbreviated form, one in
    2104             :  * int32 and one in int64, whichever fits into a by-value Datum.  In both cases
    2105             :  * the representation is negated relative to the original value, because we use
    2106             :  * the largest negative value for NaN, which sorts higher than other values. We
    2107             :  * convert the absolute value of the numeric to a 31-bit or 63-bit positive
    2108             :  * value, and then negate it if the original number was positive.
    2109             :  *
    2110             :  * We abort the abbreviation process if the abbreviation cardinality is below
    2111             :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    2112             :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    2113             :  * very small penalty), but we don't want to build up too many abbreviated
    2114             :  * values before first testing for abort, so we take the slightly pessimistic
    2115             :  * number.  We make no attempt to estimate the cardinality of the real values,
    2116             :  * since it plays no part in the cost model here (if the abbreviation is equal,
    2117             :  * the cost of comparing equal and unequal underlying values is comparable).
    2118             :  * We discontinue even checking for abort (saving us the hashing overhead) if
    2119             :  * the estimated cardinality gets to 100k; that would be enough to support many
    2120             :  * billions of rows while doing no worse than breaking even.
    2121             :  *
    2122             :  * ----------------------------------------------------------------------
    2123             :  */
    2124             : 
    2125             : /*
    2126             :  * Sort support strategy routine.
    2127             :  */
    2128             : Datum
    2129         986 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2130             : {
    2131         986 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2132             : 
    2133         986 :     ssup->comparator = numeric_fast_cmp;
    2134             : 
    2135         986 :     if (ssup->abbreviate)
    2136             :     {
    2137             :         NumericSortSupport *nss;
    2138         250 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2139             : 
    2140         250 :         nss = palloc(sizeof(NumericSortSupport));
    2141             : 
    2142             :         /*
    2143             :          * palloc a buffer for handling unaligned packed values in addition to
    2144             :          * the support struct
    2145             :          */
    2146         250 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2147             : 
    2148         250 :         nss->input_count = 0;
    2149         250 :         nss->estimating = true;
    2150         250 :         initHyperLogLog(&nss->abbr_card, 10);
    2151             : 
    2152         250 :         ssup->ssup_extra = nss;
    2153             : 
    2154         250 :         ssup->abbrev_full_comparator = ssup->comparator;
    2155         250 :         ssup->comparator = numeric_cmp_abbrev;
    2156         250 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2157         250 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2158             : 
    2159         250 :         MemoryContextSwitchTo(oldcontext);
    2160             :     }
    2161             : 
    2162         986 :     PG_RETURN_VOID();
    2163             : }
    2164             : 
    2165             : /*
    2166             :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2167             :  * (must not leak memory!)
    2168             :  */
    2169             : static Datum
    2170       19132 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2171             : {
    2172       19132 :     NumericSortSupport *nss = ssup->ssup_extra;
    2173       19132 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2174             :     Numeric     value;
    2175             :     Datum       result;
    2176             : 
    2177       19132 :     nss->input_count += 1;
    2178             : 
    2179             :     /*
    2180             :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2181             :      * we keep and reuse a buffer large enough to handle any short datum.
    2182             :      */
    2183       19132 :     if (VARATT_IS_SHORT(original_varatt))
    2184             :     {
    2185        1026 :         void       *buf = nss->buf;
    2186        1026 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2187             : 
    2188             :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2189             : 
    2190        1026 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2191        1026 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2192             : 
    2193        1026 :         value = (Numeric) buf;
    2194             :     }
    2195             :     else
    2196       18106 :         value = (Numeric) original_varatt;
    2197             : 
    2198       19132 :     if (NUMERIC_IS_SPECIAL(value))
    2199             :     {
    2200         150 :         if (NUMERIC_IS_PINF(value))
    2201          48 :             result = NUMERIC_ABBREV_PINF;
    2202         102 :         else if (NUMERIC_IS_NINF(value))
    2203          48 :             result = NUMERIC_ABBREV_NINF;
    2204             :         else
    2205          54 :             result = NUMERIC_ABBREV_NAN;
    2206             :     }
    2207             :     else
    2208             :     {
    2209             :         NumericVar  var;
    2210             : 
    2211       18982 :         init_var_from_num(value, &var);
    2212             : 
    2213       18982 :         result = numeric_abbrev_convert_var(&var, nss);
    2214             :     }
    2215             : 
    2216             :     /* should happen only for external/compressed toasts */
    2217       19132 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
    2218           0 :         pfree(original_varatt);
    2219             : 
    2220       19132 :     return result;
    2221             : }
    2222             : 
    2223             : /*
    2224             :  * Consider whether to abort abbreviation.
    2225             :  *
    2226             :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2227             :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2228             :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2229             :  * whether the underlying values are also equal.
    2230             :  */
    2231             : static bool
    2232         144 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2233             : {
    2234         144 :     NumericSortSupport *nss = ssup->ssup_extra;
    2235             :     double      abbr_card;
    2236             : 
    2237         144 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2238         144 :         return false;
    2239             : 
    2240           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2241             : 
    2242             :     /*
    2243             :      * If we have >100k distinct values, then even if we were sorting many
    2244             :      * billion rows we'd likely still break even, and the penalty of undoing
    2245             :      * that many rows of abbrevs would probably not be worth it. Stop even
    2246             :      * counting at that point.
    2247             :      */
    2248           0 :     if (abbr_card > 100000.0)
    2249             :     {
    2250           0 :         if (trace_sort)
    2251           0 :             elog(LOG,
    2252             :                  "numeric_abbrev: estimation ends at cardinality %f"
    2253             :                  " after " INT64_FORMAT " values (%d rows)",
    2254             :                  abbr_card, nss->input_count, memtupcount);
    2255           0 :         nss->estimating = false;
    2256           0 :         return false;
    2257             :     }
    2258             : 
    2259             :     /*
    2260             :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2261             :      * break even point is somewhere between one per 100k rows, where
    2262             :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2263             :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2264             :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2265             :      * abort earlier on genuinely pathological data where we've had exactly
    2266             :      * one abbreviated value in the first 10k (non-null) rows.
    2267             :      */
    2268           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2269             :     {
    2270           0 :         if (trace_sort)
    2271           0 :             elog(LOG,
    2272             :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2273             :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2274             :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2275             :                  nss->input_count, memtupcount);
    2276           0 :         return true;
    2277             :     }
    2278             : 
    2279           0 :     if (trace_sort)
    2280           0 :         elog(LOG,
    2281             :              "numeric_abbrev: cardinality %f"
    2282             :              " after " INT64_FORMAT " values (%d rows)",
    2283             :              abbr_card, nss->input_count, memtupcount);
    2284             : 
    2285           0 :     return false;
    2286             : }
    2287             : 
    2288             : /*
    2289             :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2290             :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2291             :  * are, but it is a required part of the sort support API when abbreviations
    2292             :  * are performed.
    2293             :  *
    2294             :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2295             :  * aligning short-varlena inputs, but this has not so far been considered to
    2296             :  * be worth the effort.
    2297             :  */
    2298             : static int
    2299     4556306 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2300             : {
    2301     4556306 :     Numeric     nx = DatumGetNumeric(x);
    2302     4556306 :     Numeric     ny = DatumGetNumeric(y);
    2303             :     int         result;
    2304             : 
    2305     4556306 :     result = cmp_numerics(nx, ny);
    2306             : 
    2307     4556306 :     if ((Pointer) nx != DatumGetPointer(x))
    2308      172830 :         pfree(nx);
    2309     4556306 :     if ((Pointer) ny != DatumGetPointer(y))
    2310      172824 :         pfree(ny);
    2311             : 
    2312     4556306 :     return result;
    2313             : }
    2314             : 
    2315             : /*
    2316             :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2317             :  * values differ, but if the abbreviations differ, they must reflect the
    2318             :  * ordering of the true values.)
    2319             :  */
    2320             : static int
    2321      188956 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2322             : {
    2323             :     /*
    2324             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2325             :      * negated relative to the original value, to handle NaN/infinity cases.
    2326             :      */
    2327      188956 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2328       99290 :         return 1;
    2329       89666 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2330       89432 :         return -1;
    2331         234 :     return 0;
    2332             : }
    2333             : 
    2334             : /*
    2335             :  * Abbreviate a NumericVar according to the available bit size.
    2336             :  *
    2337             :  * The 31-bit value is constructed as:
    2338             :  *
    2339             :  *  0 + 7bits digit weight + 24 bits digit value
    2340             :  *
    2341             :  * where the digit weight is in single decimal digits, not digit words, and
    2342             :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2343             :  * significant decimal digits of the value converted to binary. Values whose
    2344             :  * weights would fall outside the representable range are rounded off to zero
    2345             :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2346             :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2347             :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2348             :  * to be a serious limitation, or when values are of the same magnitude and
    2349             :  * equal in the first 7 decimal digits, which is considered to be an
    2350             :  * unavoidable limitation given the available bits. (Stealing three more bits
    2351             :  * to compare another digit would narrow the range of representable weights by
    2352             :  * a factor of 8, which starts to look like a real limiting factor.)
    2353             :  *
    2354             :  * (The value 44 for the excess is essentially arbitrary)
    2355             :  *
    2356             :  * The 63-bit value is constructed as:
    2357             :  *
    2358             :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2359             :  *
    2360             :  * The weight in this case is again stored in excess-44, but this time it is
    2361             :  * the original weight in digit words (i.e. powers of 10000). The first four
    2362             :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2363             :  * are packed into 14 bits each to form the rest of the value. Again,
    2364             :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2365             :  * representable range in this case is 10^-176 to 10^332, which is considered
    2366             :  * to be good enough for all practical purposes, and comparison of 4 words
    2367             :  * means that at least 13 decimal digits are compared, which is considered to
    2368             :  * be a reasonable compromise between effectiveness and efficiency in computing
    2369             :  * the abbreviation.
    2370             :  *
    2371             :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2372             :  * to match the value used in the 31-bit case)
    2373             :  *
    2374             :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2375             :  * and then treated as unsigned, so the smallest representable value is stored
    2376             :  * with all bits zero. This allows simple comparisons to work on the composite
    2377             :  * value.
    2378             :  */
    2379             : 
    2380             : #if NUMERIC_ABBREV_BITS == 64
    2381             : 
    2382             : static Datum
    2383       18982 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2384             : {
    2385       18982 :     int         ndigits = var->ndigits;
    2386       18982 :     int         weight = var->weight;
    2387             :     int64       result;
    2388             : 
    2389       18982 :     if (ndigits == 0 || weight < -44)
    2390             :     {
    2391          52 :         result = 0;
    2392             :     }
    2393       18930 :     else if (weight > 83)
    2394             :     {
    2395          12 :         result = PG_INT64_MAX;
    2396             :     }
    2397             :     else
    2398             :     {
    2399       18918 :         result = ((int64) (weight + 44) << 56);
    2400             : 
    2401       18918 :         switch (ndigits)
    2402             :         {
    2403           0 :             default:
    2404           0 :                 result |= ((int64) var->digits[3]);
    2405             :                 /* FALLTHROUGH */
    2406        6208 :             case 3:
    2407        6208 :                 result |= ((int64) var->digits[2]) << 14;
    2408             :                 /* FALLTHROUGH */
    2409       18292 :             case 2:
    2410       18292 :                 result |= ((int64) var->digits[1]) << 28;
    2411             :                 /* FALLTHROUGH */
    2412       18918 :             case 1:
    2413       18918 :                 result |= ((int64) var->digits[0]) << 42;
    2414       18918 :                 break;
    2415             :         }
    2416             :     }
    2417             : 
    2418             :     /* the abbrev is negated relative to the original */
    2419       18982 :     if (var->sign == NUMERIC_POS)
    2420       18884 :         result = -result;
    2421             : 
    2422       18982 :     if (nss->estimating)
    2423             :     {
    2424       18982 :         uint32      tmp = ((uint32) result
    2425       18982 :                            ^ (uint32) ((uint64) result >> 32));
    2426             : 
    2427       18982 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2428             :     }
    2429             : 
    2430       18982 :     return NumericAbbrevGetDatum(result);
    2431             : }
    2432             : 
    2433             : #endif                          /* NUMERIC_ABBREV_BITS == 64 */
    2434             : 
    2435             : #if NUMERIC_ABBREV_BITS == 32
    2436             : 
    2437             : static Datum
    2438             : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2439             : {
    2440             :     int         ndigits = var->ndigits;
    2441             :     int         weight = var->weight;
    2442             :     int32       result;
    2443             : 
    2444             :     if (ndigits == 0 || weight < -11)
    2445             :     {
    2446             :         result = 0;
    2447             :     }
    2448             :     else if (weight > 20)
    2449             :     {
    2450             :         result = PG_INT32_MAX;
    2451             :     }
    2452             :     else
    2453             :     {
    2454             :         NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
    2455             : 
    2456             :         weight = (weight + 11) * 4;
    2457             : 
    2458             :         result = var->digits[0];
    2459             : 
    2460             :         /*
    2461             :          * "result" now has 1 to 4 nonzero decimal digits. We pack in more
    2462             :          * digits to make 7 in total (largest we can fit in 24 bits)
    2463             :          */
    2464             : 
    2465             :         if (result > 999)
    2466             :         {
    2467             :             /* already have 4 digits, add 3 more */
    2468             :             result = (result * 1000) + (nxt1 / 10);
    2469             :             weight += 3;
    2470             :         }
    2471             :         else if (result > 99)
    2472             :         {
    2473             :             /* already have 3 digits, add 4 more */
    2474             :             result = (result * 10000) + nxt1;
    2475             :             weight += 2;
    2476             :         }
    2477             :         else if (result > 9)
    2478             :         {
    2479             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2480             : 
    2481             :             /* already have 2 digits, add 5 more */
    2482             :             result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
    2483             :             weight += 1;
    2484             :         }
    2485             :         else
    2486             :         {
    2487             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2488             : 
    2489             :             /* already have 1 digit, add 6 more */
    2490             :             result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
    2491             :         }
    2492             : 
    2493             :         result = result | (weight << 24);
    2494             :     }
    2495             : 
    2496             :     /* the abbrev is negated relative to the original */
    2497             :     if (var->sign == NUMERIC_POS)
    2498             :         result = -result;
    2499             : 
    2500             :     if (nss->estimating)
    2501             :     {
    2502             :         uint32      tmp = (uint32) result;
    2503             : 
    2504             :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2505             :     }
    2506             : 
    2507             :     return NumericAbbrevGetDatum(result);
    2508             : }
    2509             : 
    2510             : #endif                          /* NUMERIC_ABBREV_BITS == 32 */
    2511             : 
    2512             : /*
    2513             :  * Ordinary (non-sortsupport) comparisons follow.
    2514             :  */
    2515             : 
    2516             : Datum
    2517      767094 : numeric_cmp(PG_FUNCTION_ARGS)
    2518             : {
    2519      767094 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2520      767094 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2521             :     int         result;
    2522             : 
    2523      767094 :     result = cmp_numerics(num1, num2);
    2524             : 
    2525      767094 :     PG_FREE_IF_COPY(num1, 0);
    2526      767094 :     PG_FREE_IF_COPY(num2, 1);
    2527             : 
    2528      767094 :     PG_RETURN_INT32(result);
    2529             : }
    2530             : 
    2531             : 
    2532             : Datum
    2533      626076 : numeric_eq(PG_FUNCTION_ARGS)
    2534             : {
    2535      626076 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2536      626076 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2537             :     bool        result;
    2538             : 
    2539      626076 :     result = cmp_numerics(num1, num2) == 0;
    2540             : 
    2541      626076 :     PG_FREE_IF_COPY(num1, 0);
    2542      626076 :     PG_FREE_IF_COPY(num2, 1);
    2543             : 
    2544      626076 :     PG_RETURN_BOOL(result);
    2545             : }
    2546             : 
    2547             : Datum
    2548        5376 : numeric_ne(PG_FUNCTION_ARGS)
    2549             : {
    2550        5376 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2551        5376 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2552             :     bool        result;
    2553             : 
    2554        5376 :     result = cmp_numerics(num1, num2) != 0;
    2555             : 
    2556        5376 :     PG_FREE_IF_COPY(num1, 0);
    2557        5376 :     PG_FREE_IF_COPY(num2, 1);
    2558             : 
    2559        5376 :     PG_RETURN_BOOL(result);
    2560             : }
    2561             : 
    2562             : Datum
    2563       61448 : numeric_gt(PG_FUNCTION_ARGS)
    2564             : {
    2565       61448 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2566       61448 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2567             :     bool        result;
    2568             : 
    2569       61448 :     result = cmp_numerics(num1, num2) > 0;
    2570             : 
    2571       61448 :     PG_FREE_IF_COPY(num1, 0);
    2572       61448 :     PG_FREE_IF_COPY(num2, 1);
    2573             : 
    2574       61448 :     PG_RETURN_BOOL(result);
    2575             : }
    2576             : 
    2577             : Datum
    2578       16744 : numeric_ge(PG_FUNCTION_ARGS)
    2579             : {
    2580       16744 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2581       16744 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2582             :     bool        result;
    2583             : 
    2584       16744 :     result = cmp_numerics(num1, num2) >= 0;
    2585             : 
    2586       16744 :     PG_FREE_IF_COPY(num1, 0);
    2587       16744 :     PG_FREE_IF_COPY(num2, 1);
    2588             : 
    2589       16744 :     PG_RETURN_BOOL(result);
    2590             : }
    2591             : 
    2592             : Datum
    2593       52544 : numeric_lt(PG_FUNCTION_ARGS)
    2594             : {
    2595       52544 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2596       52544 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2597             :     bool        result;
    2598             : 
    2599       52544 :     result = cmp_numerics(num1, num2) < 0;
    2600             : 
    2601       52544 :     PG_FREE_IF_COPY(num1, 0);
    2602       52544 :     PG_FREE_IF_COPY(num2, 1);
    2603             : 
    2604       52544 :     PG_RETURN_BOOL(result);
    2605             : }
    2606             : 
    2607             : Datum
    2608       15488 : numeric_le(PG_FUNCTION_ARGS)
    2609             : {
    2610       15488 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2611       15488 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2612             :     bool        result;
    2613             : 
    2614       15488 :     result = cmp_numerics(num1, num2) <= 0;
    2615             : 
    2616       15488 :     PG_FREE_IF_COPY(num1, 0);
    2617       15488 :     PG_FREE_IF_COPY(num2, 1);
    2618             : 
    2619       15488 :     PG_RETURN_BOOL(result);
    2620             : }
    2621             : 
    2622             : static int
    2623     6122598 : cmp_numerics(Numeric num1, Numeric num2)
    2624             : {
    2625             :     int         result;
    2626             : 
    2627             :     /*
    2628             :      * We consider all NANs to be equal and larger than any non-NAN (including
    2629             :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2630             :      * a consistent sort order.
    2631             :      */
    2632     6122598 :     if (NUMERIC_IS_SPECIAL(num1))
    2633             :     {
    2634        9052 :         if (NUMERIC_IS_NAN(num1))
    2635             :         {
    2636        8962 :             if (NUMERIC_IS_NAN(num2))
    2637        1178 :                 result = 0;     /* NAN = NAN */
    2638             :             else
    2639        7784 :                 result = 1;     /* NAN > non-NAN */
    2640             :         }
    2641          90 :         else if (NUMERIC_IS_PINF(num1))
    2642             :         {
    2643          72 :             if (NUMERIC_IS_NAN(num2))
    2644           0 :                 result = -1;    /* PINF < NAN */
    2645          72 :             else if (NUMERIC_IS_PINF(num2))
    2646           6 :                 result = 0;     /* PINF = PINF */
    2647             :             else
    2648          66 :                 result = 1;     /* PINF > anything else */
    2649             :         }
    2650             :         else                    /* num1 must be NINF */
    2651             :         {
    2652          18 :             if (NUMERIC_IS_NINF(num2))
    2653           6 :                 result = 0;     /* NINF = NINF */
    2654             :             else
    2655          12 :                 result = -1;    /* NINF < anything else */
    2656             :         }
    2657             :     }
    2658     6113546 :     else if (NUMERIC_IS_SPECIAL(num2))
    2659             :     {
    2660       11256 :         if (NUMERIC_IS_NINF(num2))
    2661          12 :             result = 1;         /* normal > NINF */
    2662             :         else
    2663       11244 :             result = -1;        /* normal < NAN or PINF */
    2664             :     }
    2665             :     else
    2666             :     {
    2667    12205750 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2668     6102654 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2669     6102290 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2670     6103096 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2671             :     }
    2672             : 
    2673     6122598 :     return result;
    2674             : }
    2675             : 
    2676             : /*
    2677             :  * in_range support function for numeric.
    2678             :  */
    2679             : Datum
    2680        1152 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2681             : {
    2682        1152 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2683        1152 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2684        1152 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2685        1152 :     bool        sub = PG_GETARG_BOOL(3);
    2686        1152 :     bool        less = PG_GETARG_BOOL(4);
    2687             :     bool        result;
    2688             : 
    2689             :     /*
    2690             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2691             :      * and NaN is because appropriate semantics for that seem non-obvious.
    2692             :      */
    2693        1152 :     if (NUMERIC_IS_NAN(offset) ||
    2694        1146 :         NUMERIC_IS_NINF(offset) ||
    2695        1146 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2696           6 :         ereport(ERROR,
    2697             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2698             :                  errmsg("invalid preceding or following size in window function")));
    2699             : 
    2700             :     /*
    2701             :      * Deal with cases where val and/or base is NaN, following the rule that
    2702             :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2703             :      * the conclusion.
    2704             :      */
    2705        1146 :     if (NUMERIC_IS_NAN(val))
    2706             :     {
    2707         186 :         if (NUMERIC_IS_NAN(base))
    2708          60 :             result = true;      /* NAN = NAN */
    2709             :         else
    2710         126 :             result = !less;     /* NAN > non-NAN */
    2711             :     }
    2712         960 :     else if (NUMERIC_IS_NAN(base))
    2713             :     {
    2714         126 :         result = less;          /* non-NAN < NAN */
    2715             :     }
    2716             : 
    2717             :     /*
    2718             :      * Deal with infinite offset (necessarily +Inf, at this point).
    2719             :      */
    2720         834 :     else if (NUMERIC_IS_SPECIAL(offset))
    2721             :     {
    2722             :         Assert(NUMERIC_IS_PINF(offset));
    2723         420 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2724             :         {
    2725             :             /*
    2726             :              * base +/- offset would produce NaN, so return true for any val
    2727             :              * (see in_range_float8_float8() for reasoning).
    2728             :              */
    2729         174 :             result = true;
    2730             :         }
    2731         246 :         else if (sub)
    2732             :         {
    2733             :             /* base - offset must be -inf */
    2734         150 :             if (less)
    2735          54 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2736             :             else
    2737          96 :                 result = true;  /* any val is >= sum */
    2738             :         }
    2739             :         else
    2740             :         {
    2741             :             /* base + offset must be +inf */
    2742          96 :             if (less)
    2743           0 :                 result = true;  /* any val is <= sum */
    2744             :             else
    2745          96 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2746             :         }
    2747             :     }
    2748             : 
    2749             :     /*
    2750             :      * Deal with cases where val and/or base is infinite.  The offset, being
    2751             :      * now known finite, cannot affect the conclusion.
    2752             :      */
    2753         414 :     else if (NUMERIC_IS_SPECIAL(val))
    2754             :     {
    2755          78 :         if (NUMERIC_IS_PINF(val))
    2756             :         {
    2757          36 :             if (NUMERIC_IS_PINF(base))
    2758          24 :                 result = true;  /* PINF = PINF */
    2759             :             else
    2760          12 :                 result = !less; /* PINF > any other non-NAN */
    2761             :         }
    2762             :         else                    /* val must be NINF */
    2763             :         {
    2764          42 :             if (NUMERIC_IS_NINF(base))
    2765          30 :                 result = true;  /* NINF = NINF */
    2766             :             else
    2767          12 :                 result = less;  /* NINF < anything else */
    2768             :         }
    2769             :     }
    2770         336 :     else if (NUMERIC_IS_SPECIAL(base))
    2771             :     {
    2772          24 :         if (NUMERIC_IS_NINF(base))
    2773          12 :             result = !less;     /* normal > NINF */
    2774             :         else
    2775          12 :             result = less;      /* normal < PINF */
    2776             :     }
    2777             :     else
    2778             :     {
    2779             :         /*
    2780             :          * Otherwise go ahead and compute base +/- offset.  While it's
    2781             :          * possible for this to overflow the numeric format, it's unlikely
    2782             :          * enough that we don't take measures to prevent it.
    2783             :          */
    2784             :         NumericVar  valv;
    2785             :         NumericVar  basev;
    2786             :         NumericVar  offsetv;
    2787             :         NumericVar  sum;
    2788             : 
    2789         312 :         init_var_from_num(val, &valv);
    2790         312 :         init_var_from_num(base, &basev);
    2791         312 :         init_var_from_num(offset, &offsetv);
    2792         312 :         init_var(&sum);
    2793             : 
    2794         312 :         if (sub)
    2795         156 :             sub_var(&basev, &offsetv, &sum);
    2796             :         else
    2797         156 :             add_var(&basev, &offsetv, &sum);
    2798             : 
    2799         312 :         if (less)
    2800         156 :             result = (cmp_var(&valv, &sum) <= 0);
    2801             :         else
    2802         156 :             result = (cmp_var(&valv, &sum) >= 0);
    2803             : 
    2804         312 :         free_var(&sum);
    2805             :     }
    2806             : 
    2807        1146 :     PG_FREE_IF_COPY(val, 0);
    2808        1146 :     PG_FREE_IF_COPY(base, 1);
    2809        1146 :     PG_FREE_IF_COPY(offset, 2);
    2810             : 
    2811        1146 :     PG_RETURN_BOOL(result);
    2812             : }
    2813             : 
    2814             : Datum
    2815      607516 : hash_numeric(PG_FUNCTION_ARGS)
    2816             : {
    2817      607516 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2818             :     Datum       digit_hash;
    2819             :     Datum       result;
    2820             :     int         weight;
    2821             :     int         start_offset;
    2822             :     int         end_offset;
    2823             :     int         i;
    2824             :     int         hash_len;
    2825             :     NumericDigit *digits;
    2826             : 
    2827             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2828      607516 :     if (NUMERIC_IS_SPECIAL(key))
    2829           0 :         PG_RETURN_UINT32(0);
    2830             : 
    2831      607516 :     weight = NUMERIC_WEIGHT(key);
    2832      607516 :     start_offset = 0;
    2833      607516 :     end_offset = 0;
    2834             : 
    2835             :     /*
    2836             :      * Omit any leading or trailing zeros from the input to the hash. The
    2837             :      * numeric implementation *should* guarantee that leading and trailing
    2838             :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2839             :      * starting and ending offsets in units of NumericDigits, not bytes.
    2840             :      */
    2841      607516 :     digits = NUMERIC_DIGITS(key);
    2842      607516 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2843             :     {
    2844      605888 :         if (digits[i] != (NumericDigit) 0)
    2845      605888 :             break;
    2846             : 
    2847           0 :         start_offset++;
    2848             : 
    2849             :         /*
    2850             :          * The weight is effectively the # of digits before the decimal point,
    2851             :          * so decrement it for each leading zero we skip.
    2852             :          */
    2853           0 :         weight--;
    2854             :     }
    2855             : 
    2856             :     /*
    2857             :      * If there are no non-zero digits, then the value of the number is zero,
    2858             :      * regardless of any other fields.
    2859             :      */
    2860      607516 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2861        1628 :         PG_RETURN_UINT32(-1);
    2862             : 
    2863      605888 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2864             :     {
    2865      605888 :         if (digits[i] != (NumericDigit) 0)
    2866      605888 :             break;
    2867             : 
    2868           0 :         end_offset++;
    2869             :     }
    2870             : 
    2871             :     /* If we get here, there should be at least one non-zero digit */
    2872             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2873             : 
    2874             :     /*
    2875             :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2876             :      * compare equal but have different scales. We also don't hash on the
    2877             :      * sign, although we could: since a sign difference implies inequality,
    2878             :      * this shouldn't affect correctness.
    2879             :      */
    2880      605888 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2881      605888 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2882             :                           hash_len * sizeof(NumericDigit));
    2883             : 
    2884             :     /* Mix in the weight, via XOR */
    2885      605888 :     result = digit_hash ^ weight;
    2886             : 
    2887      605888 :     PG_RETURN_DATUM(result);
    2888             : }
    2889             : 
    2890             : /*
    2891             :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2892             :  * Otherwise, similar to hash_numeric.
    2893             :  */
    2894             : Datum
    2895          84 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2896             : {
    2897          84 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2898          84 :     uint64      seed = PG_GETARG_INT64(1);
    2899             :     Datum       digit_hash;
    2900             :     Datum       result;
    2901             :     int         weight;
    2902             :     int         start_offset;
    2903             :     int         end_offset;
    2904             :     int         i;
    2905             :     int         hash_len;
    2906             :     NumericDigit *digits;
    2907             : 
    2908             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2909          84 :     if (NUMERIC_IS_SPECIAL(key))
    2910           0 :         PG_RETURN_UINT64(seed);
    2911             : 
    2912          84 :     weight = NUMERIC_WEIGHT(key);
    2913          84 :     start_offset = 0;
    2914          84 :     end_offset = 0;
    2915             : 
    2916          84 :     digits = NUMERIC_DIGITS(key);
    2917          84 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2918             :     {
    2919          72 :         if (digits[i] != (NumericDigit) 0)
    2920          72 :             break;
    2921             : 
    2922           0 :         start_offset++;
    2923             : 
    2924           0 :         weight--;
    2925             :     }
    2926             : 
    2927          84 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2928          12 :         PG_RETURN_UINT64(seed - 1);
    2929             : 
    2930          72 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2931             :     {
    2932          72 :         if (digits[i] != (NumericDigit) 0)
    2933          72 :             break;
    2934             : 
    2935           0 :         end_offset++;
    2936             :     }
    2937             : 
    2938             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2939             : 
    2940          72 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2941          72 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2942          72 :                                                       + start_offset),
    2943             :                                    hash_len * sizeof(NumericDigit),
    2944             :                                    seed);
    2945             : 
    2946          72 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2947             : 
    2948          72 :     PG_RETURN_DATUM(result);
    2949             : }
    2950             : 
    2951             : 
    2952             : /* ----------------------------------------------------------------------
    2953             :  *
    2954             :  * Basic arithmetic functions
    2955             :  *
    2956             :  * ----------------------------------------------------------------------
    2957             :  */
    2958             : 
    2959             : 
    2960             : /*
    2961             :  * numeric_add() -
    2962             :  *
    2963             :  *  Add two numerics
    2964             :  */
    2965             : Datum
    2966      252118 : numeric_add(PG_FUNCTION_ARGS)
    2967             : {
    2968      252118 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2969      252118 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2970             :     Numeric     res;
    2971             : 
    2972      252118 :     res = numeric_add_opt_error(num1, num2, NULL);
    2973             : 
    2974      252118 :     PG_RETURN_NUMERIC(res);
    2975             : }
    2976             : 
    2977             : /*
    2978             :  * numeric_add_opt_error() -
    2979             :  *
    2980             :  *  Internal version of numeric_add().  If "*have_error" flag is provided,
    2981             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2982             :  *  need to handle errors by itself.
    2983             :  */
    2984             : Numeric
    2985      253156 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2986             : {
    2987             :     NumericVar  arg1;
    2988             :     NumericVar  arg2;
    2989             :     NumericVar  result;
    2990             :     Numeric     res;
    2991             : 
    2992             :     /*
    2993             :      * Handle NaN and infinities
    2994             :      */
    2995      253156 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2996             :     {
    2997         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2998          78 :             return make_result(&const_nan);
    2999         120 :         if (NUMERIC_IS_PINF(num1))
    3000             :         {
    3001          36 :             if (NUMERIC_IS_NINF(num2))
    3002           6 :                 return make_result(&const_nan); /* Inf + -Inf */
    3003             :             else
    3004          30 :                 return make_result(&const_pinf);
    3005             :         }
    3006          84 :         if (NUMERIC_IS_NINF(num1))
    3007             :         {
    3008          36 :             if (NUMERIC_IS_PINF(num2))
    3009           6 :                 return make_result(&const_nan); /* -Inf + Inf */
    3010             :             else
    3011          30 :                 return make_result(&const_ninf);
    3012             :         }
    3013             :         /* by here, num1 must be finite, so num2 is not */
    3014          48 :         if (NUMERIC_IS_PINF(num2))
    3015          24 :             return make_result(&const_pinf);
    3016             :         Assert(NUMERIC_IS_NINF(num2));
    3017          24 :         return make_result(&const_ninf);
    3018             :     }
    3019             : 
    3020             :     /*
    3021             :      * Unpack the values, let add_var() compute the result and return it.
    3022             :      */
    3023      252958 :     init_var_from_num(num1, &arg1);
    3024      252958 :     init_var_from_num(num2, &arg2);
    3025             : 
    3026      252958 :     init_var(&result);
    3027      252958 :     add_var(&arg1, &arg2, &result);
    3028             : 
    3029      252958 :     res = make_result_opt_error(&result, have_error);
    3030             : 
    3031      252958 :     free_var(&result);
    3032             : 
    3033      252958 :     return res;
    3034             : }
    3035             : 
    3036             : 
    3037             : /*
    3038             :  * numeric_sub() -
    3039             :  *
    3040             :  *  Subtract one numeric from another
    3041             :  */
    3042             : Datum
    3043       91856 : numeric_sub(PG_FUNCTION_ARGS)
    3044             : {
    3045       91856 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3046       91856 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3047             :     Numeric     res;
    3048             : 
    3049       91856 :     res = numeric_sub_opt_error(num1, num2, NULL);
    3050             : 
    3051       91856 :     PG_RETURN_NUMERIC(res);
    3052             : }
    3053             : 
    3054             : 
    3055             : /*
    3056             :  * numeric_sub_opt_error() -
    3057             :  *
    3058             :  *  Internal version of numeric_sub().  If "*have_error" flag is provided,
    3059             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3060             :  *  need to handle errors by itself.
    3061             :  */
    3062             : Numeric
    3063       92006 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3064             : {
    3065             :     NumericVar  arg1;
    3066             :     NumericVar  arg2;
    3067             :     NumericVar  result;
    3068             :     Numeric     res;
    3069             : 
    3070             :     /*
    3071             :      * Handle NaN and infinities
    3072             :      */
    3073       92006 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3074             :     {
    3075        2440 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3076        2320 :             return make_result(&const_nan);
    3077         120 :         if (NUMERIC_IS_PINF(num1))
    3078             :         {
    3079          36 :             if (NUMERIC_IS_PINF(num2))
    3080           6 :                 return make_result(&const_nan); /* Inf - Inf */
    3081             :             else
    3082          30 :                 return make_result(&const_pinf);
    3083             :         }
    3084          84 :         if (NUMERIC_IS_NINF(num1))
    3085             :         {
    3086          36 :             if (NUMERIC_IS_NINF(num2))
    3087           6 :                 return make_result(&const_nan); /* -Inf - -Inf */
    3088             :             else
    3089          30 :                 return make_result(&const_ninf);
    3090             :         }
    3091             :         /* by here, num1 must be finite, so num2 is not */
    3092          48 :         if (NUMERIC_IS_PINF(num2))
    3093          24 :             return make_result(&const_ninf);
    3094             :         Assert(NUMERIC_IS_NINF(num2));
    3095          24 :         return make_result(&const_pinf);
    3096             :     }
    3097             : 
    3098             :     /*
    3099             :      * Unpack the values, let sub_var() compute the result and return it.
    3100             :      */
    3101       89566 :     init_var_from_num(num1, &arg1);
    3102       89566 :     init_var_from_num(num2, &arg2);
    3103             : 
    3104       89566 :     init_var(&result);
    3105       89566 :     sub_var(&arg1, &arg2, &result);
    3106             : 
    3107       89566 :     res = make_result_opt_error(&result, have_error);
    3108             : 
    3109       89566 :     free_var(&result);
    3110             : 
    3111       89566 :     return res;
    3112             : }
    3113             : 
    3114             : 
    3115             : /*
    3116             :  * numeric_mul() -
    3117             :  *
    3118             :  *  Calculate the product of two numerics
    3119             :  */
    3120             : Datum
    3121      489704 : numeric_mul(PG_FUNCTION_ARGS)
    3122             : {
    3123      489704 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3124      489704 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3125             :     Numeric     res;
    3126             : 
    3127      489704 :     res = numeric_mul_opt_error(num1, num2, NULL);
    3128             : 
    3129      489704 :     PG_RETURN_NUMERIC(res);
    3130             : }
    3131             : 
    3132             : 
    3133             : /*
    3134             :  * numeric_mul_opt_error() -
    3135             :  *
    3136             :  *  Internal version of numeric_mul().  If "*have_error" flag is provided,
    3137             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3138             :  *  need to handle errors by itself.
    3139             :  */
    3140             : Numeric
    3141      489740 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3142             : {
    3143             :     NumericVar  arg1;
    3144             :     NumericVar  arg2;
    3145             :     NumericVar  result;
    3146             :     Numeric     res;
    3147             : 
    3148             :     /*
    3149             :      * Handle NaN and infinities
    3150             :      */
    3151      489740 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3152             :     {
    3153         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3154          78 :             return make_result(&const_nan);
    3155         120 :         if (NUMERIC_IS_PINF(num1))
    3156             :         {
    3157          36 :             switch (numeric_sign_internal(num2))
    3158             :             {
    3159           6 :                 case 0:
    3160           6 :                     return make_result(&const_nan); /* Inf * 0 */
    3161          18 :                 case 1:
    3162          18 :                     return make_result(&const_pinf);
    3163          12 :                 case -1:
    3164          12 :                     return make_result(&const_ninf);
    3165             :             }
    3166             :             Assert(false);
    3167             :         }
    3168          84 :         if (NUMERIC_IS_NINF(num1))
    3169             :         {
    3170          36 :             switch (numeric_sign_internal(num2))
    3171             :             {
    3172           6 :                 case 0:
    3173           6 :                     return make_result(&const_nan); /* -Inf * 0 */
    3174          18 :                 case 1:
    3175          18 :                     return make_result(&const_ninf);
    3176          12 :                 case -1:
    3177          12 :                     return make_result(&const_pinf);
    3178             :             }
    3179             :             Assert(false);
    3180             :         }
    3181             :         /* by here, num1 must be finite, so num2 is not */
    3182          48 :         if (NUMERIC_IS_PINF(num2))
    3183             :         {
    3184          24 :             switch (numeric_sign_internal(num1))
    3185             :             {
    3186           6 :                 case 0:
    3187           6 :                     return make_result(&const_nan); /* 0 * Inf */
    3188          12 :                 case 1:
    3189          12 :                     return make_result(&const_pinf);
    3190           6 :                 case -1:
    3191           6 :                     return make_result(&const_ninf);
    3192             :             }
    3193             :             Assert(false);
    3194             :         }
    3195             :         Assert(NUMERIC_IS_NINF(num2));
    3196          24 :         switch (numeric_sign_internal(num1))
    3197             :         {
    3198           6 :             case 0:
    3199           6 :                 return make_result(&const_nan); /* 0 * -Inf */
    3200          12 :             case 1:
    3201          12 :                 return make_result(&const_ninf);
    3202           6 :             case -1:
    3203           6 :                 return make_result(&const_pinf);
    3204             :         }
    3205             :         Assert(false);
    3206             :     }
    3207             : 
    3208             :     /*
    3209             :      * Unpack the values, let mul_var() compute the result and return it.
    3210             :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3211             :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3212             :      * we request exact representation for the product (rscale = sum(dscale of
    3213             :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3214             :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3215             :      * after computing the exact result ensures that the final result is
    3216             :      * correctly rounded (rounding in mul_var() using a truncated product
    3217             :      * would not guarantee this).
    3218             :      */
    3219      489542 :     init_var_from_num(num1, &arg1);
    3220      489542 :     init_var_from_num(num2, &arg2);
    3221             : 
    3222      489542 :     init_var(&result);
    3223      489542 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3224             : 
    3225      489542 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3226           6 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3227             : 
    3228      489542 :     res = make_result_opt_error(&result, have_error);
    3229             : 
    3230      489542 :     free_var(&result);
    3231             : 
    3232      489542 :     return res;
    3233             : }
    3234             : 
    3235             : 
    3236             : /*
    3237             :  * numeric_div() -
    3238             :  *
    3239             :  *  Divide one numeric into another
    3240             :  */
    3241             : Datum
    3242      151050 : numeric_div(PG_FUNCTION_ARGS)
    3243             : {
    3244      151050 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3245      151050 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3246             :     Numeric     res;
    3247             : 
    3248      151050 :     res = numeric_div_opt_error(num1, num2, NULL);
    3249             : 
    3250      151018 :     PG_RETURN_NUMERIC(res);
    3251             : }
    3252             : 
    3253             : 
    3254             : /*
    3255             :  * numeric_div_opt_error() -
    3256             :  *
    3257             :  *  Internal version of numeric_div().  If "*have_error" flag is provided,
    3258             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3259             :  *  need to handle errors by itself.
    3260             :  */
    3261             : Numeric
    3262      151890 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3263             : {
    3264             :     NumericVar  arg1;
    3265             :     NumericVar  arg2;
    3266             :     NumericVar  result;
    3267             :     Numeric     res;
    3268             :     int         rscale;
    3269             : 
    3270      151890 :     if (have_error)
    3271          48 :         *have_error = false;
    3272             : 
    3273             :     /*
    3274             :      * Handle NaN and infinities
    3275             :      */
    3276      151890 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3277             :     {
    3278         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3279          78 :             return make_result(&const_nan);
    3280         120 :         if (NUMERIC_IS_PINF(num1))
    3281             :         {
    3282          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3283          12 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3284          24 :             switch (numeric_sign_internal(num2))
    3285             :             {
    3286           6 :                 case 0:
    3287           6 :                     if (have_error)
    3288             :                     {
    3289           0 :                         *have_error = true;
    3290           0 :                         return NULL;
    3291             :                     }
    3292           6 :                     ereport(ERROR,
    3293             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3294             :                              errmsg("division by zero")));
    3295             :                     break;
    3296          12 :                 case 1:
    3297          12 :                     return make_result(&const_pinf);
    3298           6 :                 case -1:
    3299           6 :                     return make_result(&const_ninf);
    3300             :             }
    3301          84 :             Assert(false);
    3302             :         }
    3303          84 :         if (NUMERIC_IS_NINF(num1))
    3304             :         {
    3305          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3306          12 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
    3307          24 :             switch (numeric_sign_internal(num2))
    3308             :             {
    3309           6 :                 case 0:
    3310           6 :                     if (have_error)
    3311             :                     {
    3312           0 :                         *have_error = true;
    3313           0 :                         return NULL;
    3314             :                     }
    3315           6 :                     ereport(ERROR,
    3316             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3317             :                              errmsg("division by zero")));
    3318             :                     break;
    3319          12 :                 case 1:
    3320          12 :                     return make_result(&const_ninf);
    3321           6 :                 case -1:
    3322           6 :                     return make_result(&const_pinf);
    3323             :             }
    3324          48 :             Assert(false);
    3325             :         }
    3326             :         /* by here, num1 must be finite, so num2 is not */
    3327             : 
    3328             :         /*
    3329             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3330             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3331             :          * really do underflow, so let's just return zero.
    3332             :          */
    3333          48 :         return make_result(&const_zero);
    3334             :     }
    3335             : 
    3336             :     /*
    3337             :      * Unpack the arguments
    3338             :      */
    3339      151692 :     init_var_from_num(num1, &arg1);
    3340      151692 :     init_var_from_num(num2, &arg2);
    3341             : 
    3342      151692 :     init_var(&result);
    3343             : 
    3344             :     /*
    3345             :      * Select scale for division result
    3346             :      */
    3347      151692 :     rscale = select_div_scale(&arg1, &arg2);
    3348             : 
    3349             :     /*
    3350             :      * If "have_error" is provided, check for division by zero here
    3351             :      */
    3352      151692 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3353             :     {
    3354          12 :         *have_error = true;
    3355          12 :         return NULL;
    3356             :     }
    3357             : 
    3358             :     /*
    3359             :      * Do the divide and return the result
    3360             :      */
    3361      151680 :     div_var(&arg1, &arg2, &result, rscale, true, true);
    3362             : 
    3363      151642 :     res = make_result_opt_error(&result, have_error);
    3364             : 
    3365      151642 :     free_var(&result);
    3366             : 
    3367      151642 :     return res;
    3368             : }
    3369             : 
    3370             : 
    3371             : /*
    3372             :  * numeric_div_trunc() -
    3373             :  *
    3374             :  *  Divide one numeric into another, truncating the result to an integer
    3375             :  */
    3376             : Datum
    3377        1218 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3378             : {
    3379        1218 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3380        1218 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3381             :     NumericVar  arg1;
    3382             :     NumericVar  arg2;
    3383             :     NumericVar  result;
    3384             :     Numeric     res;
    3385             : 
    3386             :     /*
    3387             :      * Handle NaN and infinities
    3388             :      */
    3389        1218 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3390             :     {
    3391         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3392          78 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3393         120 :         if (NUMERIC_IS_PINF(num1))
    3394             :         {
    3395          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3396          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3397          24 :             switch (numeric_sign_internal(num2))
    3398             :             {
    3399           6 :                 case 0:
    3400           6 :                     ereport(ERROR,
    3401             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3402             :                              errmsg("division by zero")));
    3403             :                     break;
    3404          12 :                 case 1:
    3405          12 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3406           6 :                 case -1:
    3407           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3408             :             }
    3409          84 :             Assert(false);
    3410             :         }
    3411          84 :         if (NUMERIC_IS_NINF(num1))
    3412             :         {
    3413          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3414          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3415          24 :             switch (numeric_sign_internal(num2))
    3416             :             {
    3417           6 :                 case 0:
    3418           6 :                     ereport(ERROR,
    3419             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3420             :                              errmsg("division by zero")));
    3421             :                     break;
    3422          12 :                 case 1:
    3423          12 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3424           6 :                 case -1:
    3425           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3426             :             }
    3427          48 :             Assert(false);
    3428             :         }
    3429             :         /* by here, num1 must be finite, so num2 is not */
    3430             : 
    3431             :         /*
    3432             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3433             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3434             :          * really do underflow, so let's just return zero.
    3435             :          */
    3436          48 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3437             :     }
    3438             : 
    3439             :     /*
    3440             :      * Unpack the arguments
    3441             :      */
    3442        1020 :     init_var_from_num(num1, &arg1);
    3443        1020 :     init_var_from_num(num2, &arg2);
    3444             : 
    3445        1020 :     init_var(&result);
    3446             : 
    3447             :     /*
    3448             :      * Do the divide and return the result
    3449             :      */
    3450        1020 :     div_var(&arg1, &arg2, &result, 0, false, true);
    3451             : 
    3452        1014 :     res = make_result(&result);
    3453             : 
    3454        1014 :     free_var(&result);
    3455             : 
    3456        1014 :     PG_RETURN_NUMERIC(res);
    3457             : }
    3458             : 
    3459             : 
    3460             : /*
    3461             :  * numeric_mod() -
    3462             :  *
    3463             :  *  Calculate the modulo of two numerics
    3464             :  */
    3465             : Datum
    3466       53402 : numeric_mod(PG_FUNCTION_ARGS)
    3467             : {
    3468       53402 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3469       53402 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3470             :     Numeric     res;
    3471             : 
    3472       53402 :     res = numeric_mod_opt_error(num1, num2, NULL);
    3473             : 
    3474       53384 :     PG_RETURN_NUMERIC(res);
    3475             : }
    3476             : 
    3477             : 
    3478             : /*
    3479             :  * numeric_mod_opt_error() -
    3480             :  *
    3481             :  *  Internal version of numeric_mod().  If "*have_error" flag is provided,
    3482             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3483             :  *  need to handle errors by itself.
    3484             :  */
    3485             : Numeric
    3486       53414 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3487             : {
    3488             :     Numeric     res;
    3489             :     NumericVar  arg1;
    3490             :     NumericVar  arg2;
    3491             :     NumericVar  result;
    3492             : 
    3493       53414 :     if (have_error)
    3494           0 :         *have_error = false;
    3495             : 
    3496             :     /*
    3497             :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3498             :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3499             :      * returning NaN.  We choose to throw error only for y-is-zero.
    3500             :      */
    3501       53414 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3502             :     {
    3503         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3504          78 :             return make_result(&const_nan);
    3505         120 :         if (NUMERIC_IS_INF(num1))
    3506             :         {
    3507          72 :             if (numeric_sign_internal(num2) == 0)
    3508             :             {
    3509          12 :                 if (have_error)
    3510             :                 {
    3511           0 :                     *have_error = true;
    3512           0 :                     return NULL;
    3513             :                 }
    3514          12 :                 ereport(ERROR,
    3515             :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
    3516             :                          errmsg("division by zero")));
    3517             :             }
    3518             :             /* Inf % any nonzero = NaN */
    3519          60 :             return make_result(&const_nan);
    3520             :         }
    3521             :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3522          48 :         return duplicate_numeric(num1);
    3523             :     }
    3524             : 
    3525       53216 :     init_var_from_num(num1, &arg1);
    3526       53216 :     init_var_from_num(num2, &arg2);
    3527             : 
    3528       53216 :     init_var(&result);
    3529             : 
    3530             :     /*
    3531             :      * If "have_error" is provided, check for division by zero here
    3532             :      */
    3533       53216 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3534             :     {
    3535           0 :         *have_error = true;
    3536           0 :         return NULL;
    3537             :     }
    3538             : 
    3539       53216 :     mod_var(&arg1, &arg2, &result);
    3540             : 
    3541       53204 :     res = make_result_opt_error(&result, NULL);
    3542             : 
    3543       53204 :     free_var(&result);
    3544             : 
    3545       53204 :     return res;
    3546             : }
    3547             : 
    3548             : 
    3549             : /*
    3550             :  * numeric_inc() -
    3551             :  *
    3552             :  *  Increment a number by one
    3553             :  */
    3554             : Datum
    3555          48 : numeric_inc(PG_FUNCTION_ARGS)
    3556             : {
    3557          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3558             :     NumericVar  arg;
    3559             :     Numeric     res;
    3560             : 
    3561             :     /*
    3562             :      * Handle NaN and infinities
    3563             :      */
    3564          48 :     if (NUMERIC_IS_SPECIAL(num))
    3565          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3566             : 
    3567             :     /*
    3568             :      * Compute the result and return it
    3569             :      */
    3570          30 :     init_var_from_num(num, &arg);
    3571             : 
    3572          30 :     add_var(&arg, &const_one, &arg);
    3573             : 
    3574          30 :     res = make_result(&arg);
    3575             : 
    3576          30 :     free_var(&arg);
    3577             : 
    3578          30 :     PG_RETURN_NUMERIC(res);
    3579             : }
    3580             : 
    3581             : 
    3582             : /*
    3583             :  * numeric_smaller() -
    3584             :  *
    3585             :  *  Return the smaller of two numbers
    3586             :  */
    3587             : Datum
    3588         798 : numeric_smaller(PG_FUNCTION_ARGS)
    3589             : {
    3590         798 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3591         798 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3592             : 
    3593             :     /*
    3594             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3595             :      * particularly as regards comparisons involving NaN.
    3596             :      */
    3597         798 :     if (cmp_numerics(num1, num2) < 0)
    3598         640 :         PG_RETURN_NUMERIC(num1);
    3599             :     else
    3600         158 :         PG_RETURN_NUMERIC(num2);
    3601             : }
    3602             : 
    3603             : 
    3604             : /*
    3605             :  * numeric_larger() -
    3606             :  *
    3607             :  *  Return the larger of two numbers
    3608             :  */
    3609             : Datum
    3610       18630 : numeric_larger(PG_FUNCTION_ARGS)
    3611             : {
    3612       18630 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3613       18630 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3614             : 
    3615             :     /*
    3616             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3617             :      * particularly as regards comparisons involving NaN.
    3618             :      */
    3619       18630 :     if (cmp_numerics(num1, num2) > 0)
    3620       18078 :         PG_RETURN_NUMERIC(num1);
    3621             :     else
    3622         552 :         PG_RETURN_NUMERIC(num2);
    3623             : }
    3624             : 
    3625             : 
    3626             : /* ----------------------------------------------------------------------
    3627             :  *
    3628             :  * Advanced math functions
    3629             :  *
    3630             :  * ----------------------------------------------------------------------
    3631             :  */
    3632             : 
    3633             : /*
    3634             :  * numeric_gcd() -
    3635             :  *
    3636             :  *  Calculate the greatest common divisor of two numerics
    3637             :  */
    3638             : Datum
    3639         216 : numeric_gcd(PG_FUNCTION_ARGS)
    3640             : {
    3641         216 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3642         216 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3643             :     NumericVar  arg1;
    3644             :     NumericVar  arg2;
    3645             :     NumericVar  result;
    3646             :     Numeric     res;
    3647             : 
    3648             :     /*
    3649             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3650             :      * cases.
    3651             :      */
    3652         216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3653          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3654             : 
    3655             :     /*
    3656             :      * Unpack the arguments
    3657             :      */
    3658         120 :     init_var_from_num(num1, &arg1);
    3659         120 :     init_var_from_num(num2, &arg2);
    3660             : 
    3661         120 :     init_var(&result);
    3662             : 
    3663             :     /*
    3664             :      * Find the GCD and return the result
    3665             :      */
    3666         120 :     gcd_var(&arg1, &arg2, &result);
    3667             : 
    3668         120 :     res = make_result(&result);
    3669             : 
    3670         120 :     free_var(&result);
    3671             : 
    3672         120 :     PG_RETURN_NUMERIC(res);
    3673             : }
    3674             : 
    3675             : 
    3676             : /*
    3677             :  * numeric_lcm() -
    3678             :  *
    3679             :  *  Calculate the least common multiple of two numerics
    3680             :  */
    3681             : Datum
    3682         246 : numeric_lcm(PG_FUNCTION_ARGS)
    3683             : {
    3684         246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3685         246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3686             :     NumericVar  arg1;
    3687             :     NumericVar  arg2;
    3688             :     NumericVar  result;
    3689             :     Numeric     res;
    3690             : 
    3691             :     /*
    3692             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3693             :      * cases.
    3694             :      */
    3695         246 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3696          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3697             : 
    3698             :     /*
    3699             :      * Unpack the arguments
    3700             :      */
    3701         150 :     init_var_from_num(num1, &arg1);
    3702         150 :     init_var_from_num(num2, &arg2);
    3703             : 
    3704         150 :     init_var(&result);
    3705             : 
    3706             :     /*
    3707             :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3708             :      * zero if either input is zero.
    3709             :      *
    3710             :      * Note that the division is guaranteed to be exact, returning an integer
    3711             :      * result, so the LCM is an integral multiple of both x and y.  A display
    3712             :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3713             :      * but as with other numeric functions, we choose to return a result whose
    3714             :      * display scale is no smaller than either input.
    3715             :      */
    3716         150 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3717          48 :         set_var_from_var(&const_zero, &result);
    3718             :     else
    3719             :     {
    3720         102 :         gcd_var(&arg1, &arg2, &result);
    3721         102 :         div_var(&arg1, &result, &result, 0, false, true);
    3722         102 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3723         102 :         result.sign = NUMERIC_POS;
    3724             :     }
    3725             : 
    3726         150 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3727             : 
    3728         150 :     res = make_result(&result);
    3729             : 
    3730         144 :     free_var(&result);
    3731             : 
    3732         144 :     PG_RETURN_NUMERIC(res);
    3733             : }
    3734             : 
    3735             : 
    3736             : /*
    3737             :  * numeric_fac()
    3738             :  *
    3739             :  * Compute factorial
    3740             :  */
    3741             : Datum
    3742          42 : numeric_fac(PG_FUNCTION_ARGS)
    3743             : {
    3744          42 :     int64       num = PG_GETARG_INT64(0);
    3745             :     Numeric     res;
    3746             :     NumericVar  fact;
    3747             :     NumericVar  result;
    3748             : 
    3749          42 :     if (num < 0)
    3750           6 :         ereport(ERROR,
    3751             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3752             :                  errmsg("factorial of a negative number is undefined")));
    3753          36 :     if (num <= 1)
    3754             :     {
    3755           6 :         res = make_result(&const_one);
    3756           6 :         PG_RETURN_NUMERIC(res);
    3757             :     }
    3758             :     /* Fail immediately if the result would overflow */
    3759          30 :     if (num > 32177)
    3760           6 :         ereport(ERROR,
    3761             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3762             :                  errmsg("value overflows numeric format")));
    3763             : 
    3764          24 :     init_var(&fact);
    3765          24 :     init_var(&result);
    3766             : 
    3767          24 :     int64_to_numericvar(num, &result);
    3768             : 
    3769         294 :     for (num = num - 1; num > 1; num--)
    3770             :     {
    3771             :         /* this loop can take awhile, so allow it to be interrupted */
    3772         270 :         CHECK_FOR_INTERRUPTS();
    3773             : 
    3774         270 :         int64_to_numericvar(num, &fact);
    3775             : 
    3776         270 :         mul_var(&result, &fact, &result, 0);
    3777             :     }
    3778             : 
    3779          24 :     res = make_result(&result);
    3780             : 
    3781          24 :     free_var(&fact);
    3782          24 :     free_var(&result);
    3783             : 
    3784          24 :     PG_RETURN_NUMERIC(res);
    3785             : }
    3786             : 
    3787             : 
    3788             : /*
    3789             :  * numeric_sqrt() -
    3790             :  *
    3791             :  *  Compute the square root of a numeric.
    3792             :  */
    3793             : Datum
    3794         150 : numeric_sqrt(PG_FUNCTION_ARGS)
    3795             : {
    3796         150 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3797             :     Numeric     res;
    3798             :     NumericVar  arg;
    3799             :     NumericVar  result;
    3800             :     int         sweight;
    3801             :     int         rscale;
    3802             : 
    3803             :     /*
    3804             :      * Handle NaN and infinities
    3805             :      */
    3806         150 :     if (NUMERIC_IS_SPECIAL(num))
    3807             :     {
    3808             :         /* error should match that in sqrt_var() */
    3809          18 :         if (NUMERIC_IS_NINF(num))
    3810           6 :             ereport(ERROR,
    3811             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3812             :                      errmsg("cannot take square root of a negative number")));
    3813             :         /* For NAN or PINF, just duplicate the input */
    3814          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3815             :     }
    3816             : 
    3817             :     /*
    3818             :      * Unpack the argument and determine the result scale.  We choose a scale
    3819             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3820             :      * case not less than the input's dscale.
    3821             :      */
    3822         132 :     init_var_from_num(num, &arg);
    3823             : 
    3824         132 :     init_var(&result);
    3825             : 
    3826             :     /*
    3827             :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3828             :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3829             :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3830             :      * a few cycles, since the division is exact and there is no need to round
    3831             :      * towards negative infinity.
    3832             :      */
    3833             : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3834         132 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3835             : #else
    3836             :     if (arg.weight >= 0)
    3837             :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3838             :     else
    3839             :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3840             : #endif
    3841             : 
    3842         132 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3843         132 :     rscale = Max(rscale, arg.dscale);
    3844         132 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3845         132 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3846             : 
    3847             :     /*
    3848             :      * Let sqrt_var() do the calculation and return the result.
    3849             :      */
    3850         132 :     sqrt_var(&arg, &result, rscale);
    3851             : 
    3852         126 :     res = make_result(&result);
    3853             : 
    3854         126 :     free_var(&result);
    3855             : 
    3856         126 :     PG_RETURN_NUMERIC(res);
    3857             : }
    3858             : 
    3859             : 
    3860             : /*
    3861             :  * numeric_exp() -
    3862             :  *
    3863             :  *  Raise e to the power of x
    3864             :  */
    3865             : Datum
    3866          78 : numeric_exp(PG_FUNCTION_ARGS)
    3867             : {
    3868          78 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3869             :     Numeric     res;
    3870             :     NumericVar  arg;
    3871             :     NumericVar  result;
    3872             :     int         rscale;
    3873             :     double      val;
    3874             : 
    3875             :     /*
    3876             :      * Handle NaN and infinities
    3877             :      */
    3878          78 :     if (NUMERIC_IS_SPECIAL(num))
    3879             :     {
    3880             :         /* Per POSIX, exp(-Inf) is zero */
    3881          18 :         if (NUMERIC_IS_NINF(num))
    3882           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3883             :         /* For NAN or PINF, just duplicate the input */
    3884          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3885             :     }
    3886             : 
    3887             :     /*
    3888             :      * Unpack the argument and determine the result scale.  We choose a scale
    3889             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3890             :      * case not less than the input's dscale.
    3891             :      */
    3892          60 :     init_var_from_num(num, &arg);
    3893             : 
    3894          60 :     init_var(&result);
    3895             : 
    3896             :     /* convert input to float8, ignoring overflow */
    3897          60 :     val = numericvar_to_double_no_overflow(&arg);
    3898             : 
    3899             :     /*
    3900             :      * log10(result) = num * log10(e), so this is approximately the decimal
    3901             :      * weight of the result:
    3902             :      */
    3903          60 :     val *= 0.434294481903252;
    3904             : 
    3905             :     /* limit to something that won't cause integer overflow */
    3906          60 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3907          60 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3908             : 
    3909          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3910          60 :     rscale = Max(rscale, arg.dscale);
    3911          60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3912          60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3913             : 
    3914             :     /*
    3915             :      * Let exp_var() do the calculation and return the result.
    3916             :      */
    3917          60 :     exp_var(&arg, &result, rscale);
    3918             : 
    3919          60 :     res = make_result(&result);
    3920             : 
    3921          60 :     free_var(&result);
    3922             : 
    3923          60 :     PG_RETURN_NUMERIC(res);
    3924             : }
    3925             : 
    3926             : 
    3927             : /*
    3928             :  * numeric_ln() -
    3929             :  *
    3930             :  *  Compute the natural logarithm of x
    3931             :  */
    3932             : Datum
    3933         198 : numeric_ln(PG_FUNCTION_ARGS)
    3934             : {
    3935         198 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3936             :     Numeric     res;
    3937             :     NumericVar  arg;
    3938             :     NumericVar  result;
    3939             :     int         ln_dweight;
    3940             :     int         rscale;
    3941             : 
    3942             :     /*
    3943             :      * Handle NaN and infinities
    3944             :      */
    3945         198 :     if (NUMERIC_IS_SPECIAL(num))
    3946             :     {
    3947          18 :         if (NUMERIC_IS_NINF(num))
    3948           6 :             ereport(ERROR,
    3949             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3950             :                      errmsg("cannot take logarithm of a negative number")));
    3951             :         /* For NAN or PINF, just duplicate the input */
    3952          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3953             :     }
    3954             : 
    3955         180 :     init_var_from_num(num, &arg);
    3956         180 :     init_var(&result);
    3957             : 
    3958             :     /* Estimated dweight of logarithm */
    3959         180 :     ln_dweight = estimate_ln_dweight(&arg);
    3960             : 
    3961         180 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3962         180 :     rscale = Max(rscale, arg.dscale);
    3963         180 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3964         180 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3965             : 
    3966         180 :     ln_var(&arg, &result, rscale);
    3967             : 
    3968         156 :     res = make_result(&result);
    3969             : 
    3970         156 :     free_var(&result);
    3971             : 
    3972         156 :     PG_RETURN_NUMERIC(res);
    3973             : }
    3974             : 
    3975             : 
    3976             : /*
    3977             :  * numeric_log() -
    3978             :  *
    3979             :  *  Compute the logarithm of x in a given base
    3980             :  */
    3981             : Datum
    3982         342 : numeric_log(PG_FUNCTION_ARGS)
    3983             : {
    3984         342 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3985         342 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3986             :     Numeric     res;
    3987             :     NumericVar  arg1;
    3988             :     NumericVar  arg2;
    3989             :     NumericVar  result;
    3990             : 
    3991             :     /*
    3992             :      * Handle NaN and infinities
    3993             :      */
    3994         342 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3995             :     {
    3996             :         int         sign1,
    3997             :                     sign2;
    3998             : 
    3999         126 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    4000          54 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    4001             :         /* fail on negative inputs including -Inf, as log_var would */
    4002          72 :         sign1 = numeric_sign_internal(num1);
    4003          72 :         sign2 = numeric_sign_internal(num2);
    4004          72 :         if (sign1 < 0 || sign2 < 0)
    4005          24 :             ereport(ERROR,
    4006             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    4007             :                      errmsg("cannot take logarithm of a negative number")));
    4008             :         /* fail on zero inputs, as log_var would */
    4009          48 :         if (sign1 == 0 || sign2 == 0)
    4010           6 :             ereport(ERROR,
    4011             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    4012             :                      errmsg("cannot take logarithm of zero")));
    4013          42 :         if (NUMERIC_IS_PINF(num1))
    4014             :         {
    4015             :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    4016          18 :             if (NUMERIC_IS_PINF(num2))
    4017           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    4018             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    4019          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4020             :         }
    4021             :         Assert(NUMERIC_IS_PINF(num2));
    4022             :         /* log(finite-positive, Inf) is Inf */
    4023          24 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    4024             :     }
    4025             : 
    4026             :     /*
    4027             :      * Initialize things
    4028             :      */
    4029         216 :     init_var_from_num(num1, &arg1);
    4030         216 :     init_var_from_num(num2, &arg2);
    4031         216 :     init_var(&result);
    4032             : 
    4033             :     /*
    4034             :      * Call log_var() to compute and return the result; note it handles scale
    4035             :      * selection itself.
    4036             :      */
    4037         216 :     log_var(&arg1, &arg2, &result);
    4038             : 
    4039         156 :     res = make_result(&result);
    4040             : 
    4041         156 :     free_var(&result);
    4042             : 
    4043         156 :     PG_RETURN_NUMERIC(res);
    4044             : }
    4045             : 
    4046             : 
    4047             : /*
    4048             :  * numeric_power() -
    4049             :  *
    4050             :  *  Raise x to the power of y
    4051             :  */
    4052             : Datum
    4053        1644 : numeric_power(PG_FUNCTION_ARGS)
    4054             : {
    4055        1644 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    4056        1644 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    4057             :     Numeric     res;
    4058             :     NumericVar  arg1;
    4059             :     NumericVar  arg2;
    4060             :     NumericVar  result;
    4061             :     int         sign1,
    4062             :                 sign2;
    4063             : 
    4064             :     /*
    4065             :      * Handle NaN and infinities
    4066             :      */
    4067        1644 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    4068             :     {
    4069             :         /*
    4070             :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    4071             :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    4072             :          * (with no error).
    4073             :          */
    4074         234 :         if (NUMERIC_IS_NAN(num1))
    4075             :         {
    4076          54 :             if (!NUMERIC_IS_SPECIAL(num2))
    4077             :             {
    4078          36 :                 init_var_from_num(num2, &arg2);
    4079          36 :                 if (cmp_var(&arg2, &const_zero) == 0)
    4080          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4081             :             }
    4082          42 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    4083             :         }
    4084         180 :         if (NUMERIC_IS_NAN(num2))
    4085             :         {
    4086          42 :             if (!NUMERIC_IS_SPECIAL(num1))
    4087             :             {
    4088          36 :                 init_var_from_num(num1, &arg1);
    4089          36 :                 if (cmp_var(&arg1, &const_one) == 0)
    4090          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4091             :             }
    4092          30 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    4093             :         }
    4094             :         /* At least one input is infinite, but error rules still apply */
    4095         138 :         sign1 = numeric_sign_internal(num1);
    4096         138 :         sign2 = numeric_sign_internal(num2);
    4097         138 :         if (sign1 == 0 && sign2 < 0)
    4098           6 :             ereport(ERROR,
    4099             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4100             :                      errmsg("zero raised to a negative power is undefined")));
    4101         132 :         if (sign1 < 0 && !numeric_is_integral(num2))
    4102           6 :             ereport(ERROR,
    4103             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4104             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    4105             : 
    4106             :         /*
    4107             :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    4108             :          *
    4109             :          * For any value of y, if x is +1, 1.0 shall be returned.
    4110             :          */
    4111         126 :         if (!NUMERIC_IS_SPECIAL(num1))
    4112             :         {
    4113          42 :             init_var_from_num(num1, &arg1);
    4114          42 :             if (cmp_var(&arg1, &const_one) == 0)
    4115           6 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    4116             :         }
    4117             : 
    4118             :         /*
    4119             :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    4120             :          */
    4121         120 :         if (sign2 == 0)
    4122          12 :             PG_RETURN_NUMERIC(make_result(&const_one));
    4123             : 
    4124             :         /*
    4125             :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    4126             :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    4127             :          * be returned.  (Since we don't deal in minus zero, we need not
    4128             :          * distinguish these two cases.)
    4129             :          */
    4130         108 :         if (sign1 == 0 && sign2 > 0)
    4131           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4132             : 
    4133             :         /*
    4134             :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    4135             :          *
    4136             :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4137             :          *
    4138             :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4139             :          *
    4140             :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4141             :          *
    4142             :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4143             :          */
    4144         102 :         if (NUMERIC_IS_INF(num2))
    4145             :         {
    4146             :             bool        abs_x_gt_one;
    4147             : 
    4148          54 :             if (NUMERIC_IS_SPECIAL(num1))
    4149          24 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4150             :             else
    4151             :             {
    4152          30 :                 init_var_from_num(num1, &arg1);
    4153          30 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4154           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4155          24 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4156          24 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4157             :             }
    4158          48 :             if (abs_x_gt_one == (sign2 > 0))
    4159          30 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4160             :             else
    4161          18 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4162             :         }
    4163             : 
    4164             :         /*
    4165             :          * For y < 0, if x is +Inf, +0 shall be returned.
    4166             :          *
    4167             :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4168             :          */
    4169          48 :         if (NUMERIC_IS_PINF(num1))
    4170             :         {
    4171          24 :             if (sign2 > 0)
    4172          18 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4173             :             else
    4174           6 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4175             :         }
    4176             : 
    4177             :         Assert(NUMERIC_IS_NINF(num1));
    4178             : 
    4179             :         /*
    4180             :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4181             :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4182             :          * (Again, we need not distinguish these two cases.)
    4183             :          */
    4184          24 :         if (sign2 < 0)
    4185          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4186             : 
    4187             :         /*
    4188             :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4189             :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4190             :          */
    4191          12 :         init_var_from_num(num2, &arg2);
    4192          12 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4193          12 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4194           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4195             :         else
    4196           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4197             :     }
    4198             : 
    4199             :     /*
    4200             :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4201             :      * certain error conditions.  Specifically, we don't return a
    4202             :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4203             :      * non-integer power must produce the same error code, but that case is
    4204             :      * handled in power_var().
    4205             :      */
    4206        1410 :     sign1 = numeric_sign_internal(num1);
    4207        1410 :     sign2 = numeric_sign_internal(num2);
    4208             : 
    4209        1410 :     if (sign1 == 0 && sign2 < 0)
    4210          12 :         ereport(ERROR,
    4211             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4212             :                  errmsg("zero raised to a negative power is undefined")));
    4213             : 
    4214             :     /*
    4215             :      * Initialize things
    4216             :      */
    4217        1398 :     init_var(&result);
    4218        1398 :     init_var_from_num(num1, &arg1);
    4219        1398 :     init_var_from_num(num2, &arg2);
    4220             : 
    4221             :     /*
    4222             :      * Call power_var() to compute and return the result; note it handles
    4223             :      * scale selection itself.
    4224             :      */
    4225        1398 :     power_var(&arg1, &arg2, &result);
    4226             : 
    4227        1368 :     res = make_result(&result);
    4228             : 
    4229        1368 :     free_var(&result);
    4230             : 
    4231        1368 :     PG_RETURN_NUMERIC(res);
    4232             : }
    4233             : 
    4234             : /*
    4235             :  * numeric_scale() -
    4236             :  *
    4237             :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4238             :  */
    4239             : Datum
    4240         108 : numeric_scale(PG_FUNCTION_ARGS)
    4241             : {
    4242         108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4243             : 
    4244         108 :     if (NUMERIC_IS_SPECIAL(num))
    4245          18 :         PG_RETURN_NULL();
    4246             : 
    4247          90 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4248             : }
    4249             : 
    4250             : /*
    4251             :  * Calculate minimum scale for value.
    4252             :  */
    4253             : static int
    4254         372 : get_min_scale(NumericVar *var)
    4255             : {
    4256             :     int         min_scale;
    4257             :     int         last_digit_pos;
    4258             : 
    4259             :     /*
    4260             :      * Ordinarily, the input value will be "stripped" so that the last
    4261             :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4262             :      * loop if it isn't, so explicitly find the last nonzero digit.
    4263             :      */
    4264         372 :     last_digit_pos = var->ndigits - 1;
    4265         372 :     while (last_digit_pos >= 0 &&
    4266         342 :            var->digits[last_digit_pos] == 0)
    4267           0 :         last_digit_pos--;
    4268             : 
    4269         372 :     if (last_digit_pos >= 0)
    4270             :     {
    4271             :         /* compute min_scale assuming that last ndigit has no zeroes */
    4272         342 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4273             : 
    4274             :         /*
    4275             :          * We could get a negative result if there are no digits after the
    4276             :          * decimal point.  In this case the min_scale must be zero.
    4277             :          */
    4278         342 :         if (min_scale > 0)
    4279             :         {
    4280             :             /*
    4281             :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4282             :              * zero.
    4283             :              */
    4284         186 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4285             : 
    4286         498 :             while (last_digit % 10 == 0)
    4287             :             {
    4288         312 :                 min_scale--;
    4289         312 :                 last_digit /= 10;
    4290             :             }
    4291             :         }
    4292             :         else
    4293         156 :             min_scale = 0;
    4294             :     }
    4295             :     else
    4296          30 :         min_scale = 0;          /* result if input is zero */
    4297             : 
    4298         372 :     return min_scale;
    4299             : }
    4300             : 
    4301             : /*
    4302             :  * Returns minimum scale required to represent supplied value without loss.
    4303             :  */
    4304             : Datum
    4305          72 : numeric_min_scale(PG_FUNCTION_ARGS)
    4306             : {
    4307          72 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4308             :     NumericVar  arg;
    4309             :     int         min_scale;
    4310             : 
    4311          72 :     if (NUMERIC_IS_SPECIAL(num))
    4312          12 :         PG_RETURN_NULL();
    4313             : 
    4314          60 :     init_var_from_num(num, &arg);
    4315          60 :     min_scale = get_min_scale(&arg);
    4316          60 :     free_var(&arg);
    4317             : 
    4318          60 :     PG_RETURN_INT32(min_scale);
    4319             : }
    4320             : 
    4321             : /*
    4322             :  * Reduce scale of numeric value to represent supplied value without loss.
    4323             :  */
    4324             : Datum
    4325         324 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4326             : {
    4327         324 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4328             :     Numeric     res;
    4329             :     NumericVar  result;
    4330             : 
    4331         324 :     if (NUMERIC_IS_SPECIAL(num))
    4332          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4333             : 
    4334         312 :     init_var_from_num(num, &result);
    4335         312 :     result.dscale = get_min_scale(&result);
    4336         312 :     res = make_result(&result);
    4337         312 :     free_var(&result);
    4338             : 
    4339         312 :     PG_RETURN_NUMERIC(res);
    4340             : }
    4341             : 
    4342             : /*
    4343             :  * Return a random numeric value in the range [rmin, rmax].
    4344             :  */
    4345             : Numeric
    4346       33462 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
    4347             : {
    4348             :     NumericVar  rmin_var;
    4349             :     NumericVar  rmax_var;
    4350             :     NumericVar  result;
    4351             :     Numeric     res;
    4352             : 
    4353             :     /* Range bounds must not be NaN/infinity */
    4354       33462 :     if (NUMERIC_IS_SPECIAL(rmin))
    4355             :     {
    4356          12 :         if (NUMERIC_IS_NAN(rmin))
    4357           6 :             ereport(ERROR,
    4358             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4359             :                     errmsg("lower bound cannot be NaN"));
    4360             :         else
    4361           6 :             ereport(ERROR,
    4362             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4363             :                     errmsg("lower bound cannot be infinity"));
    4364             :     }
    4365       33450 :     if (NUMERIC_IS_SPECIAL(rmax))
    4366             :     {
    4367          12 :         if (NUMERIC_IS_NAN(rmax))
    4368           6 :             ereport(ERROR,
    4369             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4370             :                     errmsg("upper bound cannot be NaN"));
    4371             :         else
    4372           6 :             ereport(ERROR,
    4373             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4374             :                     errmsg("upper bound cannot be infinity"));
    4375             :     }
    4376             : 
    4377             :     /* Return a random value in the range [rmin, rmax] */
    4378       33438 :     init_var_from_num(rmin, &rmin_var);
    4379       33438 :     init_var_from_num(rmax, &rmax_var);
    4380             : 
    4381       33438 :     init_var(&result);
    4382             : 
    4383       33438 :     random_var(state, &rmin_var, &rmax_var, &result);
    4384             : 
    4385       33432 :     res = make_result(&result);
    4386             : 
    4387       33432 :     free_var(&result);
    4388             : 
    4389       33432 :     return res;
    4390             : }
    4391             : 
    4392             : 
    4393             : /* ----------------------------------------------------------------------
    4394             :  *
    4395             :  * Type conversion functions
    4396             :  *
    4397             :  * ----------------------------------------------------------------------
    4398             :  */
    4399             : 
    4400             : Numeric
    4401     1848780 : int64_to_numeric(int64 val)
    4402             : {
    4403             :     Numeric     res;
    4404             :     NumericVar  result;
    4405             : 
    4406     1848780 :     init_var(&result);
    4407             : 
    4408     1848780 :     int64_to_numericvar(val, &result);
    4409             : 
    4410     1848780 :     res = make_result(&result);
    4411             : 
    4412     1848780 :     free_var(&result);
    4413             : 
    4414     1848780 :     return res;
    4415             : }
    4416             : 
    4417             : /*
    4418             :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4419             :  * numeric division.
    4420             :  */
    4421             : Numeric
    4422       29380 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4423             : {
    4424             :     Numeric     res;
    4425             :     NumericVar  result;
    4426             :     int         rscale;
    4427             :     int         w;
    4428             :     int         m;
    4429             : 
    4430       29380 :     init_var(&result);
    4431             : 
    4432             :     /* result scale */
    4433       29380 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4434             : 
    4435             :     /* how much to decrease the weight by */
    4436       29380 :     w = log10val2 / DEC_DIGITS;
    4437             :     /* how much is left to divide by */
    4438       29380 :     m = log10val2 % DEC_DIGITS;
    4439       29380 :     if (m < 0)
    4440             :     {
    4441           0 :         m += DEC_DIGITS;
    4442           0 :         w--;
    4443             :     }
    4444             : 
    4445             :     /*
    4446             :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4447             :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4448             :      * one more.
    4449             :      */
    4450       29380 :     if (m > 0)
    4451             :     {
    4452             : #if DEC_DIGITS == 4
    4453             :         static const int pow10[] = {1, 10, 100, 1000};
    4454             : #elif DEC_DIGITS == 2
    4455             :         static const int pow10[] = {1, 10};
    4456             : #elif DEC_DIGITS == 1
    4457             :         static const int pow10[] = {1};
    4458             : #else
    4459             : #error unsupported NBASE
    4460             : #endif
    4461       29380 :         int64       factor = pow10[DEC_DIGITS - m];
    4462             :         int64       new_val1;
    4463             : 
    4464             :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4465             : 
    4466       29380 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4467             :         {
    4468             : #ifdef HAVE_INT128
    4469             :             /* do the multiplication using 128-bit integers */
    4470             :             int128      tmp;
    4471             : 
    4472          12 :             tmp = (int128) val1 * (int128) factor;
    4473             : 
    4474          12 :             int128_to_numericvar(tmp, &result);
    4475             : #else
    4476             :             /* do the multiplication using numerics */
    4477             :             NumericVar  tmp;
    4478             : 
    4479             :             init_var(&tmp);
    4480             : 
    4481             :             int64_to_numericvar(val1, &result);
    4482             :             int64_to_numericvar(factor, &tmp);
    4483             :             mul_var(&result, &tmp, &result, 0);
    4484             : 
    4485             :             free_var(&tmp);
    4486             : #endif
    4487             :         }
    4488             :         else
    4489       29368 :             int64_to_numericvar(new_val1, &result);
    4490             : 
    4491       29380 :         w++;
    4492             :     }
    4493             :     else
    4494           0 :         int64_to_numericvar(val1, &result);
    4495             : 
    4496       29380 :     result.weight -= w;
    4497       29380 :     result.dscale = rscale;
    4498             : 
    4499       29380 :     res = make_result(&result);
    4500             : 
    4501       29380 :     free_var(&result);
    4502             : 
    4503       29380 :     return res;
    4504             : }
    4505             : 
    4506             : Datum
    4507     1530736 : int4_numeric(PG_FUNCTION_ARGS)
    4508             : {
    4509     1530736 :     int32       val = PG_GETARG_INT32(0);
    4510             : 
    4511     1530736 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4512             : }
    4513             : 
    4514             : int32
    4515        7692 : numeric_int4_opt_error(Numeric num, bool *have_error)
    4516             : {
    4517             :     NumericVar  x;
    4518             :     int32       result;
    4519             : 
    4520        7692 :     if (have_error)
    4521        1584 :         *have_error = false;
    4522             : 
    4523        7692 :     if (NUMERIC_IS_SPECIAL(num))
    4524             :     {
    4525          18 :         if (have_error)
    4526             :         {
    4527           0 :             *have_error = true;
    4528           0 :             return 0;
    4529             :         }
    4530             :         else
    4531             :         {
    4532          18 :             if (NUMERIC_IS_NAN(num))
    4533           6 :                 ereport(ERROR,
    4534             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4535             :                          errmsg("cannot convert NaN to %s", "integer")));
    4536             :             else
    4537          12 :                 ereport(ERROR,
    4538             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4539             :                          errmsg("cannot convert infinity to %s", "integer")));
    4540             :         }
    4541             :     }
    4542             : 
    4543             :     /* Convert to variable format, then convert to int4 */
    4544        7674 :     init_var_from_num(num, &x);
    4545             : 
    4546        7674 :     if (!numericvar_to_int32(&x, &result))
    4547             :     {
    4548          90 :         if (have_error)
    4549             :         {
    4550          78 :             *have_error = true;
    4551          78 :             return 0;
    4552             :         }
    4553             :         else
    4554             :         {
    4555          12 :             ereport(ERROR,
    4556             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4557             :                      errmsg("integer out of range")));
    4558             :         }
    4559             :     }
    4560             : 
    4561        7584 :     return result;
    4562             : }
    4563             : 
    4564             : Datum
    4565        6108 : numeric_int4(PG_FUNCTION_ARGS)
    4566             : {
    4567        6108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4568             : 
    4569        6108 :     PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
    4570             : }
    4571             : 
    4572             : /*
    4573             :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4574             :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4575             :  * The input NumericVar is *not* free'd.
    4576             :  */
    4577             : static bool
    4578        8412 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4579             : {
    4580             :     int64       val;
    4581             : 
    4582        8412 :     if (!numericvar_to_int64(var, &val))
    4583           6 :         return false;
    4584             : 
    4585        8406 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4586          84 :         return false;
    4587             : 
    4588             :     /* Down-convert to int4 */
    4589        8322 :     *result = (int32) val;
    4590             : 
    4591        8322 :     return true;
    4592             : }
    4593             : 
    4594             : Datum
    4595       36850 : int8_numeric(PG_FUNCTION_ARGS)
    4596             : {
    4597       36850 :     int64       val = PG_GETARG_INT64(0);
    4598             : 
    4599       36850 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4600             : }
    4601             : 
    4602             : int64
    4603         564 : numeric_int8_opt_error(Numeric num, bool *have_error)
    4604             : {
    4605             :     NumericVar  x;
    4606             :     int64       result;
    4607             : 
    4608         564 :     if (have_error)
    4609          48 :         *have_error = false;
    4610             : 
    4611         564 :     if (NUMERIC_IS_SPECIAL(num))
    4612             :     {
    4613          18 :         if (have_error)
    4614             :         {
    4615           0 :             *have_error = true;
    4616           0 :             return 0;
    4617             :         }
    4618             :         else
    4619             :         {
    4620          18 :             if (NUMERIC_IS_NAN(num))
    4621           6 :                 ereport(ERROR,
    4622             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4623             :                          errmsg("cannot convert NaN to %s", "bigint")));
    4624             :             else
    4625          12 :                 ereport(ERROR,
    4626             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4627             :                          errmsg("cannot convert infinity to %s", "bigint")));
    4628             :         }
    4629             :     }
    4630             : 
    4631             :     /* Convert to variable format, then convert to int8 */
    4632         546 :     init_var_from_num(num, &x);
    4633             : 
    4634         546 :     if (!numericvar_to_int64(&x, &result))
    4635             :     {
    4636          60 :         if (have_error)
    4637             :         {
    4638          12 :             *have_error = true;
    4639          12 :             return 0;
    4640             :         }
    4641             :         else
    4642             :         {
    4643          48 :             ereport(ERROR,
    4644             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4645             :                      errmsg("bigint out of range")));
    4646             :         }
    4647             :     }
    4648             : 
    4649         486 :     return result;
    4650             : }
    4651             : 
    4652             : Datum
    4653         516 : numeric_int8(PG_FUNCTION_ARGS)
    4654             : {
    4655         516 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4656             : 
    4657         516 :     PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
    4658             : }
    4659             : 
    4660             : 
    4661             : Datum
    4662           6 : int2_numeric(PG_FUNCTION_ARGS)
    4663             : {
    4664           6 :     int16       val = PG_GETARG_INT16(0);
    4665             : 
    4666           6 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4667             : }
    4668             : 
    4669             : 
    4670             : Datum
    4671          96 : numeric_int2(PG_FUNCTION_ARGS)
    4672             : {
    4673          96 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4674             :     NumericVar  x;
    4675             :     int64       val;
    4676             :     int16       result;
    4677             : 
    4678          96 :     if (NUMERIC_IS_SPECIAL(num))
    4679             :     {
    4680          18 :         if (NUMERIC_IS_NAN(num))
    4681           6 :             ereport(ERROR,
    4682             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4683             :                      errmsg("cannot convert NaN to %s", "smallint")));
    4684             :         else
    4685          12 :             ereport(ERROR,
    4686             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4687             :                      errmsg("cannot convert infinity to %s", "smallint")));
    4688             :     }
    4689             : 
    4690             :     /* Convert to variable format and thence to int8 */
    4691          78 :     init_var_from_num(num, &x);
    4692             : 
    4693          78 :     if (!numericvar_to_int64(&x, &val))
    4694           0 :         ereport(ERROR,
    4695             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4696             :                  errmsg("smallint out of range")));
    4697             : 
    4698          78 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4699          12 :         ereport(ERROR,
    4700             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4701             :                  errmsg("smallint out of range")));
    4702             : 
    4703             :     /* Down-convert to int2 */
    4704          66 :     result = (int16) val;
    4705             : 
    4706          66 :     PG_RETURN_INT16(result);
    4707             : }
    4708             : 
    4709             : 
    4710             : Datum
    4711        1074 : float8_numeric(PG_FUNCTION_ARGS)
    4712             : {
    4713        1074 :     float8      val = PG_GETARG_FLOAT8(0);
    4714             :     Numeric     res;
    4715             :     NumericVar  result;
    4716             :     char        buf[DBL_DIG + 100];
    4717             :     const char *endptr;
    4718             : 
    4719        1074 :     if (isnan(val))
    4720           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4721             : 
    4722        1068 :     if (isinf(val))
    4723             :     {
    4724          12 :         if (val < 0)
    4725           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4726             :         else
    4727           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4728             :     }
    4729             : 
    4730        1056 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4731             : 
    4732        1056 :     init_var(&result);
    4733             : 
    4734             :     /* Assume we need not worry about leading/trailing spaces */
    4735        1056 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4736             : 
    4737        1056 :     res = make_result(&result);
    4738             : 
    4739        1056 :     free_var(&result);
    4740             : 
    4741        1056 :     PG_RETURN_NUMERIC(res);
    4742             : }
    4743             : 
    4744             : 
    4745             : Datum
    4746      519572 : numeric_float8(PG_FUNCTION_ARGS)
    4747             : {
    4748      519572 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4749             :     char       *tmp;
    4750             :     Datum       result;
    4751             : 
    4752      519572 :     if (NUMERIC_IS_SPECIAL(num))
    4753             :     {
    4754          78 :         if (NUMERIC_IS_PINF(num))
    4755          24 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4756          54 :         else if (NUMERIC_IS_NINF(num))
    4757          24 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4758             :         else
    4759          30 :             PG_RETURN_FLOAT8(get_float8_nan());
    4760             :     }
    4761             : 
    4762      519494 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4763             :                                               NumericGetDatum(num)));
    4764             : 
    4765      519494 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
    4766             : 
    4767      519494 :     pfree(tmp);
    4768             : 
    4769      519494 :     PG_RETURN_DATUM(result);
    4770             : }
    4771             : 
    4772             : 
    4773             : /*
    4774             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4775             :  *
    4776             :  * (internal helper function, not directly callable from SQL)
    4777             :  */
    4778             : Datum
    4779        2880 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4780             : {
    4781        2880 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4782             :     double      val;
    4783             : 
    4784        2880 :     if (NUMERIC_IS_SPECIAL(num))
    4785             :     {
    4786           0 :         if (NUMERIC_IS_PINF(num))
    4787           0 :             val = HUGE_VAL;
    4788           0 :         else if (NUMERIC_IS_NINF(num))
    4789           0 :             val = -HUGE_VAL;
    4790             :         else
    4791           0 :             val = get_float8_nan();
    4792             :     }
    4793             :     else
    4794             :     {
    4795             :         NumericVar  x;
    4796             : 
    4797        2880 :         init_var_from_num(num, &x);
    4798        2880 :         val = numericvar_to_double_no_overflow(&x);
    4799             :     }
    4800             : 
    4801        2880 :     PG_RETURN_FLOAT8(val);
    4802             : }
    4803             : 
    4804             : Datum
    4805       22036 : float4_numeric(PG_FUNCTION_ARGS)
    4806             : {
    4807       22036 :     float4      val = PG_GETARG_FLOAT4(0);
    4808             :     Numeric     res;
    4809             :     NumericVar  result;
    4810             :     char        buf[FLT_DIG + 100];
    4811             :     const char *endptr;
    4812             : 
    4813       22036 :     if (isnan(val))
    4814           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4815             : 
    4816       22030 :     if (isinf(val))
    4817             :     {
    4818          12 :         if (val < 0)
    4819           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4820             :         else
    4821           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4822             :     }
    4823             : 
    4824       22018 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4825             : 
    4826       22018 :     init_var(&result);
    4827             : 
    4828             :     /* Assume we need not worry about leading/trailing spaces */
    4829       22018 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4830             : 
    4831       22018 :     res = make_result(&result);
    4832             : 
    4833       22018 :     free_var(&result);
    4834             : 
    4835       22018 :     PG_RETURN_NUMERIC(res);
    4836             : }
    4837             : 
    4838             : 
    4839             : Datum
    4840        2954 : numeric_float4(PG_FUNCTION_ARGS)
    4841             : {
    4842        2954 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4843             :     char       *tmp;
    4844             :     Datum       result;
    4845             : 
    4846        2954 :     if (NUMERIC_IS_SPECIAL(num))
    4847             :     {
    4848          78 :         if (NUMERIC_IS_PINF(num))
    4849          24 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4850          54 :         else if (NUMERIC_IS_NINF(num))
    4851          24 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4852             :         else
    4853          30 :             PG_RETURN_FLOAT4(get_float4_nan());
    4854             :     }
    4855             : 
    4856        2876 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4857             :                                               NumericGetDatum(num)));
    4858             : 
    4859        2876 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
    4860             : 
    4861        2876 :     pfree(tmp);
    4862             : 
    4863        2876 :     PG_RETURN_DATUM(result);
    4864             : }
    4865             : 
    4866             : 
    4867             : Datum
    4868         120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4869             : {
    4870         120 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4871             :     NumericVar  x;
    4872             :     XLogRecPtr  result;
    4873             : 
    4874         120 :     if (NUMERIC_IS_SPECIAL(num))
    4875             :     {
    4876           6 :         if (NUMERIC_IS_NAN(num))
    4877           6 :             ereport(ERROR,
    4878             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4879             :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4880             :         else
    4881           0 :             ereport(ERROR,
    4882             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4883             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4884             :     }
    4885             : 
    4886             :     /* Convert to variable format and thence to pg_lsn */
    4887         114 :     init_var_from_num(num, &x);
    4888             : 
    4889         114 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4890          24 :         ereport(ERROR,
    4891             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4892             :                  errmsg("pg_lsn out of range")));
    4893             : 
    4894          90 :     PG_RETURN_LSN(result);
    4895             : }
    4896             : 
    4897             : 
    4898             : /* ----------------------------------------------------------------------
    4899             :  *
    4900             :  * Aggregate functions
    4901             :  *
    4902             :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4903             :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4904             :  * context.  The digit buffers for the NumericVars will be there too.
    4905             :  *
    4906             :  * On platforms which support 128-bit integers some aggregates instead use a
    4907             :  * 128-bit integer based transition datatype to speed up calculations.
    4908             :  *
    4909             :  * ----------------------------------------------------------------------
    4910             :  */
    4911             : 
    4912             : typedef struct NumericAggState
    4913             : {
    4914             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4915             :     MemoryContext agg_context;  /* context we're calculating in */
    4916             :     int64       N;              /* count of processed numbers */
    4917             :     NumericSumAccum sumX;       /* sum of processed numbers */
    4918             :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4919             :     int         maxScale;       /* maximum scale seen so far */
    4920             :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4921             :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4922             :     int64       NaNcount;       /* count of NaN values */
    4923             :     int64       pInfcount;      /* count of +Inf values */
    4924             :     int64       nInfcount;      /* count of -Inf values */
    4925             : } NumericAggState;
    4926             : 
    4927             : #define NA_TOTAL_COUNT(na) \
    4928             :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4929             : 
    4930             : /*
    4931             :  * Prepare state data for a numeric aggregate function that needs to compute
    4932             :  * sum, count and optionally sum of squares of the input.
    4933             :  */
    4934             : static NumericAggState *
    4935      171116 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4936             : {
    4937             :     NumericAggState *state;
    4938             :     MemoryContext agg_context;
    4939             :     MemoryContext old_context;
    4940             : 
    4941      171116 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4942           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4943             : 
    4944      171116 :     old_context = MemoryContextSwitchTo(agg_context);
    4945             : 
    4946      171116 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4947      171116 :     state->calcSumX2 = calcSumX2;
    4948      171116 :     state->agg_context = agg_context;
    4949             : 
    4950      171116 :     MemoryContextSwitchTo(old_context);
    4951             : 
    4952      171116 :     return state;
    4953             : }
    4954             : 
    4955             : /*
    4956             :  * Like makeNumericAggState(), but allocate the state in the current memory
    4957             :  * context.
    4958             :  */
    4959             : static NumericAggState *
    4960          60 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4961             : {
    4962             :     NumericAggState *state;
    4963             : 
    4964          60 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4965          60 :     state->calcSumX2 = calcSumX2;
    4966          60 :     state->agg_context = CurrentMemoryContext;
    4967             : 
    4968          60 :     return state;
    4969             : }
    4970             : 
    4971             : /*
    4972             :  * Accumulate a new input value for numeric aggregate functions.
    4973             :  */
    4974             : static void
    4975     2113552 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4976             : {
    4977             :     NumericVar  X;
    4978             :     NumericVar  X2;
    4979             :     MemoryContext old_context;
    4980             : 
    4981             :     /* Count NaN/infinity inputs separately from all else */
    4982     2113552 :     if (NUMERIC_IS_SPECIAL(newval))
    4983             :     {
    4984         162 :         if (NUMERIC_IS_PINF(newval))
    4985          72 :             state->pInfcount++;
    4986          90 :         else if (NUMERIC_IS_NINF(newval))
    4987          36 :             state->nInfcount++;
    4988             :         else
    4989          54 :             state->NaNcount++;
    4990         162 :         return;
    4991             :     }
    4992             : 
    4993             :     /* load processed number in short-lived context */
    4994     2113390 :     init_var_from_num(newval, &X);
    4995             : 
    4996             :     /*
    4997             :      * Track the highest input dscale that we've seen, to support inverse
    4998             :      * transitions (see do_numeric_discard).
    4999             :      */
    5000     2113390 :     if (X.dscale > state->maxScale)
    5001             :     {
    5002         156 :         state->maxScale = X.dscale;
    5003         156 :         state->maxScaleCount = 1;
    5004             :     }
    5005     2113234 :     else if (X.dscale == state->maxScale)
    5006     2113198 :         state->maxScaleCount++;
    5007             : 
    5008             :     /* if we need X^2, calculate that in short-lived context */
    5009     2113390 :     if (state->calcSumX2)
    5010             :     {
    5011      240732 :         init_var(&X2);
    5012      240732 :         mul_var(&X, &X, &X2, X.dscale * 2);
    5013             :     }
    5014             : 
    5015             :     /* The rest of this needs to work in the aggregate context */
    5016     2113390 :     old_context = MemoryContextSwitchTo(state->agg_context);
    5017             : 
    5018     2113390 :     state->N++;
    5019             : 
    5020             :     /* Accumulate sums */
    5021     2113390 :     accum_sum_add(&(state->sumX), &X);
    5022             : 
    5023     2113390 :     if (state->calcSumX2)
    5024      240732 :         accum_sum_add(&(state->sumX2), &X2);
    5025             : 
    5026     2113390 :     MemoryContextSwitchTo(old_context);
    5027             : }
    5028             : 
    5029             : /*
    5030             :  * Attempt to remove an input value from the aggregated state.
    5031             :  *
    5032             :  * If the value cannot be removed then the function will return false; the
    5033             :  * possible reasons for failing are described below.
    5034             :  *
    5035             :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    5036             :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    5037             :  * won't be able to tell what the new aggregated value's dscale should be.
    5038             :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    5039             :  * have been zero if we'd really aggregated only 2.
    5040             :  *
    5041             :  * Note: alternatively, we could count the number of inputs with each possible
    5042             :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    5043             :  */
    5044             : static bool
    5045         342 : do_numeric_discard(NumericAggState *state, Numeric newval)
    5046             : {
    5047             :     NumericVar  X;
    5048             :     NumericVar  X2;
    5049             :     MemoryContext old_context;
    5050             : 
    5051             :     /* Count NaN/infinity inputs separately from all else */
    5052         342 :     if (NUMERIC_IS_SPECIAL(newval))
    5053             :     {
    5054           6 :         if (NUMERIC_IS_PINF(newval))
    5055           0 :             state->pInfcount--;
    5056           6 :         else if (NUMERIC_IS_NINF(newval))
    5057           0 :             state->nInfcount--;
    5058             :         else
    5059           6 :             state->NaNcount--;
    5060           6 :         return true;
    5061             :     }
    5062             : 
    5063             :     /* load processed number in short-lived context */
    5064         336 :     init_var_from_num(newval, &X);
    5065             : 
    5066             :     /*
    5067             :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    5068             :      * Removing the last input with that dscale would require us to recompute
    5069             :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    5070             :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    5071             :      * and force the aggregation to be redone from scratch.
    5072             :      */
    5073         336 :     if (X.dscale == state->maxScale)
    5074             :     {
    5075         336 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    5076             :         {
    5077             :             /*
    5078             :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    5079             :              * above zero anyway
    5080             :              */
    5081         318 :             state->maxScaleCount--;
    5082             :         }
    5083          18 :         else if (state->N == 1)
    5084             :         {
    5085             :             /* No remaining non-NaN inputs at all, so reset maxScale */
    5086          12 :             state->maxScale = 0;
    5087          12 :             state->maxScaleCount = 0;
    5088             :         }
    5089             :         else
    5090             :         {
    5091             :             /* Correct new maxScale is uncertain, must fail */
    5092           6 :             return false;
    5093             :         }
    5094             :     }
    5095             : 
    5096             :     /* if we need X^2, calculate that in short-lived context */
    5097         330 :     if (state->calcSumX2)
    5098             :     {
    5099         288 :         init_var(&X2);
    5100         288 :         mul_var(&X, &X, &X2, X.dscale * 2);
    5101             :     }
    5102             : 
    5103             :     /* The rest of this needs to work in the aggregate context */
    5104         330 :     old_context = MemoryContextSwitchTo(state->agg_context);
    5105             : 
    5106         330 :     if (state->N-- > 1)
    5107             :     {
    5108             :         /* Negate X, to subtract it from the sum */
    5109         312 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    5110         312 :         accum_sum_add(&(state->sumX), &X);
    5111             : 
    5112         312 :         if (state->calcSumX2)
    5113             :         {
    5114             :             /* Negate X^2. X^2 is always positive */
    5115         288 :             X2.sign = NUMERIC_NEG;
    5116         288 :             accum_sum_add(&(state->sumX2), &X2);
    5117             :         }
    5118             :     }
    5119             :     else
    5120             :     {
    5121             :         /* Zero the sums */
    5122             :         Assert(state->N == 0);
    5123             : 
    5124          18 :         accum_sum_reset(&state->sumX);
    5125          18 :         if (state->calcSumX2)
    5126           0 :             accum_sum_reset(&state->sumX2);
    5127             :     }
    5128             : 
    5129         330 :     MemoryContextSwitchTo(old_context);
    5130             : 
    5131         330 :     return true;
    5132             : }
    5133             : 
    5134             : /*
    5135             :  * Generic transition function for numeric aggregates that require sumX2.
    5136             :  */
    5137             : Datum
    5138         642 : numeric_accum(PG_FUNCTION_ARGS)
    5139             : {
    5140             :     NumericAggState *state;
    5141             : 
    5142         642 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5143             : 
    5144             :     /* Create the state data on the first call */
    5145         642 :     if (state == NULL)
    5146         174 :         state = makeNumericAggState(fcinfo, true);
    5147             : 
    5148         642 :     if (!PG_ARGISNULL(1))
    5149         624 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5150             : 
    5151         642 :     PG_RETURN_POINTER(state);
    5152             : }
    5153             : 
    5154             : /*
    5155             :  * Generic combine function for numeric aggregates which require sumX2
    5156             :  */
    5157             : Datum
    5158          24 : numeric_combine(PG_FUNCTION_ARGS)
    5159             : {
    5160             :     NumericAggState *state1;
    5161             :     NumericAggState *state2;
    5162             :     MemoryContext agg_context;
    5163             :     MemoryContext old_context;
    5164             : 
    5165          24 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5166           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5167             : 
    5168          24 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5169          24 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5170             : 
    5171          24 :     if (state2 == NULL)
    5172           0 :         PG_RETURN_POINTER(state1);
    5173             : 
    5174             :     /* manually copy all fields from state2 to state1 */
    5175          24 :     if (state1 == NULL)
    5176             :     {
    5177          18 :         old_context = MemoryContextSwitchTo(agg_context);
    5178             : 
    5179          18 :         state1 = makeNumericAggStateCurrentContext(true);
    5180          18 :         state1->N = state2->N;
    5181          18 :         state1->NaNcount = state2->NaNcount;
    5182          18 :         state1->pInfcount = state2->pInfcount;
    5183          18 :         state1->nInfcount = state2->nInfcount;
    5184          18 :         state1->maxScale = state2->maxScale;
    5185          18 :         state1->maxScaleCount = state2->maxScaleCount;
    5186             : 
    5187          18 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5188          18 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5189             : 
    5190          18 :         MemoryContextSwitchTo(old_context);
    5191             : 
    5192          18 :         PG_RETURN_POINTER(state1);
    5193             :     }
    5194             : 
    5195           6 :     state1->N += state2->N;
    5196           6 :     state1->NaNcount += state2->NaNcount;
    5197           6 :     state1->pInfcount += state2->pInfcount;
    5198           6 :     state1->nInfcount += state2->nInfcount;
    5199             : 
    5200           6 :     if (state2->N > 0)
    5201             :     {
    5202             :         /*
    5203             :          * These are currently only needed for moving aggregates, but let's do
    5204             :          * the right thing anyway...
    5205             :          */
    5206           6 :         if (state2->maxScale > state1->maxScale)
    5207             :         {
    5208           0 :             state1->maxScale = state2->maxScale;
    5209           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5210             :         }
    5211           6 :         else if (state2->maxScale == state1->maxScale)
    5212           6 :             state1->maxScaleCount += state2->maxScaleCount;
    5213             : 
    5214             :         /* The rest of this needs to work in the aggregate context */
    5215           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5216             : 
    5217             :         /* Accumulate sums */
    5218           6 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5219           6 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5220             : 
    5221           6 :         MemoryContextSwitchTo(old_context);
    5222             :     }
    5223           6 :     PG_RETURN_POINTER(state1);
    5224             : }
    5225             : 
    5226             : /*
    5227             :  * Generic transition function for numeric aggregates that don't require sumX2.
    5228             :  */
    5229             : Datum
    5230     1872808 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5231             : {
    5232             :     NumericAggState *state;
    5233             : 
    5234     1872808 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5235             : 
    5236             :     /* Create the state data on the first call */
    5237     1872808 :     if (state == NULL)
    5238      170894 :         state = makeNumericAggState(fcinfo, false);
    5239             : 
    5240     1872808 :     if (!PG_ARGISNULL(1))
    5241     1872748 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5242             : 
    5243     1872808 :     PG_RETURN_POINTER(state);
    5244             : }
    5245             : 
    5246             : /*
    5247             :  * Combine function for numeric aggregates which don't require sumX2
    5248             :  */
    5249             : Datum
    5250          12 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5251             : {
    5252             :     NumericAggState *state1;
    5253             :     NumericAggState *state2;
    5254             :     MemoryContext agg_context;
    5255             :     MemoryContext old_context;
    5256             : 
    5257          12 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5258           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5259             : 
    5260          12 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5261          12 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5262             : 
    5263          12 :     if (state2 == NULL)
    5264           0 :         PG_RETURN_POINTER(state1);
    5265             : 
    5266             :     /* manually copy all fields from state2 to state1 */
    5267          12 :     if (state1 == NULL)
    5268             :     {
    5269           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5270             : 
    5271           6 :         state1 = makeNumericAggStateCurrentContext(false);
    5272           6 :         state1->N = state2->N;
    5273           6 :         state1->NaNcount = state2->NaNcount;
    5274           6 :         state1->pInfcount = state2->pInfcount;
    5275           6 :         state1->nInfcount = state2->nInfcount;
    5276           6 :         state1->maxScale = state2->maxScale;
    5277           6 :         state1->maxScaleCount = state2->maxScaleCount;
    5278             : 
    5279           6 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5280             : 
    5281           6 :         MemoryContextSwitchTo(old_context);
    5282             : 
    5283           6 :         PG_RETURN_POINTER(state1);
    5284             :     }
    5285             : 
    5286           6 :     state1->N += state2->N;
    5287           6 :     state1->NaNcount += state2->NaNcount;
    5288           6 :     state1->pInfcount += state2->pInfcount;
    5289           6 :     state1->nInfcount += state2->nInfcount;
    5290             : 
    5291           6 :     if (state2->N > 0)
    5292             :     {
    5293             :         /*
    5294             :          * These are currently only needed for moving aggregates, but let's do
    5295             :          * the right thing anyway...
    5296             :          */
    5297           6 :         if (state2->maxScale > state1->maxScale)
    5298             :         {
    5299           0 :             state1->maxScale = state2->maxScale;
    5300           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5301             :         }
    5302           6 :         else if (state2->maxScale == state1->maxScale)
    5303           6 :             state1->maxScaleCount += state2->maxScaleCount;
    5304             : 
    5305             :         /* The rest of this needs to work in the aggregate context */
    5306           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5307             : 
    5308             :         /* Accumulate sums */
    5309           6 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5310             : 
    5311           6 :         MemoryContextSwitchTo(old_context);
    5312             :     }
    5313           6 :     PG_RETURN_POINTER(state1);
    5314             : }
    5315             : 
    5316             : /*
    5317             :  * numeric_avg_serialize
    5318             :  *      Serialize NumericAggState for numeric aggregates that don't require
    5319             :  *      sumX2.
    5320             :  */
    5321             : Datum
    5322          12 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5323             : {
    5324             :     NumericAggState *state;
    5325             :     StringInfoData buf;
    5326             :     bytea      *result;
    5327             :     NumericVar  tmp_var;
    5328             : 
    5329             :     /* Ensure we disallow calling when not in aggregate context */
    5330          12 :     if (!AggCheckCallContext(fcinfo, NULL))
    5331           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5332             : 
    5333          12 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5334             : 
    5335          12 :     init_var(&tmp_var);
    5336             : 
    5337          12 :     pq_begintypsend(&buf);
    5338             : 
    5339             :     /* N */
    5340          12 :     pq_sendint64(&buf, state->N);
    5341             : 
    5342             :     /* sumX */
    5343          12 :     accum_sum_final(&state->sumX, &tmp_var);
    5344          12 :     numericvar_serialize(&buf, &tmp_var);
    5345             : 
    5346             :     /* maxScale */
    5347          12 :     pq_sendint32(&buf, state->maxScale);
    5348             : 
    5349             :     /* maxScaleCount */
    5350          12 :     pq_sendint64(&buf, state->maxScaleCount);
    5351             : 
    5352             :     /* NaNcount */
    5353          12 :     pq_sendint64(&buf, state->NaNcount);
    5354             : 
    5355             :     /* pInfcount */
    5356          12 :     pq_sendint64(&buf, state->pInfcount);
    5357             : 
    5358             :     /* nInfcount */
    5359          12 :     pq_sendint64(&buf, state->nInfcount);
    5360             : 
    5361          12 :     result = pq_endtypsend(&buf);
    5362             : 
    5363          12 :     free_var(&tmp_var);
    5364             : 
    5365          12 :     PG_RETURN_BYTEA_P(result);
    5366             : }
    5367             : 
    5368             : /*
    5369             :  * numeric_avg_deserialize
    5370             :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5371             :  *      don't require sumX2.
    5372             :  */
    5373             : Datum
    5374          12 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5375             : {
    5376             :     bytea      *sstate;
    5377             :     NumericAggState *result;
    5378             :     StringInfoData buf;
    5379             :     NumericVar  tmp_var;
    5380             : 
    5381          12 :     if (!AggCheckCallContext(fcinfo, NULL))
    5382           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5383             : 
    5384          12 :     sstate = PG_GETARG_BYTEA_PP(0);
    5385             : 
    5386          12 :     init_var(&tmp_var);
    5387             : 
    5388             :     /*
    5389             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5390             :      * recv-function infrastructure.
    5391             :      */
    5392          12 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5393          12 :                            VARSIZE_ANY_EXHDR(sstate));
    5394             : 
    5395          12 :     result = makeNumericAggStateCurrentContext(false);
    5396             : 
    5397             :     /* N */
    5398          12 :     result->N = pq_getmsgint64(&buf);
    5399             : 
    5400             :     /* sumX */
    5401          12 :     numericvar_deserialize(&buf, &tmp_var);
    5402          12 :     accum_sum_add(&(result->sumX), &tmp_var);
    5403             : 
    5404             :     /* maxScale */
    5405          12 :     result->maxScale = pq_getmsgint(&buf, 4);
    5406             : 
    5407             :     /* maxScaleCount */
    5408          12 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5409             : 
    5410             :     /* NaNcount */
    5411          12 :     result->NaNcount = pq_getmsgint64(&buf);
    5412             : 
    5413             :     /* pInfcount */
    5414          12 :     result->pInfcount = pq_getmsgint64(&buf);
    5415             : 
    5416             :     /* nInfcount */
    5417          12 :     result->nInfcount = pq_getmsgint64(&buf);
    5418             : 
    5419          12 :     pq_getmsgend(&buf);
    5420             : 
    5421          12 :     free_var(&tmp_var);
    5422             : 
    5423          12 :     PG_RETURN_POINTER(result);
    5424             : }
    5425             : 
    5426             : /*
    5427             :  * numeric_serialize
    5428             :  *      Serialization function for NumericAggState for numeric aggregates that
    5429             :  *      require sumX2.
    5430             :  */
    5431             : Datum
    5432          24 : numeric_serialize(PG_FUNCTION_ARGS)
    5433             : {
    5434             :     NumericAggState *state;
    5435             :     StringInfoData buf;
    5436             :     bytea      *result;
    5437             :     NumericVar  tmp_var;
    5438             : 
    5439             :     /* Ensure we disallow calling when not in aggregate context */
    5440          24 :     if (!AggCheckCallContext(fcinfo, NULL))
    5441           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5442             : 
    5443          24 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5444             : 
    5445          24 :     init_var(&tmp_var);
    5446             : 
    5447          24 :     pq_begintypsend(&buf);
    5448             : 
    5449             :     /* N */
    5450          24 :     pq_sendint64(&buf, state->N);
    5451             : 
    5452             :     /* sumX */
    5453          24 :     accum_sum_final(&state->sumX, &tmp_var);
    5454          24 :     numericvar_serialize(&buf, &tmp_var);
    5455             : 
    5456             :     /* sumX2 */
    5457          24 :     accum_sum_final(&state->sumX2, &tmp_var);
    5458          24 :     numericvar_serialize(&buf, &tmp_var);
    5459             : 
    5460             :     /* maxScale */
    5461          24 :     pq_sendint32(&buf, state->maxScale);
    5462             : 
    5463             :     /* maxScaleCount */
    5464          24 :     pq_sendint64(&buf, state->maxScaleCount);
    5465             : 
    5466             :     /* NaNcount */
    5467          24 :     pq_sendint64(&buf, state->NaNcount);
    5468             : 
    5469             :     /* pInfcount */
    5470          24 :     pq_sendint64(&buf, state->pInfcount);
    5471             : 
    5472             :     /* nInfcount */
    5473          24 :     pq_sendint64(&buf, state->nInfcount);
    5474             : 
    5475          24 :     result = pq_endtypsend(&buf);
    5476             : 
    5477          24 :     free_var(&tmp_var);
    5478             : 
    5479          24 :     PG_RETURN_BYTEA_P(result);
    5480             : }
    5481             : 
    5482             : /*
    5483             :  * numeric_deserialize
    5484             :  *      Deserialization function for NumericAggState for numeric aggregates that
    5485             :  *      require sumX2.
    5486             :  */
    5487             : Datum
    5488          24 : numeric_deserialize(PG_FUNCTION_ARGS)
    5489             : {
    5490             :     bytea      *sstate;
    5491             :     NumericAggState *result;
    5492             :     StringInfoData buf;
    5493             :     NumericVar  tmp_var;
    5494             : 
    5495          24 :     if (!AggCheckCallContext(fcinfo, NULL))
    5496           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5497             : 
    5498          24 :     sstate = PG_GETARG_BYTEA_PP(0);
    5499             : 
    5500          24 :     init_var(&tmp_var);
    5501             : 
    5502             :     /*
    5503             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5504             :      * recv-function infrastructure.
    5505             :      */
    5506          24 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5507          24 :                            VARSIZE_ANY_EXHDR(sstate));
    5508             : 
    5509          24 :     result = makeNumericAggStateCurrentContext(false);
    5510             : 
    5511             :     /* N */
    5512          24 :     result->N = pq_getmsgint64(&buf);
    5513             : 
    5514             :     /* sumX */
    5515          24 :     numericvar_deserialize(&buf, &tmp_var);
    5516          24 :     accum_sum_add(&(result->sumX), &tmp_var);
    5517             : 
    5518             :     /* sumX2 */
    5519          24 :     numericvar_deserialize(&buf, &tmp_var);
    5520          24 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5521             : 
    5522             :     /* maxScale */
    5523          24 :     result->maxScale = pq_getmsgint(&buf, 4);
    5524             : 
    5525             :     /* maxScaleCount */
    5526          24 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5527             : 
    5528             :     /* NaNcount */
    5529          24 :     result->NaNcount = pq_getmsgint64(&buf);
    5530             : 
    5531             :     /* pInfcount */
    5532          24 :     result->pInfcount = pq_getmsgint64(&buf);
    5533             : 
    5534             :     /* nInfcount */
    5535          24 :     result->nInfcount = pq_getmsgint64(&buf);
    5536             : 
    5537          24 :     pq_getmsgend(&buf);
    5538             : 
    5539          24 :     free_var(&tmp_var);
    5540             : 
    5541          24 :     PG_RETURN_POINTER(result);
    5542             : }
    5543             : 
    5544             : /*
    5545             :  * Generic inverse transition function for numeric aggregates
    5546             :  * (with or without requirement for X^2).
    5547             :  */
    5548             : Datum
    5549         228 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5550             : {
    5551             :     NumericAggState *state;
    5552             : 
    5553         228 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5554             : 
    5555             :     /* Should not get here with no state */
    5556         228 :     if (state == NULL)
    5557           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5558             : 
    5559         228 :     if (!PG_ARGISNULL(1))
    5560             :     {
    5561             :         /* If we fail to perform the inverse transition, return NULL */
    5562         198 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5563           6 :             PG_RETURN_NULL();
    5564             :     }
    5565             : 
    5566         222 :     PG_RETURN_POINTER(state);
    5567             : }
    5568             : 
    5569             : 
    5570             : /*
    5571             :  * Integer data types in general use Numeric accumulators to share code
    5572             :  * and avoid risk of overflow.
    5573             :  *
    5574             :  * However for performance reasons optimized special-purpose accumulator
    5575             :  * routines are used when possible.
    5576             :  *
    5577             :  * On platforms with 128-bit integer support, the 128-bit routines will be
    5578             :  * used when sum(X) or sum(X*X) fit into 128-bit.
    5579             :  *
    5580             :  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
    5581             :  * accumulators will be used for SUM and AVG of these data types.
    5582             :  */
    5583             : 
    5584             : #ifdef HAVE_INT128
    5585             : typedef struct Int128AggState
    5586             : {
    5587             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5588             :     int64       N;              /* count of processed numbers */
    5589             :     int128      sumX;           /* sum of processed numbers */
    5590             :     int128      sumX2;          /* sum of squares of processed numbers */
    5591             : } Int128AggState;
    5592             : 
    5593             : /*
    5594             :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5595             :  * sum, count and optionally sum of squares of the input.
    5596             :  */
    5597             : static Int128AggState *
    5598         846 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5599             : {
    5600             :     Int128AggState *state;
    5601             :     MemoryContext agg_context;
    5602             :     MemoryContext old_context;
    5603             : 
    5604         846 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5605           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5606             : 
    5607         846 :     old_context = MemoryContextSwitchTo(agg_context);
    5608             : 
    5609         846 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5610         846 :     state->calcSumX2 = calcSumX2;
    5611             : 
    5612         846 :     MemoryContextSwitchTo(old_context);
    5613             : 
    5614         846 :     return state;
    5615             : }
    5616             : 
    5617             : /*
    5618             :  * Like makeInt128AggState(), but allocate the state in the current memory
    5619             :  * context.
    5620             :  */
    5621             : static Int128AggState *
    5622          22 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5623             : {
    5624             :     Int128AggState *state;
    5625             : 
    5626          22 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5627          22 :     state->calcSumX2 = calcSumX2;
    5628             : 
    5629          22 :     return state;
    5630             : }
    5631             : 
    5632             : /*
    5633             :  * Accumulate a new input value for 128-bit aggregate functions.
    5634             :  */
    5635             : static void
    5636      554190 : do_int128_accum(Int128AggState *state, int128 newval)
    5637             : {
    5638      554190 :     if (state->calcSumX2)
    5639      242360 :         state->sumX2 += newval * newval;
    5640             : 
    5641      554190 :     state->sumX += newval;
    5642      554190 :     state->N++;
    5643      554190 : }
    5644             : 
    5645             : /*
    5646             :  * Remove an input value from the aggregated state.
    5647             :  */
    5648             : static void
    5649         312 : do_int128_discard(Int128AggState *state, int128 newval)
    5650             : {
    5651         312 :     if (state->calcSumX2)
    5652         288 :         state->sumX2 -= newval * newval;
    5653             : 
    5654         312 :     state->sumX -= newval;
    5655         312 :     state->N--;
    5656         312 : }
    5657             : 
    5658             : typedef Int128AggState PolyNumAggState;
    5659             : #define makePolyNumAggState makeInt128AggState
    5660             : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
    5661             : #else
    5662             : typedef NumericAggState PolyNumAggState;
    5663             : #define makePolyNumAggState makeNumericAggState
    5664             : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
    5665             : #endif
    5666             : 
    5667             : Datum
    5668         198 : int2_accum(PG_FUNCTION_ARGS)
    5669             : {
    5670             :     PolyNumAggState *state;
    5671             : 
    5672         198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5673             : 
    5674             :     /* Create the state data on the first call */
    5675         198 :     if (state == NULL)
    5676          36 :         state = makePolyNumAggState(fcinfo, true);
    5677             : 
    5678         198 :     if (!PG_ARGISNULL(1))
    5679             :     {
    5680             : #ifdef HAVE_INT128
    5681         180 :         do_int128_accum(state, (int128) PG_GETARG_INT16(1));
    5682             : #else
    5683             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
    5684             : #endif
    5685             :     }
    5686             : 
    5687         198 :     PG_RETURN_POINTER(state);
    5688             : }
    5689             : 
    5690             : Datum
    5691      242198 : int4_accum(PG_FUNCTION_ARGS)
    5692             : {
    5693             :     PolyNumAggState *state;
    5694             : 
    5695      242198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5696             : 
    5697             :     /* Create the state data on the first call */
    5698      242198 :     if (state == NULL)
    5699          64 :         state = makePolyNumAggState(fcinfo, true);
    5700             : 
    5701      242198 :     if (!PG_ARGISNULL(1))
    5702             :     {
    5703             : #ifdef HAVE_INT128
    5704      242180 :         do_int128_accum(state, (int128) PG_GETARG_INT32(1));
    5705             : #else
    5706             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
    5707             : #endif
    5708             :     }
    5709             : 
    5710      242198 :     PG_RETURN_POINTER(state);
    5711             : }
    5712             : 
    5713             : Datum
    5714      240198 : int8_accum(PG_FUNCTION_ARGS)
    5715             : {
    5716             :     NumericAggState *state;
    5717             : 
    5718      240198 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5719             : 
    5720             :     /* Create the state data on the first call */
    5721      240198 :     if (state == NULL)
    5722          48 :         state = makeNumericAggState(fcinfo, true);
    5723             : 
    5724      240198 :     if (!PG_ARGISNULL(1))
    5725      240180 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5726             : 
    5727      240198 :     PG_RETURN_POINTER(state);
    5728             : }
    5729             : 
    5730             : /*
    5731             :  * Combine function for numeric aggregates which require sumX2
    5732             :  */
    5733             : Datum
    5734           8 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5735             : {
    5736             :     PolyNumAggState *state1;
    5737             :     PolyNumAggState *state2;
    5738             :     MemoryContext agg_context;
    5739             :     MemoryContext old_context;
    5740             : 
    5741           8 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5742           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5743             : 
    5744           8 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5745           8 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5746             : 
    5747           8 :     if (state2 == NULL)
    5748           0 :         PG_RETURN_POINTER(state1);
    5749             : 
    5750             :     /* manually copy all fields from state2 to state1 */
    5751           8 :     if (state1 == NULL)
    5752             :     {
    5753           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5754             : 
    5755           6 :         state1 = makePolyNumAggState(fcinfo, true);
    5756           6 :         state1->N = state2->N;
    5757             : 
    5758             : #ifdef HAVE_INT128
    5759           6 :         state1->sumX = state2->sumX;
    5760           6 :         state1->sumX2 = state2->sumX2;
    5761             : #else
    5762             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5763             :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5764             : #endif
    5765             : 
    5766           6 :         MemoryContextSwitchTo(old_context);
    5767             : 
    5768           6 :         PG_RETURN_POINTER(state1);
    5769             :     }
    5770             : 
    5771           2 :     if (state2->N > 0)
    5772             :     {
    5773           2 :         state1->N += state2->N;
    5774             : 
    5775             : #ifdef HAVE_INT128
    5776           2 :         state1->sumX += state2->sumX;
    5777           2 :         state1->sumX2 += state2->sumX2;
    5778             : #else
    5779             :         /* The rest of this needs to work in the aggregate context */
    5780             :         old_context = MemoryContextSwitchTo(agg_context);
    5781             : 
    5782             :         /* Accumulate sums */
    5783             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5784             :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5785             : 
    5786             :         MemoryContextSwitchTo(old_context);
    5787             : #endif
    5788             : 
    5789             :     }
    5790           2 :     PG_RETURN_POINTER(state1);
    5791             : }
    5792             : 
    5793             : /*
    5794             :  * numeric_poly_serialize
    5795             :  *      Serialize PolyNumAggState into bytea for aggregate functions which
    5796             :  *      require sumX2.
    5797             :  */
    5798             : Datum
    5799           8 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5800             : {
    5801             :     PolyNumAggState *state;
    5802             :     StringInfoData buf;
    5803             :     bytea      *result;
    5804             :     NumericVar  tmp_var;
    5805             : 
    5806             :     /* Ensure we disallow calling when not in aggregate context */
    5807           8 :     if (!AggCheckCallContext(fcinfo, NULL))
    5808           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5809             : 
    5810           8 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5811             : 
    5812             :     /*
    5813             :      * If the platform supports int128 then sumX and sumX2 will be a 128 bit
    5814             :      * integer type. Here we'll convert that into a numeric type so that the
    5815             :      * combine state is in the same format for both int128 enabled machines
    5816             :      * and machines which don't support that type. The logic here is that one
    5817             :      * day we might like to send these over to another server for further
    5818             :      * processing and we want a standard format to work with.
    5819             :      */
    5820             : 
    5821           8 :     init_var(&tmp_var);
    5822             : 
    5823           8 :     pq_begintypsend(&buf);
    5824             : 
    5825             :     /* N */
    5826           8 :     pq_sendint64(&buf, state->N);
    5827             : 
    5828             :     /* sumX */
    5829             : #ifdef HAVE_INT128
    5830           8 :     int128_to_numericvar(state->sumX, &tmp_var);
    5831             : #else
    5832             :     accum_sum_final(&state->sumX, &tmp_var);
    5833             : #endif
    5834           8 :     numericvar_serialize(&buf, &tmp_var);
    5835             : 
    5836             :     /* sumX2 */
    5837             : #ifdef HAVE_INT128
    5838           8 :     int128_to_numericvar(state->sumX2, &tmp_var);
    5839             : #else
    5840             :     accum_sum_final(&state->sumX2, &tmp_var);
    5841             : #endif
    5842           8 :     numericvar_serialize(&buf, &tmp_var);
    5843             : 
    5844           8 :     result = pq_endtypsend(&buf);
    5845             : 
    5846           8 :     free_var(&tmp_var);
    5847             : 
    5848           8 :     PG_RETURN_BYTEA_P(result);
    5849             : }
    5850             : 
    5851             : /*
    5852             :  * numeric_poly_deserialize
    5853             :  *      Deserialize PolyNumAggState from bytea for aggregate functions which
    5854             :  *      require sumX2.
    5855             :  */
    5856             : Datum
    5857           8 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5858             : {
    5859             :     bytea      *sstate;
    5860             :     PolyNumAggState *result;
    5861             :     StringInfoData buf;
    5862             :     NumericVar  tmp_var;
    5863             : 
    5864           8 :     if (!AggCheckCallContext(fcinfo, NULL))
    5865           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5866             : 
    5867           8 :     sstate = PG_GETARG_BYTEA_PP(0);
    5868             : 
    5869           8 :     init_var(&tmp_var);
    5870             : 
    5871             :     /*
    5872             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5873             :      * recv-function infrastructure.
    5874             :      */
    5875           8 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5876           8 :                            VARSIZE_ANY_EXHDR(sstate));
    5877             : 
    5878           8 :     result = makePolyNumAggStateCurrentContext(false);
    5879             : 
    5880             :     /* N */
    5881           8 :     result->N = pq_getmsgint64(&buf);
    5882             : 
    5883             :     /* sumX */
    5884           8 :     numericvar_deserialize(&buf, &tmp_var);
    5885             : #ifdef HAVE_INT128
    5886           8 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5887             : #else
    5888             :     accum_sum_add(&result->sumX, &tmp_var);
    5889             : #endif
    5890             : 
    5891             :     /* sumX2 */
    5892           8 :     numericvar_deserialize(&buf, &tmp_var);
    5893             : #ifdef HAVE_INT128
    5894           8 :     numericvar_to_int128(&tmp_var, &result->sumX2);
    5895             : #else
    5896             :     accum_sum_add(&result->sumX2, &tmp_var);
    5897             : #endif
    5898             : 
    5899           8 :     pq_getmsgend(&buf);
    5900             : 
    5901           8 :     free_var(&tmp_var);
    5902             : 
    5903           8 :     PG_RETURN_POINTER(result);
    5904             : }
    5905             : 
    5906             : /*
    5907             :  * Transition function for int8 input when we don't need sumX2.
    5908             :  */
    5909             : Datum
    5910      313126 : int8_avg_accum(PG_FUNCTION_ARGS)
    5911             : {
    5912             :     PolyNumAggState *state;
    5913             : 
    5914      313126 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5915             : 
    5916             :     /* Create the state data on the first call */
    5917      313126 :     if (state == NULL)
    5918         728 :         state = makePolyNumAggState(fcinfo, false);
    5919             : 
    5920      313126 :     if (!PG_ARGISNULL(1))
    5921             :     {
    5922             : #ifdef HAVE_INT128
    5923      311830 :         do_int128_accum(state, (int128) PG_GETARG_INT64(1));
    5924             : #else
    5925             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5926             : #endif
    5927             :     }
    5928             : 
    5929      313126 :     PG_RETURN_POINTER(state);
    5930             : }
    5931             : 
    5932             : /*
    5933             :  * Combine function for PolyNumAggState for aggregates which don't require
    5934             :  * sumX2
    5935             :  */
    5936             : Datum
    5937          14 : int8_avg_combine(PG_FUNCTION_ARGS)
    5938             : {
    5939             :     PolyNumAggState *state1;
    5940             :     PolyNumAggState *state2;
    5941             :     MemoryContext agg_context;
    5942             :     MemoryContext old_context;
    5943             : 
    5944          14 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5945           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5946             : 
    5947          14 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5948          14 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5949             : 
    5950          14 :     if (state2 == NULL)
    5951           0 :         PG_RETURN_POINTER(state1);
    5952             : 
    5953             :     /* manually copy all fields from state2 to state1 */
    5954          14 :     if (state1 == NULL)
    5955             :     {
    5956          12 :         old_context = MemoryContextSwitchTo(agg_context);
    5957             : 
    5958          12 :         state1 = makePolyNumAggState(fcinfo, false);
    5959          12 :         state1->N = state2->N;
    5960             : 
    5961             : #ifdef HAVE_INT128
    5962          12 :         state1->sumX = state2->sumX;
    5963             : #else
    5964             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5965             : #endif
    5966          12 :         MemoryContextSwitchTo(old_context);
    5967             : 
    5968          12 :         PG_RETURN_POINTER(state1);
    5969             :     }
    5970             : 
    5971           2 :     if (state2->N > 0)
    5972             :     {
    5973           2 :         state1->N += state2->N;
    5974             : 
    5975             : #ifdef HAVE_INT128
    5976           2 :         state1->sumX += state2->sumX;
    5977             : #else
    5978             :         /* The rest of this needs to work in the aggregate context */
    5979             :         old_context = MemoryContextSwitchTo(agg_context);
    5980             : 
    5981             :         /* Accumulate sums */
    5982             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5983             : 
    5984             :         MemoryContextSwitchTo(old_context);
    5985             : #endif
    5986             : 
    5987             :     }
    5988           2 :     PG_RETURN_POINTER(state1);
    5989             : }
    5990             : 
    5991             : /*
    5992             :  * int8_avg_serialize
    5993             :  *      Serialize PolyNumAggState into bytea using the standard
    5994             :  *      recv-function infrastructure.
    5995             :  */
    5996             : Datum
    5997          14 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5998             : {
    5999             :     PolyNumAggState *state;
    6000             :     StringInfoData buf;
    6001             :     bytea      *result;
    6002             :     NumericVar  tmp_var;
    6003             : 
    6004             :     /* Ensure we disallow calling when not in aggregate context */
    6005          14 :     if (!AggCheckCallContext(fcinfo, NULL))
    6006           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6007             : 
    6008          14 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    6009             : 
    6010             :     /*
    6011             :      * If the platform supports int128 then sumX will be a 128 integer type.
    6012             :      * Here we'll convert that into a numeric type so that the combine state
    6013             :      * is in the same format for both int128 enabled machines and machines
    6014             :      * which don't support that type. The logic here is that one day we might
    6015             :      * like to send these over to another server for further processing and we
    6016             :      * want a standard format to work with.
    6017             :      */
    6018             : 
    6019          14 :     init_var(&tmp_var);
    6020             : 
    6021          14 :     pq_begintypsend(&buf);
    6022             : 
    6023             :     /* N */
    6024          14 :     pq_sendint64(&buf, state->N);
    6025             : 
    6026             :     /* sumX */
    6027             : #ifdef HAVE_INT128
    6028          14 :     int128_to_numericvar(state->sumX, &tmp_var);
    6029             : #else
    6030             :     accum_sum_final(&state->sumX, &tmp_var);
    6031             : #endif
    6032          14 :     numericvar_serialize(&buf, &tmp_var);
    6033             : 
    6034          14 :     result = pq_endtypsend(&buf);
    6035             : 
    6036          14 :     free_var(&tmp_var);
    6037             : 
    6038          14 :     PG_RETURN_BYTEA_P(result);
    6039             : }
    6040             : 
    6041             : /*
    6042             :  * int8_avg_deserialize
    6043             :  *      Deserialize bytea back into PolyNumAggState.
    6044             :  */
    6045             : Datum
    6046          14 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    6047             : {
    6048             :     bytea      *sstate;
    6049             :     PolyNumAggState *result;
    6050             :     StringInfoData buf;
    6051             :     NumericVar  tmp_var;
    6052             : 
    6053          14 :     if (!AggCheckCallContext(fcinfo, NULL))
    6054           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6055             : 
    6056          14 :     sstate = PG_GETARG_BYTEA_PP(0);
    6057             : 
    6058          14 :     init_var(&tmp_var);
    6059             : 
    6060             :     /*
    6061             :      * Initialize a StringInfo so that we can "receive" it using the standard
    6062             :      * recv-function infrastructure.
    6063             :      */
    6064          14 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    6065          14 :                            VARSIZE_ANY_EXHDR(sstate));
    6066             : 
    6067          14 :     result = makePolyNumAggStateCurrentContext(false);
    6068             : 
    6069             :     /* N */
    6070          14 :     result->N = pq_getmsgint64(&buf);
    6071             : 
    6072             :     /* sumX */
    6073          14 :     numericvar_deserialize(&buf, &tmp_var);
    6074             : #ifdef HAVE_INT128
    6075          14 :     numericvar_to_int128(&tmp_var, &result->sumX);
    6076             : #else
    6077             :     accum_sum_add(&result->sumX, &tmp_var);
    6078             : #endif
    6079             : 
    6080          14 :     pq_getmsgend(&buf);
    6081             : 
    6082          14 :     free_var(&tmp_var);
    6083             : 
    6084          14 :     PG_RETURN_POINTER(result);
    6085             : }
    6086             : 
    6087             : /*
    6088             :  * Inverse transition functions to go with the above.
    6089             :  */
    6090             : 
    6091             : Datum
    6092         162 : int2_accum_inv(PG_FUNCTION_ARGS)
    6093             : {
    6094             :     PolyNumAggState *state;
    6095             : 
    6096         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6097             : 
    6098             :     /* Should not get here with no state */
    6099         162 :     if (state == NULL)
    6100           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    6101             : 
    6102         162 :     if (!PG_ARGISNULL(1))
    6103             :     {
    6104             : #ifdef HAVE_INT128
    6105         144 :         do_int128_discard(state, (int128) PG_GETARG_INT16(1));
    6106             : #else
    6107             :         /* Should never fail, all inputs have dscale 0 */
    6108             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
    6109             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6110             : #endif
    6111             :     }
    6112             : 
    6113         162 :     PG_RETURN_POINTER(state);
    6114             : }
    6115             : 
    6116             : Datum
    6117         162 : int4_accum_inv(PG_FUNCTION_ARGS)
    6118             : {
    6119             :     PolyNumAggState *state;
    6120             : 
    6121         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6122             : 
    6123             :     /* Should not get here with no state */
    6124         162 :     if (state == NULL)
    6125           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    6126             : 
    6127         162 :     if (!PG_ARGISNULL(1))
    6128             :     {
    6129             : #ifdef HAVE_INT128
    6130         144 :         do_int128_discard(state, (int128) PG_GETARG_INT32(1));
    6131             : #else
    6132             :         /* Should never fail, all inputs have dscale 0 */
    6133             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
    6134             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6135             : #endif
    6136             :     }
    6137             : 
    6138         162 :     PG_RETURN_POINTER(state);
    6139             : }
    6140             : 
    6141             : Datum
    6142         162 : int8_accum_inv(PG_FUNCTION_ARGS)
    6143             : {
    6144             :     NumericAggState *state;
    6145             : 
    6146         162 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6147             : 
    6148             :     /* Should not get here with no state */
    6149         162 :     if (state == NULL)
    6150           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    6151             : 
    6152         162 :     if (!PG_ARGISNULL(1))
    6153             :     {
    6154             :         /* Should never fail, all inputs have dscale 0 */
    6155         144 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6156           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6157             :     }
    6158             : 
    6159         162 :     PG_RETURN_POINTER(state);
    6160             : }
    6161             : 
    6162             : Datum
    6163          36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    6164             : {
    6165             :     PolyNumAggState *state;
    6166             : 
    6167          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6168             : 
    6169             :     /* Should not get here with no state */
    6170          36 :     if (state == NULL)
    6171           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    6172             : 
    6173          36 :     if (!PG_ARGISNULL(1))
    6174             :     {
    6175             : #ifdef HAVE_INT128
    6176          24 :         do_int128_discard(state, (int128) PG_GETARG_INT64(1));
    6177             : #else
    6178             :         /* Should never fail, all inputs have dscale 0 */
    6179             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6180             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6181             : #endif
    6182             :     }
    6183             : 
    6184          36 :     PG_RETURN_POINTER(state);
    6185             : }
    6186             : 
    6187             : Datum
    6188         960 : numeric_poly_sum(PG_FUNCTION_ARGS)
    6189             : {
    6190             : #ifdef HAVE_INT128
    6191             :     PolyNumAggState *state;
    6192             :     Numeric     res;
    6193             :     NumericVar  result;
    6194             : 
    6195         960 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6196             : 
    6197             :     /* If there were no non-null inputs, return NULL */
    6198         960 :     if (state == NULL || state->N == 0)
    6199          24 :         PG_RETURN_NULL();
    6200             : 
    6201         936 :     init_var(&result);
    6202             : 
    6203         936 :     int128_to_numericvar(state->sumX, &result);
    6204             : 
    6205         936 :     res = make_result(&result);
    6206             : 
    6207         936 :     free_var(&result);
    6208             : 
    6209         936 :     PG_RETURN_NUMERIC(res);
    6210             : #else
    6211             :     return numeric_sum(fcinfo);
    6212             : #endif
    6213             : }
    6214             : 
    6215             : Datum
    6216          36 : numeric_poly_avg(PG_FUNCTION_ARGS)
    6217             : {
    6218             : #ifdef HAVE_INT128
    6219             :     PolyNumAggState *state;
    6220             :     NumericVar  result;
    6221             :     Datum       countd,
    6222             :                 sumd;
    6223             : 
    6224          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6225             : 
    6226             :     /* If there were no non-null inputs, return NULL */
    6227          36 :     if (state == NULL || state->N == 0)
    6228          18 :         PG_RETURN_NULL();
    6229             : 
    6230          18 :     init_var(&result);
    6231             : 
    6232          18 :     int128_to_numericvar(state->sumX, &result);
    6233             : 
    6234          18 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    6235          18 :     sumd = NumericGetDatum(make_result(&result));
    6236             : 
    6237          18 :     free_var(&result);
    6238             : 
    6239          18 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6240             : #else
    6241             :     return numeric_avg(fcinfo);
    6242             : #endif
    6243             : }
    6244             : 
    6245             : Datum
    6246          78 : numeric_avg(PG_FUNCTION_ARGS)
    6247             : {
    6248             :     NumericAggState *state;
    6249             :     Datum       N_datum;
    6250             :     Datum       sumX_datum;
    6251             :     NumericVar  sumX_var;
    6252             : 
    6253          78 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6254             : 
    6255             :     /* If there were no non-null inputs, return NULL */
    6256          78 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6257          18 :         PG_RETURN_NULL();
    6258             : 
    6259          60 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6260           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6261             : 
    6262             :     /* adding plus and minus infinities gives NaN */
    6263          54 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6264           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6265          48 :     if (state->pInfcount > 0)
    6266          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6267          30 :     if (state->nInfcount > 0)
    6268           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6269             : 
    6270          24 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    6271             : 
    6272          24 :     init_var(&sumX_var);
    6273          24 :     accum_sum_final(&state->sumX, &sumX_var);
    6274          24 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    6275          24 :     free_var(&sumX_var);
    6276             : 
    6277          24 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    6278             : }
    6279             : 
    6280             : Datum
    6281      170906 : numeric_sum(PG_FUNCTION_ARGS)
    6282             : {
    6283             :     NumericAggState *state;
    6284             :     NumericVar  sumX_var;
    6285             :     Numeric     result;
    6286             : 
    6287      170906 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6288             : 
    6289             :     /* If there were no non-null inputs, return NULL */
    6290      170906 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6291          18 :         PG_RETURN_NULL();
    6292             : 
    6293      170888 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6294          18 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6295             : 
    6296             :     /* adding plus and minus infinities gives NaN */
    6297      170870 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6298           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6299      170864 :     if (state->pInfcount > 0)
    6300          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6301      170846 :     if (state->nInfcount > 0)
    6302           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6303             : 
    6304      170840 :     init_var(&sumX_var);
    6305      170840 :     accum_sum_final(&state->sumX, &sumX_var);
    6306      170840 :     result = make_result(&sumX_var);
    6307      170840 :     free_var(&sumX_var);
    6308             : 
    6309      170840 :     PG_RETURN_NUMERIC(result);
    6310             : }
    6311             : 
    6312             : /*
    6313             :  * Workhorse routine for the standard deviance and variance
    6314             :  * aggregates. 'state' is aggregate's transition state.
    6315             :  * 'variance' specifies whether we should calculate the
    6316             :  * variance or the standard deviation. 'sample' indicates whether the
    6317             :  * caller is interested in the sample or the population
    6318             :  * variance/stddev.
    6319             :  *
    6320             :  * If appropriate variance statistic is undefined for the input,
    6321             :  * *is_null is set to true and NULL is returned.
    6322             :  */
    6323             : static Numeric
    6324         986 : numeric_stddev_internal(NumericAggState *state,
    6325             :                         bool variance, bool sample,
    6326             :                         bool *is_null)
    6327             : {
    6328             :     Numeric     res;
    6329             :     NumericVar  vN,
    6330             :                 vsumX,
    6331             :                 vsumX2,
    6332             :                 vNminus1;
    6333             :     int64       totCount;
    6334             :     int         rscale;
    6335             : 
    6336             :     /*
    6337             :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6338             :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6339             :      * and infinities count as normal inputs for this purpose).
    6340             :      */
    6341         986 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6342             :     {
    6343           0 :         *is_null = true;
    6344           0 :         return NULL;
    6345             :     }
    6346             : 
    6347         986 :     if (sample && totCount <= 1)
    6348             :     {
    6349         132 :         *is_null = true;
    6350         132 :         return NULL;
    6351             :     }
    6352             : 
    6353         854 :     *is_null = false;
    6354             : 
    6355             :     /*
    6356             :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6357             :      * float8 functions, any infinity input produces NaN output.
    6358             :      */
    6359         854 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6360          54 :         return make_result(&const_nan);
    6361             : 
    6362             :     /* OK, normal calculation applies */
    6363         800 :     init_var(&vN);
    6364         800 :     init_var(&vsumX);
    6365         800 :     init_var(&vsumX2);
    6366             : 
    6367         800 :     int64_to_numericvar(state->N, &vN);
    6368         800 :     accum_sum_final(&(state->sumX), &vsumX);
    6369         800 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6370             : 
    6371         800 :     init_var(&vNminus1);
    6372         800 :     sub_var(&vN, &const_one, &vNminus1);
    6373             : 
    6374             :     /* compute rscale for mul_var calls */
    6375         800 :     rscale = vsumX.dscale * 2;
    6376             : 
    6377         800 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6378         800 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6379         800 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6380             : 
    6381         800 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6382             :     {
    6383             :         /* Watch out for roundoff error producing a negative numerator */
    6384          80 :         res = make_result(&const_zero);
    6385             :     }
    6386             :     else
    6387             :     {
    6388         720 :         if (sample)
    6389         492 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6390             :         else
    6391         228 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6392         720 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6393         720 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true);    /* variance */
    6394         720 :         if (!variance)
    6395         378 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6396             : 
    6397         720 :         res = make_result(&vsumX);
    6398             :     }
    6399             : 
    6400         800 :     free_var(&vNminus1);
    6401         800 :     free_var(&vsumX);
    6402         800 :     free_var(&vsumX2);
    6403             : 
    6404         800 :     return res;
    6405             : }
    6406             : 
    6407             : Datum
    6408         180 : numeric_var_samp(PG_FUNCTION_ARGS)
    6409             : {
    6410             :     NumericAggState *state;
    6411             :     Numeric     res;
    6412             :     bool        is_null;
    6413             : 
    6414         180 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6415             : 
    6416         180 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6417             : 
    6418         180 :     if (is_null)
    6419          42 :         PG_RETURN_NULL();
    6420             :     else
    6421         138 :         PG_RETURN_NUMERIC(res);
    6422             : }
    6423             : 
    6424             : Datum
    6425         174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6426             : {
    6427             :     NumericAggState *state;
    6428             :     Numeric     res;
    6429             :     bool        is_null;
    6430             : 
    6431         174 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6432             : 
    6433         174 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6434             : 
    6435         174 :     if (is_null)
    6436          42 :         PG_RETURN_NULL();
    6437             :     else
    6438         132 :         PG_RETURN_NUMERIC(res);
    6439             : }
    6440             : 
    6441             : Datum
    6442         114 : numeric_var_pop(PG_FUNCTION_ARGS)
    6443             : {
    6444             :     NumericAggState *state;
    6445             :     Numeric     res;
    6446             :     bool        is_null;
    6447             : 
    6448         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6449             : 
    6450         114 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6451             : 
    6452         114 :     if (is_null)
    6453           0 :         PG_RETURN_NULL();
    6454             :     else
    6455         114 :         PG_RETURN_NUMERIC(res);
    6456             : }
    6457             : 
    6458             : Datum
    6459          96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6460             : {
    6461             :     NumericAggState *state;
    6462             :     Numeric     res;
    6463             :     bool        is_null;
    6464             : 
    6465          96 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6466             : 
    6467          96 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6468             : 
    6469          96 :     if (is_null)
    6470           0 :         PG_RETURN_NULL();
    6471             :     else
    6472          96 :         PG_RETURN_NUMERIC(res);
    6473             : }
    6474             : 
    6475             : #ifdef HAVE_INT128
    6476             : static Numeric
    6477         422 : numeric_poly_stddev_internal(Int128AggState *state,
    6478             :                              bool variance, bool sample,
    6479             :                              bool *is_null)
    6480             : {
    6481             :     NumericAggState numstate;
    6482             :     Numeric     res;
    6483             : 
    6484             :     /* Initialize an empty agg state */
    6485         422 :     memset(&numstate, 0, sizeof(NumericAggState));
    6486             : 
    6487         422 :     if (state)
    6488             :     {
    6489             :         NumericVar  tmp_var;
    6490             : 
    6491         422 :         numstate.N = state->N;
    6492             : 
    6493         422 :         init_var(&tmp_var);
    6494             : 
    6495         422 :         int128_to_numericvar(state->sumX, &tmp_var);
    6496         422 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6497             : 
    6498         422 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6499         422 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6500             : 
    6501         422 :         free_var(&tmp_var);
    6502             :     }
    6503             : 
    6504         422 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6505             : 
    6506         422 :     if (numstate.sumX.ndigits > 0)
    6507             :     {
    6508         422 :         pfree(numstate.sumX.pos_digits);
    6509         422 :         pfree(numstate.sumX.neg_digits);
    6510             :     }
    6511         422 :     if (numstate.sumX2.ndigits > 0)
    6512             :     {
    6513         422 :         pfree(numstate.sumX2.pos_digits);
    6514         422 :         pfree(numstate.sumX2.neg_digits);
    6515             :     }
    6516             : 
    6517         422 :     return res;
    6518             : }
    6519             : #endif
    6520             : 
    6521             : Datum
    6522         126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6523             : {
    6524             : #ifdef HAVE_INT128
    6525             :     PolyNumAggState *state;
    6526             :     Numeric     res;
    6527             :     bool        is_null;
    6528             : 
    6529         126 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6530             : 
    6531         126 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6532             : 
    6533         126 :     if (is_null)
    6534          24 :         PG_RETURN_NULL();
    6535             :     else
    6536         102 :         PG_RETURN_NUMERIC(res);
    6537             : #else
    6538             :     return numeric_var_samp(fcinfo);
    6539             : #endif
    6540             : }
    6541             : 
    6542             : Datum
    6543         164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6544             : {
    6545             : #ifdef HAVE_INT128
    6546             :     PolyNumAggState *state;
    6547             :     Numeric     res;
    6548             :     bool        is_null;
    6549             : 
    6550         164 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6551             : 
    6552         164 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6553             : 
    6554         164 :     if (is_null)
    6555          24 :         PG_RETURN_NULL();
    6556             :     else
    6557         140 :         PG_RETURN_NUMERIC(res);
    6558             : #else
    6559             :     return numeric_stddev_samp(fcinfo);
    6560             : #endif
    6561             : }
    6562             : 
    6563             : Datum
    6564          60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6565             : {
    6566             : #ifdef HAVE_INT128
    6567             :     PolyNumAggState *state;
    6568             :     Numeric     res;
    6569             :     bool        is_null;
    6570             : 
    6571          60 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6572             : 
    6573          60 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6574             : 
    6575          60 :     if (is_null)
    6576           0 :         PG_RETURN_NULL();
    6577             :     else
    6578          60 :         PG_RETURN_NUMERIC(res);
    6579             : #else
    6580             :     return numeric_var_pop(fcinfo);
    6581             : #endif
    6582             : }
    6583             : 
    6584             : Datum
    6585          72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6586             : {
    6587             : #ifdef HAVE_INT128
    6588             :     PolyNumAggState *state;
    6589             :     Numeric     res;
    6590             :     bool        is_null;
    6591             : 
    6592          72 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6593             : 
    6594          72 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6595             : 
    6596          72 :     if (is_null)
    6597           0 :         PG_RETURN_NULL();
    6598             :     else
    6599          72 :         PG_RETURN_NUMERIC(res);
    6600             : #else
    6601             :     return numeric_stddev_pop(fcinfo);
    6602             : #endif
    6603             : }
    6604             : 
    6605             : /*
    6606             :  * SUM transition functions for integer datatypes.
    6607             :  *
    6608             :  * To avoid overflow, we use accumulators wider than the input datatype.
    6609             :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6610             :  * inputs, we use int8 accumulators which should be sufficient for practical
    6611             :  * purposes.  (The latter two therefore don't really belong in this file,
    6612             :  * but we keep them here anyway.)
    6613             :  *
    6614             :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6615             :  * the initial condition of the transition data value needs to be NULL. This
    6616             :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6617             :  * data value into the transition data: it doesn't know how to do the type
    6618             :  * conversion.  The upshot is that these routines have to be marked non-strict
    6619             :  * and handle substitution of the first non-null input themselves.
    6620             :  *
    6621             :  * Note: these functions are used only in plain aggregation mode.
    6622             :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6623             :  */
    6624             : 
    6625             : Datum
    6626          24 : int2_sum(PG_FUNCTION_ARGS)
    6627             : {
    6628             :     int64       newval;
    6629             : 
    6630          24 :     if (PG_ARGISNULL(0))
    6631             :     {
    6632             :         /* No non-null input seen so far... */
    6633           6 :         if (PG_ARGISNULL(1))
    6634           0 :             PG_RETURN_NULL();   /* still no non-null */
    6635             :         /* This is the first non-null input. */
    6636           6 :         newval = (int64) PG_GETARG_INT16(1);
    6637           6 :         PG_RETURN_INT64(newval);
    6638             :     }
    6639             : 
    6640             :     /*
    6641             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6642             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6643             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6644             :      * then of course this is useless as well as incorrect, so just ifdef it
    6645             :      * out.)
    6646             :      */
    6647             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6648             :     if (AggCheckCallContext(fcinfo, NULL))
    6649             :     {
    6650             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6651             : 
    6652             :         /* Leave the running sum unchanged in the new input is null */
    6653             :         if (!PG_ARGISNULL(1))
    6654             :             *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
    6655             : 
    6656             :         PG_RETURN_POINTER(oldsum);
    6657             :     }
    6658             :     else
    6659             : #endif
    6660             :     {
    6661          18 :         int64       oldsum = PG_GETARG_INT64(0);
    6662             : 
    6663             :         /* Leave sum unchanged if new input is null. */
    6664          18 :         if (PG_ARGISNULL(1))
    6665           0 :             PG_RETURN_INT64(oldsum);
    6666             : 
    6667             :         /* OK to do the addition. */
    6668          18 :         newval = oldsum + (int64) PG_GETARG_INT16(1);
    6669             : 
    6670          18 :         PG_RETURN_INT64(newval);
    6671             :     }
    6672             : }
    6673             : 
    6674             : Datum
    6675     3692120 : int4_sum(PG_FUNCTION_ARGS)
    6676             : {
    6677             :     int64       newval;
    6678             : 
    6679     3692120 :     if (PG_ARGISNULL(0))
    6680             :     {
    6681             :         /* No non-null input seen so far... */
    6682      206562 :         if (PG_ARGISNULL(1))
    6683         986 :             PG_RETURN_NULL();   /* still no non-null */
    6684             :         /* This is the first non-null input. */
    6685      205576 :         newval = (int64) PG_GETARG_INT32(1);
    6686      205576 :         PG_RETURN_INT64(newval);
    6687             :     }
    6688             : 
    6689             :     /*
    6690             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6691             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6692             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6693             :      * then of course this is useless as well as incorrect, so just ifdef it
    6694             :      * out.)
    6695             :      */
    6696             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6697             :     if (AggCheckCallContext(fcinfo, NULL))
    6698             :     {
    6699             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6700             : 
    6701             :         /* Leave the running sum unchanged in the new input is null */
    6702             :         if (!PG_ARGISNULL(1))
    6703             :             *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
    6704             : 
    6705             :         PG_RETURN_POINTER(oldsum);
    6706             :     }
    6707             :     else
    6708             : #endif
    6709             :     {
    6710     3485558 :         int64       oldsum = PG_GETARG_INT64(0);
    6711             : 
    6712             :         /* Leave sum unchanged if new input is null. */
    6713     3485558 :         if (PG_ARGISNULL(1))
    6714       30874 :             PG_RETURN_INT64(oldsum);
    6715             : 
    6716             :         /* OK to do the addition. */
    6717     3454684 :         newval = oldsum + (int64) PG_GETARG_INT32(1);
    6718             : 
    6719     3454684 :         PG_RETURN_INT64(newval);
    6720             :     }
    6721             : }
    6722             : 
    6723             : /*
    6724             :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6725             :  */
    6726             : Datum
    6727           0 : int8_sum(PG_FUNCTION_ARGS)
    6728             : {
    6729             :     Numeric     oldsum;
    6730             : 
    6731           0 :     if (PG_ARGISNULL(0))
    6732             :     {
    6733             :         /* No non-null input seen so far... */
    6734           0 :         if (PG_ARGISNULL(1))
    6735           0 :             PG_RETURN_NULL();   /* still no non-null */
    6736             :         /* This is the first non-null input. */
    6737           0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6738             :     }
    6739             : 
    6740             :     /*
    6741             :      * Note that we cannot special-case the aggregate case here, as we do for
    6742             :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6743             :      * our first parameter in-place.
    6744             :      */
    6745             : 
    6746           0 :     oldsum = PG_GETARG_NUMERIC(0);
    6747             : 
    6748             :     /* Leave sum unchanged if new input is null. */
    6749           0 :     if (PG_ARGISNULL(1))
    6750           0 :         PG_RETURN_NUMERIC(oldsum);
    6751             : 
    6752             :     /* OK to do the addition. */
    6753           0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6754             :                                         NumericGetDatum(oldsum),
    6755             :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6756             : }
    6757             : 
    6758             : 
    6759             : /*
    6760             :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6761             :  * is a two-element int8 array, holding count and sum.
    6762             :  *
    6763             :  * These functions are also used for sum(int2) and sum(int4) when
    6764             :  * operating in moving-aggregate mode, since for correct inverse transitions
    6765             :  * we need to count the inputs.
    6766             :  */
    6767             : 
    6768             : typedef struct Int8TransTypeData
    6769             : {
    6770             :     int64       count;
    6771             :     int64       sum;
    6772             : } Int8TransTypeData;
    6773             : 
    6774             : Datum
    6775          42 : int2_avg_accum(PG_FUNCTION_ARGS)
    6776             : {
    6777             :     ArrayType  *transarray;
    6778          42 :     int16       newval = PG_GETARG_INT16(1);
    6779             :     Int8TransTypeData *transdata;
    6780             : 
    6781             :     /*
    6782             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6783             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6784             :      * a copy of it before scribbling on it.
    6785             :      */
    6786          42 :     if (AggCheckCallContext(fcinfo, NULL))
    6787          42 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6788             :     else
    6789           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6790             : 
    6791          42 :     if (ARR_HASNULL(transarray) ||
    6792          42 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6793           0 :         elog(ERROR, "expected 2-element int8 array");
    6794             : 
    6795          42 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6796          42 :     transdata->count++;
    6797          42 :     transdata->sum += newval;
    6798             : 
    6799          42 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6800             : }
    6801             : 
    6802             : Datum
    6803     2620302 : int4_avg_accum(PG_FUNCTION_ARGS)
    6804             : {
    6805             :     ArrayType  *transarray;
    6806     2620302 :     int32       newval = PG_GETARG_INT32(1);
    6807             :     Int8TransTypeData *transdata;
    6808             : 
    6809             :     /*
    6810             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6811             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6812             :      * a copy of it before scribbling on it.
    6813             :      */
    6814     2620302 :     if (AggCheckCallContext(fcinfo, NULL))
    6815     2620302 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6816             :     else
    6817           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6818             : 
    6819     2620302 :     if (ARR_HASNULL(transarray) ||
    6820     2620302 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6821           0 :         elog(ERROR, "expected 2-element int8 array");
    6822             : 
    6823     2620302 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6824     2620302 :     transdata->count++;
    6825     2620302 :     transdata->sum += newval;
    6826             : 
    6827     2620302 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6828             : }
    6829             : 
    6830             : Datum
    6831        3502 : int4_avg_combine(PG_FUNCTION_ARGS)
    6832             : {
    6833             :     ArrayType  *transarray1;
    6834             :     ArrayType  *transarray2;
    6835             :     Int8TransTypeData *state1;
    6836             :     Int8TransTypeData *state2;
    6837             : 
    6838        3502 :     if (!AggCheckCallContext(fcinfo, NULL))
    6839           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6840             : 
    6841        3502 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6842        3502 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6843             : 
    6844        3502 :     if (ARR_HASNULL(transarray1) ||
    6845        3502 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6846           0 :         elog(ERROR, "expected 2-element int8 array");
    6847             : 
    6848        3502 :     if (ARR_HASNULL(transarray2) ||
    6849        3502 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6850           0 :         elog(ERROR, "expected 2-element int8 array");
    6851             : 
    6852        3502 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6853        3502 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6854             : 
    6855        3502 :     state1->count += state2->count;
    6856        3502 :     state1->sum += state2->sum;
    6857             : 
    6858        3502 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6859             : }
    6860             : 
    6861             : Datum
    6862          12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6863             : {
    6864             :     ArrayType  *transarray;
    6865          12 :     int16       newval = PG_GETARG_INT16(1);
    6866             :     Int8TransTypeData *transdata;
    6867             : 
    6868             :     /*
    6869             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6870             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6871             :      * a copy of it before scribbling on it.
    6872             :      */
    6873          12 :     if (AggCheckCallContext(fcinfo, NULL))
    6874          12 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6875             :     else
    6876           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6877             : 
    6878          12 :     if (ARR_HASNULL(transarray) ||
    6879          12 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6880           0 :         elog(ERROR, "expected 2-element int8 array");
    6881             : 
    6882          12 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6883          12 :     transdata->count--;
    6884          12 :     transdata->sum -= newval;
    6885             : 
    6886          12 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6887             : }
    6888             : 
    6889             : Datum
    6890        1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6891             : {
    6892             :     ArrayType  *transarray;
    6893        1452 :     int32       newval = PG_GETARG_INT32(1);
    6894             :     Int8TransTypeData *transdata;
    6895             : 
    6896             :     /*
    6897             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6898             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6899             :      * a copy of it before scribbling on it.
    6900             :      */
    6901        1452 :     if (AggCheckCallContext(fcinfo, NULL))
    6902        1452 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6903             :     else
    6904           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6905             : 
    6906        1452 :     if (ARR_HASNULL(transarray) ||
    6907        1452 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6908           0 :         elog(ERROR, "expected 2-element int8 array");
    6909             : 
    6910        1452 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6911        1452 :     transdata->count--;
    6912        1452 :     transdata->sum -= newval;
    6913             : 
    6914        1452 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6915             : }
    6916             : 
    6917             : Datum
    6918       10774 : int8_avg(PG_FUNCTION_ARGS)
    6919             : {
    6920       10774 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6921             :     Int8TransTypeData *transdata;
    6922             :     Datum       countd,
    6923             :                 sumd;
    6924             : 
    6925       10774 :     if (ARR_HASNULL(transarray) ||
    6926       10774 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6927           0 :         elog(ERROR, "expected 2-element int8 array");
    6928       10774 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6929             : 
    6930             :     /* SQL defines AVG of no values to be NULL */
    6931       10774 :     if (transdata->count == 0)
    6932         118 :         PG_RETURN_NULL();
    6933             : 
    6934       10656 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6935       10656 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6936             : 
    6937       10656 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6938             : }
    6939             : 
    6940             : /*
    6941             :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6942             :  * final function for both.
    6943             :  */
    6944             : Datum
    6945        3834 : int2int4_sum(PG_FUNCTION_ARGS)
    6946             : {
    6947        3834 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6948             :     Int8TransTypeData *transdata;
    6949             : 
    6950        3834 :     if (ARR_HASNULL(transarray) ||
    6951        3834 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6952           0 :         elog(ERROR, "expected 2-element int8 array");
    6953        3834 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6954             : 
    6955             :     /* SQL defines SUM of no values to be NULL */
    6956        3834 :     if (transdata->count == 0)
    6957         480 :         PG_RETURN_NULL();
    6958             : 
    6959        3354 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6960             : }
    6961             : 
    6962             : 
    6963             : /* ----------------------------------------------------------------------
    6964             :  *
    6965             :  * Debug support
    6966             :  *
    6967             :  * ----------------------------------------------------------------------
    6968             :  */
    6969             : 
    6970             : #ifdef NUMERIC_DEBUG
    6971             : 
    6972             : /*
    6973             :  * dump_numeric() - Dump a value in the db storage format for debugging
    6974             :  */
    6975             : static void
    6976             : dump_numeric(const char *str, Numeric num)
    6977             : {
    6978             :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6979             :     int         ndigits;
    6980             :     int         i;
    6981             : 
    6982             :     ndigits = NUMERIC_NDIGITS(num);
    6983             : 
    6984             :     printf("%s: NUMERIC w=%d d=%d ", str,
    6985             :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6986             :     switch (NUMERIC_SIGN(num))
    6987             :     {
    6988             :         case NUMERIC_POS:
    6989             :             printf("POS");
    6990             :             break;
    6991             :         case NUMERIC_NEG:
    6992             :             printf("NEG");
    6993             :             break;
    6994             :         case NUMERIC_NAN:
    6995             :             printf("NaN");
    6996             :             break;
    6997             :         case NUMERIC_PINF:
    6998             :             printf("Infinity");
    6999             :             break;
    7000             :         case NUMERIC_NINF:
    7001             :             printf("-Infinity");
    7002             :             break;
    7003             :         default:
    7004             :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    7005             :             break;
    7006             :     }
    7007             : 
    7008             :     for (i = 0; i < ndigits; i++)
    7009             :         printf(" %0*d", DEC_DIGITS, digits[i]);
    7010             :     printf("\n");
    7011             : }
    7012             : 
    7013             : 
    7014             : /*
    7015             :  * dump_var() - Dump a value in the variable format for debugging
    7016             :  */
    7017             : static void
    7018             : dump_var(const char *str, NumericVar *var)
    7019             : {
    7020             :     int         i;
    7021             : 
    7022             :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    7023             :     switch (var->sign)
    7024             :     {
    7025             :         case NUMERIC_POS:
    7026             :             printf("POS");
    7027             :             break;
    7028             :         case NUMERIC_NEG:
    7029             :             printf("NEG");
    7030             :             break;
    7031             :         case NUMERIC_NAN:
    7032             :             printf("NaN");
    7033             :             break;
    7034             :         case NUMERIC_PINF:
    7035             :             printf("Infinity");
    7036             :             break;
    7037             :         case NUMERIC_NINF:
    7038             :             printf("-Infinity");
    7039             :             break;
    7040             :         default:
    7041             :             printf("SIGN=0x%x", var->sign);
    7042             :             break;
    7043             :     }
    7044             : 
    7045             :     for (i = 0; i < var->ndigits; i++)
    7046             :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    7047             : 
    7048             :     printf("\n");
    7049             : }
    7050             : #endif                          /* NUMERIC_DEBUG */
    7051             : 
    7052             : 
    7053             : /* ----------------------------------------------------------------------
    7054             :  *
    7055             :  * Local functions follow
    7056             :  *
    7057             :  * In general, these do not support "special" (NaN or infinity) inputs;
    7058             :  * callers should handle those possibilities first.
    7059             :  * (There are one or two exceptions, noted in their header comments.)
    7060             :  *
    7061             :  * ----------------------------------------------------------------------
    7062             :  */
    7063             : 
    7064             : 
    7065             : /*
    7066             :  * alloc_var() -
    7067             :  *
    7068             :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    7069             :  */
    7070             : static void
    7071     2116476 : alloc_var(NumericVar *var, int ndigits)
    7072             : {
    7073     2116476 :     digitbuf_free(var->buf);
    7074     2116476 :     var->buf = digitbuf_alloc(ndigits + 1);
    7075     2116476 :     var->buf[0] = 0;         /* spare digit for rounding */
    7076     2116476 :     var->digits = var->buf + 1;
    7077     2116476 :     var->ndigits = ndigits;
    7078     2116476 : }
    7079             : 
    7080             : 
    7081             : /*
    7082             :  * free_var() -
    7083             :  *
    7084             :  *  Return the digit buffer of a variable to the free pool
    7085             :  */
    7086             : static void
    7087     3422116 : free_var(NumericVar *var)
    7088             : {
    7089     3422116 :     digitbuf_free(var->buf);
    7090     3422116 :     var->buf = NULL;
    7091     3422116 :     var->digits = NULL;
    7092     3422116 :     var->sign = NUMERIC_NAN;
    7093     3422116 : }
    7094             : 
    7095             : 
    7096             : /*
    7097             :  * zero_var() -
    7098             :  *
    7099             :  *  Set a variable to ZERO.
    7100             :  *  Note: its dscale is not touched.
    7101             :  */
    7102             : static void
    7103       40634 : zero_var(NumericVar *var)
    7104             : {
    7105       40634 :     digitbuf_free(var->buf);
    7106       40634 :     var->buf = NULL;
    7107       40634 :     var->digits = NULL;
    7108       40634 :     var->ndigits = 0;
    7109       40634 :     var->weight = 0;         /* by convention; doesn't really matter */
    7110       40634 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    7111       40634 : }
    7112             : 
    7113             : 
    7114             : /*
    7115             :  * set_var_from_str()
    7116             :  *
    7117             :  *  Parse a string and put the number into a variable
    7118             :  *
    7119             :  * This function does not handle leading or trailing spaces.  It returns
    7120             :  * the end+1 position parsed into *endptr, so that caller can check for
    7121             :  * trailing spaces/garbage if deemed necessary.
    7122             :  *
    7123             :  * cp is the place to actually start parsing; str is what to use in error
    7124             :  * reports.  (Typically cp would be the same except advanced over spaces.)
    7125             :  *
    7126             :  * Returns true on success, false on failure (if escontext points to an
    7127             :  * ErrorSaveContext; otherwise errors are thrown).
    7128             :  */
    7129             : static bool
    7130      141026 : set_var_from_str(const char *str, const char *cp,
    7131             :                  NumericVar *dest, const char **endptr,
    7132             :                  Node *escontext)
    7133             : {
    7134      141026 :     bool        have_dp = false;
    7135             :     int         i;
    7136             :     unsigned char *decdigits;
    7137      141026 :     int         sign = NUMERIC_POS;
    7138      141026 :     int         dweight = -1;
    7139             :     int         ddigits;
    7140      141026 :     int         dscale = 0;
    7141             :     int         weight;
    7142             :     int         ndigits;
    7143             :     int         offset;
    7144             :     NumericDigit *digits;
    7145             : 
    7146             :     /*
    7147             :      * We first parse the string to extract decimal digits and determine the
    7148             :      * correct decimal weight.  Then convert to NBASE representation.
    7149             :      */
    7150      141026 :     switch (*cp)
    7151             :     {
    7152           0 :         case '+':
    7153           0 :             sign = NUMERIC_POS;
    7154           0 :             cp++;
    7155           0 :             break;
    7156             : 
    7157         300 :         case '-':
    7158         300 :             sign = NUMERIC_NEG;
    7159         300 :             cp++;
    7160         300 :             break;
    7161             :     }
    7162             : 
    7163      141026 :     if (*cp == '.')
    7164             :     {
    7165         384 :         have_dp = true;
    7166         384 :         cp++;
    7167             :     }
    7168             : 
    7169      141026 :     if (!isdigit((unsigned char) *cp))
    7170           0 :         goto invalid_syntax;
    7171             : 
    7172      141026 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    7173             : 
    7174             :     /* leading padding for digit alignment later */
    7175      141026 :     memset(decdigits, 0, DEC_DIGITS);
    7176      141026 :     i = DEC_DIGITS;
    7177             : 
    7178      608956 :     while (*cp)
    7179             :     {
    7180      469262 :         if (isdigit((unsigned char) *cp))
    7181             :         {
    7182      450546 :             decdigits[i++] = *cp++ - '0';
    7183      450546 :             if (!have_dp)
    7184      377882 :                 dweight++;
    7185             :             else
    7186       72664 :                 dscale++;
    7187             :         }
    7188       18716 :         else if (*cp == '.')
    7189             :         {
    7190       17222 :             if (have_dp)
    7191           0 :                 goto invalid_syntax;
    7192       17222 :             have_dp = true;
    7193       17222 :             cp++;
    7194             :             /* decimal point must not be followed by underscore */
    7195       17222 :             if (*cp == '_')
    7196           6 :                 goto invalid_syntax;
    7197             :         }
    7198        1494 :         else if (*cp == '_')
    7199             :         {
    7200             :             /* underscore must be followed by more digits */
    7201         186 :             cp++;
    7202         186 :             if (!isdigit((unsigned char) *cp))
    7203          18 :                 goto invalid_syntax;
    7204             :         }
    7205             :         else
    7206        1308 :             break;
    7207             :     }
    7208             : 
    7209      141002 :     ddigits = i - DEC_DIGITS;
    7210             :     /* trailing padding for digit alignment later */
    7211      141002 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    7212             : 
    7213             :     /* Handle exponent, if any */
    7214      141002 :     if (*cp == 'e' || *cp == 'E')
    7215             :     {
    7216        1260 :         int64       exponent = 0;
    7217        1260 :         bool        neg = false;
    7218             : 
    7219             :         /*
    7220             :          * At this point, dweight and dscale can't be more than about
    7221             :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    7222             :          * constraining the exponent similarly should be enough to prevent
    7223             :          * integer overflow in this function.  If the value is too large to
    7224             :          * fit in storage format, make_result() will complain about it later;
    7225             :          * for consistency use the same ereport errcode/text as make_result().
    7226             :          */
    7227             : 
    7228             :         /* exponent sign */
    7229        1260 :         cp++;
    7230        1260 :         if (*cp == '+')
    7231         154 :             cp++;
    7232        1106 :         else if (*cp == '-')
    7233             :         {
    7234         470 :             neg = true;
    7235         470 :             cp++;
    7236             :         }
    7237             : 
    7238             :         /* exponent digits */
    7239        1260 :         if (!isdigit((unsigned char) *cp))
    7240           6 :             goto invalid_syntax;
    7241             : 
    7242        4440 :         while (*cp)
    7243             :         {
    7244        3204 :             if (isdigit((unsigned char) *cp))
    7245             :             {
    7246        3162 :                 exponent = exponent * 10 + (*cp++ - '0');
    7247        3162 :                 if (exponent > PG_INT32_MAX / 2)
    7248           6 :                     goto out_of_range;
    7249             :             }
    7250          42 :             else if (*cp == '_')
    7251             :             {
    7252             :                 /* underscore must be followed by more digits */
    7253          42 :                 cp++;
    7254          42 :                 if (!isdigit((unsigned char) *cp))
    7255          12 :                     goto invalid_syntax;
    7256             :             }
    7257             :             else
    7258           0 :                 break;
    7259             :         }
    7260             : 
    7261        1236 :         if (neg)
    7262         470 :             exponent = -exponent;
    7263             : 
    7264        1236 :         dweight += (int) exponent;
    7265        1236 :         dscale -= (int) exponent;
    7266        1236 :         if (dscale < 0)
    7267         562 :             dscale = 0;
    7268             :     }
    7269             : 
    7270             :     /*
    7271             :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    7272             :      * to determine the converted weight and ndigits.  offset is the number of
    7273             :      * decimal zeroes to insert before the first given digit to have a
    7274             :      * correctly aligned first NBASE digit.
    7275             :      */
    7276      140978 :     if (dweight >= 0)
    7277      140226 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    7278             :     else
    7279         752 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    7280      140978 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    7281      140978 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    7282             : 
    7283      140978 :     alloc_var(dest, ndigits);
    7284      140978 :     dest->sign = sign;
    7285      140978 :     dest->weight = weight;
    7286      140978 :     dest->dscale = dscale;
    7287             : 
    7288      140978 :     i = DEC_DIGITS - offset;
    7289      140978 :     digits = dest->digits;
    7290             : 
    7291      349190 :     while (ndigits-- > 0)
    7292             :     {
    7293             : #if DEC_DIGITS == 4
    7294      208212 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    7295      208212 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    7296             : #elif DEC_DIGITS == 2
    7297             :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    7298             : #elif DEC_DIGITS == 1
    7299             :         *digits++ = decdigits[i];
    7300             : #else
    7301             : #error unsupported NBASE
    7302             : #endif
    7303      208212 :         i += DEC_DIGITS;
    7304             :     }
    7305             : 
    7306      140978 :     pfree(decdigits);
    7307             : 
    7308             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    7309      140978 :     strip_var(dest);
    7310             : 
    7311             :     /* Return end+1 position for caller */
    7312      140978 :     *endptr = cp;
    7313             : 
    7314      140978 :     return true;
    7315             : 
    7316           6 : out_of_range:
    7317           6 :     ereturn(escontext, false,
    7318             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7319             :              errmsg("value overflows numeric format")));
    7320             : 
    7321          42 : invalid_syntax:
    7322          42 :     ereturn(escontext, false,
    7323             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7324             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7325             :                     "numeric", str)));
    7326             : }
    7327             : 
    7328             : 
    7329             : /*
    7330             :  * Return the numeric value of a single hex digit.
    7331             :  */
    7332             : static inline int
    7333         708 : xdigit_value(char dig)
    7334             : {
    7335         894 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    7336         294 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    7337         108 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    7338             : }
    7339             : 
    7340             : /*
    7341             :  * set_var_from_non_decimal_integer_str()
    7342             :  *
    7343             :  *  Parse a string containing a non-decimal integer
    7344             :  *
    7345             :  * This function does not handle leading or trailing spaces.  It returns
    7346             :  * the end+1 position parsed into *endptr, so that caller can check for
    7347             :  * trailing spaces/garbage if deemed necessary.
    7348             :  *
    7349             :  * cp is the place to actually start parsing; str is what to use in error
    7350             :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    7351             :  * assumed to have already been parsed, so cp should point to the number's
    7352             :  * first digit in the base specified.
    7353             :  *
    7354             :  * base is expected to be 2, 8 or 16.
    7355             :  *
    7356             :  * Returns true on success, false on failure (if escontext points to an
    7357             :  * ErrorSaveContext; otherwise errors are thrown).
    7358             :  */
    7359             : static bool
    7360         156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7361             :                                      int base, NumericVar *dest,
    7362             :                                      const char **endptr, Node *escontext)
    7363             : {
    7364         156 :     const char *firstdigit = cp;
    7365             :     int64       tmp;
    7366             :     int64       mul;
    7367             :     NumericVar  tmp_var;
    7368             : 
    7369         156 :     init_var(&tmp_var);
    7370             : 
    7371         156 :     zero_var(dest);
    7372             : 
    7373             :     /*
    7374             :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7375             :      * value of the digits in the group, and "mul" is base^n, where n is the
    7376             :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7377             :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7378             :      */
    7379         156 :     tmp = 0;
    7380         156 :     mul = 1;
    7381             : 
    7382         156 :     if (base == 16)
    7383             :     {
    7384         828 :         while (*cp)
    7385             :         {
    7386         798 :             if (isxdigit((unsigned char) *cp))
    7387             :             {
    7388         708 :                 if (mul > PG_INT64_MAX / 16)
    7389             :                 {
    7390             :                     /* Add the contribution from this group of digits */
    7391          30 :                     int64_to_numericvar(mul, &tmp_var);
    7392          30 :                     mul_var(dest, &tmp_var, dest, 0);
    7393          30 :                     int64_to_numericvar(tmp, &tmp_var);
    7394          30 :                     add_var(dest, &tmp_var, dest);
    7395             : 
    7396             :                     /* Result will overflow if weight overflows int16 */
    7397          30 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7398           0 :                         goto out_of_range;
    7399             : 
    7400             :                     /* Begin a new group */
    7401          30 :                     tmp = 0;
    7402          30 :                     mul = 1;
    7403             :                 }
    7404             : 
    7405         708 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7406         708 :                 mul = mul * 16;
    7407             :             }
    7408          90 :             else if (*cp == '_')
    7409             :             {
    7410             :                 /* Underscore must be followed by more digits */
    7411          66 :                 cp++;
    7412          66 :                 if (!isxdigit((unsigned char) *cp))
    7413          18 :                     goto invalid_syntax;
    7414             :             }
    7415             :             else
    7416          24 :                 break;
    7417             :         }
    7418             :     }
    7419          84 :     else if (base == 8)
    7420             :     {
    7421         636 :         while (*cp)
    7422             :         {
    7423         606 :             if (*cp >= '0' && *cp <= '7')
    7424             :             {
    7425         558 :                 if (mul > PG_INT64_MAX / 8)
    7426             :                 {
    7427             :                     /* Add the contribution from this group of digits */
    7428          18 :                     int64_to_numericvar(mul, &tmp_var);
    7429          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7430          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7431          18 :                     add_var(dest, &tmp_var, dest);
    7432             : 
    7433             :                     /* Result will overflow if weight overflows int16 */
    7434          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7435           0 :                         goto out_of_range;
    7436             : 
    7437             :                     /* Begin a new group */
    7438          18 :                     tmp = 0;
    7439          18 :                     mul = 1;
    7440             :                 }
    7441             : 
    7442         558 :                 tmp = tmp * 8 + (*cp++ - '0');
    7443         558 :                 mul = mul * 8;
    7444             :             }
    7445          48 :             else if (*cp == '_')
    7446             :             {
    7447             :                 /* Underscore must be followed by more digits */
    7448          36 :                 cp++;
    7449          36 :                 if (*cp < '0' || *cp > '7')
    7450           0 :                     goto invalid_syntax;
    7451             :             }
    7452             :             else
    7453          12 :                 break;
    7454             :         }
    7455             :     }
    7456          42 :     else if (base == 2)
    7457             :     {
    7458        1560 :         while (*cp)
    7459             :         {
    7460        1530 :             if (*cp >= '0' && *cp <= '1')
    7461             :             {
    7462        1416 :                 if (mul > PG_INT64_MAX / 2)
    7463             :                 {
    7464             :                     /* Add the contribution from this group of digits */
    7465          18 :                     int64_to_numericvar(mul, &tmp_var);
    7466          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7467          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7468          18 :                     add_var(dest, &tmp_var, dest);
    7469             : 
    7470             :                     /* Result will overflow if weight overflows int16 */
    7471          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7472           0 :                         goto out_of_range;
    7473             : 
    7474             :                     /* Begin a new group */
    7475          18 :                     tmp = 0;
    7476          18 :                     mul = 1;
    7477             :                 }
    7478             : 
    7479        1416 :                 tmp = tmp * 2 + (*cp++ - '0');
    7480        1416 :                 mul = mul * 2;
    7481             :             }
    7482         114 :             else if (*cp == '_')
    7483             :             {
    7484             :                 /* Underscore must be followed by more digits */
    7485         102 :                 cp++;
    7486         102 :                 if (*cp < '0' || *cp > '1')
    7487           0 :                     goto invalid_syntax;
    7488             :             }
    7489             :             else
    7490          12 :                 break;
    7491             :         }
    7492             :     }
    7493             :     else
    7494             :         /* Should never happen; treat as invalid input */
    7495           0 :         goto invalid_syntax;
    7496             : 
    7497             :     /* Check that we got at least one digit */
    7498         138 :     if (unlikely(cp == firstdigit))
    7499           0 :         goto invalid_syntax;
    7500             : 
    7501             :     /* Add the contribution from the final group of digits */
    7502         138 :     int64_to_numericvar(mul, &tmp_var);
    7503         138 :     mul_var(dest, &tmp_var, dest, 0);
    7504         138 :     int64_to_numericvar(tmp, &tmp_var);
    7505         138 :     add_var(dest, &tmp_var, dest);
    7506             : 
    7507         138 :     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7508           0 :         goto out_of_range;
    7509             : 
    7510         138 :     dest->sign = sign;
    7511             : 
    7512         138 :     free_var(&tmp_var);
    7513             : 
    7514             :     /* Return end+1 position for caller */
    7515         138 :     *endptr = cp;
    7516             : 
    7517         138 :     return true;
    7518             : 
    7519           0 : out_of_range:
    7520           0 :     ereturn(escontext, false,
    7521             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7522             :              errmsg("value overflows numeric format")));
    7523             : 
    7524          18 : invalid_syntax:
    7525          18 :     ereturn(escontext, false,
    7526             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7527             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7528             :                     "numeric", str)));
    7529             : }
    7530             : 
    7531             : 
    7532             : /*
    7533             :  * set_var_from_num() -
    7534             :  *
    7535             :  *  Convert the packed db format into a variable
    7536             :  */
    7537             : static void
    7538       12988 : set_var_from_num(Numeric num, NumericVar *dest)
    7539             : {
    7540             :     int         ndigits;
    7541             : 
    7542       12988 :     ndigits = NUMERIC_NDIGITS(num);
    7543             : 
    7544       12988 :     alloc_var(dest, ndigits);
    7545             : 
    7546       12988 :     dest->weight = NUMERIC_WEIGHT(num);
    7547       12988 :     dest->sign = NUMERIC_SIGN(num);
    7548       12988 :     dest->dscale = NUMERIC_DSCALE(num);
    7549             : 
    7550       12988 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7551       12988 : }
    7552             : 
    7553             : 
    7554             : /*
    7555             :  * init_var_from_num() -
    7556             :  *
    7557             :  *  Initialize a variable from packed db format. The digits array is not
    7558             :  *  copied, which saves some cycles when the resulting var is not modified.
    7559             :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7560             :  *  other value to it (with set_var_* functions, or by using the var as the
    7561             :  *  destination of a function like add_var())
    7562             :  *
    7563             :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7564             :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7565             :  *  propagate to the original Numeric! It's OK to use it as the destination
    7566             :  *  argument of one of the calculational functions, though.
    7567             :  */
    7568             : static void
    7569     5093484 : init_var_from_num(Numeric num, NumericVar *dest)
    7570             : {
    7571     5093484 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7572     5093484 :     dest->weight = NUMERIC_WEIGHT(num);
    7573     5093484 :     dest->sign = NUMERIC_SIGN(num);
    7574     5093484 :     dest->dscale = NUMERIC_DSCALE(num);
    7575     5093484 :     dest->digits = NUMERIC_DIGITS(num);
    7576     5093484 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7577     5093484 : }
    7578             : 
    7579             : 
    7580             : /*
    7581             :  * set_var_from_var() -
    7582             :  *
    7583             :  *  Copy one variable into another
    7584             :  */
    7585             : static void
    7586       35202 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7587             : {
    7588             :     NumericDigit *newbuf;
    7589             : 
    7590       35202 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7591       35202 :     newbuf[0] = 0;              /* spare digit for rounding */
    7592       35202 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7593       34256 :         memcpy(newbuf + 1, value->digits,
    7594       34256 :                value->ndigits * sizeof(NumericDigit));
    7595             : 
    7596       35202 :     digitbuf_free(dest->buf);
    7597             : 
    7598       35202 :     memmove(dest, value, sizeof(NumericVar));
    7599       35202 :     dest->buf = newbuf;
    7600       35202 :     dest->digits = newbuf + 1;
    7601       35202 : }
    7602             : 
    7603             : 
    7604             : /*
    7605             :  * get_str_from_var() -
    7606             :  *
    7607             :  *  Convert a var to text representation (guts of numeric_out).
    7608             :  *  The var is displayed to the number of digits indicated by its dscale.
    7609             :  *  Returns a palloc'd string.
    7610             :  */
    7611             : static char *
    7612      802194 : get_str_from_var(const NumericVar *var)
    7613             : {
    7614             :     int         dscale;
    7615             :     char       *str;
    7616             :     char       *cp;
    7617             :     char       *endcp;
    7618             :     int         i;
    7619             :     int         d;
    7620             :     NumericDigit dig;
    7621             : 
    7622             : #if DEC_DIGITS > 1
    7623             :     NumericDigit d1;
    7624             : #endif
    7625             : 
    7626      802194 :     dscale = var->dscale;
    7627             : 
    7628             :     /*
    7629             :      * Allocate space for the result.
    7630             :      *
    7631             :      * i is set to the # of decimal digits before decimal point. dscale is the
    7632             :      * # of decimal digits we will print after decimal point. We may generate
    7633             :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7634             :      * need room for sign, decimal point, null terminator.
    7635             :      */
    7636      802194 :     i = (var->weight + 1) * DEC_DIGITS;
    7637      802194 :     if (i <= 0)
    7638      140434 :         i = 1;
    7639             : 
    7640      802194 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7641      802194 :     cp = str;
    7642             : 
    7643             :     /*
    7644             :      * Output a dash for negative values
    7645             :      */
    7646      802194 :     if (var->sign == NUMERIC_NEG)
    7647        5566 :         *cp++ = '-';
    7648             : 
    7649             :     /*
    7650             :      * Output all digits before the decimal point
    7651             :      */
    7652      802194 :     if (var->weight < 0)
    7653             :     {
    7654      140434 :         d = var->weight + 1;
    7655      140434 :         *cp++ = '0';
    7656             :     }
    7657             :     else
    7658             :     {
    7659     1429448 :         for (d = 0; d <= var->weight; d++)
    7660             :         {
    7661      767688 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7662             :             /* In the first digit, suppress extra leading decimal zeroes */
    7663             : #if DEC_DIGITS == 4
    7664             :             {
    7665      767688 :                 bool        putit = (d > 0);
    7666             : 
    7667      767688 :                 d1 = dig / 1000;
    7668      767688 :                 dig -= d1 * 1000;
    7669      767688 :                 putit |= (d1 > 0);
    7670      767688 :                 if (putit)
    7671      112858 :                     *cp++ = d1 + '0';
    7672      767688 :                 d1 = dig / 100;
    7673      767688 :                 dig -= d1 * 100;
    7674      767688 :                 putit |= (d1 > 0);
    7675      767688 :                 if (putit)
    7676      517942 :                     *cp++ = d1 + '0';
    7677      767688 :                 d1 = dig / 10;
    7678      767688 :                 dig -= d1 * 10;
    7679      767688 :                 putit |= (d1 > 0);
    7680      767688 :                 if (putit)
    7681      645202 :                     *cp++ = d1 + '0';
    7682      767688 :                 *cp++ = dig + '0';
    7683             :             }
    7684             : #elif DEC_DIGITS == 2
    7685             :             d1 = dig / 10;
    7686             :             dig -= d1 * 10;
    7687             :             if (d1 > 0 || d > 0)
    7688             :                 *cp++ = d1 + '0';
    7689             :             *cp++ = dig + '0';
    7690             : #elif DEC_DIGITS == 1
    7691             :             *cp++ = dig + '0';
    7692             : #else
    7693             : #error unsupported NBASE
    7694             : #endif
    7695             :         }
    7696             :     }
    7697             : 
    7698             :     /*
    7699             :      * If requested, output a decimal point and all the digits that follow it.
    7700             :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7701             :      * needed.
    7702             :      */
    7703      802194 :     if (dscale > 0)
    7704             :     {
    7705      646160 :         *cp++ = '.';
    7706      646160 :         endcp = cp + dscale;
    7707     1907382 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7708             :         {
    7709     1261222 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7710             : #if DEC_DIGITS == 4
    7711     1261222 :             d1 = dig / 1000;
    7712     1261222 :             dig -= d1 * 1000;
    7713     1261222 :             *cp++ = d1 + '0';
    7714     1261222 :             d1 = dig / 100;
    7715     1261222 :             dig -= d1 * 100;
    7716     1261222 :             *cp++ = d1 + '0';
    7717     1261222 :             d1 = dig / 10;
    7718     1261222 :             dig -= d1 * 10;
    7719     1261222 :             *cp++ = d1 + '0';
    7720     1261222 :             *cp++ = dig + '0';
    7721             : #elif DEC_DIGITS == 2
    7722             :             d1 = dig / 10;
    7723             :             dig -= d1 * 10;
    7724             :             *cp++ = d1 + '0';
    7725             :             *cp++ = dig + '0';
    7726             : #elif DEC_DIGITS == 1
    7727             :             *cp++ = dig + '0';
    7728             : #else
    7729             : #error unsupported NBASE
    7730             : #endif
    7731             :         }
    7732      646160 :         cp = endcp;
    7733             :     }
    7734             : 
    7735             :     /*
    7736             :      * terminate the string and return it
    7737             :      */
    7738      802194 :     *cp = '\0';
    7739      802194 :     return str;
    7740             : }
    7741             : 
    7742             : /*
    7743             :  * get_str_from_var_sci() -
    7744             :  *
    7745             :  *  Convert a var to a normalised scientific notation text representation.
    7746             :  *  This function does the heavy lifting for numeric_out_sci().
    7747             :  *
    7748             :  *  This notation has the general form a * 10^b, where a is known as the
    7749             :  *  "significand" and b is known as the "exponent".
    7750             :  *
    7751             :  *  Because we can't do superscript in ASCII (and because we want to copy
    7752             :  *  printf's behaviour) we display the exponent using E notation, with a
    7753             :  *  minimum of two exponent digits.
    7754             :  *
    7755             :  *  For example, the value 1234 could be output as 1.2e+03.
    7756             :  *
    7757             :  *  We assume that the exponent can fit into an int32.
    7758             :  *
    7759             :  *  rscale is the number of decimal digits desired after the decimal point in
    7760             :  *  the output, negative values will be treated as meaning zero.
    7761             :  *
    7762             :  *  Returns a palloc'd string.
    7763             :  */
    7764             : static char *
    7765         228 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7766             : {
    7767             :     int32       exponent;
    7768             :     NumericVar  tmp_var;
    7769             :     size_t      len;
    7770             :     char       *str;
    7771             :     char       *sig_out;
    7772             : 
    7773         228 :     if (rscale < 0)
    7774           0 :         rscale = 0;
    7775             : 
    7776             :     /*
    7777             :      * Determine the exponent of this number in normalised form.
    7778             :      *
    7779             :      * This is the exponent required to represent the number with only one
    7780             :      * significant digit before the decimal place.
    7781             :      */
    7782         228 :     if (var->ndigits > 0)
    7783             :     {
    7784         210 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7785             : 
    7786             :         /*
    7787             :          * Compensate for leading decimal zeroes in the first numeric digit by
    7788             :          * decrementing the exponent.
    7789             :          */
    7790         210 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7791             :     }
    7792             :     else
    7793             :     {
    7794             :         /*
    7795             :          * If var has no digits, then it must be zero.
    7796             :          *
    7797             :          * Zero doesn't technically have a meaningful exponent in normalised
    7798             :          * notation, but we just display the exponent as zero for consistency
    7799             :          * of output.
    7800             :          */
    7801          18 :         exponent = 0;
    7802             :     }
    7803             : 
    7804             :     /*
    7805             :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7806             :      * decimal digits in the process.
    7807             :      */
    7808         228 :     init_var(&tmp_var);
    7809             : 
    7810         228 :     power_ten_int(exponent, &tmp_var);
    7811         228 :     div_var(var, &tmp_var, &tmp_var, rscale, true, true);
    7812         228 :     sig_out = get_str_from_var(&tmp_var);
    7813             : 
    7814         228 :     free_var(&tmp_var);
    7815             : 
    7816             :     /*
    7817             :      * Allocate space for the result.
    7818             :      *
    7819             :      * In addition to the significand, we need room for the exponent
    7820             :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7821             :      * exponent itself, and of course the null terminator.
    7822             :      */
    7823         228 :     len = strlen(sig_out) + 13;
    7824         228 :     str = palloc(len);
    7825         228 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7826             : 
    7827         228 :     pfree(sig_out);
    7828             : 
    7829         228 :     return str;
    7830             : }
    7831             : 
    7832             : 
    7833             : /*
    7834             :  * numericvar_serialize - serialize NumericVar to binary format
    7835             :  *
    7836             :  * At variable level, no checks are performed on the weight or dscale, allowing
    7837             :  * us to pass around intermediate values with higher precision than supported
    7838             :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7839             :  * which use 16-bit integers for these fields.
    7840             :  */
    7841             : static void
    7842          90 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7843             : {
    7844             :     int         i;
    7845             : 
    7846          90 :     pq_sendint32(buf, var->ndigits);
    7847          90 :     pq_sendint32(buf, var->weight);
    7848          90 :     pq_sendint32(buf, var->sign);
    7849          90 :     pq_sendint32(buf, var->dscale);
    7850      637768 :     for (i = 0; i < var->ndigits; i++)
    7851      637678 :         pq_sendint16(buf, var->digits[i]);
    7852          90 : }
    7853             : 
    7854             : /*
    7855             :  * numericvar_deserialize - deserialize binary format to NumericVar
    7856             :  */
    7857             : static void
    7858          90 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7859             : {
    7860             :     int         len,
    7861             :                 i;
    7862             : 
    7863          90 :     len = pq_getmsgint(buf, sizeof(int32));
    7864             : 
    7865          90 :     alloc_var(var, len);        /* sets var->ndigits */
    7866             : 
    7867          90 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7868          90 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7869          90 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7870      637768 :     for (i = 0; i < len; i++)
    7871      637678 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7872          90 : }
    7873             : 
    7874             : 
    7875             : /*
    7876             :  * duplicate_numeric() - copy a packed-format Numeric
    7877             :  *
    7878             :  * This will handle NaN and Infinity cases.
    7879             :  */
    7880             : static Numeric
    7881       28496 : duplicate_numeric(Numeric num)
    7882             : {
    7883             :     Numeric     res;
    7884             : 
    7885       28496 :     res = (Numeric) palloc(VARSIZE(num));
    7886       28496 :     memcpy(res, num, VARSIZE(num));
    7887       28496 :     return res;
    7888             : }
    7889             : 
    7890             : /*
    7891             :  * make_result_opt_error() -
    7892             :  *
    7893             :  *  Create the packed db numeric format in palloc()'d memory from
    7894             :  *  a variable.  This will handle NaN and Infinity cases.
    7895             :  *
    7896             :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
    7897             :  *  NULL is returned.  This is helpful when caller needs to handle errors.
    7898             :  */
    7899             : static Numeric
    7900     3285182 : make_result_opt_error(const NumericVar *var, bool *have_error)
    7901             : {
    7902             :     Numeric     result;
    7903     3285182 :     NumericDigit *digits = var->digits;
    7904     3285182 :     int         weight = var->weight;
    7905     3285182 :     int         sign = var->sign;
    7906             :     int         n;
    7907             :     Size        len;
    7908             : 
    7909     3285182 :     if (have_error)
    7910      118354 :         *have_error = false;
    7911             : 
    7912     3285182 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7913             :     {
    7914             :         /*
    7915             :          * Verify valid special value.  This could be just an Assert, perhaps,
    7916             :          * but it seems worthwhile to expend a few cycles to ensure that we
    7917             :          * never write any nonzero reserved bits to disk.
    7918             :          */
    7919        5510 :         if (!(sign == NUMERIC_NAN ||
    7920             :               sign == NUMERIC_PINF ||
    7921             :               sign == NUMERIC_NINF))
    7922           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7923             : 
    7924        5510 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7925             : 
    7926        5510 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7927        5510 :         result->choice.n_header = sign;
    7928             :         /* the header word is all we need */
    7929             : 
    7930             :         dump_numeric("make_result()", result);
    7931        5510 :         return result;
    7932             :     }
    7933             : 
    7934     3279672 :     n = var->ndigits;
    7935             : 
    7936             :     /* truncate leading zeroes */
    7937     3279708 :     while (n > 0 && *digits == 0)
    7938             :     {
    7939          36 :         digits++;
    7940          36 :         weight--;
    7941          36 :         n--;
    7942             :     }
    7943             :     /* truncate trailing zeroes */
    7944     3365008 :     while (n > 0 && digits[n - 1] == 0)
    7945       85336 :         n--;
    7946             : 
    7947             :     /* If zero result, force to weight=0 and positive sign */
    7948     3279672 :     if (n == 0)
    7949             :     {
    7950      104334 :         weight = 0;
    7951      104334 :         sign = NUMERIC_POS;
    7952             :     }
    7953             : 
    7954             :     /* Build the result */
    7955     3279672 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7956             :     {
    7957     3277644 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7958     3277644 :         result = (Numeric) palloc(len);
    7959     3277644 :         SET_VARSIZE(result, len);
    7960     3277644 :         result->choice.n_short.n_header =
    7961             :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7962             :              : NUMERIC_SHORT)
    7963     3277644 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7964     3277644 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7965     3277644 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7966             :     }
    7967             :     else
    7968             :     {
    7969        2028 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7970        2028 :         result = (Numeric) palloc(len);
    7971        2028 :         SET_VARSIZE(result, len);
    7972        2028 :         result->choice.n_long.n_sign_dscale =
    7973        2028 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7974        2028 :         result->choice.n_long.n_weight = weight;
    7975             :     }
    7976             : 
    7977             :     Assert(NUMERIC_NDIGITS(result) == n);
    7978     3279672 :     if (n > 0)
    7979     3175338 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7980             : 
    7981             :     /* Check for overflow of int16 fields */
    7982     3279672 :     if (NUMERIC_WEIGHT(result) != weight ||
    7983     3279642 :         NUMERIC_DSCALE(result) != var->dscale)
    7984             :     {
    7985          30 :         if (have_error)
    7986             :         {
    7987          18 :             *have_error = true;
    7988          18 :             return NULL;
    7989             :         }
    7990             :         else
    7991             :         {
    7992          12 :             ereport(ERROR,
    7993             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7994             :                      errmsg("value overflows numeric format")));
    7995             :         }
    7996             :     }
    7997             : 
    7998             :     dump_numeric("make_result()", result);
    7999     3279642 :     return result;
    8000             : }
    8001             : 
    8002             : 
    8003             : /*
    8004             :  * make_result() -
    8005             :  *
    8006             :  *  An interface to make_result_opt_error() without "have_error" argument.
    8007             :  */
    8008             : static Numeric
    8009     2130324 : make_result(const NumericVar *var)
    8010             : {
    8011     2130324 :     return make_result_opt_error(var, NULL);
    8012             : }
    8013             : 
    8014             : 
    8015             : /*
    8016             :  * apply_typmod() -
    8017             :  *
    8018             :  *  Do bounds checking and rounding according to the specified typmod.
    8019             :  *  Note that this is only applied to normal finite values.
    8020             :  *
    8021             :  * Returns true on success, false on failure (if escontext points to an
    8022             :  * ErrorSaveContext; otherwise errors are thrown).
    8023             :  */
    8024             : static bool
    8025      122518 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    8026             : {
    8027             :     int         precision;
    8028             :     int         scale;
    8029             :     int         maxdigits;
    8030             :     int         ddigits;
    8031             :     int         i;
    8032             : 
    8033             :     /* Do nothing if we have an invalid typmod */
    8034      122518 :     if (!is_valid_numeric_typmod(typmod))
    8035      117820 :         return true;
    8036             : 
    8037        4698 :     precision = numeric_typmod_precision(typmod);
    8038        4698 :     scale = numeric_typmod_scale(typmod);
    8039        4698 :     maxdigits = precision - scale;
    8040             : 
    8041             :     /* Round to target scale (and set var->dscale) */
    8042        4698 :     round_var(var, scale);
    8043             : 
    8044             :     /* but don't allow var->dscale to be negative */
    8045        4698 :     if (var->dscale < 0)
    8046         126 :         var->dscale = 0;
    8047             : 
    8048             :     /*
    8049             :      * Check for overflow - note we can't do this before rounding, because
    8050             :      * rounding could raise the weight.  Also note that the var's weight could
    8051             :      * be inflated by leading zeroes, which will be stripped before storage
    8052             :      * but perhaps might not have been yet. In any case, we must recognize a
    8053             :      * true zero, whose weight doesn't mean anything.
    8054             :      */
    8055        4698 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    8056        4698 :     if (ddigits > maxdigits)
    8057             :     {
    8058             :         /* Determine true weight; and check for all-zero result */
    8059         410 :         for (i = 0; i < var->ndigits; i++)
    8060             :         {
    8061         394 :             NumericDigit dig = var->digits[i];
    8062             : 
    8063         394 :             if (dig)
    8064             :             {
    8065             :                 /* Adjust for any high-order decimal zero digits */
    8066             : #if DEC_DIGITS == 4
    8067         394 :                 if (dig < 10)
    8068         252 :                     ddigits -= 3;
    8069         142 :                 else if (dig < 100)
    8070          72 :                     ddigits -= 2;
    8071          70 :                 else if (dig < 1000)
    8072          52 :                     ddigits -= 1;
    8073             : #elif DEC_DIGITS == 2
    8074             :                 if (dig < 10)
    8075             :                     ddigits -= 1;
    8076             : #elif DEC_DIGITS == 1
    8077             :                 /* no adjustment */
    8078             : #else
    8079             : #error unsupported NBASE
    8080             : #endif
    8081         394 :                 if (ddigits > maxdigits)
    8082          84 :                     ereturn(escontext, false,
    8083             :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    8084             :                              errmsg("numeric field overflow"),
    8085             :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    8086             :                                        precision, scale,
    8087             :                     /* Display 10^0 as 1 */
    8088             :                                        maxdigits ? "10^" : "",
    8089             :                                        maxdigits ? maxdigits : 1
    8090             :                                        )));
    8091         310 :                 break;
    8092             :             }
    8093           0 :             ddigits -= DEC_DIGITS;
    8094             :         }
    8095             :     }
    8096             : 
    8097        4614 :     return true;
    8098             : }
    8099             : 
    8100             : /*
    8101             :  * apply_typmod_special() -
    8102             :  *
    8103             :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    8104             :  *  For convenience of most callers, the value is presented in packed form.
    8105             :  *
    8106             :  * Returns true on success, false on failure (if escontext points to an
    8107             :  * ErrorSaveContext; otherwise errors are thrown).
    8108             :  */
    8109             : static bool
    8110        1882 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    8111             : {
    8112             :     int         precision;
    8113             :     int         scale;
    8114             : 
    8115             :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    8116             : 
    8117             :     /*
    8118             :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    8119             :      * but it's a longstanding behavior.  Inf is rejected if we have any
    8120             :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    8121             :      * any finite number of digits.
    8122             :      */
    8123        1882 :     if (NUMERIC_IS_NAN(num))
    8124         784 :         return true;
    8125             : 
    8126             :     /* Do nothing if we have a default typmod (-1) */
    8127        1098 :     if (!is_valid_numeric_typmod(typmod))
    8128        1080 :         return true;
    8129             : 
    8130          18 :     precision = numeric_typmod_precision(typmod);
    8131          18 :     scale = numeric_typmod_scale(typmod);
    8132             : 
    8133          18 :     ereturn(escontext, false,
    8134             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    8135             :              errmsg("numeric field overflow"),
    8136             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    8137             :                        precision, scale)));
    8138             : }
    8139             : 
    8140             : 
    8141             : /*
    8142             :  * Convert numeric to int8, rounding if needed.
    8143             :  *
    8144             :  * If overflow, return false (no error is raised).  Return true if okay.
    8145             :  */
    8146             : static bool
    8147       10308 : numericvar_to_int64(const NumericVar *var, int64 *result)
    8148             : {
    8149             :     NumericDigit *digits;
    8150             :     int         ndigits;
    8151             :     int         weight;
    8152             :     int         i;
    8153             :     int64       val;
    8154             :     bool        neg;
    8155             :     NumericVar  rounded;
    8156             : 
    8157             :     /* Round to nearest integer */
    8158       10308 :     init_var(&rounded);
    8159       10308 :     set_var_from_var(var, &rounded);
    8160       10308 :     round_var(&rounded, 0);
    8161             : 
    8162             :     /* Check for zero input */
    8163       10308 :     strip_var(&rounded);
    8164       10308 :     ndigits = rounded.ndigits;
    8165       10308 :     if (ndigits == 0)
    8166             :     {
    8167         478 :         *result = 0;
    8168         478 :         free_var(&rounded);
    8169         478 :         return true;
    8170             :     }
    8171             : 
    8172             :     /*
    8173             :      * For input like 10000000000, we must treat stripped digits as real. So
    8174             :      * the loop assumes there are weight+1 digits before the decimal point.
    8175             :      */
    8176        9830 :     weight = rounded.weight;
    8177             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8178             : 
    8179             :     /*
    8180             :      * Construct the result. To avoid issues with converting a value
    8181             :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    8182             :      * bit two's complement integer), accumulate value as a negative number.
    8183             :      */
    8184        9830 :     digits = rounded.digits;
    8185        9830 :     neg = (rounded.sign == NUMERIC_NEG);
    8186        9830 :     val = -digits[0];
    8187       14054 :     for (i = 1; i <= weight; i++)
    8188             :     {
    8189        4272 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    8190             :         {
    8191          30 :             free_var(&rounded);
    8192          30 :             return false;
    8193             :         }
    8194             : 
    8195        4242 :         if (i < ndigits)
    8196             :         {
    8197        3964 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    8198             :             {
    8199          18 :                 free_var(&rounded);
    8200          18 :                 return false;
    8201             :             }
    8202             :         }
    8203             :     }
    8204             : 
    8205        9782 :     free_var(&rounded);
    8206             : 
    8207        9782 :     if (!neg)
    8208             :     {
    8209        8990 :         if (unlikely(val == PG_INT64_MIN))
    8210          24 :             return false;
    8211        8966 :         val = -val;
    8212             :     }
    8213        9758 :     *result = val;
    8214             : 
    8215        9758 :     return true;
    8216             : }
    8217             : 
    8218             : /*
    8219             :  * Convert int8 value to numeric.
    8220             :  */
    8221             : static void
    8222     1880394 : int64_to_numericvar(int64 val, NumericVar *var)
    8223             : {
    8224             :     uint64      uval,
    8225             :                 newuval;
    8226             :     NumericDigit *ptr;
    8227             :     int         ndigits;
    8228             : 
    8229             :     /* int64 can require at most 19 decimal digits; add one for safety */
    8230     1880394 :     alloc_var(var, 20 / DEC_DIGITS);
    8231     1880394 :     if (val < 0)
    8232             :     {
    8233        1814 :         var->sign = NUMERIC_NEG;
    8234        1814 :         uval = pg_abs_s64(val);
    8235             :     }
    8236             :     else
    8237             :     {
    8238     1878580 :         var->sign = NUMERIC_POS;
    8239     1878580 :         uval = val;
    8240             :     }
    8241     1880394 :     var->dscale = 0;
    8242     1880394 :     if (val == 0)
    8243             :     {
    8244       35354 :         var->ndigits = 0;
    8245       35354 :         var->weight = 0;
    8246       35354 :         return;
    8247             :     }
    8248     1845040 :     ptr = var->digits + var->ndigits;
    8249     1845040 :     ndigits = 0;
    8250             :     do
    8251             :     {
    8252     2168824 :         ptr--;
    8253     2168824 :         ndigits++;
    8254     2168824 :         newuval = uval / NBASE;
    8255     2168824 :         *ptr = uval - newuval * NBASE;
    8256     2168824 :         uval = newuval;
    8257     2168824 :     } while (uval);
    8258     1845040 :     var->digits = ptr;
    8259     1845040 :     var->ndigits = ndigits;
    8260     1845040 :     var->weight = ndigits - 1;
    8261             : }
    8262             : 
    8263             : /*
    8264             :  * Convert numeric to uint64, rounding if needed.
    8265             :  *
    8266             :  * If overflow, return false (no error is raised).  Return true if okay.
    8267             :  */
    8268             : static bool
    8269         114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    8270             : {
    8271             :     NumericDigit *digits;
    8272             :     int         ndigits;
    8273             :     int         weight;
    8274             :     int         i;
    8275             :     uint64      val;
    8276             :     NumericVar  rounded;
    8277             : 
    8278             :     /* Round to nearest integer */
    8279         114 :     init_var(&rounded);
    8280         114 :     set_var_from_var(var, &rounded);
    8281         114 :     round_var(&rounded, 0);
    8282             : 
    8283             :     /* Check for zero input */
    8284         114 :     strip_var(&rounded);
    8285         114 :     ndigits = rounded.ndigits;
    8286         114 :     if (ndigits == 0)
    8287             :     {
    8288          18 :         *result = 0;
    8289          18 :         free_var(&rounded);
    8290          18 :         return true;
    8291             :     }
    8292             : 
    8293             :     /* Check for negative input */
    8294          96 :     if (rounded.sign == NUMERIC_NEG)
    8295             :     {
    8296          12 :         free_var(&rounded);
    8297          12 :         return false;
    8298             :     }
    8299             : 
    8300             :     /*
    8301             :      * For input like 10000000000, we must treat stripped digits as real. So
    8302             :      * the loop assumes there are weight+1 digits before the decimal point.
    8303             :      */
    8304          84 :     weight = rounded.weight;
    8305             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8306             : 
    8307             :     /* Construct the result */
    8308          84 :     digits = rounded.digits;
    8309          84 :     val = digits[0];
    8310         246 :     for (i = 1; i <= weight; i++)
    8311             :     {
    8312         174 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    8313             :         {
    8314           0 :             free_var(&rounded);
    8315           0 :             return false;
    8316             :         }
    8317             : 
    8318         174 :         if (i < ndigits)
    8319             :         {
    8320         174 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    8321             :             {
    8322          12 :                 free_var(&rounded);
    8323          12 :                 return false;
    8324             :             }
    8325             :         }
    8326             :     }
    8327             : 
    8328          72 :     free_var(&rounded);
    8329             : 
    8330          72 :     *result = val;
    8331             : 
    8332          72 :     return true;
    8333             : }
    8334             : 
    8335             : #ifdef HAVE_INT128
    8336             : /*
    8337             :  * Convert numeric to int128, rounding if needed.
    8338             :  *
    8339             :  * If overflow, return false (no error is raised).  Return true if okay.
    8340             :  */
    8341             : static bool
    8342          30 : numericvar_to_int128(const NumericVar *var, int128 *result)
    8343             : {
    8344             :     NumericDigit *digits;
    8345             :     int         ndigits;
    8346             :     int         weight;
    8347             :     int         i;
    8348             :     int128      val,
    8349             :                 oldval;
    8350             :     bool        neg;
    8351             :     NumericVar  rounded;
    8352             : 
    8353             :     /* Round to nearest integer */
    8354          30 :     init_var(&rounded);
    8355          30 :     set_var_from_var(var, &rounded);
    8356          30 :     round_var(&rounded, 0);
    8357             : 
    8358             :     /* Check for zero input */
    8359          30 :     strip_var(&rounded);
    8360          30 :     ndigits = rounded.ndigits;
    8361          30 :     if (ndigits == 0)
    8362             :     {
    8363           0 :         *result = 0;
    8364           0 :         free_var(&rounded);
    8365           0 :         return true;
    8366             :     }
    8367             : 
    8368             :     /*
    8369             :      * For input like 10000000000, we must treat stripped digits as real. So
    8370             :      * the loop assumes there are weight+1 digits before the decimal point.
    8371             :      */
    8372          30 :     weight = rounded.weight;
    8373             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8374             : 
    8375             :     /* Construct the result */
    8376          30 :     digits = rounded.digits;
    8377          30 :     neg = (rounded.sign == NUMERIC_NEG);
    8378          30 :     val = digits[0];
    8379          86 :     for (i = 1; i <= weight; i++)
    8380             :     {
    8381          56 :         oldval = val;
    8382          56 :         val *= NBASE;
    8383          56 :         if (i < ndigits)
    8384          44 :             val += digits[i];
    8385             : 
    8386             :         /*
    8387             :          * The overflow check is a bit tricky because we want to accept
    8388             :          * INT128_MIN, which will overflow the positive accumulator.  We can
    8389             :          * detect this case easily though because INT128_MIN is the only
    8390             :          * nonzero value for which -val == val (on a two's complement machine,
    8391             :          * anyway).
    8392             :          */
    8393          56 :         if ((val / NBASE) != oldval)    /* possible overflow? */
    8394             :         {
    8395           0 :             if (!neg || (-val) != val || val == 0 || oldval < 0)
    8396             :             {
    8397           0 :                 free_var(&rounded);
    8398           0 :                 return false;
    8399             :             }
    8400             :         }
    8401             :     }
    8402             : 
    8403          30 :     free_var(&rounded);
    8404             : 
    8405          30 :     *result = neg ? -val : val;
    8406          30 :     return true;
    8407             : }
    8408             : 
    8409             : /*
    8410             :  * Convert 128 bit integer to numeric.
    8411             :  */
    8412             : static void
    8413        8734 : int128_to_numericvar(int128 val, NumericVar *var)
    8414             : {
    8415             :     uint128     uval,
    8416             :                 newuval;
    8417             :     NumericDigit *ptr;
    8418             :     int         ndigits;
    8419             : 
    8420             :     /* int128 can require at most 39 decimal digits; add one for safety */
    8421        8734 :     alloc_var(var, 40 / DEC_DIGITS);
    8422        8734 :     if (val < 0)
    8423             :     {
    8424           0 :         var->sign = NUMERIC_NEG;
    8425           0 :         uval = -val;
    8426             :     }
    8427             :     else
    8428             :     {
    8429        8734 :         var->sign = NUMERIC_POS;
    8430        8734 :         uval = val;
    8431             :     }
    8432        8734 :     var->dscale = 0;
    8433        8734 :     if (val == 0)
    8434             :     {
    8435         230 :         var->ndigits = 0;
    8436         230 :         var->weight = 0;
    8437         230 :         return;
    8438             :     }
    8439        8504 :     ptr = var->digits + var->ndigits;
    8440        8504 :     ndigits = 0;
    8441             :     do
    8442             :     {
    8443       44988 :         ptr--;
    8444       44988 :         ndigits++;
    8445       44988 :         newuval = uval / NBASE;
    8446       44988 :         *ptr = uval - newuval * NBASE;
    8447       44988 :         uval = newuval;
    8448       44988 :     } while (uval);
    8449        8504 :     var->digits = ptr;
    8450        8504 :     var->ndigits = ndigits;
    8451        8504 :     var->weight = ndigits - 1;
    8452             : }
    8453             : #endif
    8454             : 
    8455             : /*
    8456             :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    8457             :  */
    8458             : static double
    8459        3306 : numericvar_to_double_no_overflow(const NumericVar *var)
    8460             : {
    8461             :     char       *tmp;
    8462             :     double      val;
    8463             :     char       *endptr;
    8464             : 
    8465        3306 :     tmp = get_str_from_var(var);
    8466             : 
    8467             :     /* unlike float8in, we ignore ERANGE from strtod */
    8468        3306 :     val = strtod(tmp, &endptr);
    8469        3306 :     if (*endptr != '\0')
    8470             :     {
    8471             :         /* shouldn't happen ... */
    8472           0 :         ereport(ERROR,
    8473             :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8474             :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8475             :                         "double precision", tmp)));
    8476             :     }
    8477             : 
    8478        3306 :     pfree(tmp);
    8479             : 
    8480        3306 :     return val;
    8481             : }
    8482             : 
    8483             : 
    8484             : /*
    8485             :  * cmp_var() -
    8486             :  *
    8487             :  *  Compare two values on variable level.  We assume zeroes have been
    8488             :  *  truncated to no digits.
    8489             :  */
    8490             : static int
    8491       50204 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8492             : {
    8493      100408 :     return cmp_var_common(var1->digits, var1->ndigits,
    8494             :                           var1->weight, var1->sign,
    8495       50204 :                           var2->digits, var2->ndigits,
    8496             :                           var2->weight, var2->sign);
    8497             : }
    8498             : 
    8499             : /*
    8500             :  * cmp_var_common() -
    8501             :  *
    8502             :  *  Main routine of cmp_var(). This function can be used by both
    8503             :  *  NumericVar and Numeric.
    8504             :  */
    8505             : static int
    8506     6152494 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8507             :                int var1weight, int var1sign,
    8508             :                const NumericDigit *var2digits, int var2ndigits,
    8509             :                int var2weight, int var2sign)
    8510             : {
    8511     6152494 :     if (var1ndigits == 0)
    8512             :     {
    8513      185074 :         if (var2ndigits == 0)
    8514      156862 :             return 0;
    8515       28212 :         if (var2sign == NUMERIC_NEG)
    8516        4272 :             return 1;
    8517       23940 :         return -1;
    8518             :     }
    8519     5967420 :     if (var2ndigits == 0)
    8520             :     {
    8521       32266 :         if (var1sign == NUMERIC_POS)
    8522       25268 :             return 1;
    8523        6998 :         return -1;
    8524             :     }
    8525             : 
    8526     5935154 :     if (var1sign == NUMERIC_POS)
    8527             :     {
    8528     5846444 :         if (var2sign == NUMERIC_NEG)
    8529       26646 :             return 1;
    8530     5819798 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8531             :                               var2digits, var2ndigits, var2weight);
    8532             :     }
    8533             : 
    8534       88710 :     if (var2sign == NUMERIC_POS)
    8535       28742 :         return -1;
    8536             : 
    8537       59968 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8538             :                           var1digits, var1ndigits, var1weight);
    8539             : }
    8540             : 
    8541             : 
    8542             : /*
    8543             :  * add_var() -
    8544             :  *
    8545             :  *  Full version of add functionality on variable level (handling signs).
    8546             :  *  result might point to one of the operands too without danger.
    8547             :  */
    8548             : static void
    8549      497968 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8550             : {
    8551             :     /*
    8552             :      * Decide on the signs of the two variables what to do
    8553             :      */
    8554      497968 :     if (var1->sign == NUMERIC_POS)
    8555             :     {
    8556      496402 :         if (var2->sign == NUMERIC_POS)
    8557             :         {
    8558             :             /*
    8559             :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8560             :              */
    8561      296098 :             add_abs(var1, var2, result);
    8562      296098 :             result->sign = NUMERIC_POS;
    8563             :         }
    8564             :         else
    8565             :         {
    8566             :             /*
    8567             :              * var1 is positive, var2 is negative Must compare absolute values
    8568             :              */
    8569      200304 :             switch (cmp_abs(var1, var2))
    8570             :             {
    8571         184 :                 case 0:
    8572             :                     /* ----------
    8573             :                      * ABS(var1) == ABS(var2)
    8574             :                      * result = ZERO
    8575             :                      * ----------
    8576             :                      */
    8577         184 :                     zero_var(result);
    8578         184 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8579         184 :                     break;
    8580             : 
    8581      186104 :                 case 1:
    8582             :                     /* ----------
    8583             :                      * ABS(var1) > ABS(var2)
    8584             :                      * result = +(ABS(var1) - ABS(var2))
    8585             :                      * ----------
    8586             :                      */
    8587      186104 :                     sub_abs(var1, var2, result);
    8588      186104 :                     result->sign = NUMERIC_POS;
    8589      186104 :                     break;
    8590             : 
    8591       14016 :                 case -1:
    8592             :                     /* ----------
    8593             :                      * ABS(var1) < ABS(var2)
    8594             :                      * result = -(ABS(var2) - ABS(var1))
    8595             :                      * ----------
    8596             :                      */
    8597       14016 :                     sub_abs(var2, var1, result);
    8598       14016 :                     result->sign = NUMERIC_NEG;
    8599       14016 :                     break;
    8600             :             }
    8601      496402 :         }
    8602             :     }
    8603             :     else
    8604             :     {
    8605        1566 :         if (var2->sign == NUMERIC_POS)
    8606             :         {
    8607             :             /* ----------
    8608             :              * var1 is negative, var2 is positive
    8609             :              * Must compare absolute values
    8610             :              * ----------
    8611             :              */
    8612         468 :             switch (cmp_abs(var1, var2))
    8613             :             {
    8614          30 :                 case 0:
    8615             :                     /* ----------
    8616             :                      * ABS(var1) == ABS(var2)
    8617             :                      * result = ZERO
    8618             :                      * ----------
    8619             :                      */
    8620          30 :                     zero_var(result);
    8621          30 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8622          30 :                     break;
    8623             : 
    8624         294 :                 case 1:
    8625             :                     /* ----------
    8626             :                      * ABS(var1) > ABS(var2)
    8627             :                      * result = -(ABS(var1) - ABS(var2))
    8628             :                      * ----------
    8629             :                      */
    8630         294 :                     sub_abs(var1, var2, result);
    8631         294 :                     result->sign = NUMERIC_NEG;
    8632         294 :                     break;
    8633             : 
    8634         144 :                 case -1:
    8635             :                     /* ----------
    8636             :                      * ABS(var1) < ABS(var2)
    8637             :                      * result = +(ABS(var2) - ABS(var1))
    8638             :                      * ----------
    8639             :                      */
    8640         144 :                     sub_abs(var2, var1, result);
    8641         144 :                     result->sign = NUMERIC_POS;
    8642         144 :                     break;
    8643             :             }
    8644         468 :         }
    8645             :         else
    8646             :         {
    8647             :             /* ----------
    8648             :              * Both are negative
    8649             :              * result = -(ABS(var1) + ABS(var2))
    8650             :              * ----------
    8651             :              */
    8652        1098 :             add_abs(var1, var2, result);
    8653        1098 :             result->sign = NUMERIC_NEG;
    8654             :         }
    8655             :     }
    8656      497968 : }
    8657             : 
    8658             : 
    8659             : /*
    8660             :  * sub_var() -
    8661             :  *
    8662             :  *  Full version of sub functionality on variable level (handling signs).
    8663             :  *  result might point to one of the operands too without danger.
    8664             :  */
    8665             : static void
    8666      186922 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8667             : {
    8668             :     /*
    8669             :      * Decide on the signs of the two variables what to do
    8670             :      */
    8671      186922 :     if (var1->sign == NUMERIC_POS)
    8672             :     {
    8673      184152 :         if (var2->sign == NUMERIC_NEG)
    8674             :         {
    8675             :             /* ----------
    8676             :              * var1 is positive, var2 is negative
    8677             :              * result = +(ABS(var1) + ABS(var2))
    8678             :              * ----------
    8679             :              */
    8680       33052 :             add_abs(var1, var2, result);
    8681       33052 :             result->sign = NUMERIC_POS;
    8682             :         }
    8683             :         else
    8684             :         {
    8685             :             /* ----------
    8686             :              * Both are positive
    8687             :              * Must compare absolute values
    8688             :              * ----------
    8689             :              */
    8690      151100 :             switch (cmp_abs(var1, var2))
    8691             :             {
    8692       29888 :                 case 0:
    8693             :                     /* ----------
    8694             :                      * ABS(var1) == ABS(var2)
    8695             :                      * result = ZERO
    8696             :                      * ----------
    8697             :                      */
    8698       29888 :                     zero_var(result);
    8699       29888 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8700       29888 :                     break;
    8701             : 
    8702      107376 :                 case 1:
    8703             :                     /* ----------
    8704             :                      * ABS(var1) > ABS(var2)
    8705             :                      * result = +(ABS(var1) - ABS(var2))
    8706             :                      * ----------
    8707             :                      */
    8708      107376 :                     sub_abs(var1, var2, result);
    8709      107376 :                     result->sign = NUMERIC_POS;
    8710      107376 :                     break;
    8711             : 
    8712       13836 :                 case -1:
    8713             :                     /* ----------
    8714             :                      * ABS(var1) < ABS(var2)
    8715             :                      * result = -(ABS(var2) - ABS(var1))
    8716             :                      * ----------
    8717             :                      */
    8718       13836 :                     sub_abs(var2, var1, result);
    8719       13836 :                     result->sign = NUMERIC_NEG;
    8720       13836 :                     break;
    8721             :             }
    8722      184152 :         }
    8723             :     }
    8724             :     else
    8725             :     {
    8726        2770 :         if (var2->sign == NUMERIC_NEG)
    8727             :         {
    8728             :             /* ----------
    8729             :              * Both are negative
    8730             :              * Must compare absolute values
    8731             :              * ----------
    8732             :              */
    8733        2314 :             switch (cmp_abs(var1, var2))
    8734             :             {
    8735         166 :                 case 0:
    8736             :                     /* ----------
    8737             :                      * ABS(var1) == ABS(var2)
    8738             :                      * result = ZERO
    8739             :                      * ----------
    8740             :                      */
    8741         166 :                     zero_var(result);
    8742         166 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8743         166 :                     break;
    8744             : 
    8745         240 :                 case 1:
    8746             :                     /* ----------
    8747             :                      * ABS(var1) > ABS(var2)
    8748             :                      * result = -(ABS(var1) - ABS(var2))
    8749             :                      * ----------
    8750             :                      */
    8751         240 :                     sub_abs(var1, var2, result);
    8752         240 :                     result->sign = NUMERIC_NEG;
    8753         240 :                     break;
    8754             : 
    8755        1908 :                 case -1:
    8756             :                     /* ----------
    8757             :                      * ABS(var1) < ABS(var2)
    8758             :                      * result = +(ABS(var2) - ABS(var1))
    8759             :                      * ----------
    8760             :                      */
    8761        1908 :                     sub_abs(var2, var1, result);
    8762        1908 :                     result->sign = NUMERIC_POS;
    8763        1908 :                     break;
    8764             :             }
    8765        2314 :         }
    8766             :         else
    8767             :         {
    8768             :             /* ----------
    8769             :              * var1 is negative, var2 is positive
    8770             :              * result = -(ABS(var1) + ABS(var2))
    8771             :              * ----------
    8772             :              */
    8773         456 :             add_abs(var1, var2, result);
    8774         456 :             result->sign = NUMERIC_NEG;
    8775             :         }
    8776             :     }
    8777      186922 : }
    8778             : 
    8779             : 
    8780             : /*
    8781             :  * mul_var() -
    8782             :  *
    8783             :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8784             :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8785             :  */
    8786             : static void
    8787      829820 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8788             :         int rscale)
    8789             : {
    8790             :     int         res_ndigits;
    8791             :     int         res_ndigitpairs;
    8792             :     int         res_sign;
    8793             :     int         res_weight;
    8794             :     int         pair_offset;
    8795             :     int         maxdigits;
    8796             :     int         maxdigitpairs;
    8797             :     uint64     *dig,
    8798             :                *dig_i1_off;
    8799             :     uint64      maxdig;
    8800             :     uint64      carry;
    8801             :     uint64      newdig;
    8802             :     int         var1ndigits;
    8803             :     int         var2ndigits;
    8804             :     int         var1ndigitpairs;
    8805             :     int         var2ndigitpairs;
    8806             :     NumericDigit *var1digits;
    8807             :     NumericDigit *var2digits;
    8808             :     uint32      var1digitpair;
    8809             :     uint32     *var2digitpairs;
    8810             :     NumericDigit *res_digits;
    8811             :     int         i,
    8812             :                 i1,
    8813             :                 i2,
    8814             :                 i2limit;
    8815             : 
    8816             :     /*
    8817             :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8818             :      * performance because the inner multiplication loop is much simpler than
    8819             :      * the outer loop, so it's better to have a smaller number of iterations
    8820             :      * of the outer loop.  This also reduces the number of times that the
    8821             :      * accumulator array needs to be normalized.
    8822             :      */
    8823      829820 :     if (var1->ndigits > var2->ndigits)
    8824             :     {
    8825       14064 :         const NumericVar *tmp = var1;
    8826             : 
    8827       14064 :         var1 = var2;
    8828       14064 :         var2 = tmp;
    8829             :     }
    8830             : 
    8831             :     /* copy these values into local vars for speed in inner loop */
    8832      829820 :     var1ndigits = var1->ndigits;
    8833      829820 :     var2ndigits = var2->ndigits;
    8834      829820 :     var1digits = var1->digits;
    8835      829820 :     var2digits = var2->digits;
    8836             : 
    8837      829820 :     if (var1ndigits == 0)
    8838             :     {
    8839             :         /* one or both inputs is zero; so is result */
    8840        1712 :         zero_var(result);
    8841        1712 :         result->dscale = rscale;
    8842        1712 :         return;
    8843             :     }
    8844             : 
    8845             :     /*
    8846             :      * If var1 has 1-6 digits and the exact result was requested, delegate to
    8847             :      * mul_var_short() which uses a faster direct multiplication algorithm.
    8848             :      */
    8849      828108 :     if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
    8850             :     {
    8851      799632 :         mul_var_short(var1, var2, result);
    8852      799632 :         return;
    8853             :     }
    8854             : 
    8855             :     /* Determine result sign */
    8856       28476 :     if (var1->sign == var2->sign)
    8857       26994 :         res_sign = NUMERIC_POS;
    8858             :     else
    8859        1482 :         res_sign = NUMERIC_NEG;
    8860             : 
    8861             :     /*
    8862             :      * Determine the number of result digits to compute and the (maximum
    8863             :      * possible) result weight.  If the exact result would have more than
    8864             :      * rscale fractional digits, truncate the computation with
    8865             :      * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
    8866             :      * only contribute to the right of that.  (This will give the exact
    8867             :      * rounded-to-rscale answer unless carries out of the ignored positions
    8868             :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8869             :      *
    8870             :      * Note: an exact computation could not produce more than var1ndigits +
    8871             :      * var2ndigits digits, but we allocate at least one extra output digit in
    8872             :      * case rscale-driven rounding produces a carry out of the highest exact
    8873             :      * digit.
    8874             :      *
    8875             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    8876             :      * actually process the input digits in pairs, producing a base-NBASE^2
    8877             :      * intermediate result.  This significantly improves performance, since
    8878             :      * schoolbook multiplication is O(N^2) in the number of input digits, and
    8879             :      * working in base NBASE^2 effectively halves "N".
    8880             :      *
    8881             :      * Note: in a truncated computation, we must compute at least one extra
    8882             :      * output digit to ensure that all the guard digits are fully computed.
    8883             :      */
    8884             :     /* digit pairs in each input */
    8885       28476 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    8886       28476 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    8887             : 
    8888             :     /* digits in exact result */
    8889       28476 :     res_ndigits = var1ndigits + var2ndigits;
    8890             : 
    8891             :     /* digit pairs in exact result with at least one extra output digit */
    8892       28476 :     res_ndigitpairs = res_ndigits / 2 + 1;
    8893             : 
    8894             :     /* pair offset to align result to end of dig[] */
    8895       28476 :     pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
    8896             : 
    8897             :     /* maximum possible result weight (odd-length inputs shifted up below) */
    8898       28476 :     res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
    8899       28476 :         res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
    8900             : 
    8901             :     /* rscale-based truncation with at least one extra output digit */
    8902       28476 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8903             :         MUL_GUARD_DIGITS;
    8904       28476 :     maxdigitpairs = maxdigits / 2 + 1;
    8905             : 
    8906       28476 :     res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
    8907       28476 :     res_ndigits = 2 * res_ndigitpairs;
    8908             : 
    8909             :     /*
    8910             :      * In the computation below, digit pair i1 of var1 and digit pair i2 of
    8911             :      * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
    8912             :      * input digit pairs with index >= res_ndigitpairs - pair_offset don't
    8913             :      * contribute to the result, and can be ignored.
    8914             :      */
    8915       28476 :     if (res_ndigitpairs <= pair_offset)
    8916             :     {
    8917             :         /* All input digits will be ignored; so result is zero */
    8918          12 :         zero_var(result);
    8919          12 :         result->dscale = rscale;
    8920          12 :         return;
    8921             :     }
    8922       28464 :     var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
    8923       28464 :     var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
    8924             : 
    8925             :     /*
    8926             :      * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
    8927             :      * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
    8928             :      * headroom to avoid normalizing carries immediately.
    8929             :      *
    8930             :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8931             :      * threatens to exceed PG_UINT64_MAX, we take the time to propagate
    8932             :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    8933             :      * during the carry propagation passes either.  The carry values could be
    8934             :      * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
    8935             :      * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
    8936             :      *
    8937             :      * To avoid overflow in maxdig itself, it actually represents the maximum
    8938             :      * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
    8939             :      * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
    8940             :      *
    8941             :      * The conversion of var1 to base NBASE^2 is done on the fly, as each new
    8942             :      * digit is required.  The digits of var2 are converted upfront, and
    8943             :      * stored at the end of dig[].  To avoid loss of precision, the input
    8944             :      * digits are aligned with the start of digit pair array, effectively
    8945             :      * shifting them up (multiplying by NBASE) if the inputs have an odd
    8946             :      * number of NBASE digits.
    8947             :      */
    8948       28464 :     dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
    8949             :                             var2ndigitpairs * sizeof(uint32));
    8950             : 
    8951             :     /* convert var2 to base NBASE^2, shifting up if its length is odd */
    8952       28464 :     var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
    8953             : 
    8954     1547190 :     for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
    8955     1518726 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8956             : 
    8957       28464 :     if (2 * i2 + 1 < var2ndigits)
    8958       20448 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8959             :     else
    8960        8016 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
    8961             : 
    8962             :     /*
    8963             :      * Start by multiplying var2 by the least significant contributing digit
    8964             :      * pair from var1, storing the results at the end of dig[], and filling
    8965             :      * the leading digits with zeros.
    8966             :      *
    8967             :      * The loop here is the same as the inner loop below, except that we set
    8968             :      * the results in dig[], rather than adding to them.  This is the
    8969             :      * performance bottleneck for multiplication, so we want to keep it simple
    8970             :      * enough so that it can be auto-vectorized.  Accordingly, process the
    8971             :      * digits left-to-right even though schoolbook multiplication would
    8972             :      * suggest right-to-left.  Since we aren't propagating carries in this
    8973             :      * loop, the order does not matter.
    8974             :      */
    8975       28464 :     i1 = var1ndigitpairs - 1;
    8976       28464 :     if (2 * i1 + 1 < var1ndigits)
    8977       12720 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8978             :     else
    8979       15744 :         var1digitpair = var1digits[2 * i1] * NBASE;
    8980       28464 :     maxdig = var1digitpair;
    8981             : 
    8982       28464 :     i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8983       28464 :     dig_i1_off = &dig[i1 + pair_offset];
    8984             : 
    8985       28464 :     memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
    8986     1376622 :     for (i2 = 0; i2 < i2limit; i2++)
    8987     1348158 :         dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
    8988             : 
    8989             :     /*
    8990             :      * Next, multiply var2 by the remaining digit pairs from var1, adding the
    8991             :      * results to dig[] at the appropriate offsets, and normalizing whenever
    8992             :      * there is a risk of any dig[] entry overflowing.
    8993             :      */
    8994     1501710 :     for (i1 = i1 - 1; i1 >= 0; i1--)
    8995             :     {
    8996     1473246 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8997     1473246 :         if (var1digitpair == 0)
    8998     1179516 :             continue;
    8999             : 
    9000             :         /* Time to normalize? */
    9001      293730 :         maxdig += var1digitpair;
    9002      293730 :         if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
    9003             :         {
    9004             :             /* Yes, do it (to base NBASE^2) */
    9005          30 :             carry = 0;
    9006      119964 :             for (i = res_ndigitpairs - 1; i >= 0; i--)
    9007             :             {
    9008      119934 :                 newdig = dig[i] + carry;
    9009      119934 :                 if (newdig >= NBASE_SQR)
    9010             :                 {
    9011      115242 :                     carry = newdig / NBASE_SQR;
    9012      115242 :                     newdig -= carry * NBASE_SQR;
    9013             :                 }
    9014             :                 else
    9015        4692 :                     carry = 0;
    9016      119934 :                 dig[i] = newdig;
    9017             :             }
    9018             :             Assert(carry == 0);
    9019             :             /* Reset maxdig to indicate new worst-case */
    9020          30 :             maxdig = 1 + var1digitpair;
    9021             :         }
    9022             : 
    9023             :         /* Multiply and add */
    9024      293730 :         i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    9025      293730 :         dig_i1_off = &dig[i1 + pair_offset];
    9026             : 
    9027   124047846 :         for (i2 = 0; i2 < i2limit; i2++)
    9028   123754116 :             dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
    9029             :     }
    9030             : 
    9031             :     /*
    9032             :      * Now we do a final carry propagation pass to normalize back to base
    9033             :      * NBASE^2, and construct the base-NBASE result digits.  Note that this is
    9034             :      * still done at full precision w/guard digits.
    9035             :      */
    9036       28464 :     alloc_var(result, res_ndigits);
    9037       28464 :     res_digits = result->digits;
    9038       28464 :     carry = 0;
    9039     2882922 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9040             :     {
    9041     2854458 :         newdig = dig[i] + carry;
    9042     2854458 :         if (newdig >= NBASE_SQR)
    9043             :         {
    9044      406914 :             carry = newdig / NBASE_SQR;
    9045      406914 :             newdig -= carry * NBASE_SQR;
    9046             :         }
    9047             :         else
    9048     2447544 :             carry = 0;
    9049     2854458 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9050     2854458 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9051             :     }
    9052             :     Assert(carry == 0);
    9053             : 
    9054       28464 :     pfree(dig);
    9055             : 
    9056             :     /*
    9057             :      * Finally, round the result to the requested precision.
    9058             :      */
    9059       28464 :     result->weight = res_weight;
    9060       28464 :     result->sign = res_sign;
    9061             : 
    9062             :     /* Round to target rscale (and set result->dscale) */
    9063       28464 :     round_var(result, rscale);
    9064             : 
    9065             :     /* Strip leading and trailing zeroes */
    9066       28464 :     strip_var(result);
    9067             : }
    9068             : 
    9069             : 
    9070             : /*
    9071             :  * mul_var_short() -
    9072             :  *
    9073             :  *  Special-case multiplication function used when var1 has 1-6 digits, var2
    9074             :  *  has at least as many digits as var1, and the exact product var1 * var2 is
    9075             :  *  requested.
    9076             :  */
    9077             : static void
    9078      799632 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
    9079             :               NumericVar *result)
    9080             : {
    9081      799632 :     int         var1ndigits = var1->ndigits;
    9082      799632 :     int         var2ndigits = var2->ndigits;
    9083      799632 :     NumericDigit *var1digits = var1->digits;
    9084      799632 :     NumericDigit *var2digits = var2->digits;
    9085             :     int         res_sign;
    9086             :     int         res_weight;
    9087             :     int         res_ndigits;
    9088             :     NumericDigit *res_buf;
    9089             :     NumericDigit *res_digits;
    9090      799632 :     uint32      carry = 0;
    9091             :     uint32      term;
    9092             : 
    9093             :     /* Check preconditions */
    9094             :     Assert(var1ndigits >= 1);
    9095             :     Assert(var1ndigits <= 6);
    9096             :     Assert(var2ndigits >= var1ndigits);
    9097             : 
    9098             :     /*
    9099             :      * Determine the result sign, weight, and number of digits to calculate.
    9100             :      * The weight figured here is correct if the product has no leading zero
    9101             :      * digits; otherwise strip_var() will fix things up.  Note that, unlike
    9102             :      * mul_var(), we do not need to allocate an extra output digit, because we
    9103             :      * are not rounding here.
    9104             :      */
    9105      799632 :     if (var1->sign == var2->sign)
    9106      798440 :         res_sign = NUMERIC_POS;
    9107             :     else
    9108        1192 :         res_sign = NUMERIC_NEG;
    9109      799632 :     res_weight = var1->weight + var2->weight + 1;
    9110      799632 :     res_ndigits = var1ndigits + var2ndigits;
    9111             : 
    9112             :     /* Allocate result digit array */
    9113      799632 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9114      799632 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9115      799632 :     res_digits = res_buf + 1;
    9116             : 
    9117             :     /*
    9118             :      * Compute the result digits in reverse, in one pass, propagating the
    9119             :      * carry up as we go.  The i'th result digit consists of the sum of the
    9120             :      * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
    9121             :      */
    9122             : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
    9123             : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
    9124             : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
    9125             : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
    9126             : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
    9127             : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
    9128             : 
    9129      799632 :     switch (var1ndigits)
    9130             :     {
    9131      793926 :         case 1:
    9132             :             /* ---------
    9133             :              * 1-digit case:
    9134             :              *      var1ndigits = 1
    9135             :              *      var2ndigits >= 1
    9136             :              *      res_ndigits = var2ndigits + 1
    9137             :              * ----------
    9138             :              */
    9139     2887664 :             for (int i = var2ndigits - 1; i >= 0; i--)
    9140             :             {
    9141     2093738 :                 term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
    9142     2093738 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9143     2093738 :                 carry = term / NBASE;
    9144             :             }
    9145      793926 :             res_digits[0] = (NumericDigit) carry;
    9146      793926 :             break;
    9147             : 
    9148         756 :         case 2:
    9149             :             /* ---------
    9150             :              * 2-digit case:
    9151             :              *      var1ndigits = 2
    9152             :              *      var2ndigits >= 2
    9153             :              *      res_ndigits = var2ndigits + 2
    9154             :              * ----------
    9155             :              */
    9156             :             /* last result digit and carry */
    9157         756 :             term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
    9158         756 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9159         756 :             carry = term / NBASE;
    9160             : 
    9161             :             /* remaining digits, except for the first two */
    9162        2304 :             for (int i = var2ndigits - 1; i >= 1; i--)
    9163             :             {
    9164        1548 :                 term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
    9165        1548 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9166        1548 :                 carry = term / NBASE;
    9167             :             }
    9168         756 :             break;
    9169             : 
    9170         204 :         case 3:
    9171             :             /* ---------
    9172             :              * 3-digit case:
    9173             :              *      var1ndigits = 3
    9174             :              *      var2ndigits >= 3
    9175             :              *      res_ndigits = var2ndigits + 3
    9176             :              * ----------
    9177             :              */
    9178             :             /* last two result digits */
    9179         204 :             term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
    9180         204 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9181         204 :             carry = term / NBASE;
    9182             : 
    9183         204 :             term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9184         204 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9185         204 :             carry = term / NBASE;
    9186             : 
    9187             :             /* remaining digits, except for the first three */
    9188         546 :             for (int i = var2ndigits - 1; i >= 2; i--)
    9189             :             {
    9190         342 :                 term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
    9191         342 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9192         342 :                 carry = term / NBASE;
    9193             :             }
    9194         204 :             break;
    9195             : 
    9196        4038 :         case 4:
    9197             :             /* ---------
    9198             :              * 4-digit case:
    9199             :              *      var1ndigits = 4
    9200             :              *      var2ndigits >= 4
    9201             :              *      res_ndigits = var2ndigits + 4
    9202             :              * ----------
    9203             :              */
    9204             :             /* last three result digits */
    9205        4038 :             term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
    9206        4038 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9207        4038 :             carry = term / NBASE;
    9208             : 
    9209        4038 :             term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9210        4038 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9211        4038 :             carry = term / NBASE;
    9212             : 
    9213        4038 :             term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9214        4038 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9215        4038 :             carry = term / NBASE;
    9216             : 
    9217             :             /* remaining digits, except for the first four */
    9218       11268 :             for (int i = var2ndigits - 1; i >= 3; i--)
    9219             :             {
    9220        7230 :                 term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
    9221        7230 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9222        7230 :                 carry = term / NBASE;
    9223             :             }
    9224        4038 :             break;
    9225             : 
    9226         114 :         case 5:
    9227             :             /* ---------
    9228             :              * 5-digit case:
    9229             :              *      var1ndigits = 5
    9230             :              *      var2ndigits >= 5
    9231             :              *      res_ndigits = var2ndigits + 5
    9232             :              * ----------
    9233             :              */
    9234             :             /* last four result digits */
    9235         114 :             term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
    9236         114 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9237         114 :             carry = term / NBASE;
    9238             : 
    9239         114 :             term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    9240         114 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9241         114 :             carry = term / NBASE;
    9242             : 
    9243         114 :             term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9244         114 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9245         114 :             carry = term / NBASE;
    9246             : 
    9247         114 :             term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9248         114 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    9249         114 :             carry = term / NBASE;
    9250             : 
    9251             :             /* remaining digits, except for the first five */
    9252         300 :             for (int i = var2ndigits - 1; i >= 4; i--)
    9253             :             {
    9254         186 :                 term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
    9255         186 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9256         186 :                 carry = term / NBASE;
    9257             :             }
    9258         114 :             break;
    9259             : 
    9260         594 :         case 6:
    9261             :             /* ---------
    9262             :              * 6-digit case:
    9263             :              *      var1ndigits = 6
    9264             :              *      var2ndigits >= 6
    9265             :              *      res_ndigits = var2ndigits + 6
    9266             :              * ----------
    9267             :              */
    9268             :             /* last five result digits */
    9269         594 :             term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
    9270         594 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    9271         594 :             carry = term / NBASE;
    9272             : 
    9273         594 :             term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
    9274         594 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    9275         594 :             carry = term / NBASE;
    9276             : 
    9277         594 :             term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    9278         594 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    9279         594 :             carry = term / NBASE;
    9280             : 
    9281         594 :             term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    9282         594 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    9283         594 :             carry = term / NBASE;
    9284             : 
    9285         594 :             term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    9286         594 :             res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
    9287         594 :             carry = term / NBASE;
    9288             : 
    9289             :             /* remaining digits, except for the first six */
    9290        1656 :             for (int i = var2ndigits - 1; i >= 5; i--)
    9291             :             {
    9292        1062 :                 term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
    9293        1062 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    9294        1062 :                 carry = term / NBASE;
    9295             :             }
    9296         594 :             break;
    9297             :     }
    9298             : 
    9299             :     /*
    9300             :      * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
    9301             :      * significant result digits.
    9302             :      */
    9303      799632 :     switch (var1ndigits)
    9304             :     {
    9305         594 :         case 6:
    9306         594 :             term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
    9307         594 :             res_digits[5] = (NumericDigit) (term % NBASE);
    9308         594 :             carry = term / NBASE;
    9309             :             /* FALLTHROUGH */
    9310         708 :         case 5:
    9311         708 :             term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
    9312         708 :             res_digits[4] = (NumericDigit) (term % NBASE);
    9313         708 :             carry = term / NBASE;
    9314             :             /* FALLTHROUGH */
    9315        4746 :         case 4:
    9316        4746 :             term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
    9317        4746 :             res_digits[3] = (NumericDigit) (term % NBASE);
    9318        4746 :             carry = term / NBASE;
    9319             :             /* FALLTHROUGH */
    9320        4950 :         case 3:
    9321        4950 :             term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
    9322        4950 :             res_digits[2] = (NumericDigit) (term % NBASE);
    9323        4950 :             carry = term / NBASE;
    9324             :             /* FALLTHROUGH */
    9325        5706 :         case 2:
    9326        5706 :             term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
    9327        5706 :             res_digits[1] = (NumericDigit) (term % NBASE);
    9328        5706 :             res_digits[0] = (NumericDigit) (term / NBASE);
    9329        5706 :             break;
    9330             :     }
    9331             : 
    9332             :     /* Store the product in result */
    9333      799632 :     digitbuf_free(result->buf);
    9334      799632 :     result->ndigits = res_ndigits;
    9335      799632 :     result->buf = res_buf;
    9336      799632 :     result->digits = res_digits;
    9337      799632 :     result->weight = res_weight;
    9338      799632 :     result->sign = res_sign;
    9339      799632 :     result->dscale = var1->dscale + var2->dscale;
    9340             : 
    9341             :     /* Strip leading and trailing zeroes */
    9342      799632 :     strip_var(result);
    9343      799632 : }
    9344             : 
    9345             : 
    9346             : /*
    9347             :  * div_var() -
    9348             :  *
    9349             :  *  Compute the quotient var1 / var2 to rscale fractional digits.
    9350             :  *
    9351             :  *  If "round" is true, the result is rounded at the rscale'th digit; if
    9352             :  *  false, it is truncated (towards zero) at that digit.
    9353             :  *
    9354             :  *  If "exact" is true, the exact result is computed to the specified rscale;
    9355             :  *  if false, successive quotient digits are approximated up to rscale plus
    9356             :  *  DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
    9357             :  *  the right of that, before rounding or truncating to the specified rscale.
    9358             :  *  This can be significantly faster, and usually gives the same result as the
    9359             :  *  exact computation, but it may occasionally be off by one in the final
    9360             :  *  digit, if contributions from the ignored digits would have propagated
    9361             :  *  through the guard digits.  This is good enough for the transcendental
    9362             :  *  functions, where small errors are acceptable.
    9363             :  */
    9364             : static void
    9365      214016 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    9366             :         int rscale, bool round, bool exact)
    9367             : {
    9368      214016 :     int         var1ndigits = var1->ndigits;
    9369      214016 :     int         var2ndigits = var2->ndigits;
    9370             :     int         res_sign;
    9371             :     int         res_weight;
    9372             :     int         res_ndigits;
    9373             :     int         var1ndigitpairs;
    9374             :     int         var2ndigitpairs;
    9375             :     int         res_ndigitpairs;
    9376             :     int         div_ndigitpairs;
    9377             :     int64      *dividend;
    9378             :     int32      *divisor;
    9379             :     double      fdivisor,
    9380             :                 fdivisorinverse,
    9381             :                 fdividend,
    9382             :                 fquotient;
    9383             :     int64       maxdiv;
    9384             :     int         qi;
    9385             :     int32       qdigit;
    9386             :     int64       carry;
    9387             :     int64       newdig;
    9388             :     int64      *remainder;
    9389             :     NumericDigit *res_digits;
    9390             :     int         i;
    9391             : 
    9392             :     /*
    9393             :      * First of all division by zero check; we must not be handed an
    9394             :      * unnormalized divisor.
    9395             :      */
    9396      214016 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    9397          62 :         ereport(ERROR,
    9398             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    9399             :                  errmsg("division by zero")));
    9400             : 
    9401             :     /*
    9402             :      * If the divisor has just one or two digits, delegate to div_var_int(),
    9403             :      * which uses fast short division.
    9404             :      *
    9405             :      * Similarly, on platforms with 128-bit integer support, delegate to
    9406             :      * div_var_int64() for divisors with three or four digits.
    9407             :      */
    9408      213954 :     if (var2ndigits <= 2)
    9409             :     {
    9410             :         int         idivisor;
    9411             :         int         idivisor_weight;
    9412             : 
    9413      205096 :         idivisor = var2->digits[0];
    9414      205096 :         idivisor_weight = var2->weight;
    9415      205096 :         if (var2ndigits == 2)
    9416             :         {
    9417        3938 :             idivisor = idivisor * NBASE + var2->digits[1];
    9418        3938 :             idivisor_weight--;
    9419             :         }
    9420      205096 :         if (var2->sign == NUMERIC_NEG)
    9421         654 :             idivisor = -idivisor;
    9422             : 
    9423      205096 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    9424      205096 :         return;
    9425             :     }
    9426             : #ifdef HAVE_INT128
    9427        8858 :     if (var2ndigits <= 4)
    9428             :     {
    9429             :         int64       idivisor;
    9430             :         int         idivisor_weight;
    9431             : 
    9432         540 :         idivisor = var2->digits[0];
    9433         540 :         idivisor_weight = var2->weight;
    9434        2016 :         for (i = 1; i < var2ndigits; i++)
    9435             :         {
    9436        1476 :             idivisor = idivisor * NBASE + var2->digits[i];
    9437        1476 :             idivisor_weight--;
    9438             :         }
    9439         540 :         if (var2->sign == NUMERIC_NEG)
    9440         120 :             idivisor = -idivisor;
    9441             : 
    9442         540 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    9443         540 :         return;
    9444             :     }
    9445             : #endif
    9446             : 
    9447             :     /*
    9448             :      * Otherwise, perform full long division.
    9449             :      */
    9450             : 
    9451             :     /* Result zero check */
    9452        8318 :     if (var1ndigits == 0)
    9453             :     {
    9454          36 :         zero_var(result);
    9455          36 :         result->dscale = rscale;
    9456          36 :         return;
    9457             :     }
    9458             : 
    9459             :     /*
    9460             :      * The approximate computation can be significantly faster than the exact
    9461             :      * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
    9462             :      * shorter below.  However, that comes with the tradeoff of computing
    9463             :      * DIV_GUARD_DIGITS extra base-NBASE result digits.  Ignoring all other
    9464             :      * overheads, that suggests that, in theory, the approximate computation
    9465             :      * will only be faster than the exact one when var2ndigits is greater than
    9466             :      * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
    9467             :      *
    9468             :      * Thus, we're better off doing an exact computation when var2 is shorter
    9469             :      * than this.  Empirically, it has been found that the exact threshold is
    9470             :      * a little higher, due to other overheads in the outer division loop.
    9471             :      */
    9472        8282 :     if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
    9473        6504 :         exact = true;
    9474             : 
    9475             :     /*
    9476             :      * Determine the result sign, weight and number of digits to calculate.
    9477             :      * The weight figured here is correct if the emitted quotient has no
    9478             :      * leading zero digits; otherwise strip_var() will fix things up.
    9479             :      */
    9480        8282 :     if (var1->sign == var2->sign)
    9481        8150 :         res_sign = NUMERIC_POS;
    9482             :     else
    9483         132 :         res_sign = NUMERIC_NEG;
    9484        8282 :     res_weight = var1->weight - var2->weight + 1;
    9485             :     /* The number of accurate result digits we need to produce: */
    9486        8282 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9487             :     /* ... but always at least 1 */
    9488        8282 :     res_ndigits = Max(res_ndigits, 1);
    9489             :     /* If rounding needed, figure one more digit to ensure correct result */
    9490        8282 :     if (round)
    9491        3746 :         res_ndigits++;
    9492             :     /* Add guard digits for roundoff error when producing approx result */
    9493        8282 :     if (!exact)
    9494        1722 :         res_ndigits += DIV_GUARD_DIGITS;
    9495             : 
    9496             :     /*
    9497             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    9498             :      * actually process the input digits in pairs, producing a base-NBASE^2
    9499             :      * intermediate result.  This significantly improves performance, since
    9500             :      * the computation is O(N^2) in the number of input digits, and working in
    9501             :      * base NBASE^2 effectively halves "N".
    9502             :      */
    9503        8282 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    9504        8282 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    9505        8282 :     res_ndigitpairs = (res_ndigits + 1) / 2;
    9506        8282 :     res_ndigits = 2 * res_ndigitpairs;
    9507             : 
    9508             :     /*
    9509             :      * We do the arithmetic in an array "dividend[]" of signed 64-bit
    9510             :      * integers.  Since PG_INT64_MAX is much larger than NBASE^4, this gives
    9511             :      * us a lot of headroom to avoid normalizing carries immediately.
    9512             :      *
    9513             :      * When performing an exact computation, the working dividend requires
    9514             :      * res_ndigitpairs + var2ndigitpairs digits.  If var1 is larger than that,
    9515             :      * the extra digits do not contribute to the result, and are ignored.
    9516             :      *
    9517             :      * When performing an approximate computation, the working dividend only
    9518             :      * requires res_ndigitpairs digits (which includes the extra guard
    9519             :      * digits).  All input digits beyond that are ignored.
    9520             :      */
    9521        8282 :     if (exact)
    9522             :     {
    9523        6560 :         div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
    9524        6560 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9525             :     }
    9526             :     else
    9527             :     {
    9528        1722 :         div_ndigitpairs = res_ndigitpairs;
    9529        1722 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9530        1722 :         var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
    9531             :     }
    9532             : 
    9533             :     /*
    9534             :      * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
    9535             :      * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
    9536             :      *
    9537             :      * For convenience, we allocate one extra dividend digit, which is set to
    9538             :      * zero and not counted in div_ndigitpairs, so that the main loop below
    9539             :      * can safely read and write the (qi+1)'th digit in the approximate case.
    9540             :      */
    9541        8282 :     dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
    9542             :                                 var2ndigitpairs * sizeof(int32));
    9543        8282 :     divisor = (int32 *) (dividend + div_ndigitpairs + 1);
    9544             : 
    9545             :     /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
    9546       60596 :     for (i = 0; i < var1ndigitpairs - 1; i++)
    9547       52314 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9548             : 
    9549        8282 :     if (2 * i + 1 < var1ndigits)
    9550        3752 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9551             :     else
    9552        4530 :         dividend[i] = var1->digits[2 * i] * NBASE;
    9553             : 
    9554        8282 :     memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
    9555             : 
    9556             :     /* load var2 into divisor[0 .. var2ndigitpairs-1] */
    9557       52040 :     for (i = 0; i < var2ndigitpairs - 1; i++)
    9558       43758 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9559             : 
    9560        8282 :     if (2 * i + 1 < var2ndigits)
    9561        2970 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9562             :     else
    9563        5312 :         divisor[i] = var2->digits[2 * i] * NBASE;
    9564             : 
    9565             :     /*
    9566             :      * We estimate each quotient digit using floating-point arithmetic, taking
    9567             :      * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
    9568             :      * This must be float to avoid overflow.
    9569             :      *
    9570             :      * Since the floating-point dividend and divisor use 4 base-NBASE input
    9571             :      * digits, they include roughly 40-53 bits of information from their
    9572             :      * respective inputs (assuming NBASE is 10000), which fits well in IEEE
    9573             :      * double-precision variables.  The relative error in the floating-point
    9574             :      * quotient digit will then be less than around 2/NBASE^3, so the
    9575             :      * estimated base-NBASE^2 quotient digit will typically be correct, and
    9576             :      * should not be off by more than one from the correct value.
    9577             :      */
    9578        8282 :     fdivisor = (double) divisor[0] * NBASE_SQR;
    9579        8282 :     if (var2ndigitpairs > 1)
    9580        8282 :         fdivisor += (double) divisor[1];
    9581        8282 :     fdivisorinverse = 1.0 / fdivisor;
    9582             : 
    9583             :     /*
    9584             :      * maxdiv tracks the maximum possible absolute value of any dividend[]
    9585             :      * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
    9586             :      * propagate carries.  Furthermore, we need to ensure that overflow
    9587             :      * doesn't occur during the carry propagation passes either.  The carry
    9588             :      * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
    9589             :      * so really we must normalize when digits threaten to exceed PG_INT64_MAX
    9590             :      * - PG_INT64_MAX/NBASE^2 - 1.
    9591             :      *
    9592             :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9593             :      * value divided by NBASE^2-1, i.e., at the top of the loop it is known
    9594             :      * that no dividend[] entry has an absolute value exceeding maxdiv *
    9595             :      * (NBASE^2-1).
    9596             :      *
    9597             :      * Actually, though, that holds good only for dividend[] entries after
    9598             :      * dividend[qi]; the adjustment done at the bottom of the loop may cause
    9599             :      * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
    9600             :      * the next iteration is beyond the limit.  This does not cause problems,
    9601             :      * as explained below.
    9602             :      */
    9603        8282 :     maxdiv = 1;
    9604             : 
    9605             :     /*
    9606             :      * Outer loop computes next quotient digit, which goes in dividend[qi].
    9607             :      */
    9608       63826 :     for (qi = 0; qi < res_ndigitpairs; qi++)
    9609             :     {
    9610             :         /* Approximate the current dividend value */
    9611       55544 :         fdividend = (double) dividend[qi] * NBASE_SQR;
    9612       55544 :         fdividend += (double) dividend[qi + 1];
    9613             : 
    9614             :         /* Compute the (approximate) quotient digit */
    9615       55544 :         fquotient = fdividend * fdivisorinverse;
    9616       55544 :         qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9617           6 :             (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9618             : 
    9619       55544 :         if (qdigit != 0)
    9620             :         {
    9621             :             /* Do we need to normalize now? */
    9622       49510 :             maxdiv += i64abs(qdigit);
    9623       49510 :             if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
    9624             :             {
    9625             :                 /*
    9626             :                  * Yes, do it.  Note that if var2ndigitpairs is much smaller
    9627             :                  * than div_ndigitpairs, we can save a significant amount of
    9628             :                  * effort here by noting that we only need to normalise those
    9629             :                  * dividend[] entries touched where prior iterations
    9630             :                  * subtracted multiples of the divisor.
    9631             :                  */
    9632           6 :                 carry = 0;
    9633        6750 :                 for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
    9634             :                 {
    9635        6744 :                     newdig = dividend[i] + carry;
    9636        6744 :                     if (newdig < 0)
    9637             :                     {
    9638        6744 :                         carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9639        6744 :                         newdig -= carry * NBASE_SQR;
    9640             :                     }
    9641           0 :                     else if (newdig >= NBASE_SQR)
    9642             :                     {
    9643           0 :                         carry = newdig / NBASE_SQR;
    9644           0 :                         newdig -= carry * NBASE_SQR;
    9645             :                     }
    9646             :                     else
    9647           0 :                         carry = 0;
    9648        6744 :                     dividend[i] = newdig;
    9649             :                 }
    9650           6 :                 dividend[qi] += carry;
    9651             : 
    9652             :                 /*
    9653             :                  * All the dividend[] digits except possibly dividend[qi] are
    9654             :                  * now in the range 0..NBASE^2-1.  We do not need to consider
    9655             :                  * dividend[qi] in the maxdiv value anymore, so we can reset
    9656             :                  * maxdiv to 1.
    9657             :                  */
    9658           6 :                 maxdiv = 1;
    9659             : 
    9660             :                 /*
    9661             :                  * Recompute the quotient digit since new info may have
    9662             :                  * propagated into the top two dividend digits.
    9663             :                  */
    9664           6 :                 fdividend = (double) dividend[qi] * NBASE_SQR;
    9665           6 :                 fdividend += (double) dividend[qi + 1];
    9666           6 :                 fquotient = fdividend * fdivisorinverse;
    9667           6 :                 qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9668           0 :                     (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9669             : 
    9670           6 :                 maxdiv += i64abs(qdigit);
    9671             :             }
    9672             : 
    9673             :             /*
    9674             :              * Subtract off the appropriate multiple of the divisor.
    9675             :              *
    9676             :              * The digits beyond dividend[qi] cannot overflow, because we know
    9677             :              * they will fall within the maxdiv limit.  As for dividend[qi]
    9678             :              * itself, note that qdigit is approximately trunc(dividend[qi] /
    9679             :              * divisor[0]), which would make the new value simply dividend[qi]
    9680             :              * mod divisor[0].  The lower-order terms in qdigit can change
    9681             :              * this result by not more than about twice PG_INT64_MAX/NBASE^2,
    9682             :              * so overflow is impossible.
    9683             :              *
    9684             :              * This inner loop is the performance bottleneck for division, so
    9685             :              * code it in the same way as the inner loop of mul_var() so that
    9686             :              * it can be auto-vectorized.
    9687             :              */
    9688       49510 :             if (qdigit != 0)
    9689             :             {
    9690       49510 :                 int         istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
    9691       49510 :                 int64      *dividend_qi = &dividend[qi];
    9692             : 
    9693     7907282 :                 for (i = 0; i < istop; i++)
    9694     7857772 :                     dividend_qi[i] -= (int64) qdigit * divisor[i];
    9695             :             }
    9696             :         }
    9697             : 
    9698             :         /*
    9699             :          * The dividend digit we are about to replace might still be nonzero.
    9700             :          * Fold it into the next digit position.
    9701             :          *
    9702             :          * There is no risk of overflow here, although proving that requires
    9703             :          * some care.  Much as with the argument for dividend[qi] not
    9704             :          * overflowing, if we consider the first two terms in the numerator
    9705             :          * and denominator of qdigit, we can see that the final value of
    9706             :          * dividend[qi + 1] will be approximately a remainder mod
    9707             :          * (divisor[0]*NBASE^2 + divisor[1]).  Accounting for the lower-order
    9708             :          * terms is a bit complicated but ends up adding not much more than
    9709             :          * PG_INT64_MAX/NBASE^2 to the possible range.  Thus, dividend[qi + 1]
    9710             :          * cannot overflow here, and in its role as dividend[qi] in the next
    9711             :          * loop iteration, it can't be large enough to cause overflow in the
    9712             :          * carry propagation step (if any), either.
    9713             :          *
    9714             :          * But having said that: dividend[qi] can be more than
    9715             :          * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
    9716             :          * dividend[qi] * NBASE^2 *can* overflow.  When that happens, adding
    9717             :          * it to dividend[qi + 1] will always cause a canceling overflow so
    9718             :          * that the end result is correct.  We could avoid the intermediate
    9719             :          * overflow by doing the multiplication and addition using unsigned
    9720             :          * int64 arithmetic, which is modulo 2^64, but so far there appears no
    9721             :          * need.
    9722             :          */
    9723       55544 :         dividend[qi + 1] += dividend[qi] * NBASE_SQR;
    9724             : 
    9725       55544 :         dividend[qi] = qdigit;
    9726             :     }
    9727             : 
    9728             :     /*
    9729             :      * If an exact result was requested, use the remainder to correct the
    9730             :      * approximate quotient.  The remainder is in dividend[], immediately
    9731             :      * after the quotient digits.  Note, however, that although the remainder
    9732             :      * starts at dividend[qi = res_ndigitpairs], the first digit is the result
    9733             :      * of folding two remainder digits into one above, and the remainder
    9734             :      * currently only occupies var2ndigitpairs - 1 digits (the last digit of
    9735             :      * the working dividend was untouched by the computation above).  Thus we
    9736             :      * expand the remainder down by one base-NBASE^2 digit when we normalize
    9737             :      * it, so that it completely fills the last var2ndigitpairs digits of the
    9738             :      * dividend array.
    9739             :      */
    9740        8282 :     if (exact)
    9741             :     {
    9742             :         /* Normalize the remainder, expanding it down by one digit */
    9743        6560 :         remainder = &dividend[qi];
    9744        6560 :         carry = 0;
    9745       32414 :         for (i = var2ndigitpairs - 2; i >= 0; i--)
    9746             :         {
    9747       25854 :             newdig = remainder[i] + carry;
    9748       25854 :             if (newdig < 0)
    9749             :             {
    9750       19204 :                 carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9751       19204 :                 newdig -= carry * NBASE_SQR;
    9752             :             }
    9753        6650 :             else if (newdig >= NBASE_SQR)
    9754             :             {
    9755        6504 :                 carry = newdig / NBASE_SQR;
    9756        6504 :                 newdig -= carry * NBASE_SQR;
    9757             :             }
    9758             :             else
    9759         146 :                 carry = 0;
    9760       25854 :             remainder[i + 1] = newdig;
    9761             :         }
    9762        6560 :         remainder[0] = carry;
    9763             : 
    9764        6560 :         if (remainder[0] < 0)
    9765             :         {
    9766             :             /*
    9767             :              * The remainder is negative, so the approximate quotient is too
    9768             :              * large.  Correct by reducing the quotient by one and adding the
    9769             :              * divisor to the remainder until the remainder is positive.  We
    9770             :              * expect the quotient to be off by at most one, which has been
    9771             :              * borne out in all testing, but not conclusively proven, so we
    9772             :              * allow for larger corrections, just in case.
    9773             :              */
    9774             :             do
    9775             :             {
    9776             :                 /* Add the divisor to the remainder */
    9777          26 :                 carry = 0;
    9778        1138 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9779             :                 {
    9780        1112 :                     newdig = remainder[i] + divisor[i] + carry;
    9781        1112 :                     if (newdig >= NBASE_SQR)
    9782             :                     {
    9783         966 :                         remainder[i] = newdig - NBASE_SQR;
    9784         966 :                         carry = 1;
    9785             :                     }
    9786             :                     else
    9787             :                     {
    9788         146 :                         remainder[i] = newdig;
    9789         146 :                         carry = 0;
    9790             :                     }
    9791             :                 }
    9792          26 :                 remainder[0] += divisor[0] + carry;
    9793             : 
    9794             :                 /* Subtract 1 from the quotient (propagating carries later) */
    9795          26 :                 dividend[qi - 1]--;
    9796             : 
    9797          26 :             } while (remainder[0] < 0);
    9798             :         }
    9799             :         else
    9800             :         {
    9801             :             /*
    9802             :              * The remainder is nonnegative.  If it's greater than or equal to
    9803             :              * the divisor, then the approximate quotient is too small and
    9804             :              * must be corrected.  As above, we don't expect to have to apply
    9805             :              * more than one correction, but allow for it just in case.
    9806             :              */
    9807             :             while (true)
    9808           6 :             {
    9809        6540 :                 bool        less = false;
    9810             : 
    9811             :                 /* Is remainder < divisor? */
    9812        6558 :                 for (i = 0; i < var2ndigitpairs; i++)
    9813             :                 {
    9814        6552 :                     if (remainder[i] < divisor[i])
    9815             :                     {
    9816        6534 :                         less = true;
    9817        6534 :                         break;
    9818             :                     }
    9819          18 :                     if (remainder[i] > divisor[i])
    9820           0 :                         break;  /* remainder > divisor */
    9821             :                 }
    9822        6540 :                 if (less)
    9823        6534 :                     break;      /* quotient is correct */
    9824             : 
    9825             :                 /* Subtract the divisor from the remainder */
    9826           6 :                 carry = 0;
    9827          18 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9828             :                 {
    9829          12 :                     newdig = remainder[i] - divisor[i] + carry;
    9830          12 :                     if (newdig < 0)
    9831             :                     {
    9832           0 :                         remainder[i] = newdig + NBASE_SQR;
    9833           0 :                         carry = -1;
    9834             :                     }
    9835             :                     else
    9836             :                     {
    9837          12 :                         remainder[i] = newdig;
    9838          12 :                         carry = 0;
    9839             :                     }
    9840             :                 }
    9841           6 :                 remainder[0] = remainder[0] - divisor[0] + carry;
    9842             : 
    9843             :                 /* Add 1 to the quotient (propagating carries later) */
    9844           6 :                 dividend[qi - 1]++;
    9845             :             }
    9846             :         }
    9847             :     }
    9848             : 
    9849             :     /*
    9850             :      * Because the quotient digits were estimates that might have been off by
    9851             :      * one (and we didn't bother propagating carries when adjusting the
    9852             :      * quotient above), some quotient digits might be out of range, so do a
    9853             :      * final carry propagation pass to normalize back to base NBASE^2, and
    9854             :      * construct the base-NBASE result digits.  Note that this is still done
    9855             :      * at full precision w/guard digits.
    9856             :      */
    9857        8282 :     alloc_var(result, res_ndigits);
    9858        8282 :     res_digits = result->digits;
    9859        8282 :     carry = 0;
    9860       63826 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9861             :     {
    9862       55544 :         newdig = dividend[i] + carry;
    9863       55544 :         if (newdig < 0)
    9864             :         {
    9865          66 :             carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9866          66 :             newdig -= carry * NBASE_SQR;
    9867             :         }
    9868       55478 :         else if (newdig >= NBASE_SQR)
    9869             :         {
    9870           0 :             carry = newdig / NBASE_SQR;
    9871           0 :             newdig -= carry * NBASE_SQR;
    9872             :         }
    9873             :         else
    9874       55478 :             carry = 0;
    9875       55544 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9876       55544 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9877             :     }
    9878             :     Assert(carry == 0);
    9879             : 
    9880        8282 :     pfree(dividend);
    9881             : 
    9882             :     /*
    9883             :      * Finally, round or truncate the result to the requested precision.
    9884             :      */
    9885        8282 :     result->weight = res_weight;
    9886        8282 :     result->sign = res_sign;
    9887             : 
    9888             :     /* Round or truncate to target rscale (and set result->dscale) */
    9889        8282 :     if (round)
    9890        3746 :         round_var(result, rscale);
    9891             :     else
    9892        4536 :         trunc_var(result, rscale);
    9893             : 
    9894             :     /* Strip leading and trailing zeroes */
    9895        8282 :     strip_var(result);
    9896             : }
    9897             : 
    9898             : 
    9899             : /*
    9900             :  * div_var_int() -
    9901             :  *
    9902             :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9903             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9904             :  */
    9905             : static void
    9906      224254 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9907             :             NumericVar *result, int rscale, bool round)
    9908             : {
    9909      224254 :     NumericDigit *var_digits = var->digits;
    9910      224254 :     int         var_ndigits = var->ndigits;
    9911             :     int         res_sign;
    9912             :     int         res_weight;
    9913             :     int         res_ndigits;
    9914             :     NumericDigit *res_buf;
    9915             :     NumericDigit *res_digits;
    9916             :     uint32      divisor;
    9917             :     int         i;
    9918             : 
    9919             :     /* Guard against division by zero */
    9920      224254 :     if (ival == 0)
    9921           0 :         ereport(ERROR,
    9922             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9923             :                 errmsg("division by zero"));
    9924             : 
    9925             :     /* Result zero check */
    9926      224254 :     if (var_ndigits == 0)
    9927             :     {
    9928        2300 :         zero_var(result);
    9929        2300 :         result->dscale = rscale;
    9930        2300 :         return;
    9931             :     }
    9932             : 
    9933             :     /*
    9934             :      * Determine the result sign, weight and number of digits to calculate.
    9935             :      * The weight figured here is correct if the emitted quotient has no
    9936             :      * leading zero digits; otherwise strip_var() will fix things up.
    9937             :      */
    9938      221954 :     if (var->sign == NUMERIC_POS)
    9939      218966 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9940             :     else
    9941        2988 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9942      221954 :     res_weight = var->weight - ival_weight;
    9943             :     /* The number of accurate result digits we need to produce: */
    9944      221954 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9945             :     /* ... but always at least 1 */
    9946      221954 :     res_ndigits = Max(res_ndigits, 1);
    9947             :     /* If rounding needed, figure one more digit to ensure correct result */
    9948      221954 :     if (round)
    9949      166626 :         res_ndigits++;
    9950             : 
    9951      221954 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9952      221954 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9953      221954 :     res_digits = res_buf + 1;
    9954             : 
    9955             :     /*
    9956             :      * Now compute the quotient digits.  This is the short division algorithm
    9957             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9958             :      * allow the divisor to exceed the internal base.
    9959             :      *
    9960             :      * In this algorithm, the carry from one digit to the next is at most
    9961             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9962             :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9963             :      * integer if this exceeds UINT_MAX.
    9964             :      */
    9965      221954 :     divisor = abs(ival);
    9966             : 
    9967      221954 :     if (divisor <= UINT_MAX / NBASE)
    9968             :     {
    9969             :         /* carry cannot overflow 32 bits */
    9970      218616 :         uint32      carry = 0;
    9971             : 
    9972     2124396 :         for (i = 0; i < res_ndigits; i++)
    9973             :         {
    9974     1905780 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9975     1905780 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9976     1905780 :             carry = carry % divisor;
    9977             :         }
    9978             :     }
    9979             :     else
    9980             :     {
    9981             :         /* carry may exceed 32 bits */
    9982        3338 :         uint64      carry = 0;
    9983             : 
    9984       10680 :         for (i = 0; i < res_ndigits; i++)
    9985             :         {
    9986        7342 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9987        7342 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9988        7342 :             carry = carry % divisor;
    9989             :         }
    9990             :     }
    9991             : 
    9992             :     /* Store the quotient in result */
    9993      221954 :     digitbuf_free(result->buf);
    9994      221954 :     result->ndigits = res_ndigits;
    9995      221954 :     result->buf = res_buf;
    9996      221954 :     result->digits = res_digits;
    9997      221954 :     result->weight = res_weight;
    9998      221954 :     result->sign = res_sign;
    9999             : 
   10000             :     /* Round or truncate to target rscale (and set result->dscale) */
   10001      221954 :     if (round)
   10002      166626 :         round_var(result, rscale);
   10003             :     else
   10004       55328 :         trunc_var(result, rscale);
   10005             : 
   10006             :     /* Strip leading/trailing zeroes */
   10007      221954 :     strip_var(result);
   10008             : }
   10009             : 
   10010             : 
   10011             : #ifdef HAVE_INT128
   10012             : /*
   10013             :  * div_var_int64() -
   10014             :  *
   10015             :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
   10016             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
   10017             :  *
   10018             :  *  This duplicates the logic in div_var_int(), so any changes made there
   10019             :  *  should be made here too.
   10020             :  */
   10021             : static void
   10022         540 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
   10023             :               NumericVar *result, int rscale, bool round)
   10024             : {
   10025         540 :     NumericDigit *var_digits = var->digits;
   10026         540 :     int         var_ndigits = var->ndigits;
   10027             :     int         res_sign;
   10028             :     int         res_weight;
   10029             :     int         res_ndigits;
   10030             :     NumericDigit *res_buf;
   10031             :     NumericDigit *res_digits;
   10032             :     uint64      divisor;
   10033             :     int         i;
   10034             : 
   10035             :     /* Guard against division by zero */
   10036         540 :     if (ival == 0)
   10037           0 :         ereport(ERROR,
   10038             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
   10039             :                 errmsg("division by zero"));
   10040             : 
   10041             :     /* Result zero check */
   10042         540 :     if (var_ndigits == 0)
   10043             :     {
   10044          96 :         zero_var(result);
   10045          96 :         result->dscale = rscale;
   10046          96 :         return;
   10047             :     }
   10048             : 
   10049             :     /*
   10050             :      * Determine the result sign, weight and number of digits to calculate.
   10051             :      * The weight figured here is correct if the emitted quotient has no
   10052             :      * leading zero digits; otherwise strip_var() will fix things up.
   10053             :      */
   10054         444 :     if (var->sign == NUMERIC_POS)
   10055         270 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
   10056             :     else
   10057         174 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
   10058         444 :     res_weight = var->weight - ival_weight;
   10059             :     /* The number of accurate result digits we need to produce: */
   10060         444 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   10061             :     /* ... but always at least 1 */
   10062         444 :     res_ndigits = Max(res_ndigits, 1);
   10063             :     /* If rounding needed, figure one more digit to ensure correct result */
   10064         444 :     if (round)
   10065         438 :         res_ndigits++;
   10066             : 
   10067         444 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   10068         444 :     res_buf[0] = 0;             /* spare digit for later rounding */
   10069         444 :     res_digits = res_buf + 1;
   10070             : 
   10071             :     /*
   10072             :      * Now compute the quotient digits.  This is the short division algorithm
   10073             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
   10074             :      * allow the divisor to exceed the internal base.
   10075             :      *
   10076             :      * In this algorithm, the carry from one digit to the next is at most
   10077             :      * divisor - 1.  Therefore, while processing the next digit, carry may
   10078             :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
   10079             :      * integer if this exceeds PG_UINT64_MAX.
   10080             :      */
   10081         444 :     divisor = i64abs(ival);
   10082             : 
   10083         444 :     if (divisor <= PG_UINT64_MAX / NBASE)
   10084             :     {
   10085             :         /* carry cannot overflow 64 bits */
   10086         348 :         uint64      carry = 0;
   10087             : 
   10088        3542 :         for (i = 0; i < res_ndigits; i++)
   10089             :         {
   10090        3194 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
   10091        3194 :             res_digits[i] = (NumericDigit) (carry / divisor);
   10092        3194 :             carry = carry % divisor;
   10093             :         }
   10094             :     }
   10095             :     else
   10096             :     {
   10097             :         /* carry may exceed 64 bits */
   10098          96 :         uint128     carry = 0;
   10099             : 
   10100        1032 :         for (i = 0; i < res_ndigits; i++)
   10101             :         {
   10102         936 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
   10103         936 :             res_digits[i] = (NumericDigit) (carry / divisor);
   10104         936 :             carry = carry % divisor;
   10105             :         }
   10106             :     }
   10107             : 
   10108             :     /* Store the quotient in result */
   10109         444 :     digitbuf_free(result->buf);
   10110         444 :     result->ndigits = res_ndigits;
   10111         444 :     result->buf = res_buf;
   10112         444 :     result->digits = res_digits;
   10113         444 :     result->weight = res_weight;
   10114         444 :     result->sign = res_sign;
   10115             : 
   10116             :     /* Round or truncate to target rscale (and set result->dscale) */
   10117         444 :     if (round)
   10118         438 :         round_var(result, rscale);
   10119             :     else
   10120           6 :         trunc_var(result, rscale);
   10121             : 
   10122             :     /* Strip leading/trailing zeroes */
   10123         444 :     strip_var(result);
   10124             : }
   10125             : #endif
   10126             : 
   10127             : 
   10128             : /*
   10129             :  * Default scale selection for division
   10130             :  *
   10131             :  * Returns the appropriate result scale for the division result.
   10132             :  */
   10133             : static int
   10134      152412 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
   10135             : {
   10136             :     int         weight1,
   10137             :                 weight2,
   10138             :                 qweight,
   10139             :                 i;
   10140             :     NumericDigit firstdigit1,
   10141             :                 firstdigit2;
   10142             :     int         rscale;
   10143             : 
   10144             :     /*
   10145             :      * The result scale of a division isn't specified in any SQL standard. For
   10146             :      * PostgreSQL we select a result scale that will give at least
   10147             :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
   10148             :      * result no less accurate than float8; but use a scale not less than
   10149             :      * either input's display scale.
   10150             :      */
   10151             : 
   10152             :     /* Get the actual (normalized) weight and first digit of each input */
   10153             : 
   10154      152412 :     weight1 = 0;                /* values to use if var1 is zero */
   10155      152412 :     firstdigit1 = 0;
   10156      152412 :     for (i = 0; i < var1->ndigits; i++)
   10157             :     {
   10158      150712 :         firstdigit1 = var1->digits[i];
   10159      150712 :         if (firstdigit1 != 0)
   10160             :         {
   10161      150712 :             weight1 = var1->weight - i;
   10162      150712 :             break;
   10163             :         }
   10164             :     }
   10165             : 
   10166      152412 :     weight2 = 0;                /* values to use if var2 is zero */
   10167      152412 :     firstdigit2 = 0;
   10168      152412 :     for (i = 0; i < var2->ndigits; i++)
   10169             :     {
   10170      152362 :         firstdigit2 = var2->digits[i];
   10171      152362 :         if (firstdigit2 != 0)
   10172             :         {
   10173      152362 :             weight2 = var2->weight - i;
   10174      152362 :             break;
   10175             :         }
   10176             :     }
   10177             : 
   10178             :     /*
   10179             :      * Estimate weight of quotient.  If the two first digits are equal, we
   10180             :      * can't be sure, but assume that var1 is less than var2.
   10181             :      */
   10182      152412 :     qweight = weight1 - weight2;
   10183      152412 :     if (firstdigit1 <= firstdigit2)
   10184      135142 :         qweight--;
   10185             : 
   10186             :     /* Select result scale */
   10187      152412 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
   10188      152412 :     rscale = Max(rscale, var1->dscale);
   10189      152412 :     rscale = Max(rscale, var2->dscale);
   10190      152412 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10191      152412 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10192             : 
   10193      152412 :     return rscale;
   10194             : }
   10195             : 
   10196             : 
   10197             : /*
   10198             :  * mod_var() -
   10199             :  *
   10200             :  *  Calculate the modulo of two numerics at variable level
   10201             :  */
   10202             : static void
   10203       53804 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   10204             : {
   10205             :     NumericVar  tmp;
   10206             : 
   10207       53804 :     init_var(&tmp);
   10208             : 
   10209             :     /* ---------
   10210             :      * We do this using the equation
   10211             :      *      mod(x,y) = x - trunc(x/y)*y
   10212             :      * div_var can be persuaded to give us trunc(x/y) directly.
   10213             :      * ----------
   10214             :      */
   10215       53804 :     div_var(var1, var2, &tmp, 0, false, true);
   10216             : 
   10217       53792 :     mul_var(var2, &tmp, &tmp, var2->dscale);
   10218             : 
   10219       53792 :     sub_var(var1, &tmp, result);
   10220             : 
   10221       53792 :     free_var(&tmp);
   10222       53792 : }
   10223             : 
   10224             : 
   10225             : /*
   10226             :  * div_mod_var() -
   10227             :  *
   10228             :  *  Calculate the truncated integer quotient and numeric remainder of two
   10229             :  *  numeric variables.  The remainder is precise to var2's dscale.
   10230             :  */
   10231             : static void
   10232        4518 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
   10233             :             NumericVar *quot, NumericVar *rem)
   10234             : {
   10235             :     NumericVar  q;
   10236             :     NumericVar  r;
   10237             : 
   10238        4518 :     init_var(&q);
   10239        4518 :     init_var(&r);
   10240             : 
   10241             :     /*
   10242             :      * Use div_var() with exact = false to get an initial estimate for the
   10243             :      * integer quotient (truncated towards zero).  This might be slightly
   10244             :      * inaccurate, but we correct it below.
   10245             :      */
   10246        4518 :     div_var(var1, var2, &q, 0, false, false);
   10247             : 
   10248             :     /* Compute initial estimate of remainder using the quotient estimate. */
   10249        4518 :     mul_var(var2, &q, &r, var2->dscale);
   10250        4518 :     sub_var(var1, &r, &r);
   10251             : 
   10252             :     /*
   10253             :      * Adjust the results if necessary --- the remainder should have the same
   10254             :      * sign as var1, and its absolute value should be less than the absolute
   10255             :      * value of var2.
   10256             :      */
   10257        4518 :     while (r.ndigits != 0 && r.sign != var1->sign)
   10258             :     {
   10259             :         /* The absolute value of the quotient is too large */
   10260           0 :         if (var1->sign == var2->sign)
   10261             :         {
   10262           0 :             sub_var(&q, &const_one, &q);
   10263           0 :             add_var(&r, var2, &r);
   10264             :         }
   10265             :         else
   10266             :         {
   10267           0 :             add_var(&q, &const_one, &q);
   10268           0 :             sub_var(&r, var2, &r);
   10269             :         }
   10270             :     }
   10271             : 
   10272        4518 :     while (cmp_abs(&r, var2) >= 0)
   10273             :     {
   10274             :         /* The absolute value of the quotient is too small */
   10275           0 :         if (var1->sign == var2->sign)
   10276             :         {
   10277           0 :             add_var(&q, &const_one, &q);
   10278           0 :             sub_var(&r, var2, &r);
   10279             :         }
   10280             :         else
   10281             :         {
   10282           0 :             sub_var(&q, &const_one, &q);
   10283           0 :             add_var(&r, var2, &r);
   10284             :         }
   10285             :     }
   10286             : 
   10287        4518 :     set_var_from_var(&q, quot);
   10288        4518 :     set_var_from_var(&r, rem);
   10289             : 
   10290        4518 :     free_var(&q);
   10291        4518 :     free_var(&r);
   10292        4518 : }
   10293             : 
   10294             : 
   10295             : /*
   10296             :  * ceil_var() -
   10297             :  *
   10298             :  *  Return the smallest integer greater than or equal to the argument
   10299             :  *  on variable level
   10300             :  */
   10301             : static void
   10302         204 : ceil_var(const NumericVar *var, NumericVar *result)
   10303             : {
   10304             :     NumericVar  tmp;
   10305             : 
   10306         204 :     init_var(&tmp);
   10307         204 :     set_var_from_var(var, &tmp);
   10308             : 
   10309         204 :     trunc_var(&tmp, 0);
   10310             : 
   10311         204 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
   10312          60 :         add_var(&tmp, &const_one, &tmp);
   10313             : 
   10314         204 :     set_var_from_var(&tmp, result);
   10315         204 :     free_var(&tmp);
   10316         204 : }
   10317             : 
   10318             : 
   10319             : /*
   10320             :  * floor_var() -
   10321             :  *
   10322             :  *  Return the largest integer equal to or less than the argument
   10323             :  *  on variable level
   10324             :  */
   10325             : static void
   10326         108 : floor_var(const NumericVar *var, NumericVar *result)
   10327             : {
   10328             :     NumericVar  tmp;
   10329             : 
   10330         108 :     init_var(&tmp);
   10331         108 :     set_var_from_var(var, &tmp);
   10332             : 
   10333         108 :     trunc_var(&tmp, 0);
   10334             : 
   10335         108 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
   10336          30 :         sub_var(&tmp, &const_one, &tmp);
   10337             : 
   10338         108 :     set_var_from_var(&tmp, result);
   10339         108 :     free_var(&tmp);
   10340         108 : }
   10341             : 
   10342             : 
   10343             : /*
   10344             :  * gcd_var() -
   10345             :  *
   10346             :  *  Calculate the greatest common divisor of two numerics at variable level
   10347             :  */
   10348             : static void
   10349         222 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   10350             : {
   10351             :     int         res_dscale;
   10352             :     int         cmp;
   10353             :     NumericVar  tmp_arg;
   10354             :     NumericVar  mod;
   10355             : 
   10356         222 :     res_dscale = Max(var1->dscale, var2->dscale);
   10357             : 
   10358             :     /*
   10359             :      * Arrange for var1 to be the number with the greater absolute value.
   10360             :      *
   10361             :      * This would happen automatically in the loop below, but avoids an
   10362             :      * expensive modulo operation.
   10363             :      */
   10364         222 :     cmp = cmp_abs(var1, var2);
   10365         222 :     if (cmp < 0)
   10366             :     {
   10367          84 :         const NumericVar *tmp = var1;
   10368             : 
   10369          84 :         var1 = var2;
   10370          84 :         var2 = tmp;
   10371             :     }
   10372             : 
   10373             :     /*
   10374             :      * Also avoid the taking the modulo if the inputs have the same absolute
   10375             :      * value, or if the smaller input is zero.
   10376             :      */
   10377         222 :     if (cmp == 0 || var2->ndigits == 0)
   10378             :     {
   10379          72 :         set_var_from_var(var1, result);
   10380          72 :         result->sign = NUMERIC_POS;
   10381          72 :         result->dscale = res_dscale;
   10382          72 :         return;
   10383             :     }
   10384             : 
   10385         150 :     init_var(&tmp_arg);
   10386         150 :     init_var(&mod);
   10387             : 
   10388             :     /* Use the Euclidean algorithm to find the GCD */
   10389         150 :     set_var_from_var(var1, &tmp_arg);
   10390         150 :     set_var_from_var(var2, result);
   10391             : 
   10392             :     for (;;)
   10393             :     {
   10394             :         /* this loop can take a while, so allow it to be interrupted */
   10395         588 :         CHECK_FOR_INTERRUPTS();
   10396             : 
   10397         588 :         mod_var(&tmp_arg, result, &mod);
   10398         588 :         if (mod.ndigits == 0)
   10399         150 :             break;
   10400         438 :         set_var_from_var(result, &tmp_arg);
   10401         438 :         set_var_from_var(&mod, result);
   10402             :     }
   10403         150 :     result->sign = NUMERIC_POS;
   10404         150 :     result->dscale = res_dscale;
   10405             : 
   10406         150 :     free_var(&tmp_arg);
   10407         150 :     free_var(&mod);
   10408             : }
   10409             : 
   10410             : 
   10411             : /*
   10412             :  * sqrt_var() -
   10413             :  *
   10414             :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
   10415             :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
   10416             :  *  point.
   10417             :  */
   10418             : static void
   10419        4194 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
   10420             : {
   10421             :     int         stat;
   10422             :     int         res_weight;
   10423             :     int         res_ndigits;
   10424             :     int         src_ndigits;
   10425             :     int         step;
   10426             :     int         ndigits[32];
   10427             :     int         blen;
   10428             :     int64       arg_int64;
   10429             :     int         src_idx;
   10430             :     int64       s_int64;
   10431             :     int64       r_int64;
   10432             :     NumericVar  s_var;
   10433             :     NumericVar  r_var;
   10434             :     NumericVar  a0_var;
   10435             :     NumericVar  a1_var;
   10436             :     NumericVar  q_var;
   10437             :     NumericVar  u_var;
   10438             : 
   10439        4194 :     stat = cmp_var(arg, &const_zero);
   10440        4194 :     if (stat == 0)
   10441             :     {
   10442          18 :         zero_var(result);
   10443          18 :         result->dscale = rscale;
   10444          18 :         return;
   10445             :     }
   10446             : 
   10447             :     /*
   10448             :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
   10449             :      * SQLSTATE error code if the operand is negative.
   10450             :      */
   10451        4176 :     if (stat < 0)
   10452           6 :         ereport(ERROR,
   10453             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10454             :                  errmsg("cannot take square root of a negative number")));
   10455             : 
   10456        4170 :     init_var(&s_var);
   10457        4170 :     init_var(&r_var);
   10458        4170 :     init_var(&a0_var);
   10459        4170 :     init_var(&a1_var);
   10460        4170 :     init_var(&q_var);
   10461        4170 :     init_var(&u_var);
   10462             : 
   10463             :     /*
   10464             :      * The result weight is half the input weight, rounded towards minus
   10465             :      * infinity --- res_weight = floor(arg->weight / 2).
   10466             :      */
   10467        4170 :     if (arg->weight >= 0)
   10468        3858 :         res_weight = arg->weight / 2;
   10469             :     else
   10470         312 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10471             : 
   10472             :     /*
   10473             :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10474             :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10475             :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10476             :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10477             :      */
   10478        4170 :     if (rscale + 1 >= 0)
   10479        4170 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10480             :     else
   10481           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10482        4170 :     res_ndigits = Max(res_ndigits, 1);
   10483             : 
   10484             :     /*
   10485             :      * Number of source NBASE digits logically required to produce a result
   10486             :      * with this precision --- every digit before the decimal point, plus 2
   10487             :      * for each result digit after the decimal point (or minus 2 for each
   10488             :      * result digit we round before the decimal point).
   10489             :      */
   10490        4170 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10491        4170 :     src_ndigits = Max(src_ndigits, 1);
   10492             : 
   10493             :     /* ----------
   10494             :      * From this point on, we treat the input and the result as integers and
   10495             :      * compute the integer square root and remainder using the Karatsuba
   10496             :      * Square Root algorithm, which may be written recursively as follows:
   10497             :      *
   10498             :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10499             :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10500             :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10501             :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10502             :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10503             :      *      Let s = s*b + q
   10504             :      *      Let r = u*b + a0 - q^2
   10505             :      *      If r < 0 Then
   10506             :      *          Let r = r + s
   10507             :      *          Let s = s - 1
   10508             :      *          Let r = r + s
   10509             :      *      Return (s,r)
   10510             :      *
   10511             :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10512             :      * RR-3805, November 1999.  At the time of writing this was available
   10513             :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10514             :      *
   10515             :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10516             :      * "choose a base b such that n requires at least four base-b digits to
   10517             :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10518             :      * than b".  For optimal performance, b should have approximately a
   10519             :      * quarter the number of digits in the input, so that the outer square
   10520             :      * root computes roughly twice as many digits as the inner one.  For
   10521             :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10522             :      *
   10523             :      * We implement the algorithm iteratively rather than recursively, to
   10524             :      * allow the working variables to be reused.  With this approach, each
   10525             :      * digit of the input is read precisely once --- src_idx tracks the number
   10526             :      * of input digits used so far.
   10527             :      *
   10528             :      * The array ndigits[] holds the number of NBASE digits of the input that
   10529             :      * will have been used at the end of each iteration, which roughly doubles
   10530             :      * each time.  Note that the array elements are stored in reverse order,
   10531             :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10532             :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10533             :      * the square root of the 3 most significant NBASE digits.
   10534             :      *
   10535             :      * In each iteration, we choose blen to be the largest integer for which
   10536             :      * the input number has a3 >= b/4, when written in the form above.  In
   10537             :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10538             :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10539             :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10540             :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10541             :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10542             :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10543             :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10544             :      * the first input digit.
   10545             :      *
   10546             :      * Additionally, we can put an upper bound on the number of steps required
   10547             :      * as follows --- suppose that the number of source digits is an n-bit
   10548             :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10549             :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10550             :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10551             :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10552             :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10553             :      * This pattern repeats, and in the worst case the array ndigits[] will
   10554             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10555             :      * will require n steps.  Therefore, since all digit array sizes are
   10556             :      * signed 32-bit integers, the number of steps required is guaranteed to
   10557             :      * be less than 32.
   10558             :      * ----------
   10559             :      */
   10560        4170 :     step = 0;
   10561       19962 :     while ((ndigits[step] = src_ndigits) > 4)
   10562             :     {
   10563             :         /* Choose b so that a3 >= b/4, as described above */
   10564       15792 :         blen = src_ndigits / 4;
   10565       15792 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10566         324 :             blen--;
   10567             : 
   10568             :         /* Number of digits in the next step (inner square root) */
   10569       15792 :         src_ndigits -= 2 * blen;
   10570       15792 :         step++;
   10571             :     }
   10572             : 
   10573             :     /*
   10574             :      * First iteration (innermost square root and remainder):
   10575             :      *
   10576             :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10577             :      * has at most 9 decimal digits, so estimate it using double precision
   10578             :      * arithmetic, which will in fact almost certainly return the correct
   10579             :      * result with no further correction required.
   10580             :      */
   10581        4170 :     arg_int64 = arg->digits[0];
   10582       13314 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10583             :     {
   10584        9144 :         arg_int64 *= NBASE;
   10585        9144 :         if (src_idx < arg->ndigits)
   10586        7686 :             arg_int64 += arg->digits[src_idx];
   10587             :     }
   10588             : 
   10589        4170 :     s_int64 = (int64) sqrt((double) arg_int64);
   10590        4170 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10591             : 
   10592             :     /*
   10593             :      * Use Newton's method to correct the result, if necessary.
   10594             :      *
   10595             :      * This uses integer division with truncation to compute the truncated
   10596             :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10597             :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10598             :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10599             :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10600             :      * checking the remainder.
   10601             :      */
   10602        4170 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10603             :     {
   10604           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10605           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10606             :     }
   10607             : 
   10608             :     /*
   10609             :      * Iterations with src_ndigits <= 8:
   10610             :      *
   10611             :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10612             :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10613             :      * input no longer does) and we can continue to compute using int64
   10614             :      * variables to avoid more expensive numeric computations.
   10615             :      *
   10616             :      * It is fairly easy to see that there is no risk of the intermediate
   10617             :      * values below overflowing 64-bit integers.  In the worst case, the
   10618             :      * previous iteration will have computed a 3-digit square root (of a
   10619             :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10620             :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10621             :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10622             :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10623             :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10624             :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10625             :      * in 64-bit integers.
   10626             :      */
   10627        4170 :     step--;
   10628       10566 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10629             :     {
   10630             :         int         b;
   10631             :         int         a0;
   10632             :         int         a1;
   10633             :         int         i;
   10634             :         int64       numer;
   10635             :         int64       denom;
   10636             :         int64       q;
   10637             :         int64       u;
   10638             : 
   10639        6396 :         blen = (src_ndigits - src_idx) / 2;
   10640             : 
   10641             :         /* Extract a1 and a0, and compute b */
   10642        6396 :         a0 = 0;
   10643        6396 :         a1 = 0;
   10644        6396 :         b = 1;
   10645             : 
   10646       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10647             :         {
   10648        6540 :             b *= NBASE;
   10649        6540 :             a1 *= NBASE;
   10650        6540 :             if (src_idx < arg->ndigits)
   10651        4800 :                 a1 += arg->digits[src_idx];
   10652             :         }
   10653             : 
   10654       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10655             :         {
   10656        6540 :             a0 *= NBASE;
   10657        6540 :             if (src_idx < arg->ndigits)
   10658        4644 :                 a0 += arg->digits[src_idx];
   10659             :         }
   10660             : 
   10661             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10662        6396 :         numer = r_int64 * b + a1;
   10663        6396 :         denom = 2 * s_int64;
   10664        6396 :         q = numer / denom;
   10665        6396 :         u = numer - q * denom;
   10666             : 
   10667             :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10668        6396 :         s_int64 = s_int64 * b + q;
   10669        6396 :         r_int64 = u * b + a0 - q * q;
   10670             : 
   10671        6396 :         if (r_int64 < 0)
   10672             :         {
   10673             :             /* s is too large by 1; set r += s, s--, r += s */
   10674         210 :             r_int64 += s_int64;
   10675         210 :             s_int64--;
   10676         210 :             r_int64 += s_int64;
   10677             :         }
   10678             : 
   10679             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10680        6396 :         step--;
   10681             :     }
   10682             : 
   10683             :     /*
   10684             :      * On platforms with 128-bit integer support, we can further delay the
   10685             :      * need to use numeric variables.
   10686             :      */
   10687             : #ifdef HAVE_INT128
   10688        4170 :     if (step >= 0)
   10689             :     {
   10690             :         int128      s_int128;
   10691             :         int128      r_int128;
   10692             : 
   10693        4170 :         s_int128 = s_int64;
   10694        4170 :         r_int128 = r_int64;
   10695             : 
   10696             :         /*
   10697             :          * Iterations with src_ndigits <= 16:
   10698             :          *
   10699             :          * The result fits in an int128 (even though the input doesn't) so we
   10700             :          * use int128 variables to avoid more expensive numeric computations.
   10701             :          */
   10702        9048 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10703             :         {
   10704             :             int64       b;
   10705             :             int64       a0;
   10706             :             int64       a1;
   10707             :             int64       i;
   10708             :             int128      numer;
   10709             :             int128      denom;
   10710             :             int128      q;
   10711             :             int128      u;
   10712             : 
   10713        4878 :             blen = (src_ndigits - src_idx) / 2;
   10714             : 
   10715             :             /* Extract a1 and a0, and compute b */
   10716        4878 :             a0 = 0;
   10717        4878 :             a1 = 0;
   10718        4878 :             b = 1;
   10719             : 
   10720       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10721             :             {
   10722       11202 :                 b *= NBASE;
   10723       11202 :                 a1 *= NBASE;
   10724       11202 :                 if (src_idx < arg->ndigits)
   10725        6606 :                     a1 += arg->digits[src_idx];
   10726             :             }
   10727             : 
   10728       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10729             :             {
   10730       11202 :                 a0 *= NBASE;
   10731       11202 :                 if (src_idx < arg->ndigits)
   10732        4470 :                     a0 += arg->digits[src_idx];
   10733             :             }
   10734             : 
   10735             :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10736        4878 :             numer = r_int128 * b + a1;
   10737        4878 :             denom = 2 * s_int128;
   10738        4878 :             q = numer / denom;
   10739        4878 :             u = numer - q * denom;
   10740             : 
   10741             :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10742        4878 :             s_int128 = s_int128 * b + q;
   10743        4878 :             r_int128 = u * b + a0 - q * q;
   10744             : 
   10745        4878 :             if (r_int128 < 0)
   10746             :             {
   10747             :                 /* s is too large by 1; set r += s, s--, r += s */
   10748         192 :                 r_int128 += s_int128;
   10749         192 :                 s_int128--;
   10750         192 :                 r_int128 += s_int128;
   10751             :             }
   10752             : 
   10753             :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10754        4878 :             step--;
   10755             :         }
   10756             : 
   10757             :         /*
   10758             :          * All remaining iterations require numeric variables.  Convert the
   10759             :          * integer values to NumericVar and continue.  Note that in the final
   10760             :          * iteration we don't need the remainder, so we can save a few cycles
   10761             :          * there by not fully computing it.
   10762             :          */
   10763        4170 :         int128_to_numericvar(s_int128, &s_var);
   10764        4170 :         if (step >= 0)
   10765        2724 :             int128_to_numericvar(r_int128, &r_var);
   10766             :     }
   10767             :     else
   10768             :     {
   10769           0 :         int64_to_numericvar(s_int64, &s_var);
   10770             :         /* step < 0, so we certainly don't need r */
   10771             :     }
   10772             : #else                           /* !HAVE_INT128 */
   10773             :     int64_to_numericvar(s_int64, &s_var);
   10774             :     if (step >= 0)
   10775             :         int64_to_numericvar(r_int64, &r_var);
   10776             : #endif                          /* HAVE_INT128 */
   10777             : 
   10778             :     /*
   10779             :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10780             :      * use numeric variables.
   10781             :      */
   10782        8688 :     while (step >= 0)
   10783             :     {
   10784             :         int         tmp_len;
   10785             : 
   10786        4518 :         src_ndigits = ndigits[step];
   10787        4518 :         blen = (src_ndigits - src_idx) / 2;
   10788             : 
   10789             :         /* Extract a1 and a0 */
   10790        4518 :         if (src_idx < arg->ndigits)
   10791             :         {
   10792        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10793        1512 :             alloc_var(&a1_var, tmp_len);
   10794        1512 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10795             :                    tmp_len * sizeof(NumericDigit));
   10796        1512 :             a1_var.weight = blen - 1;
   10797        1512 :             a1_var.sign = NUMERIC_POS;
   10798        1512 :             a1_var.dscale = 0;
   10799        1512 :             strip_var(&a1_var);
   10800             :         }
   10801             :         else
   10802             :         {
   10803        3006 :             zero_var(&a1_var);
   10804        3006 :             a1_var.dscale = 0;
   10805             :         }
   10806        4518 :         src_idx += blen;
   10807             : 
   10808        4518 :         if (src_idx < arg->ndigits)
   10809             :         {
   10810        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10811        1512 :             alloc_var(&a0_var, tmp_len);
   10812        1512 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10813             :                    tmp_len * sizeof(NumericDigit));
   10814        1512 :             a0_var.weight = blen - 1;
   10815        1512 :             a0_var.sign = NUMERIC_POS;
   10816        1512 :             a0_var.dscale = 0;
   10817        1512 :             strip_var(&a0_var);
   10818             :         }
   10819             :         else
   10820             :         {
   10821        3006 :             zero_var(&a0_var);
   10822        3006 :             a0_var.dscale = 0;
   10823             :         }
   10824        4518 :         src_idx += blen;
   10825             : 
   10826             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10827        4518 :         set_var_from_var(&r_var, &q_var);
   10828        4518 :         q_var.weight += blen;
   10829        4518 :         add_var(&q_var, &a1_var, &q_var);
   10830        4518 :         add_var(&s_var, &s_var, &u_var);
   10831        4518 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10832             : 
   10833             :         /* Compute s = s*b + q */
   10834        4518 :         s_var.weight += blen;
   10835        4518 :         add_var(&s_var, &q_var, &s_var);
   10836             : 
   10837             :         /*
   10838             :          * Compute r = u*b + a0 - q^2.
   10839             :          *
   10840             :          * In the final iteration, we don't actually need r; we just need to
   10841             :          * know whether it is negative, so that we know whether to adjust s.
   10842             :          * So instead of the final subtraction we can just compare.
   10843             :          */
   10844        4518 :         u_var.weight += blen;
   10845        4518 :         add_var(&u_var, &a0_var, &u_var);
   10846        4518 :         mul_var(&q_var, &q_var, &q_var, 0);
   10847             : 
   10848        4518 :         if (step > 0)
   10849             :         {
   10850             :             /* Need r for later iterations */
   10851        1794 :             sub_var(&u_var, &q_var, &r_var);
   10852        1794 :             if (r_var.sign == NUMERIC_NEG)
   10853             :             {
   10854             :                 /* s is too large by 1; set r += s, s--, r += s */
   10855         120 :                 add_var(&r_var, &s_var, &r_var);
   10856         120 :                 sub_var(&s_var, &const_one, &s_var);
   10857         120 :                 add_var(&r_var, &s_var, &r_var);
   10858             :             }
   10859             :         }
   10860             :         else
   10861             :         {
   10862             :             /* Don't need r anymore, except to test if s is too large by 1 */
   10863        2724 :             if (cmp_var(&u_var, &q_var) < 0)
   10864          36 :                 sub_var(&s_var, &const_one, &s_var);
   10865             :         }
   10866             : 
   10867             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10868        4518 :         step--;
   10869             :     }
   10870             : 
   10871             :     /*
   10872             :      * Construct the final result, rounding it to the requested precision.
   10873             :      */
   10874        4170 :     set_var_from_var(&s_var, result);
   10875        4170 :     result->weight = res_weight;
   10876        4170 :     result->sign = NUMERIC_POS;
   10877             : 
   10878             :     /* Round to target rscale (and set result->dscale) */
   10879        4170 :     round_var(result, rscale);
   10880             : 
   10881             :     /* Strip leading and trailing zeroes */
   10882        4170 :     strip_var(result);
   10883             : 
   10884        4170 :     free_var(&s_var);
   10885        4170 :     free_var(&r_var);
   10886        4170 :     free_var(&a0_var);
   10887        4170 :     free_var(&a1_var);
   10888        4170 :     free_var(&q_var);
   10889        4170 :     free_var(&u_var);
   10890             : }
   10891             : 
   10892             : 
   10893             : /*
   10894             :  * exp_var() -
   10895             :  *
   10896             :  *  Raise e to the power of x, computed to rscale fractional digits
   10897             :  */
   10898             : static void
   10899         180 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10900             : {
   10901             :     NumericVar  x;
   10902             :     NumericVar  elem;
   10903             :     int         ni;
   10904             :     double      val;
   10905             :     int         dweight;
   10906             :     int         ndiv2;
   10907             :     int         sig_digits;
   10908             :     int         local_rscale;
   10909             : 
   10910         180 :     init_var(&x);
   10911         180 :     init_var(&elem);
   10912             : 
   10913         180 :     set_var_from_var(arg, &x);
   10914             : 
   10915             :     /*
   10916             :      * Estimate the dweight of the result using floating point arithmetic, so
   10917             :      * that we can choose an appropriate local rscale for the calculation.
   10918             :      */
   10919         180 :     val = numericvar_to_double_no_overflow(&x);
   10920             : 
   10921             :     /* Guard against overflow/underflow */
   10922             :     /* If you change this limit, see also power_var()'s limit */
   10923         180 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10924             :     {
   10925           6 :         if (val > 0)
   10926           0 :             ereport(ERROR,
   10927             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10928             :                      errmsg("value overflows numeric format")));
   10929           6 :         zero_var(result);
   10930           6 :         result->dscale = rscale;
   10931           6 :         return;
   10932             :     }
   10933             : 
   10934             :     /* decimal weight = log10(e^x) = x * log10(e) */
   10935         174 :     dweight = (int) (val * 0.434294481903252);
   10936             : 
   10937             :     /*
   10938             :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10939             :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10940             :      *
   10941             :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10942             :      * means that ndiv2 <= 20 here.
   10943             :      */
   10944         174 :     if (fabs(val) > 0.01)
   10945             :     {
   10946         144 :         ndiv2 = 1;
   10947         144 :         val /= 2;
   10948             : 
   10949        1818 :         while (fabs(val) > 0.01)
   10950             :         {
   10951        1674 :             ndiv2++;
   10952        1674 :             val /= 2;
   10953             :         }
   10954             : 
   10955         144 :         local_rscale = x.dscale + ndiv2;
   10956         144 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10957             :     }
   10958             :     else
   10959          30 :         ndiv2 = 0;
   10960             : 
   10961             :     /*
   10962             :      * Set the scale for the Taylor series expansion.  The final result has
   10963             :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10964             :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10965             :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10966             :      * extra digits of precision (plus a few more for good measure).
   10967             :      */
   10968         174 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10969         174 :     sig_digits = Max(sig_digits, 0) + 8;
   10970             : 
   10971         174 :     local_rscale = sig_digits - 1;
   10972             : 
   10973             :     /*
   10974             :      * Use the Taylor series
   10975             :      *
   10976             :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10977             :      *
   10978             :      * Given the limited range of x, this should converge reasonably quickly.
   10979             :      * We run the series until the terms fall below the local_rscale limit.
   10980             :      */
   10981         174 :     add_var(&const_one, &x, result);
   10982             : 
   10983         174 :     mul_var(&x, &x, &elem, local_rscale);
   10984         174 :     ni = 2;
   10985         174 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10986             : 
   10987        4992 :     while (elem.ndigits != 0)
   10988             :     {
   10989        4818 :         add_var(result, &elem, result);
   10990             : 
   10991        4818 :         mul_var(&elem, &x, &elem, local_rscale);
   10992        4818 :         ni++;
   10993        4818 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10994             :     }
   10995             : 
   10996             :     /*
   10997             :      * Compensate for the argument range reduction.  Since the weight of the
   10998             :      * result doubles with each multiplication, we can reduce the local rscale
   10999             :      * as we proceed.
   11000             :      */
   11001        1992 :     while (ndiv2-- > 0)
   11002             :     {
   11003        1818 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   11004        1818 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11005        1818 :         mul_var(result, result, result, local_rscale);
   11006             :     }
   11007             : 
   11008             :     /* Round to requested rscale */
   11009         174 :     round_var(result, rscale);
   11010             : 
   11011         174 :     free_var(&x);
   11012         174 :     free_var(&elem);
   11013             : }
   11014             : 
   11015             : 
   11016             : /*
   11017             :  * Estimate the dweight of the most significant decimal digit of the natural
   11018             :  * logarithm of a number.
   11019             :  *
   11020             :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   11021             :  * determine the appropriate rscale when computing natural logarithms.
   11022             :  *
   11023             :  * Note: many callers call this before range-checking the input.  Therefore,
   11024             :  * we must be robust against values that are invalid to apply ln() to.
   11025             :  * We don't wish to throw an error here, so just return zero in such cases.
   11026             :  */
   11027             : static int
   11028         738 : estimate_ln_dweight(const NumericVar *var)
   11029             : {
   11030             :     int         ln_dweight;
   11031             : 
   11032             :     /* Caller should fail on ln(negative), but for the moment return zero */
   11033         738 :     if (var->sign != NUMERIC_POS)
   11034          42 :         return 0;
   11035             : 
   11036        1314 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   11037         618 :         cmp_var(var, &const_one_point_one) <= 0)
   11038          90 :     {
   11039             :         /*
   11040             :          * 0.9 <= var <= 1.1
   11041             :          *
   11042             :          * ln(var) has a negative weight (possibly very large).  To get a
   11043             :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   11044             :          */
   11045             :         NumericVar  x;
   11046             : 
   11047          90 :         init_var(&x);
   11048          90 :         sub_var(var, &const_one, &x);
   11049             : 
   11050          90 :         if (x.ndigits > 0)
   11051             :         {
   11052             :             /* Use weight of most significant decimal digit of x */
   11053          42 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   11054             :         }
   11055             :         else
   11056             :         {
   11057             :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   11058          48 :             ln_dweight = 0;
   11059             :         }
   11060             : 
   11061          90 :         free_var(&x);
   11062             :     }
   11063             :     else
   11064             :     {
   11065             :         /*
   11066             :          * Estimate the logarithm using the first couple of digits from the
   11067             :          * input number.  This will give an accurate result whenever the input
   11068             :          * is not too close to 1.
   11069             :          */
   11070         606 :         if (var->ndigits > 0)
   11071             :         {
   11072             :             int         digits;
   11073             :             int         dweight;
   11074             :             double      ln_var;
   11075             : 
   11076         564 :             digits = var->digits[0];
   11077         564 :             dweight = var->weight * DEC_DIGITS;
   11078             : 
   11079         564 :             if (var->ndigits > 1)
   11080             :             {
   11081         342 :                 digits = digits * NBASE + var->digits[1];
   11082         342 :                 dweight -= DEC_DIGITS;
   11083             :             }
   11084             : 
   11085             :             /*----------
   11086             :              * We have var ~= digits * 10^dweight
   11087             :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   11088             :              *----------
   11089             :              */
   11090         564 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   11091         564 :             ln_dweight = (int) log10(fabs(ln_var));
   11092             :         }
   11093             :         else
   11094             :         {
   11095             :             /* Caller should fail on ln(0), but for the moment return zero */
   11096          42 :             ln_dweight = 0;
   11097             :         }
   11098             :     }
   11099             : 
   11100         696 :     return ln_dweight;
   11101             : }
   11102             : 
   11103             : 
   11104             : /*
   11105             :  * ln_var() -
   11106             :  *
   11107             :  *  Compute the natural log of x
   11108             :  */
   11109             : static void
   11110         834 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   11111             : {
   11112             :     NumericVar  x;
   11113             :     NumericVar  xx;
   11114             :     int         ni;
   11115             :     NumericVar  elem;
   11116             :     NumericVar  fact;
   11117             :     int         nsqrt;
   11118             :     int         local_rscale;
   11119             :     int         cmp;
   11120             : 
   11121         834 :     cmp = cmp_var(arg, &const_zero);
   11122         834 :     if (cmp == 0)
   11123          42 :         ereport(ERROR,
   11124             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   11125             :                  errmsg("cannot take logarithm of zero")));
   11126         792 :     else if (cmp < 0)
   11127          36 :         ereport(ERROR,
   11128             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   11129             :                  errmsg("cannot take logarithm of a negative number")));
   11130             : 
   11131         756 :     init_var(&x);
   11132         756 :     init_var(&xx);
   11133         756 :     init_var(&elem);
   11134         756 :     init_var(&fact);
   11135             : 
   11136         756 :     set_var_from_var(arg, &x);
   11137         756 :     set_var_from_var(&const_two, &fact);
   11138             : 
   11139             :     /*
   11140             :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   11141             :      *
   11142             :      * The final logarithm will have up to around rscale+6 significant digits.
   11143             :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   11144             :      * rscale as we work so that we keep this many significant digits at each
   11145             :      * step (plus a few more for good measure).
   11146             :      *
   11147             :      * Note that we allow local_rscale < 0 during this input reduction
   11148             :      * process, which implies rounding before the decimal point.  sqrt_var()
   11149             :      * explicitly supports this, and it significantly reduces the work
   11150             :      * required to reduce very large inputs to the required range.  Once the
   11151             :      * input reduction is complete, x.weight will be 0 and its display scale
   11152             :      * will be non-negative again.
   11153             :      */
   11154         756 :     nsqrt = 0;
   11155        1068 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   11156             :     {
   11157         312 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   11158         312 :         sqrt_var(&x, &x, local_rscale);
   11159         312 :         mul_var(&fact, &const_two, &fact, 0);
   11160         312 :         nsqrt++;
   11161             :     }
   11162        4128 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   11163             :     {
   11164        3372 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   11165        3372 :         sqrt_var(&x, &x, local_rscale);
   11166        3372 :         mul_var(&fact, &const_two, &fact, 0);
   11167        3372 :         nsqrt++;
   11168             :     }
   11169             : 
   11170             :     /*
   11171             :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   11172             :      *
   11173             :      * z + z^3/3 + z^5/5 + ...
   11174             :      *
   11175             :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   11176             :      * due to the above range-reduction of x.
   11177             :      *
   11178             :      * The convergence of this is not as fast as one would like, but is
   11179             :      * tolerable given that z is small.
   11180             :      *
   11181             :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   11182             :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   11183             :      * digits of precision (plus a few more for good measure).
   11184             :      */
   11185         756 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   11186             : 
   11187         756 :     sub_var(&x, &const_one, result);
   11188         756 :     add_var(&x, &const_one, &elem);
   11189         756 :     div_var(result, &elem, result, local_rscale, true, false);
   11190         756 :     set_var_from_var(result, &xx);
   11191         756 :     mul_var(result, result, &x, local_rscale);
   11192             : 
   11193         756 :     ni = 1;
   11194             : 
   11195             :     for (;;)
   11196             :     {
   11197       14022 :         ni += 2;
   11198       14022 :         mul_var(&xx, &x, &xx, local_rscale);
   11199       14022 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   11200             : 
   11201       14022 :         if (elem.ndigits == 0)
   11202         756 :             break;
   11203             : 
   11204       13266 :         add_var(result, &elem, result);
   11205             : 
   11206       13266 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   11207           0 :             break;
   11208             :     }
   11209             : 
   11210             :     /* Compensate for argument range reduction, round to requested rscale */
   11211         756 :     mul_var(result, &fact, result, rscale);
   11212             : 
   11213         756 :     free_var(&x);
   11214         756 :     free_var(&xx);
   11215         756 :     free_var(&elem);
   11216         756 :     free_var(&fact);
   11217         756 : }
   11218             : 
   11219             : 
   11220             : /*
   11221             :  * log_var() -
   11222             :  *
   11223             :  *  Compute the logarithm of num in a given base.
   11224             :  *
   11225             :  *  Note: this routine chooses dscale of the result.
   11226             :  */
   11227             : static void
   11228         216 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   11229             : {
   11230             :     NumericVar  ln_base;
   11231             :     NumericVar  ln_num;
   11232             :     int         ln_base_dweight;
   11233             :     int         ln_num_dweight;
   11234             :     int         result_dweight;
   11235             :     int         rscale;
   11236             :     int         ln_base_rscale;
   11237             :     int         ln_num_rscale;
   11238             : 
   11239         216 :     init_var(&ln_base);
   11240         216 :     init_var(&ln_num);
   11241             : 
   11242             :     /* Estimated dweights of ln(base), ln(num) and the final result */
   11243         216 :     ln_base_dweight = estimate_ln_dweight(base);
   11244         216 :     ln_num_dweight = estimate_ln_dweight(num);
   11245         216 :     result_dweight = ln_num_dweight - ln_base_dweight;
   11246             : 
   11247             :     /*
   11248             :      * Select the scale of the result so that it will have at least
   11249             :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   11250             :      * input's display scale.
   11251             :      */
   11252         216 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   11253         216 :     rscale = Max(rscale, base->dscale);
   11254         216 :     rscale = Max(rscale, num->dscale);
   11255         216 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11256         216 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11257             : 
   11258             :     /*
   11259             :      * Set the scales for ln(base) and ln(num) so that they each have more
   11260             :      * significant digits than the final result.
   11261             :      */
   11262         216 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   11263         216 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11264             : 
   11265         216 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   11266         216 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11267             : 
   11268             :     /* Form natural logarithms */
   11269         216 :     ln_var(base, &ln_base, ln_base_rscale);
   11270         192 :     ln_var(num, &ln_num, ln_num_rscale);
   11271             : 
   11272             :     /* Divide and round to the required scale */
   11273         162 :     div_var(&ln_num, &ln_base, result, rscale, true, false);
   11274             : 
   11275         156 :     free_var(&ln_num);
   11276         156 :     free_var(&ln_base);
   11277         156 : }
   11278             : 
   11279             : 
   11280             : /*
   11281             :  * power_var() -
   11282             :  *
   11283             :  *  Raise base to the power of exp
   11284             :  *
   11285             :  *  Note: this routine chooses dscale of the result.
   11286             :  */
   11287             : static void
   11288        1398 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   11289             : {
   11290             :     int         res_sign;
   11291             :     NumericVar  abs_base;
   11292             :     NumericVar  ln_base;
   11293             :     NumericVar  ln_num;
   11294             :     int         ln_dweight;
   11295             :     int         rscale;
   11296             :     int         sig_digits;
   11297             :     int         local_rscale;
   11298             :     double      val;
   11299             : 
   11300             :     /* If exp can be represented as an integer, use power_var_int */
   11301        1398 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   11302             :     {
   11303             :         /* exact integer, but does it fit in int? */
   11304             :         int64       expval64;
   11305             : 
   11306        1272 :         if (numericvar_to_int64(exp, &expval64))
   11307             :         {
   11308        1266 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   11309             :             {
   11310             :                 /* Okay, use power_var_int */
   11311        1236 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   11312        1224 :                 return;
   11313             :             }
   11314             :         }
   11315             :     }
   11316             : 
   11317             :     /*
   11318             :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   11319             :      * handled by power_var_int().
   11320             :      */
   11321         162 :     if (cmp_var(base, &const_zero) == 0)
   11322             :     {
   11323          18 :         set_var_from_var(&const_zero, result);
   11324          18 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   11325          18 :         return;
   11326             :     }
   11327             : 
   11328         144 :     init_var(&abs_base);
   11329         144 :     init_var(&ln_base);
   11330         144 :     init_var(&ln_num);
   11331             : 
   11332             :     /*
   11333             :      * If base is negative, insist that exp be an integer.  The result is then
   11334             :      * positive if exp is even and negative if exp is odd.
   11335             :      */
   11336         144 :     if (base->sign == NUMERIC_NEG)
   11337             :     {
   11338             :         /*
   11339             :          * Check that exp is an integer.  This error code is defined by the
   11340             :          * SQL standard, and matches other errors in numeric_power().
   11341             :          */
   11342          36 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   11343          18 :             ereport(ERROR,
   11344             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   11345             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   11346             : 
   11347             :         /* Test if exp is odd or even */
   11348          18 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   11349          12 :             (exp->digits[exp->ndigits - 1] & 1))
   11350           6 :             res_sign = NUMERIC_NEG;
   11351             :         else
   11352          12 :             res_sign = NUMERIC_POS;
   11353             : 
   11354             :         /* Then work with abs(base) below */
   11355          18 :         set_var_from_var(base, &abs_base);
   11356          18 :         abs_base.sign = NUMERIC_POS;
   11357          18 :         base = &abs_base;
   11358             :     }
   11359             :     else
   11360         108 :         res_sign = NUMERIC_POS;
   11361             : 
   11362             :     /*----------
   11363             :      * Decide on the scale for the ln() calculation.  For this we need an
   11364             :      * estimate of the weight of the result, which we obtain by doing an
   11365             :      * initial low-precision calculation of exp * ln(base).
   11366             :      *
   11367             :      * We want result = e ^ (exp * ln(base))
   11368             :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   11369             :      *
   11370             :      * We also perform a crude overflow test here so that we can exit early if
   11371             :      * the full-precision result is sure to overflow, and to guard against
   11372             :      * integer overflow when determining the scale for the real calculation.
   11373             :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   11374             :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   11375             :      * Since the values here are only approximations, we apply a small fuzz
   11376             :      * factor to this overflow test and let exp_var() determine the exact
   11377             :      * overflow threshold so that it is consistent for all inputs.
   11378             :      *----------
   11379             :      */
   11380         126 :     ln_dweight = estimate_ln_dweight(base);
   11381             : 
   11382             :     /*
   11383             :      * Set the scale for the low-precision calculation, computing ln(base) to
   11384             :      * around 8 significant digits.  Note that ln_dweight may be as small as
   11385             :      * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
   11386             :      * here.
   11387             :      */
   11388         126 :     local_rscale = 8 - ln_dweight;
   11389         126 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11390             : 
   11391         126 :     ln_var(base, &ln_base, local_rscale);
   11392             : 
   11393         126 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11394             : 
   11395         126 :     val = numericvar_to_double_no_overflow(&ln_num);
   11396             : 
   11397             :     /* initial overflow/underflow test with fuzz factor */
   11398         126 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   11399             :     {
   11400           6 :         if (val > 0)
   11401           0 :             ereport(ERROR,
   11402             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11403             :                      errmsg("value overflows numeric format")));
   11404           6 :         zero_var(result);
   11405           6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11406           6 :         return;
   11407             :     }
   11408             : 
   11409         120 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   11410             : 
   11411             :     /* choose the result scale */
   11412         120 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   11413         120 :     rscale = Max(rscale, base->dscale);
   11414         120 :     rscale = Max(rscale, exp->dscale);
   11415         120 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11416         120 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11417             : 
   11418             :     /* significant digits required in the result */
   11419         120 :     sig_digits = rscale + (int) val;
   11420         120 :     sig_digits = Max(sig_digits, 0);
   11421             : 
   11422             :     /* set the scale for the real exp * ln(base) calculation */
   11423         120 :     local_rscale = sig_digits - ln_dweight + 8;
   11424         120 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11425             : 
   11426             :     /* and do the real calculation */
   11427             : 
   11428         120 :     ln_var(base, &ln_base, local_rscale);
   11429             : 
   11430         120 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11431             : 
   11432         120 :     exp_var(&ln_num, result, rscale);
   11433             : 
   11434         120 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   11435           6 :         result->sign = NUMERIC_NEG;
   11436             : 
   11437         120 :     free_var(&ln_num);
   11438         120 :     free_var(&ln_base);
   11439         120 :     free_var(&abs_base);
   11440             : }
   11441             : 
   11442             : /*
   11443             :  * power_var_int() -
   11444             :  *
   11445             :  *  Raise base to the power of exp, where exp is an integer.
   11446             :  *
   11447             :  *  Note: this routine chooses dscale of the result.
   11448             :  */
   11449             : static void
   11450        1236 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   11451             :               NumericVar *result)
   11452             : {
   11453             :     double      f;
   11454             :     int         p;
   11455             :     int         i;
   11456             :     int         rscale;
   11457             :     int         sig_digits;
   11458             :     unsigned int mask;
   11459             :     bool        neg;
   11460             :     NumericVar  base_prod;
   11461             :     int         local_rscale;
   11462             : 
   11463             :     /*
   11464             :      * Choose the result scale.  For this we need an estimate of the decimal
   11465             :      * weight of the result, which we obtain by approximating using double
   11466             :      * precision arithmetic.
   11467             :      *
   11468             :      * We also perform crude overflow/underflow tests here so that we can exit
   11469             :      * early if the result is sure to overflow/underflow, and to guard against
   11470             :      * integer overflow when choosing the result scale.
   11471             :      */
   11472        1236 :     if (base->ndigits != 0)
   11473             :     {
   11474             :         /*----------
   11475             :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11476             :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11477             :          *----------
   11478             :          */
   11479        1206 :         f = base->digits[0];
   11480        1206 :         p = base->weight * DEC_DIGITS;
   11481             : 
   11482        1290 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11483             :         {
   11484          84 :             f = f * NBASE + base->digits[i];
   11485          84 :             p -= DEC_DIGITS;
   11486             :         }
   11487             : 
   11488        1206 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11489             :     }
   11490             :     else
   11491          30 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11492             : 
   11493             :     /* overflow/underflow tests with fuzz factors */
   11494        1236 :     if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
   11495          12 :         ereport(ERROR,
   11496             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11497             :                  errmsg("value overflows numeric format")));
   11498        1224 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11499             :     {
   11500          12 :         zero_var(result);
   11501          12 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11502         216 :         return;
   11503             :     }
   11504             : 
   11505             :     /*
   11506             :      * Choose the result scale in the same way as power_var(), so it has at
   11507             :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11508             :      * either input's display scale.
   11509             :      */
   11510        1212 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11511        1212 :     rscale = Max(rscale, base->dscale);
   11512        1212 :     rscale = Max(rscale, exp_dscale);
   11513        1212 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11514        1212 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11515             : 
   11516             :     /* Handle some common special cases, as well as corner cases */
   11517        1212 :     switch (exp)
   11518             :     {
   11519          72 :         case 0:
   11520             : 
   11521             :             /*
   11522             :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11523             :              * it as 1 because most programming languages do this. SQL:2003
   11524             :              * also requires a return value of 1.
   11525             :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11526             :              */
   11527          72 :             set_var_from_var(&const_one, result);
   11528          72 :             result->dscale = rscale; /* no need to round */
   11529          72 :             return;
   11530          48 :         case 1:
   11531          48 :             set_var_from_var(base, result);
   11532          48 :             round_var(result, rscale);
   11533          48 :             return;
   11534          30 :         case -1:
   11535          30 :             div_var(&const_one, base, result, rscale, true, true);
   11536          30 :             return;
   11537          54 :         case 2:
   11538          54 :             mul_var(base, base, result, rscale);
   11539          54 :             return;
   11540        1008 :         default:
   11541        1008 :             break;
   11542             :     }
   11543             : 
   11544             :     /* Handle the special case where the base is zero */
   11545        1008 :     if (base->ndigits == 0)
   11546             :     {
   11547           0 :         if (exp < 0)
   11548           0 :             ereport(ERROR,
   11549             :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11550             :                      errmsg("division by zero")));
   11551           0 :         zero_var(result);
   11552           0 :         result->dscale = rscale;
   11553           0 :         return;
   11554             :     }
   11555             : 
   11556             :     /*
   11557             :      * The general case repeatedly multiplies base according to the bit
   11558             :      * pattern of exp.
   11559             :      *
   11560             :      * The local rscale used for each multiplication is varied to keep a fixed
   11561             :      * number of significant digits, sufficient to give the required result
   11562             :      * scale.
   11563             :      */
   11564             : 
   11565             :     /*
   11566             :      * Approximate number of significant digits in the result.  Note that the
   11567             :      * underflow test above, together with the choice of rscale, ensures that
   11568             :      * this approximation is necessarily > 0.
   11569             :      */
   11570        1008 :     sig_digits = 1 + rscale + (int) f;
   11571             : 
   11572             :     /*
   11573             :      * The multiplications to produce the result may introduce an error of up
   11574             :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11575             :      * of precision (plus a few more for good measure).
   11576             :      */
   11577        1008 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11578             : 
   11579             :     /*
   11580             :      * Now we can proceed with the multiplications.
   11581             :      */
   11582        1008 :     neg = (exp < 0);
   11583        1008 :     mask = pg_abs_s32(exp);
   11584             : 
   11585        1008 :     init_var(&base_prod);
   11586        1008 :     set_var_from_var(base, &base_prod);
   11587             : 
   11588        1008 :     if (mask & 1)
   11589         498 :         set_var_from_var(base, result);
   11590             :     else
   11591         510 :         set_var_from_var(&const_one, result);
   11592             : 
   11593        5076 :     while ((mask >>= 1) > 0)
   11594             :     {
   11595             :         /*
   11596             :          * Do the multiplications using rscales large enough to hold the
   11597             :          * results to the required number of significant digits, but don't
   11598             :          * waste time by exceeding the scales of the numbers themselves.
   11599             :          */
   11600        4068 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11601        4068 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11602        4068 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11603             : 
   11604        4068 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11605             : 
   11606        4068 :         if (mask & 1)
   11607             :         {
   11608        2658 :             local_rscale = sig_digits -
   11609        2658 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11610        2658 :             local_rscale = Min(local_rscale,
   11611             :                                base_prod.dscale + result->dscale);
   11612        2658 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11613             : 
   11614        2658 :             mul_var(&base_prod, result, result, local_rscale);
   11615             :         }
   11616             : 
   11617             :         /*
   11618             :          * When abs(base) > 1, the number of digits to the left of the decimal
   11619             :          * point in base_prod doubles at each iteration, so if exp is large we
   11620             :          * could easily spend large amounts of time and memory space doing the
   11621             :          * multiplications.  But once the weight exceeds what will fit in
   11622             :          * int16, the final result is guaranteed to overflow (or underflow, if
   11623             :          * exp < 0), so we can give up before wasting too many cycles.
   11624             :          */
   11625        4068 :         if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
   11626        4068 :             result->weight > NUMERIC_WEIGHT_MAX)
   11627             :         {
   11628             :             /* overflow, unless neg, in which case result should be 0 */
   11629           0 :             if (!neg)
   11630           0 :                 ereport(ERROR,
   11631             :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11632             :                          errmsg("value overflows numeric format")));
   11633           0 :             zero_var(result);
   11634           0 :             neg = false;
   11635           0 :             break;
   11636             :         }
   11637             :     }
   11638             : 
   11639        1008 :     free_var(&base_prod);
   11640             : 
   11641             :     /* Compensate for input sign, and round to requested rscale */
   11642        1008 :     if (neg)
   11643         486 :         div_var(&const_one, result, result, rscale, true, false);
   11644             :     else
   11645         522 :         round_var(result, rscale);
   11646             : }
   11647             : 
   11648             : /*
   11649             :  * power_ten_int() -
   11650             :  *
   11651             :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11652             :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11653             :  */
   11654             : static void
   11655         228 : power_ten_int(int exp, NumericVar *result)
   11656             : {
   11657             :     /* Construct the result directly, starting from 10^0 = 1 */
   11658         228 :     set_var_from_var(&const_one, result);
   11659             : 
   11660             :     /* Scale needed to represent the result exactly */
   11661         228 :     result->dscale = exp < 0 ? -exp : 0;
   11662             : 
   11663             :     /* Base-NBASE weight of result and remaining exponent */
   11664         228 :     if (exp >= 0)
   11665         162 :         result->weight = exp / DEC_DIGITS;
   11666             :     else
   11667          66 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11668             : 
   11669         228 :     exp -= result->weight * DEC_DIGITS;
   11670             : 
   11671             :     /* Final adjustment of the result's single NBASE digit */
   11672         594 :     while (exp-- > 0)
   11673         366 :         result->digits[0] *= 10;
   11674         228 : }
   11675             : 
   11676             : /*
   11677             :  * random_var() - return a random value in the range [rmin, rmax].
   11678             :  */
   11679             : static void
   11680       33438 : random_var(pg_prng_state *state, const NumericVar *rmin,
   11681             :            const NumericVar *rmax, NumericVar *result)
   11682             : {
   11683             :     int         rscale;
   11684             :     NumericVar  rlen;
   11685             :     int         res_ndigits;
   11686             :     int         n;
   11687             :     int         pow10;
   11688             :     int         i;
   11689             :     uint64      rlen64;
   11690             :     int         rlen64_ndigits;
   11691             : 
   11692       33438 :     rscale = Max(rmin->dscale, rmax->dscale);
   11693             : 
   11694             :     /* Compute rlen = rmax - rmin and check the range bounds */
   11695       33438 :     init_var(&rlen);
   11696       33438 :     sub_var(rmax, rmin, &rlen);
   11697             : 
   11698       33438 :     if (rlen.sign == NUMERIC_NEG)
   11699           6 :         ereport(ERROR,
   11700             :                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
   11701             :                 errmsg("lower bound must be less than or equal to upper bound"));
   11702             : 
   11703             :     /* Special case for an empty range */
   11704       33432 :     if (rlen.ndigits == 0)
   11705             :     {
   11706          12 :         set_var_from_var(rmin, result);
   11707          12 :         result->dscale = rscale;
   11708          12 :         free_var(&rlen);
   11709          12 :         return;
   11710             :     }
   11711             : 
   11712             :     /*
   11713             :      * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
   11714             :      * and shift it to the required range by adding rmin.
   11715             :      */
   11716             : 
   11717             :     /* Required result digits */
   11718       33420 :     res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   11719             : 
   11720             :     /*
   11721             :      * To get the required rscale, the final result digit must be a multiple
   11722             :      * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
   11723             :      */
   11724       33420 :     n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
   11725       33420 :     pow10 = 1;
   11726       87900 :     for (i = 0; i < n; i++)
   11727       54480 :         pow10 *= 10;
   11728             : 
   11729             :     /*
   11730             :      * To choose a random value uniformly from the range [0, rlen], we choose
   11731             :      * from the slightly larger range [0, rlen2], where rlen2 is formed from
   11732             :      * rlen by copying the first 4 NBASE digits, and setting all remaining
   11733             :      * decimal digits to "9".
   11734             :      *
   11735             :      * Without loss of generality, we can ignore the weight of rlen2 and treat
   11736             :      * it as a pure integer for the purposes of this discussion.  The process
   11737             :      * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
   11738             :      * is a 64-bit integer formed from the first 4 NBASE digits copied from
   11739             :      * rlen.  Since this trivially factors into smaller pieces that fit in
   11740             :      * 64-bit integers, the task of choosing a random value uniformly from the
   11741             :      * rlen2 + 1 possible values in [0, rlen2] is much simpler.
   11742             :      *
   11743             :      * If the random value selected is too large, it is rejected, and we try
   11744             :      * again until we get a result <= rlen, ensuring that the overall result
   11745             :      * is uniform (no particular value is any more likely than any other).
   11746             :      *
   11747             :      * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
   11748             :      * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
   11749             :      * when DEC_DIGITS is 4). Therefore the probability of needing to reject
   11750             :      * the value chosen and retry is less than 1e-13.
   11751             :      */
   11752       33420 :     rlen64 = (uint64) rlen.digits[0];
   11753       33420 :     rlen64_ndigits = 1;
   11754       76212 :     while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
   11755             :     {
   11756       42792 :         rlen64 *= NBASE;
   11757       42792 :         if (rlen64_ndigits < rlen.ndigits)
   11758        6612 :             rlen64 += rlen.digits[rlen64_ndigits];
   11759       42792 :         rlen64_ndigits++;
   11760             :     }
   11761             : 
   11762             :     /* Loop until we get a result <= rlen */
   11763             :     do
   11764             :     {
   11765             :         NumericDigit *res_digits;
   11766             :         uint64      rand;
   11767             :         int         whole_ndigits;
   11768             : 
   11769       33420 :         alloc_var(result, res_ndigits);
   11770       33420 :         result->sign = NUMERIC_POS;
   11771       33420 :         result->weight = rlen.weight;
   11772       33420 :         result->dscale = rscale;
   11773       33420 :         res_digits = result->digits;
   11774             : 
   11775             :         /*
   11776             :          * Set the first rlen64_ndigits using a random value in [0, rlen64].
   11777             :          *
   11778             :          * If this is the whole result, and rscale is not a multiple of
   11779             :          * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
   11780             :          * multiple of pow10.
   11781             :          */
   11782       33420 :         if (rlen64_ndigits == res_ndigits && pow10 != 1)
   11783       21132 :             rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
   11784             :         else
   11785       12288 :             rand = pg_prng_uint64_range(state, 0, rlen64);
   11786             : 
   11787      109632 :         for (i = rlen64_ndigits - 1; i >= 0; i--)
   11788             :         {
   11789       76212 :             res_digits[i] = (NumericDigit) (rand % NBASE);
   11790       76212 :             rand = rand / NBASE;
   11791             :         }
   11792             : 
   11793             :         /*
   11794             :          * Set the remaining digits to random values in range [0, NBASE),
   11795             :          * noting that the last digit needs to be a multiple of pow10.
   11796             :          */
   11797       33420 :         whole_ndigits = res_ndigits;
   11798       33420 :         if (pow10 != 1)
   11799       33210 :             whole_ndigits--;
   11800             : 
   11801             :         /* Set whole digits in groups of 4 for best performance */
   11802       33420 :         i = rlen64_ndigits;
   11803       33480 :         while (i < whole_ndigits - 3)
   11804             :         {
   11805          60 :             rand = pg_prng_uint64_range(state, 0,
   11806             :                                         (uint64) NBASE * NBASE * NBASE * NBASE - 1);
   11807          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11808          60 :             rand = rand / NBASE;
   11809          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11810          60 :             rand = rand / NBASE;
   11811          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11812          60 :             rand = rand / NBASE;
   11813          60 :             res_digits[i++] = (NumericDigit) rand;
   11814             :         }
   11815             : 
   11816             :         /* Remaining whole digits */
   11817       33630 :         while (i < whole_ndigits)
   11818             :         {
   11819         210 :             rand = pg_prng_uint64_range(state, 0, NBASE - 1);
   11820         210 :             res_digits[i++] = (NumericDigit) rand;
   11821             :         }
   11822             : 
   11823             :         /* Final partial digit (multiple of pow10) */
   11824       33420 :         if (i < res_ndigits)
   11825             :         {
   11826       12078 :             rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
   11827       12078 :             res_digits[i] = (NumericDigit) rand;
   11828             :         }
   11829             : 
   11830             :         /* Remove leading/trailing zeroes */
   11831       33420 :         strip_var(result);
   11832             : 
   11833             :         /* If result > rlen, try again */
   11834             : 
   11835       33420 :     } while (cmp_var(result, &rlen) > 0);
   11836             : 
   11837             :     /* Offset the result to the required range */
   11838       33420 :     add_var(result, rmin, result);
   11839             : 
   11840       33420 :     free_var(&rlen);
   11841             : }
   11842             : 
   11843             : 
   11844             : /* ----------------------------------------------------------------------
   11845             :  *
   11846             :  * Following are the lowest level functions that operate unsigned
   11847             :  * on the variable level
   11848             :  *
   11849             :  * ----------------------------------------------------------------------
   11850             :  */
   11851             : 
   11852             : 
   11853             : /* ----------
   11854             :  * cmp_abs() -
   11855             :  *
   11856             :  *  Compare the absolute values of var1 and var2
   11857             :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11858             :  *              0  for ABS(var1) == ABS(var2)
   11859             :  *              1  for ABS(var1) > ABS(var2)
   11860             :  * ----------
   11861             :  */
   11862             : static int
   11863      358926 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11864             : {
   11865      717852 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11866      358926 :                           var2->digits, var2->ndigits, var2->weight);
   11867             : }
   11868             : 
   11869             : /* ----------
   11870             :  * cmp_abs_common() -
   11871             :  *
   11872             :  *  Main routine of cmp_abs(). This function can be used by both
   11873             :  *  NumericVar and Numeric.
   11874             :  * ----------
   11875             :  */
   11876             : static int
   11877     6238692 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11878             :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11879             : {
   11880     6238692 :     int         i1 = 0;
   11881     6238692 :     int         i2 = 0;
   11882             : 
   11883             :     /* Check any digits before the first common digit */
   11884             : 
   11885     6238692 :     while (var1weight > var2weight && i1 < var1ndigits)
   11886             :     {
   11887       29018 :         if (var1digits[i1++] != 0)
   11888       29018 :             return 1;
   11889           0 :         var1weight--;
   11890             :     }
   11891     6209674 :     while (var2weight > var1weight && i2 < var2ndigits)
   11892             :     {
   11893       32756 :         if (var2digits[i2++] != 0)
   11894       32756 :             return -1;
   11895           0 :         var2weight--;
   11896             :     }
   11897             : 
   11898             :     /* At this point, either w1 == w2 or we've run out of digits */
   11899             : 
   11900     6176918 :     if (var1weight == var2weight)
   11901             :     {
   11902    11499820 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11903             :         {
   11904     7757012 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11905             : 
   11906     7757012 :             if (stat)
   11907             :             {
   11908     2427700 :                 if (stat > 0)
   11909     1606040 :                     return 1;
   11910      821660 :                 return -1;
   11911             :             }
   11912             :         }
   11913             :     }
   11914             : 
   11915             :     /*
   11916             :      * At this point, we've run out of digits on one side or the other; so any
   11917             :      * remaining nonzero digits imply that side is larger
   11918             :      */
   11919     3749518 :     while (i1 < var1ndigits)
   11920             :     {
   11921        8268 :         if (var1digits[i1++] != 0)
   11922        7968 :             return 1;
   11923             :     }
   11924     3741502 :     while (i2 < var2ndigits)
   11925             :     {
   11926        1192 :         if (var2digits[i2++] != 0)
   11927         940 :             return -1;
   11928             :     }
   11929             : 
   11930     3740310 :     return 0;
   11931             : }
   11932             : 
   11933             : 
   11934             : /*
   11935             :  * add_abs() -
   11936             :  *
   11937             :  *  Add the absolute values of two variables into result.
   11938             :  *  result might point to one of the operands without danger.
   11939             :  */
   11940             : static void
   11941      330704 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11942             : {
   11943             :     NumericDigit *res_buf;
   11944             :     NumericDigit *res_digits;
   11945             :     int         res_ndigits;
   11946             :     int         res_weight;
   11947             :     int         res_rscale,
   11948             :                 rscale1,
   11949             :                 rscale2;
   11950             :     int         res_dscale;
   11951             :     int         i,
   11952             :                 i1,
   11953             :                 i2;
   11954      330704 :     int         carry = 0;
   11955             : 
   11956             :     /* copy these values into local vars for speed in inner loop */
   11957      330704 :     int         var1ndigits = var1->ndigits;
   11958      330704 :     int         var2ndigits = var2->ndigits;
   11959      330704 :     NumericDigit *var1digits = var1->digits;
   11960      330704 :     NumericDigit *var2digits = var2->digits;
   11961             : 
   11962      330704 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11963             : 
   11964      330704 :     res_dscale = Max(var1->dscale, var2->dscale);
   11965             : 
   11966             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11967      330704 :     rscale1 = var1->ndigits - var1->weight - 1;
   11968      330704 :     rscale2 = var2->ndigits - var2->weight - 1;
   11969      330704 :     res_rscale = Max(rscale1, rscale2);
   11970             : 
   11971      330704 :     res_ndigits = res_rscale + res_weight + 1;
   11972      330704 :     if (res_ndigits <= 0)
   11973           0 :         res_ndigits = 1;
   11974             : 
   11975      330704 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11976      330704 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11977      330704 :     res_digits = res_buf + 1;
   11978             : 
   11979      330704 :     i1 = res_rscale + var1->weight + 1;
   11980      330704 :     i2 = res_rscale + var2->weight + 1;
   11981     3314500 :     for (i = res_ndigits - 1; i >= 0; i--)
   11982             :     {
   11983     2983796 :         i1--;
   11984     2983796 :         i2--;
   11985     2983796 :         if (i1 >= 0 && i1 < var1ndigits)
   11986     1316942 :             carry += var1digits[i1];
   11987     2983796 :         if (i2 >= 0 && i2 < var2ndigits)
   11988     1037256 :             carry += var2digits[i2];
   11989             : 
   11990     2983796 :         if (carry >= NBASE)
   11991             :         {
   11992      233830 :             res_digits[i] = carry - NBASE;
   11993      233830 :             carry = 1;
   11994             :         }
   11995             :         else
   11996             :         {
   11997     2749966 :             res_digits[i] = carry;
   11998     2749966 :             carry = 0;
   11999             :         }
   12000             :     }
   12001             : 
   12002             :     Assert(carry == 0);         /* else we failed to allow for carry out */
   12003             : 
   12004      330704 :     digitbuf_free(result->buf);
   12005      330704 :     result->ndigits = res_ndigits;
   12006      330704 :     result->buf = res_buf;
   12007      330704 :     result->digits = res_digits;
   12008      330704 :     result->weight = res_weight;
   12009      330704 :     result->dscale = res_dscale;
   12010             : 
   12011             :     /* Remove leading/trailing zeroes */
   12012      330704 :     strip_var(result);
   12013      330704 : }
   12014             : 
   12015             : 
   12016             : /*
   12017             :  * sub_abs()
   12018             :  *
   12019             :  *  Subtract the absolute value of var2 from the absolute value of var1
   12020             :  *  and store in result. result might point to one of the operands
   12021             :  *  without danger.
   12022             :  *
   12023             :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   12024             :  */
   12025             : static void
   12026      323918 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   12027             : {
   12028             :     NumericDigit *res_buf;
   12029             :     NumericDigit *res_digits;
   12030             :     int         res_ndigits;
   12031             :     int         res_weight;
   12032             :     int         res_rscale,
   12033             :                 rscale1,
   12034             :                 rscale2;
   12035             :     int         res_dscale;
   12036             :     int         i,
   12037             :                 i1,
   12038             :                 i2;
   12039      323918 :     int         borrow = 0;
   12040             : 
   12041             :     /* copy these values into local vars for speed in inner loop */
   12042      323918 :     int         var1ndigits = var1->ndigits;
   12043      323918 :     int         var2ndigits = var2->ndigits;
   12044      323918 :     NumericDigit *var1digits = var1->digits;
   12045      323918 :     NumericDigit *var2digits = var2->digits;
   12046             : 
   12047      323918 :     res_weight = var1->weight;
   12048             : 
   12049      323918 :     res_dscale = Max(var1->dscale, var2->dscale);
   12050             : 
   12051             :     /* Note: here we are figuring rscale in base-NBASE digits */
   12052      323918 :     rscale1 = var1->ndigits - var1->weight - 1;
   12053      323918 :     rscale2 = var2->ndigits - var2->weight - 1;
   12054      323918 :     res_rscale = Max(rscale1, rscale2);
   12055             : 
   12056      323918 :     res_ndigits = res_rscale + res_weight + 1;
   12057      323918 :     if (res_ndigits <= 0)
   12058           0 :         res_ndigits = 1;
   12059             : 
   12060      323918 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   12061      323918 :     res_buf[0] = 0;             /* spare digit for later rounding */
   12062      323918 :     res_digits = res_buf + 1;
   12063             : 
   12064      323918 :     i1 = res_rscale + var1->weight + 1;
   12065      323918 :     i2 = res_rscale + var2->weight + 1;
   12066     4567962 :     for (i = res_ndigits - 1; i >= 0; i--)
   12067             :     {
   12068     4244044 :         i1--;
   12069     4244044 :         i2--;
   12070     4244044 :         if (i1 >= 0 && i1 < var1ndigits)
   12071     3824288 :             borrow += var1digits[i1];
   12072     4244044 :         if (i2 >= 0 && i2 < var2ndigits)
   12073     3726238 :             borrow -= var2digits[i2];
   12074             : 
   12075     4244044 :         if (borrow < 0)
   12076             :         {
   12077      466620 :             res_digits[i] = borrow + NBASE;
   12078      466620 :             borrow = -1;
   12079             :         }
   12080             :         else
   12081             :         {
   12082     3777424 :             res_digits[i] = borrow;
   12083     3777424 :             borrow = 0;
   12084             :         }
   12085             :     }
   12086             : 
   12087             :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   12088             : 
   12089      323918 :     digitbuf_free(result->buf);
   12090      323918 :     result->ndigits = res_ndigits;
   12091      323918 :     result->buf = res_buf;
   12092      323918 :     result->digits = res_digits;
   12093      323918 :     result->weight = res_weight;
   12094      323918 :     result->dscale = res_dscale;
   12095             : 
   12096             :     /* Remove leading/trailing zeroes */
   12097      323918 :     strip_var(result);
   12098      323918 : }
   12099             : 
   12100             : /*
   12101             :  * round_var
   12102             :  *
   12103             :  * Round the value of a variable to no more than rscale decimal digits
   12104             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   12105             :  * rounding before the decimal point.
   12106             :  */
   12107             : static void
   12108      227056 : round_var(NumericVar *var, int rscale)
   12109             : {
   12110      227056 :     NumericDigit *digits = var->digits;
   12111             :     int         di;
   12112             :     int         ndigits;
   12113             :     int         carry;
   12114             : 
   12115      227056 :     var->dscale = rscale;
   12116             : 
   12117             :     /* decimal digits wanted */
   12118      227056 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   12119             : 
   12120             :     /*
   12121             :      * If di = 0, the value loses all digits, but could round up to 1 if its
   12122             :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   12123             :      */
   12124      227056 :     if (di < 0)
   12125             :     {
   12126         104 :         var->ndigits = 0;
   12127         104 :         var->weight = 0;
   12128         104 :         var->sign = NUMERIC_POS;
   12129             :     }
   12130             :     else
   12131             :     {
   12132             :         /* NBASE digits wanted */
   12133      226952 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   12134             : 
   12135             :         /* 0, or number of decimal digits to keep in last NBASE digit */
   12136      226952 :         di %= DEC_DIGITS;
   12137             : 
   12138      226952 :         if (ndigits < var->ndigits ||
   12139       21374 :             (ndigits == var->ndigits && di > 0))
   12140             :         {
   12141      208770 :             var->ndigits = ndigits;
   12142             : 
   12143             : #if DEC_DIGITS == 1
   12144             :             /* di must be zero */
   12145             :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   12146             : #else
   12147      208770 :             if (di == 0)
   12148      167084 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   12149             :             else
   12150             :             {
   12151             :                 /* Must round within last NBASE digit */
   12152             :                 int         extra,
   12153             :                             pow10;
   12154             : 
   12155             : #if DEC_DIGITS == 4
   12156       41686 :                 pow10 = round_powers[di];
   12157             : #elif DEC_DIGITS == 2
   12158             :                 pow10 = 10;
   12159             : #else
   12160             : #error unsupported NBASE
   12161             : #endif
   12162       41686 :                 extra = digits[--ndigits] % pow10;
   12163       41686 :                 digits[ndigits] -= extra;
   12164       41686 :                 carry = 0;
   12165       41686 :                 if (extra >= pow10 / 2)
   12166             :                 {
   12167       19486 :                     pow10 += digits[ndigits];
   12168       19486 :                     if (pow10 >= NBASE)
   12169             :                     {
   12170         812 :                         pow10 -= NBASE;
   12171         812 :                         carry = 1;
   12172             :                     }
   12173       19486 :                     digits[ndigits] = pow10;
   12174             :                 }
   12175             :             }
   12176             : #endif
   12177             : 
   12178             :             /* Propagate carry if needed */
   12179      243886 :             while (carry)
   12180             :             {
   12181       35116 :                 carry += digits[--ndigits];
   12182       35116 :                 if (carry >= NBASE)
   12183             :                 {
   12184       24726 :                     digits[ndigits] = carry - NBASE;
   12185       24726 :                     carry = 1;
   12186             :                 }
   12187             :                 else
   12188             :                 {
   12189       10390 :                     digits[ndigits] = carry;
   12190       10390 :                     carry = 0;
   12191             :                 }
   12192             :             }
   12193             : 
   12194      208770 :             if (ndigits < 0)
   12195             :             {
   12196             :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   12197             :                 Assert(var->digits > var->buf);
   12198          96 :                 var->digits--;
   12199          96 :                 var->ndigits++;
   12200          96 :                 var->weight++;
   12201             :             }
   12202             :         }
   12203             :     }
   12204      227056 : }
   12205             : 
   12206             : /*
   12207             :  * trunc_var
   12208             :  *
   12209             :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   12210             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   12211             :  * truncation before the decimal point.
   12212             :  */
   12213             : static void
   12214       60904 : trunc_var(NumericVar *var, int rscale)
   12215             : {
   12216             :     int         di;
   12217             :     int         ndigits;
   12218             : 
   12219       60904 :     var->dscale = rscale;
   12220             : 
   12221             :     /* decimal digits wanted */
   12222       60904 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   12223             : 
   12224             :     /*
   12225             :      * If di <= 0, the value loses all digits.
   12226             :      */
   12227       60904 :     if (di <= 0)
   12228             :     {
   12229          90 :         var->ndigits = 0;
   12230          90 :         var->weight = 0;
   12231          90 :         var->sign = NUMERIC_POS;
   12232             :     }
   12233             :     else
   12234             :     {
   12235             :         /* NBASE digits wanted */
   12236       60814 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   12237             : 
   12238       60814 :         if (ndigits <= var->ndigits)
   12239             :         {
   12240       60544 :             var->ndigits = ndigits;
   12241             : 
   12242             : #if DEC_DIGITS == 1
   12243             :             /* no within-digit stuff to worry about */
   12244             : #else
   12245             :             /* 0, or number of decimal digits to keep in last NBASE digit */
   12246       60544 :             di %= DEC_DIGITS;
   12247             : 
   12248       60544 :             if (di > 0)
   12249             :             {
   12250             :                 /* Must truncate within last NBASE digit */
   12251         106 :                 NumericDigit *digits = var->digits;
   12252             :                 int         extra,
   12253             :                             pow10;
   12254             : 
   12255             : #if DEC_DIGITS == 4
   12256         106 :                 pow10 = round_powers[di];
   12257             : #elif DEC_DIGITS == 2
   12258             :                 pow10 = 10;
   12259             : #else
   12260             : #error unsupported NBASE
   12261             : #endif
   12262         106 :                 extra = digits[--ndigits] % pow10;
   12263         106 :                 digits[ndigits] -= extra;
   12264             :             }
   12265             : #endif
   12266             :         }
   12267             :     }
   12268       60904 : }
   12269             : 
   12270             : /*
   12271             :  * strip_var
   12272             :  *
   12273             :  * Strip any leading and trailing zeroes from a numeric variable
   12274             :  */
   12275             : static void
   12276     2077984 : strip_var(NumericVar *var)
   12277             : {
   12278     2077984 :     NumericDigit *digits = var->digits;
   12279     2077984 :     int         ndigits = var->ndigits;
   12280             : 
   12281             :     /* Strip leading zeroes */
   12282     3942288 :     while (ndigits > 0 && *digits == 0)
   12283             :     {
   12284     1864304 :         digits++;
   12285     1864304 :         var->weight--;
   12286     1864304 :         ndigits--;
   12287             :     }
   12288             : 
   12289             :     /* Strip trailing zeroes */
   12290     2750000 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   12291      672016 :         ndigits--;
   12292             : 
   12293             :     /* If it's zero, normalize the sign and weight */
   12294     2077984 :     if (ndigits == 0)
   12295             :     {
   12296       36236 :         var->sign = NUMERIC_POS;
   12297       36236 :         var->weight = 0;
   12298             :     }
   12299             : 
   12300     2077984 :     var->digits = digits;
   12301     2077984 :     var->ndigits = ndigits;
   12302     2077984 : }
   12303             : 
   12304             : 
   12305             : /* ----------------------------------------------------------------------
   12306             :  *
   12307             :  * Fast sum accumulator functions
   12308             :  *
   12309             :  * ----------------------------------------------------------------------
   12310             :  */
   12311             : 
   12312             : /*
   12313             :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   12314             :  * are not free'd.
   12315             :  */
   12316             : static void
   12317          18 : accum_sum_reset(NumericSumAccum *accum)
   12318             : {
   12319             :     int         i;
   12320             : 
   12321          18 :     accum->dscale = 0;
   12322          66 :     for (i = 0; i < accum->ndigits; i++)
   12323             :     {
   12324          48 :         accum->pos_digits[i] = 0;
   12325          48 :         accum->neg_digits[i] = 0;
   12326             :     }
   12327          18 : }
   12328             : 
   12329             : /*
   12330             :  * Accumulate a new value.
   12331             :  */
   12332             : static void
   12333     2355644 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   12334             : {
   12335             :     int32      *accum_digits;
   12336             :     int         i,
   12337             :                 val_i;
   12338             :     int         val_ndigits;
   12339             :     NumericDigit *val_digits;
   12340             : 
   12341             :     /*
   12342             :      * If we have accumulated too many values since the last carry
   12343             :      * propagation, do it now, to avoid overflowing.  (We could allow more
   12344             :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   12345             :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   12346             :      * seldom, that the performance difference is negligible.)
   12347             :      */
   12348     2355644 :     if (accum->num_uncarried == NBASE - 1)
   12349         174 :         accum_sum_carry(accum);
   12350             : 
   12351             :     /*
   12352             :      * Adjust the weight or scale of the old value, so that it can accommodate
   12353             :      * the new value.
   12354             :      */
   12355     2355644 :     accum_sum_rescale(accum, val);
   12356             : 
   12357             :     /* */
   12358     2355644 :     if (val->sign == NUMERIC_POS)
   12359     1754966 :         accum_digits = accum->pos_digits;
   12360             :     else
   12361      600678 :         accum_digits = accum->neg_digits;
   12362             : 
   12363             :     /* copy these values into local vars for speed in loop */
   12364     2355644 :     val_ndigits = val->ndigits;
   12365     2355644 :     val_digits = val->digits;
   12366             : 
   12367     2355644 :     i = accum->weight - val->weight;
   12368    11889762 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   12369             :     {
   12370     9534118 :         accum_digits[i] += (int32) val_digits[val_i];
   12371     9534118 :         i++;
   12372             :     }
   12373             : 
   12374     2355644 :     accum->num_uncarried++;
   12375     2355644 : }
   12376             : 
   12377             : /*
   12378             :  * Propagate carries.
   12379             :  */
   12380             : static void
   12381      172716 : accum_sum_carry(NumericSumAccum *accum)
   12382             : {
   12383             :     int         i;
   12384             :     int         ndigits;
   12385             :     int32      *dig;
   12386             :     int32       carry;
   12387      172716 :     int32       newdig = 0;
   12388             : 
   12389             :     /*
   12390             :      * If no new values have been added since last carry propagation, nothing
   12391             :      * to do.
   12392             :      */
   12393      172716 :     if (accum->num_uncarried == 0)
   12394          72 :         return;
   12395             : 
   12396             :     /*
   12397             :      * We maintain that the weight of the accumulator is always one larger
   12398             :      * than needed to hold the current value, before carrying, to make sure
   12399             :      * there is enough space for the possible extra digit when carry is
   12400             :      * propagated.  We cannot expand the buffer here, unless we require
   12401             :      * callers of accum_sum_final() to switch to the right memory context.
   12402             :      */
   12403             :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12404             : 
   12405      172644 :     ndigits = accum->ndigits;
   12406             : 
   12407             :     /* Propagate carry in the positive sum */
   12408      172644 :     dig = accum->pos_digits;
   12409      172644 :     carry = 0;
   12410     2605390 :     for (i = ndigits - 1; i >= 0; i--)
   12411             :     {
   12412     2432746 :         newdig = dig[i] + carry;
   12413     2432746 :         if (newdig >= NBASE)
   12414             :         {
   12415      110790 :             carry = newdig / NBASE;
   12416      110790 :             newdig -= carry * NBASE;
   12417             :         }
   12418             :         else
   12419     2321956 :             carry = 0;
   12420     2432746 :         dig[i] = newdig;
   12421             :     }
   12422             :     /* Did we use up the digit reserved for carry propagation? */
   12423      172644 :     if (newdig > 0)
   12424        2618 :         accum->have_carry_space = false;
   12425             : 
   12426             :     /* And the same for the negative sum */
   12427      172644 :     dig = accum->neg_digits;
   12428      172644 :     carry = 0;
   12429     2605390 :     for (i = ndigits - 1; i >= 0; i--)
   12430             :     {
   12431     2432746 :         newdig = dig[i] + carry;
   12432     2432746 :         if (newdig >= NBASE)
   12433             :         {
   12434         198 :             carry = newdig / NBASE;
   12435         198 :             newdig -= carry * NBASE;
   12436             :         }
   12437             :         else
   12438     2432548 :             carry = 0;
   12439     2432746 :         dig[i] = newdig;
   12440             :     }
   12441      172644 :     if (newdig > 0)
   12442          30 :         accum->have_carry_space = false;
   12443             : 
   12444      172644 :     accum->num_uncarried = 0;
   12445             : }
   12446             : 
   12447             : /*
   12448             :  * Re-scale accumulator to accommodate new value.
   12449             :  *
   12450             :  * If the new value has more digits than the current digit buffers in the
   12451             :  * accumulator, enlarge the buffers.
   12452             :  */
   12453             : static void
   12454     2355644 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   12455             : {
   12456     2355644 :     int         old_weight = accum->weight;
   12457     2355644 :     int         old_ndigits = accum->ndigits;
   12458             :     int         accum_ndigits;
   12459             :     int         accum_weight;
   12460             :     int         accum_rscale;
   12461             :     int         val_rscale;
   12462             : 
   12463     2355644 :     accum_weight = old_weight;
   12464     2355644 :     accum_ndigits = old_ndigits;
   12465             : 
   12466             :     /*
   12467             :      * Does the new value have a larger weight? If so, enlarge the buffers,
   12468             :      * and shift the existing value to the new weight, by adding leading
   12469             :      * zeros.
   12470             :      *
   12471             :      * We enforce that the accumulator always has a weight one larger than
   12472             :      * needed for the inputs, so that we have space for an extra digit at the
   12473             :      * final carry-propagation phase, if necessary.
   12474             :      */
   12475     2355644 :     if (val->weight >= accum_weight)
   12476             :     {
   12477      262178 :         accum_weight = val->weight + 1;
   12478      262178 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   12479             :     }
   12480             : 
   12481             :     /*
   12482             :      * Even though the new value is small, we might've used up the space
   12483             :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   12484             :      * so, enlarge to make room for another one.
   12485             :      */
   12486     2093466 :     else if (!accum->have_carry_space)
   12487             :     {
   12488          68 :         accum_weight++;
   12489          68 :         accum_ndigits++;
   12490             :     }
   12491             : 
   12492             :     /* Is the new value wider on the right side? */
   12493     2355644 :     accum_rscale = accum_ndigits - accum_weight - 1;
   12494     2355644 :     val_rscale = val->ndigits - val->weight - 1;
   12495     2355644 :     if (val_rscale > accum_rscale)
   12496      172186 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   12497             : 
   12498     2355644 :     if (accum_ndigits != old_ndigits ||
   12499             :         accum_weight != old_weight)
   12500             :     {
   12501             :         int32      *new_pos_digits;
   12502             :         int32      *new_neg_digits;
   12503             :         int         weightdiff;
   12504             : 
   12505      262510 :         weightdiff = accum_weight - old_weight;
   12506             : 
   12507      262510 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   12508      262510 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   12509             : 
   12510      262510 :         if (accum->pos_digits)
   12511             :         {
   12512       90394 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   12513             :                    old_ndigits * sizeof(int32));
   12514       90394 :             pfree(accum->pos_digits);
   12515             : 
   12516       90394 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   12517             :                    old_ndigits * sizeof(int32));
   12518       90394 :             pfree(accum->neg_digits);
   12519             :         }
   12520             : 
   12521      262510 :         accum->pos_digits = new_pos_digits;
   12522      262510 :         accum->neg_digits = new_neg_digits;
   12523             : 
   12524      262510 :         accum->weight = accum_weight;
   12525      262510 :         accum->ndigits = accum_ndigits;
   12526             : 
   12527             :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12528      262510 :         accum->have_carry_space = true;
   12529             :     }
   12530             : 
   12531     2355644 :     if (val->dscale > accum->dscale)
   12532         300 :         accum->dscale = val->dscale;
   12533     2355644 : }
   12534             : 
   12535             : /*
   12536             :  * Return the current value of the accumulator.  This perform final carry
   12537             :  * propagation, and adds together the positive and negative sums.
   12538             :  *
   12539             :  * Unlike all the other routines, the caller is not required to switch to
   12540             :  * the memory context that holds the accumulator.
   12541             :  */
   12542             : static void
   12543      172542 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   12544             : {
   12545             :     int         i;
   12546             :     NumericVar  pos_var;
   12547             :     NumericVar  neg_var;
   12548             : 
   12549      172542 :     if (accum->ndigits == 0)
   12550             :     {
   12551           0 :         set_var_from_var(&const_zero, result);
   12552           0 :         return;
   12553             :     }
   12554             : 
   12555             :     /* Perform final carry */
   12556      172542 :     accum_sum_carry(accum);
   12557             : 
   12558             :     /* Create NumericVars representing the positive and negative sums */
   12559      172542 :     init_var(&pos_var);
   12560      172542 :     init_var(&neg_var);
   12561             : 
   12562      172542 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   12563      172542 :     pos_var.weight = neg_var.weight = accum->weight;
   12564      172542 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   12565      172542 :     pos_var.sign = NUMERIC_POS;
   12566      172542 :     neg_var.sign = NUMERIC_NEG;
   12567             : 
   12568      172542 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   12569      172542 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   12570             : 
   12571     2604874 :     for (i = 0; i < accum->ndigits; i++)
   12572             :     {
   12573             :         Assert(accum->pos_digits[i] < NBASE);
   12574     2432332 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   12575             : 
   12576             :         Assert(accum->neg_digits[i] < NBASE);
   12577     2432332 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   12578             :     }
   12579             : 
   12580             :     /* And add them together */
   12581      172542 :     add_var(&pos_var, &neg_var, result);
   12582             : 
   12583             :     /* Remove leading/trailing zeroes */
   12584      172542 :     strip_var(result);
   12585             : }
   12586             : 
   12587             : /*
   12588             :  * Copy an accumulator's state.
   12589             :  *
   12590             :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   12591             :  * freeing old values.
   12592             :  */
   12593             : static void
   12594          42 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   12595             : {
   12596          42 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12597          42 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12598             : 
   12599          42 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12600          42 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12601          42 :     dst->num_uncarried = src->num_uncarried;
   12602          42 :     dst->ndigits = src->ndigits;
   12603          42 :     dst->weight = src->weight;
   12604          42 :     dst->dscale = src->dscale;
   12605          42 : }
   12606             : 
   12607             : /*
   12608             :  * Add the current value of 'accum2' into 'accum'.
   12609             :  */
   12610             : static void
   12611          18 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12612             : {
   12613             :     NumericVar  tmp_var;
   12614             : 
   12615          18 :     init_var(&tmp_var);
   12616             : 
   12617          18 :     accum_sum_final(accum2, &tmp_var);
   12618          18 :     accum_sum_add(accum, &tmp_var);
   12619             : 
   12620          18 :     free_var(&tmp_var);
   12621          18 : }

Generated by: LCOV version 1.14