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

Generated by: LCOV version 1.16