LCOV - code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 3795 4011 94.6 %
Date: 2025-08-20 10:17:27 Functions: 210 211 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 "common/int128.h"
      32             : #include "funcapi.h"
      33             : #include "lib/hyperloglog.h"
      34             : #include "libpq/pqformat.h"
      35             : #include "miscadmin.h"
      36             : #include "nodes/nodeFuncs.h"
      37             : #include "nodes/supportnodes.h"
      38             : #include "optimizer/optimizer.h"
      39             : #include "utils/array.h"
      40             : #include "utils/builtins.h"
      41             : #include "utils/float.h"
      42             : #include "utils/guc.h"
      43             : #include "utils/numeric.h"
      44             : #include "utils/pg_lsn.h"
      45             : #include "utils/sortsupport.h"
      46             : 
      47             : /* ----------
      48             :  * Uncomment the following to enable compilation of dump_numeric()
      49             :  * and dump_var() and to get a dump of any result produced by make_result().
      50             :  * ----------
      51             : #define NUMERIC_DEBUG
      52             :  */
      53             : 
      54             : 
      55             : /* ----------
      56             :  * Local data types
      57             :  *
      58             :  * Numeric values are represented in a base-NBASE floating point format.
      59             :  * Each "digit" ranges from 0 to NBASE-1.  The type NumericDigit is signed
      60             :  * and wide enough to store a digit.  We assume that NBASE*NBASE can fit in
      61             :  * an int.  Although the purely calculational routines could handle any even
      62             :  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
      63             :  * in NBASE a power of ten, so that I/O conversions and decimal rounding
      64             :  * are easy.  Also, it's actually more efficient if NBASE is rather less than
      65             :  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var to
      66             :  * postpone processing carries.
      67             :  *
      68             :  * Values of NBASE other than 10000 are considered of historical interest only
      69             :  * and are no longer supported in any sense; no mechanism exists for the client
      70             :  * to discover the base, so every client supporting binary mode expects the
      71             :  * base-10000 format.  If you plan to change this, also note the numeric
      72             :  * abbreviation code, which assumes NBASE=10000.
      73             :  * ----------
      74             :  */
      75             : 
      76             : #if 0
      77             : #define NBASE       10
      78             : #define HALF_NBASE  5
      79             : #define DEC_DIGITS  1           /* decimal digits per NBASE digit */
      80             : #define MUL_GUARD_DIGITS    4   /* these are measured in NBASE digits */
      81             : #define DIV_GUARD_DIGITS    8
      82             : 
      83             : typedef signed char NumericDigit;
      84             : #endif
      85             : 
      86             : #if 0
      87             : #define NBASE       100
      88             : #define HALF_NBASE  50
      89             : #define DEC_DIGITS  2           /* decimal digits per NBASE digit */
      90             : #define MUL_GUARD_DIGITS    3   /* these are measured in NBASE digits */
      91             : #define DIV_GUARD_DIGITS    6
      92             : 
      93             : typedef signed char NumericDigit;
      94             : #endif
      95             : 
      96             : #if 1
      97             : #define NBASE       10000
      98             : #define HALF_NBASE  5000
      99             : #define DEC_DIGITS  4           /* decimal digits per NBASE digit */
     100             : #define MUL_GUARD_DIGITS    2   /* these are measured in NBASE digits */
     101             : #define DIV_GUARD_DIGITS    4
     102             : 
     103             : typedef int16 NumericDigit;
     104             : #endif
     105             : 
     106             : #define NBASE_SQR   (NBASE * NBASE)
     107             : 
     108             : /*
     109             :  * The Numeric type as stored on disk.
     110             :  *
     111             :  * If the high bits of the first word of a NumericChoice (n_header, or
     112             :  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
     113             :  * numeric follows the NumericShort format; if they are NUMERIC_POS or
     114             :  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
     115             :  * the value is a NaN or Infinity.  We currently always store SPECIAL values
     116             :  * using just two bytes (i.e. only n_header), but previous releases used only
     117             :  * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
     118             :  * on disk if a database has been migrated using pg_upgrade.  In either case,
     119             :  * the low-order bits of a special value's header are reserved and currently
     120             :  * should always be set to zero.
     121             :  *
     122             :  * In the NumericShort format, the remaining 14 bits of the header word
     123             :  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
     124             :  * negative), 6 for dynamic scale, and 7 for weight.  In practice, most
     125             :  * commonly-encountered values can be represented this way.
     126             :  *
     127             :  * In the NumericLong format, the remaining 14 bits of the header word
     128             :  * (n_long.n_sign_dscale) represent the display scale; and the weight is
     129             :  * stored separately in n_weight.
     130             :  *
     131             :  * NOTE: by convention, values in the packed form have been stripped of
     132             :  * all leading and trailing zero digits (where a "digit" is of base NBASE).
     133             :  * In particular, if the value is zero, there will be no digits at all!
     134             :  * The weight is arbitrary in that case, but we normally set it to zero.
     135             :  */
     136             : 
     137             : struct NumericShort
     138             : {
     139             :     uint16      n_header;       /* Sign + display scale + weight */
     140             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     141             : };
     142             : 
     143             : struct NumericLong
     144             : {
     145             :     uint16      n_sign_dscale;  /* Sign + display scale */
     146             :     int16       n_weight;       /* Weight of 1st digit  */
     147             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     148             : };
     149             : 
     150             : union NumericChoice
     151             : {
     152             :     uint16      n_header;       /* Header word */
     153             :     struct NumericLong n_long;  /* Long form (4-byte header) */
     154             :     struct NumericShort n_short;    /* Short form (2-byte header) */
     155             : };
     156             : 
     157             : struct NumericData
     158             : {
     159             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     160             :     union NumericChoice choice; /* choice of format */
     161             : };
     162             : 
     163             : 
     164             : /*
     165             :  * Interpretation of high bits.
     166             :  */
     167             : 
     168             : #define NUMERIC_SIGN_MASK   0xC000
     169             : #define NUMERIC_POS         0x0000
     170             : #define NUMERIC_NEG         0x4000
     171             : #define NUMERIC_SHORT       0x8000
     172             : #define NUMERIC_SPECIAL     0xC000
     173             : 
     174             : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
     175             : #define NUMERIC_IS_SHORT(n)     (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
     176             : #define NUMERIC_IS_SPECIAL(n)   (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
     177             : 
     178             : #define NUMERIC_HDRSZ   (VARHDRSZ + sizeof(uint16) + sizeof(int16))
     179             : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
     180             : 
     181             : /*
     182             :  * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
     183             :  * header; otherwise, we want the long one.  Instead of testing against each
     184             :  * value, we can just look at the high bit, for a slight efficiency gain.
     185             :  */
     186             : #define NUMERIC_HEADER_IS_SHORT(n)  (((n)->choice.n_header & 0x8000) != 0)
     187             : #define NUMERIC_HEADER_SIZE(n) \
     188             :     (VARHDRSZ + sizeof(uint16) + \
     189             :      (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
     190             : 
     191             : /*
     192             :  * Definitions for special values (NaN, positive infinity, negative infinity).
     193             :  *
     194             :  * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
     195             :  * infinity, 11 for negative infinity.  (This makes the sign bit match where
     196             :  * it is in a short-format value, though we make no use of that at present.)
     197             :  * We could mask off the remaining bits before testing the active bits, but
     198             :  * currently those bits must be zeroes, so masking would just add cycles.
     199             :  */
     200             : #define NUMERIC_EXT_SIGN_MASK   0xF000  /* high bits plus NaN/Inf flag bits */
     201             : #define NUMERIC_NAN             0xC000
     202             : #define NUMERIC_PINF            0xD000
     203             : #define NUMERIC_NINF            0xF000
     204             : #define NUMERIC_INF_SIGN_MASK   0x2000
     205             : 
     206             : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
     207             : #define NUMERIC_IS_NAN(n)       ((n)->choice.n_header == NUMERIC_NAN)
     208             : #define NUMERIC_IS_PINF(n)      ((n)->choice.n_header == NUMERIC_PINF)
     209             : #define NUMERIC_IS_NINF(n)      ((n)->choice.n_header == NUMERIC_NINF)
     210             : #define NUMERIC_IS_INF(n) \
     211             :     (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
     212             : 
     213             : /*
     214             :  * Short format definitions.
     215             :  */
     216             : 
     217             : #define NUMERIC_SHORT_SIGN_MASK         0x2000
     218             : #define NUMERIC_SHORT_DSCALE_MASK       0x1F80
     219             : #define NUMERIC_SHORT_DSCALE_SHIFT      7
     220             : #define NUMERIC_SHORT_DSCALE_MAX        \
     221             :     (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
     222             : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK  0x0040
     223             : #define NUMERIC_SHORT_WEIGHT_MASK       0x003F
     224             : #define NUMERIC_SHORT_WEIGHT_MAX        NUMERIC_SHORT_WEIGHT_MASK
     225             : #define NUMERIC_SHORT_WEIGHT_MIN        (-(NUMERIC_SHORT_WEIGHT_MASK+1))
     226             : 
     227             : /*
     228             :  * Extract sign, display scale, weight.  These macros extract field values
     229             :  * suitable for the NumericVar format from the Numeric (on-disk) format.
     230             :  *
     231             :  * Note that we don't trouble to ensure that dscale and weight read as zero
     232             :  * for an infinity; however, that doesn't matter since we never convert
     233             :  * "special" numerics to NumericVar form.  Only the constants defined below
     234             :  * (const_nan, etc) ever represent a non-finite value as a NumericVar.
     235             :  */
     236             : 
     237             : #define NUMERIC_DSCALE_MASK         0x3FFF
     238             : #define NUMERIC_DSCALE_MAX          NUMERIC_DSCALE_MASK
     239             : 
     240             : #define NUMERIC_SIGN(n) \
     241             :     (NUMERIC_IS_SHORT(n) ? \
     242             :         (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
     243             :          NUMERIC_NEG : NUMERIC_POS) : \
     244             :         (NUMERIC_IS_SPECIAL(n) ? \
     245             :          NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
     246             : #define NUMERIC_DSCALE(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     247             :     ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
     248             :         >> NUMERIC_SHORT_DSCALE_SHIFT \
     249             :     : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
     250             : #define NUMERIC_WEIGHT(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     251             :     (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
     252             :         ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
     253             :      | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
     254             :     : ((n)->choice.n_long.n_weight))
     255             : 
     256             : /*
     257             :  * Maximum weight of a stored Numeric value (based on the use of int16 for the
     258             :  * weight in NumericLong).  Note that intermediate values held in NumericVar
     259             :  * and NumericSumAccum variables may have much larger weights.
     260             :  */
     261             : #define NUMERIC_WEIGHT_MAX          PG_INT16_MAX
     262             : 
     263             : /* ----------
     264             :  * NumericVar is the format we use for arithmetic.  The digit-array part
     265             :  * is the same as the NumericData storage format, but the header is more
     266             :  * complex.
     267             :  *
     268             :  * The value represented by a NumericVar is determined by the sign, weight,
     269             :  * ndigits, and digits[] array.  If it is a "special" value (NaN or Inf)
     270             :  * then only the sign field matters; ndigits should be zero, and the weight
     271             :  * and dscale fields are ignored.
     272             :  *
     273             :  * Note: the first digit of a NumericVar's value is assumed to be multiplied
     274             :  * by NBASE ** weight.  Another way to say it is that there are weight+1
     275             :  * digits before the decimal point.  It is possible to have weight < 0.
     276             :  *
     277             :  * buf points at the physical start of the palloc'd digit buffer for the
     278             :  * NumericVar.  digits points at the first digit in actual use (the one
     279             :  * with the specified weight).  We normally leave an unused digit or two
     280             :  * (preset to zeroes) between buf and digits, so that there is room to store
     281             :  * a carry out of the top digit without reallocating space.  We just need to
     282             :  * decrement digits (and increment weight) to make room for the carry digit.
     283             :  * (There is no such extra space in a numeric value stored in the database,
     284             :  * only in a NumericVar in memory.)
     285             :  *
     286             :  * If buf is NULL then the digit buffer isn't actually palloc'd and should
     287             :  * not be freed --- see the constants below for an example.
     288             :  *
     289             :  * dscale, or display scale, is the nominal precision expressed as number
     290             :  * of digits after the decimal point (it must always be >= 0 at present).
     291             :  * dscale may be more than the number of physically stored fractional digits,
     292             :  * implying that we have suppressed storage of significant trailing zeroes.
     293             :  * It should never be less than the number of stored digits, since that would
     294             :  * imply hiding digits that are present.  NOTE that dscale is always expressed
     295             :  * in *decimal* digits, and so it may correspond to a fractional number of
     296             :  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
     297             :  *
     298             :  * rscale, or result scale, is the target precision for a computation.
     299             :  * Like dscale it is expressed as number of *decimal* digits after the decimal
     300             :  * point, and is always >= 0 at present.
     301             :  * Note that rscale is not stored in variables --- it's figured on-the-fly
     302             :  * from the dscales of the inputs.
     303             :  *
     304             :  * While we consistently use "weight" to refer to the base-NBASE weight of
     305             :  * a numeric value, it is convenient in some scale-related calculations to
     306             :  * make use of the base-10 weight (ie, the approximate log10 of the value).
     307             :  * To avoid confusion, such a decimal-units weight is called a "dweight".
     308             :  *
     309             :  * NB: All the variable-level functions are written in a style that makes it
     310             :  * possible to give one and the same variable as argument and destination.
     311             :  * This is feasible because the digit buffer is separate from the variable.
     312             :  * ----------
     313             :  */
     314             : typedef struct NumericVar
     315             : {
     316             :     int         ndigits;        /* # of digits in digits[] - can be 0! */
     317             :     int         weight;         /* weight of first digit */
     318             :     int         sign;           /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
     319             :     int         dscale;         /* display scale */
     320             :     NumericDigit *buf;          /* start of palloc'd space for digits[] */
     321             :     NumericDigit *digits;       /* base-NBASE digits */
     322             : } NumericVar;
     323             : 
     324             : 
     325             : /* ----------
     326             :  * Data for generate_series
     327             :  * ----------
     328             :  */
     329             : typedef struct
     330             : {
     331             :     NumericVar  current;
     332             :     NumericVar  stop;
     333             :     NumericVar  step;
     334             : } generate_series_numeric_fctx;
     335             : 
     336             : 
     337             : /* ----------
     338             :  * Sort support.
     339             :  * ----------
     340             :  */
     341             : typedef struct
     342             : {
     343             :     void       *buf;            /* buffer for short varlenas */
     344             :     int64       input_count;    /* number of non-null values seen */
     345             :     bool        estimating;     /* true if estimating cardinality */
     346             : 
     347             :     hyperLogLogState abbr_card; /* cardinality estimator */
     348             : } NumericSortSupport;
     349             : 
     350             : 
     351             : /* ----------
     352             :  * Fast sum accumulator.
     353             :  *
     354             :  * NumericSumAccum is used to implement SUM(), and other standard aggregates
     355             :  * that track the sum of input values.  It uses 32-bit integers to store the
     356             :  * digits, instead of the normal 16-bit integers (with NBASE=10000).  This
     357             :  * way, we can safely accumulate up to NBASE - 1 values without propagating
     358             :  * carry, before risking overflow of any of the digits.  'num_uncarried'
     359             :  * tracks how many values have been accumulated without propagating carry.
     360             :  *
     361             :  * Positive and negative values are accumulated separately, in 'pos_digits'
     362             :  * and 'neg_digits'.  This is simpler and faster than deciding whether to add
     363             :  * or subtract from the current value, for each new value (see sub_var() for
     364             :  * the logic we avoid by doing this).  Both buffers are of same size, and
     365             :  * have the same weight and scale.  In accum_sum_final(), the positive and
     366             :  * negative sums are added together to produce the final result.
     367             :  *
     368             :  * When a new value has a larger ndigits or weight than the accumulator
     369             :  * currently does, the accumulator is enlarged to accommodate the new value.
     370             :  * We normally have one zero digit reserved for carry propagation, and that
     371             :  * is indicated by the 'have_carry_space' flag.  When accum_sum_carry() uses
     372             :  * up the reserved digit, it clears the 'have_carry_space' flag.  The next
     373             :  * call to accum_sum_add() will enlarge the buffer, to make room for the
     374             :  * extra digit, and set the flag again.
     375             :  *
     376             :  * To initialize a new accumulator, simply reset all fields to zeros.
     377             :  *
     378             :  * The accumulator does not handle NaNs.
     379             :  * ----------
     380             :  */
     381             : typedef struct NumericSumAccum
     382             : {
     383             :     int         ndigits;
     384             :     int         weight;
     385             :     int         dscale;
     386             :     int         num_uncarried;
     387             :     bool        have_carry_space;
     388             :     int32      *pos_digits;
     389             :     int32      *neg_digits;
     390             : } NumericSumAccum;
     391             : 
     392             : 
     393             : /*
     394             :  * We define our own macros for packing and unpacking abbreviated-key
     395             :  * representations, just to have a notational indication that that's
     396             :  * what we're doing.  Now that sizeof(Datum) is always 8, we can rely
     397             :  * on fitting an int64 into Datum.
     398             :  *
     399             :  * The range of abbreviations for finite values is from +PG_INT64_MAX
     400             :  * to -PG_INT64_MAX.  NaN has the abbreviation PG_INT64_MIN, and we
     401             :  * define the sort ordering to make that work out properly (see further
     402             :  * comments below).  PINF and NINF share the abbreviations of the largest
     403             :  * and smallest finite abbreviation classes.
     404             :  */
     405             : #define NumericAbbrevGetDatum(X) Int64GetDatum(X)
     406             : #define DatumGetNumericAbbrev(X) DatumGetInt64(X)
     407             : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT64_MIN)
     408             : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT64_MAX)
     409             : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT64_MAX)
     410             : 
     411             : 
     412             : /* ----------
     413             :  * Some preinitialized constants
     414             :  * ----------
     415             :  */
     416             : static const NumericDigit const_zero_data[1] = {0};
     417             : static const NumericVar const_zero =
     418             : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
     419             : 
     420             : static const NumericDigit const_one_data[1] = {1};
     421             : static const NumericVar const_one =
     422             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
     423             : 
     424             : static const NumericVar const_minus_one =
     425             : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
     426             : 
     427             : static const NumericDigit const_two_data[1] = {2};
     428             : static const NumericVar const_two =
     429             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
     430             : 
     431             : #if DEC_DIGITS == 4
     432             : static const NumericDigit const_zero_point_nine_data[1] = {9000};
     433             : #elif DEC_DIGITS == 2
     434             : static const NumericDigit const_zero_point_nine_data[1] = {90};
     435             : #elif DEC_DIGITS == 1
     436             : static const NumericDigit const_zero_point_nine_data[1] = {9};
     437             : #endif
     438             : static const NumericVar const_zero_point_nine =
     439             : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
     440             : 
     441             : #if DEC_DIGITS == 4
     442             : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
     443             : #elif DEC_DIGITS == 2
     444             : static const NumericDigit const_one_point_one_data[2] = {1, 10};
     445             : #elif DEC_DIGITS == 1
     446             : static const NumericDigit const_one_point_one_data[2] = {1, 1};
     447             : #endif
     448             : static const NumericVar const_one_point_one =
     449             : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
     450             : 
     451             : static const NumericVar const_nan =
     452             : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
     453             : 
     454             : static const NumericVar const_pinf =
     455             : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
     456             : 
     457             : static const NumericVar const_ninf =
     458             : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
     459             : 
     460             : #if DEC_DIGITS == 4
     461             : static const int round_powers[4] = {0, 1000, 100, 10};
     462             : #endif
     463             : 
     464             : 
     465             : /* ----------
     466             :  * Local functions
     467             :  * ----------
     468             :  */
     469             : 
     470             : #ifdef NUMERIC_DEBUG
     471             : static void dump_numeric(const char *str, Numeric num);
     472             : static void dump_var(const char *str, NumericVar *var);
     473             : #else
     474             : #define dump_numeric(s,n)
     475             : #define dump_var(s,v)
     476             : #endif
     477             : 
     478             : #define digitbuf_alloc(ndigits)  \
     479             :     ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
     480             : #define digitbuf_free(buf)  \
     481             :     do { \
     482             :          if ((buf) != NULL) \
     483             :              pfree(buf); \
     484             :     } while (0)
     485             : 
     486             : #define init_var(v)     memset(v, 0, sizeof(NumericVar))
     487             : 
     488             : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
     489             :     (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
     490             : #define NUMERIC_NDIGITS(num) \
     491             :     ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
     492             : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
     493             :     ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
     494             :     (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
     495             :     (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
     496             : 
     497             : static void alloc_var(NumericVar *var, int ndigits);
     498             : static void free_var(NumericVar *var);
     499             : static void zero_var(NumericVar *var);
     500             : 
     501             : static bool set_var_from_str(const char *str, const char *cp,
     502             :                              NumericVar *dest, const char **endptr,
     503             :                              Node *escontext);
     504             : static bool set_var_from_non_decimal_integer_str(const char *str,
     505             :                                                  const char *cp, int sign,
     506             :                                                  int base, NumericVar *dest,
     507             :                                                  const char **endptr,
     508             :                                                  Node *escontext);
     509             : static void set_var_from_num(Numeric num, NumericVar *dest);
     510             : static void init_var_from_num(Numeric num, NumericVar *dest);
     511             : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
     512             : static char *get_str_from_var(const NumericVar *var);
     513             : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
     514             : 
     515             : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
     516             : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
     517             : 
     518             : static Numeric duplicate_numeric(Numeric num);
     519             : static Numeric make_result(const NumericVar *var);
     520             : static Numeric make_result_opt_error(const NumericVar *var, bool *have_error);
     521             : 
     522             : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
     523             : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
     524             : 
     525             : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
     526             : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
     527             : static void int64_to_numericvar(int64 val, NumericVar *var);
     528             : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
     529             : static void int128_to_numericvar(INT128 val, NumericVar *var);
     530             : static double numericvar_to_double_no_overflow(const NumericVar *var);
     531             : 
     532             : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
     533             : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
     534             : static int  numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
     535             : static int  numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
     536             : 
     537             : static Datum numeric_abbrev_convert_var(const NumericVar *var,
     538             :                                         NumericSortSupport *nss);
     539             : 
     540             : static int  cmp_numerics(Numeric num1, Numeric num2);
     541             : static int  cmp_var(const NumericVar *var1, const NumericVar *var2);
     542             : static int  cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
     543             :                            int var1weight, int var1sign,
     544             :                            const NumericDigit *var2digits, int var2ndigits,
     545             :                            int var2weight, int var2sign);
     546             : static void add_var(const NumericVar *var1, const NumericVar *var2,
     547             :                     NumericVar *result);
     548             : static void sub_var(const NumericVar *var1, const NumericVar *var2,
     549             :                     NumericVar *result);
     550             : static void mul_var(const NumericVar *var1, const NumericVar *var2,
     551             :                     NumericVar *result,
     552             :                     int rscale);
     553             : static void mul_var_short(const NumericVar *var1, const NumericVar *var2,
     554             :                           NumericVar *result);
     555             : static void div_var(const NumericVar *var1, const NumericVar *var2,
     556             :                     NumericVar *result, int rscale, bool round, bool exact);
     557             : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
     558             :                         NumericVar *result, int rscale, bool round);
     559             : #ifdef HAVE_INT128
     560             : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
     561             :                           NumericVar *result, int rscale, bool round);
     562             : #endif
     563             : static int  select_div_scale(const NumericVar *var1, const NumericVar *var2);
     564             : static void mod_var(const NumericVar *var1, const NumericVar *var2,
     565             :                     NumericVar *result);
     566             : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
     567             :                         NumericVar *quot, NumericVar *rem);
     568             : static void ceil_var(const NumericVar *var, NumericVar *result);
     569             : static void floor_var(const NumericVar *var, NumericVar *result);
     570             : 
     571             : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
     572             :                     NumericVar *result);
     573             : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
     574             : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
     575             : static int  estimate_ln_dweight(const NumericVar *var);
     576             : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
     577             : static void log_var(const NumericVar *base, const NumericVar *num,
     578             :                     NumericVar *result);
     579             : static void power_var(const NumericVar *base, const NumericVar *exp,
     580             :                       NumericVar *result);
     581             : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
     582             :                           NumericVar *result);
     583             : static void power_ten_int(int exp, NumericVar *result);
     584             : static void random_var(pg_prng_state *state, const NumericVar *rmin,
     585             :                        const NumericVar *rmax, NumericVar *result);
     586             : 
     587             : static int  cmp_abs(const NumericVar *var1, const NumericVar *var2);
     588             : static int  cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
     589             :                            int var1weight,
     590             :                            const NumericDigit *var2digits, int var2ndigits,
     591             :                            int var2weight);
     592             : static void add_abs(const NumericVar *var1, const NumericVar *var2,
     593             :                     NumericVar *result);
     594             : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
     595             :                     NumericVar *result);
     596             : static void round_var(NumericVar *var, int rscale);
     597             : static void trunc_var(NumericVar *var, int rscale);
     598             : static void strip_var(NumericVar *var);
     599             : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
     600             :                            const NumericVar *count_var,
     601             :                            NumericVar *result_var);
     602             : 
     603             : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
     604             : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
     605             : static void accum_sum_carry(NumericSumAccum *accum);
     606             : static void accum_sum_reset(NumericSumAccum *accum);
     607             : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
     608             : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
     609             : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
     610             : 
     611             : 
     612             : /* ----------------------------------------------------------------------
     613             :  *
     614             :  * Input-, output- and rounding-functions
     615             :  *
     616             :  * ----------------------------------------------------------------------
     617             :  */
     618             : 
     619             : 
     620             : /*
     621             :  * numeric_in() -
     622             :  *
     623             :  *  Input function for numeric data type
     624             :  */
     625             : Datum
     626      163516 : numeric_in(PG_FUNCTION_ARGS)
     627             : {
     628      163516 :     char       *str = PG_GETARG_CSTRING(0);
     629             : #ifdef NOT_USED
     630             :     Oid         typelem = PG_GETARG_OID(1);
     631             : #endif
     632      163516 :     int32       typmod = PG_GETARG_INT32(2);
     633      163516 :     Node       *escontext = fcinfo->context;
     634             :     Numeric     res;
     635             :     const char *cp;
     636             :     const char *numstart;
     637             :     int         sign;
     638             : 
     639             :     /* Skip leading spaces */
     640      163516 :     cp = str;
     641      187936 :     while (*cp)
     642             :     {
     643      187918 :         if (!isspace((unsigned char) *cp))
     644      163498 :             break;
     645       24420 :         cp++;
     646             :     }
     647             : 
     648             :     /*
     649             :      * Process the number's sign. This duplicates logic in set_var_from_str(),
     650             :      * but it's worth doing here, since it simplifies the handling of
     651             :      * infinities and non-decimal integers.
     652             :      */
     653      163516 :     numstart = cp;
     654      163516 :     sign = NUMERIC_POS;
     655             : 
     656      163516 :     if (*cp == '+')
     657          48 :         cp++;
     658      163468 :     else if (*cp == '-')
     659             :     {
     660        4092 :         sign = NUMERIC_NEG;
     661        4092 :         cp++;
     662             :     }
     663             : 
     664             :     /*
     665             :      * Check for NaN and infinities.  We recognize the same strings allowed by
     666             :      * float8in().
     667             :      *
     668             :      * Since all other legal inputs have a digit or a decimal point after the
     669             :      * sign, we need only check for NaN/infinity if that's not the case.
     670             :      */
     671      163516 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
     672             :     {
     673             :         /*
     674             :          * The number must be NaN or infinity; anything else can only be a
     675             :          * syntax error. Note that NaN mustn't have a sign.
     676             :          */
     677        1796 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     678             :         {
     679         606 :             res = make_result(&const_nan);
     680         606 :             cp = numstart + 3;
     681             :         }
     682        1190 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     683             :         {
     684         492 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     685         492 :             cp += 8;
     686             :         }
     687         698 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
     688             :         {
     689         588 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     690         588 :             cp += 3;
     691             :         }
     692             :         else
     693         110 :             goto invalid_syntax;
     694             : 
     695             :         /*
     696             :          * Check for trailing junk; there should be nothing left but spaces.
     697             :          *
     698             :          * We intentionally do this check before applying the typmod because
     699             :          * we would like to throw any trailing-junk syntax error before any
     700             :          * semantic error resulting from apply_typmod_special().
     701             :          */
     702        1728 :         while (*cp)
     703             :         {
     704          42 :             if (!isspace((unsigned char) *cp))
     705           0 :                 goto invalid_syntax;
     706          42 :             cp++;
     707             :         }
     708             : 
     709        1686 :         if (!apply_typmod_special(res, typmod, escontext))
     710           0 :             PG_RETURN_NULL();
     711             :     }
     712             :     else
     713             :     {
     714             :         /*
     715             :          * We have a normal numeric value, which may be a non-decimal integer
     716             :          * or a regular decimal number.
     717             :          */
     718             :         NumericVar  value;
     719             :         int         base;
     720             :         bool        have_error;
     721             : 
     722      161720 :         init_var(&value);
     723             : 
     724             :         /*
     725             :          * Determine the number's base by looking for a non-decimal prefix
     726             :          * indicator ("0x", "0o", or "0b").
     727             :          */
     728      161720 :         if (cp[0] == '0')
     729             :         {
     730       49628 :             switch (cp[1])
     731             :             {
     732          72 :                 case 'x':
     733             :                 case 'X':
     734          72 :                     base = 16;
     735          72 :                     break;
     736          42 :                 case 'o':
     737             :                 case 'O':
     738          42 :                     base = 8;
     739          42 :                     break;
     740          42 :                 case 'b':
     741             :                 case 'B':
     742          42 :                     base = 2;
     743          42 :                     break;
     744       49472 :                 default:
     745       49472 :                     base = 10;
     746             :             }
     747             :         }
     748             :         else
     749      112092 :             base = 10;
     750             : 
     751             :         /* Parse the rest of the number and apply the sign */
     752      161720 :         if (base == 10)
     753             :         {
     754      161564 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     755          42 :                 PG_RETURN_NULL();
     756      161516 :             value.sign = sign;
     757             :         }
     758             :         else
     759             :         {
     760         156 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
     761             :                                                       &value, &cp, escontext))
     762           0 :                 PG_RETURN_NULL();
     763             :         }
     764             : 
     765             :         /*
     766             :          * Should be nothing left but spaces. As above, throw any typmod error
     767             :          * after finishing syntax check.
     768             :          */
     769      161732 :         while (*cp)
     770             :         {
     771         150 :             if (!isspace((unsigned char) *cp))
     772          72 :                 goto invalid_syntax;
     773          78 :             cp++;
     774             :         }
     775             : 
     776      161582 :         if (!apply_typmod(&value, typmod, escontext))
     777          24 :             PG_RETURN_NULL();
     778             : 
     779      161558 :         res = make_result_opt_error(&value, &have_error);
     780             : 
     781      161558 :         if (have_error)
     782          18 :             ereturn(escontext, (Datum) 0,
     783             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     784             :                      errmsg("value overflows numeric format")));
     785             : 
     786      161540 :         free_var(&value);
     787             :     }
     788             : 
     789      163226 :     PG_RETURN_NUMERIC(res);
     790             : 
     791         182 : invalid_syntax:
     792         182 :     ereturn(escontext, (Datum) 0,
     793             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     794             :              errmsg("invalid input syntax for type %s: \"%s\"",
     795             :                     "numeric", str)));
     796             : }
     797             : 
     798             : 
     799             : /*
     800             :  * numeric_out() -
     801             :  *
     802             :  *  Output function for numeric data type
     803             :  */
     804             : Datum
     805      851658 : numeric_out(PG_FUNCTION_ARGS)
     806             : {
     807      851658 :     Numeric     num = PG_GETARG_NUMERIC(0);
     808             :     NumericVar  x;
     809             :     char       *str;
     810             : 
     811             :     /*
     812             :      * Handle NaN and infinities
     813             :      */
     814      851658 :     if (NUMERIC_IS_SPECIAL(num))
     815             :     {
     816        3612 :         if (NUMERIC_IS_PINF(num))
     817        1040 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     818        2572 :         else if (NUMERIC_IS_NINF(num))
     819         658 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     820             :         else
     821        1914 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     822             :     }
     823             : 
     824             :     /*
     825             :      * Get the number in the variable format.
     826             :      */
     827      848046 :     init_var_from_num(num, &x);
     828             : 
     829      848046 :     str = get_str_from_var(&x);
     830             : 
     831      848046 :     PG_RETURN_CSTRING(str);
     832             : }
     833             : 
     834             : /*
     835             :  * numeric_is_nan() -
     836             :  *
     837             :  *  Is Numeric value a NaN?
     838             :  */
     839             : bool
     840        7554 : numeric_is_nan(Numeric num)
     841             : {
     842        7554 :     return NUMERIC_IS_NAN(num);
     843             : }
     844             : 
     845             : /*
     846             :  * numeric_is_inf() -
     847             :  *
     848             :  *  Is Numeric value an infinity?
     849             :  */
     850             : bool
     851         312 : numeric_is_inf(Numeric num)
     852             : {
     853         312 :     return NUMERIC_IS_INF(num);
     854             : }
     855             : 
     856             : /*
     857             :  * numeric_is_integral() -
     858             :  *
     859             :  *  Is Numeric value integral?
     860             :  */
     861             : static bool
     862          66 : numeric_is_integral(Numeric num)
     863             : {
     864             :     NumericVar  arg;
     865             : 
     866             :     /* Reject NaN, but infinities are considered integral */
     867          66 :     if (NUMERIC_IS_SPECIAL(num))
     868             :     {
     869          30 :         if (NUMERIC_IS_NAN(num))
     870           0 :             return false;
     871          30 :         return true;
     872             :     }
     873             : 
     874             :     /* Integral if there are no digits to the right of the decimal point */
     875          36 :     init_var_from_num(num, &arg);
     876             : 
     877          36 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
     878             : }
     879             : 
     880             : /*
     881             :  * make_numeric_typmod() -
     882             :  *
     883             :  *  Pack numeric precision and scale values into a typmod.  The upper 16 bits
     884             :  *  are used for the precision (though actually not all these bits are needed,
     885             :  *  since the maximum allowed precision is 1000).  The lower 16 bits are for
     886             :  *  the scale, but since the scale is constrained to the range [-1000, 1000],
     887             :  *  we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
     888             :  *  unset, for possible future use.
     889             :  *
     890             :  *  For purely historical reasons VARHDRSZ is then added to the result, thus
     891             :  *  the unused space in the upper 16 bits is not all as freely available as it
     892             :  *  might seem.  (We can't let the result overflow to a negative int32, as
     893             :  *  other parts of the system would interpret that as not-a-valid-typmod.)
     894             :  */
     895             : static inline int32
     896        1894 : make_numeric_typmod(int precision, int scale)
     897             : {
     898        1894 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
     899             : }
     900             : 
     901             : /*
     902             :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
     903             :  */
     904             : static inline bool
     905      186614 : is_valid_numeric_typmod(int32 typmod)
     906             : {
     907      186614 :     return typmod >= (int32) VARHDRSZ;
     908             : }
     909             : 
     910             : /*
     911             :  * numeric_typmod_precision() -
     912             :  *
     913             :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
     914             :  */
     915             : static inline int
     916       48618 : numeric_typmod_precision(int32 typmod)
     917             : {
     918       48618 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
     919             : }
     920             : 
     921             : /*
     922             :  * numeric_typmod_scale() -
     923             :  *
     924             :  *  Extract the scale from a numeric typmod --- see make_numeric_typmod().
     925             :  *
     926             :  *  Note that the scale may be negative, so we must do sign extension when
     927             :  *  unpacking it.  We do this using the bit hack (x^1024)-1024, which sign
     928             :  *  extends an 11-bit two's complement number x.
     929             :  */
     930             : static inline int
     931       41524 : numeric_typmod_scale(int32 typmod)
     932             : {
     933       41524 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
     934             : }
     935             : 
     936             : /*
     937             :  * numeric_maximum_size() -
     938             :  *
     939             :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
     940             :  */
     941             : int32
     942        7094 : numeric_maximum_size(int32 typmod)
     943             : {
     944             :     int         precision;
     945             :     int         numeric_digits;
     946             : 
     947        7094 :     if (!is_valid_numeric_typmod(typmod))
     948           0 :         return -1;
     949             : 
     950             :     /* precision (ie, max # of digits) is in upper bits of typmod */
     951        7094 :     precision = numeric_typmod_precision(typmod);
     952             : 
     953             :     /*
     954             :      * This formula computes the maximum number of NumericDigits we could need
     955             :      * in order to store the specified number of decimal digits. Because the
     956             :      * weight is stored as a number of NumericDigits rather than a number of
     957             :      * decimal digits, it's possible that the first NumericDigit will contain
     958             :      * only a single decimal digit.  Thus, the first two decimal digits can
     959             :      * require two NumericDigits to store, but it isn't until we reach
     960             :      * DEC_DIGITS + 2 decimal digits that we potentially need a third
     961             :      * NumericDigit.
     962             :      */
     963        7094 :     numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
     964             : 
     965             :     /*
     966             :      * In most cases, the size of a numeric will be smaller than the value
     967             :      * computed below, because the varlena header will typically get toasted
     968             :      * down to a single byte before being stored on disk, and it may also be
     969             :      * possible to use a short numeric header.  But our job here is to compute
     970             :      * the worst case.
     971             :      */
     972        7094 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
     973             : }
     974             : 
     975             : /*
     976             :  * numeric_out_sci() -
     977             :  *
     978             :  *  Output function for numeric data type in scientific notation.
     979             :  */
     980             : char *
     981         246 : numeric_out_sci(Numeric num, int scale)
     982             : {
     983             :     NumericVar  x;
     984             :     char       *str;
     985             : 
     986             :     /*
     987             :      * Handle NaN and infinities
     988             :      */
     989         246 :     if (NUMERIC_IS_SPECIAL(num))
     990             :     {
     991          18 :         if (NUMERIC_IS_PINF(num))
     992           6 :             return pstrdup("Infinity");
     993          12 :         else if (NUMERIC_IS_NINF(num))
     994           6 :             return pstrdup("-Infinity");
     995             :         else
     996           6 :             return pstrdup("NaN");
     997             :     }
     998             : 
     999         228 :     init_var_from_num(num, &x);
    1000             : 
    1001         228 :     str = get_str_from_var_sci(&x, scale);
    1002             : 
    1003         228 :     return str;
    1004             : }
    1005             : 
    1006             : /*
    1007             :  * numeric_normalize() -
    1008             :  *
    1009             :  *  Output function for numeric data type, suppressing insignificant trailing
    1010             :  *  zeroes and then any trailing decimal point.  The intent of this is to
    1011             :  *  produce strings that are equal if and only if the input numeric values
    1012             :  *  compare equal.
    1013             :  */
    1014             : char *
    1015       36110 : numeric_normalize(Numeric num)
    1016             : {
    1017             :     NumericVar  x;
    1018             :     char       *str;
    1019             :     int         last;
    1020             : 
    1021             :     /*
    1022             :      * Handle NaN and infinities
    1023             :      */
    1024       36110 :     if (NUMERIC_IS_SPECIAL(num))
    1025             :     {
    1026           0 :         if (NUMERIC_IS_PINF(num))
    1027           0 :             return pstrdup("Infinity");
    1028           0 :         else if (NUMERIC_IS_NINF(num))
    1029           0 :             return pstrdup("-Infinity");
    1030             :         else
    1031           0 :             return pstrdup("NaN");
    1032             :     }
    1033             : 
    1034       36110 :     init_var_from_num(num, &x);
    1035             : 
    1036       36110 :     str = get_str_from_var(&x);
    1037             : 
    1038             :     /* If there's no decimal point, there's certainly nothing to remove. */
    1039       36110 :     if (strchr(str, '.') != NULL)
    1040             :     {
    1041             :         /*
    1042             :          * Back up over trailing fractional zeroes.  Since there is a decimal
    1043             :          * point, this loop will terminate safely.
    1044             :          */
    1045          42 :         last = strlen(str) - 1;
    1046          84 :         while (str[last] == '0')
    1047          42 :             last--;
    1048             : 
    1049             :         /* We want to get rid of the decimal point too, if it's now last. */
    1050          42 :         if (str[last] == '.')
    1051          42 :             last--;
    1052             : 
    1053             :         /* Delete whatever we backed up over. */
    1054          42 :         str[last + 1] = '\0';
    1055             :     }
    1056             : 
    1057       36110 :     return str;
    1058             : }
    1059             : 
    1060             : /*
    1061             :  *      numeric_recv            - converts external binary format to numeric
    1062             :  *
    1063             :  * External format is a sequence of int16's:
    1064             :  * ndigits, weight, sign, dscale, NumericDigits.
    1065             :  */
    1066             : Datum
    1067         102 : numeric_recv(PG_FUNCTION_ARGS)
    1068             : {
    1069         102 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    1070             : 
    1071             : #ifdef NOT_USED
    1072             :     Oid         typelem = PG_GETARG_OID(1);
    1073             : #endif
    1074         102 :     int32       typmod = PG_GETARG_INT32(2);
    1075             :     NumericVar  value;
    1076             :     Numeric     res;
    1077             :     int         len,
    1078             :                 i;
    1079             : 
    1080         102 :     init_var(&value);
    1081             : 
    1082         102 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1083             : 
    1084         102 :     alloc_var(&value, len);
    1085             : 
    1086         102 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
    1087             :     /* we allow any int16 for weight --- OK? */
    1088             : 
    1089         102 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1090         102 :     if (!(value.sign == NUMERIC_POS ||
    1091           0 :           value.sign == NUMERIC_NEG ||
    1092           0 :           value.sign == NUMERIC_NAN ||
    1093           0 :           value.sign == NUMERIC_PINF ||
    1094           0 :           value.sign == NUMERIC_NINF))
    1095           0 :         ereport(ERROR,
    1096             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1097             :                  errmsg("invalid sign in external \"numeric\" value")));
    1098             : 
    1099         102 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1100         102 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
    1101           0 :         ereport(ERROR,
    1102             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1103             :                  errmsg("invalid scale in external \"numeric\" value")));
    1104             : 
    1105         274 :     for (i = 0; i < len; i++)
    1106             :     {
    1107         172 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
    1108             : 
    1109         172 :         if (d < 0 || d >= NBASE)
    1110           0 :             ereport(ERROR,
    1111             :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1112             :                      errmsg("invalid digit in external \"numeric\" value")));
    1113         172 :         value.digits[i] = d;
    1114             :     }
    1115             : 
    1116             :     /*
    1117             :      * If the given dscale would hide any digits, truncate those digits away.
    1118             :      * We could alternatively throw an error, but that would take a bunch of
    1119             :      * extra code (about as much as trunc_var involves), and it might cause
    1120             :      * client compatibility issues.  Be careful not to apply trunc_var to
    1121             :      * special values, as it could do the wrong thing; we don't need it
    1122             :      * anyway, since make_result will ignore all but the sign field.
    1123             :      *
    1124             :      * After doing that, be sure to check the typmod restriction.
    1125             :      */
    1126         102 :     if (value.sign == NUMERIC_POS ||
    1127           0 :         value.sign == NUMERIC_NEG)
    1128             :     {
    1129         102 :         trunc_var(&value, value.dscale);
    1130             : 
    1131         102 :         (void) apply_typmod(&value, typmod, NULL);
    1132             : 
    1133         102 :         res = make_result(&value);
    1134             :     }
    1135             :     else
    1136             :     {
    1137             :         /* apply_typmod_special wants us to make the Numeric first */
    1138           0 :         res = make_result(&value);
    1139             : 
    1140           0 :         (void) apply_typmod_special(res, typmod, NULL);
    1141             :     }
    1142             : 
    1143         102 :     free_var(&value);
    1144             : 
    1145         102 :     PG_RETURN_NUMERIC(res);
    1146             : }
    1147             : 
    1148             : /*
    1149             :  *      numeric_send            - converts numeric to binary format
    1150             :  */
    1151             : Datum
    1152          70 : numeric_send(PG_FUNCTION_ARGS)
    1153             : {
    1154          70 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1155             :     NumericVar  x;
    1156             :     StringInfoData buf;
    1157             :     int         i;
    1158             : 
    1159          70 :     init_var_from_num(num, &x);
    1160             : 
    1161          70 :     pq_begintypsend(&buf);
    1162             : 
    1163          70 :     pq_sendint16(&buf, x.ndigits);
    1164          70 :     pq_sendint16(&buf, x.weight);
    1165          70 :     pq_sendint16(&buf, x.sign);
    1166          70 :     pq_sendint16(&buf, x.dscale);
    1167         194 :     for (i = 0; i < x.ndigits; i++)
    1168         124 :         pq_sendint16(&buf, x.digits[i]);
    1169             : 
    1170          70 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    1171             : }
    1172             : 
    1173             : 
    1174             : /*
    1175             :  * numeric_support()
    1176             :  *
    1177             :  * Planner support function for the numeric() length coercion function.
    1178             :  *
    1179             :  * Flatten calls that solely represent increases in allowable precision.
    1180             :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
    1181             :  * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
    1182             :  * an unconstrained numeric to any constrained numeric is also unoptimizable.
    1183             :  */
    1184             : Datum
    1185         516 : numeric_support(PG_FUNCTION_ARGS)
    1186             : {
    1187         516 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1188         516 :     Node       *ret = NULL;
    1189             : 
    1190         516 :     if (IsA(rawreq, SupportRequestSimplify))
    1191             :     {
    1192         228 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
    1193         228 :         FuncExpr   *expr = req->fcall;
    1194             :         Node       *typmod;
    1195             : 
    1196             :         Assert(list_length(expr->args) >= 2);
    1197             : 
    1198         228 :         typmod = (Node *) lsecond(expr->args);
    1199             : 
    1200         228 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
    1201             :         {
    1202         228 :             Node       *source = (Node *) linitial(expr->args);
    1203         228 :             int32       old_typmod = exprTypmod(source);
    1204         228 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    1205         228 :             int32       old_scale = numeric_typmod_scale(old_typmod);
    1206         228 :             int32       new_scale = numeric_typmod_scale(new_typmod);
    1207         228 :             int32       old_precision = numeric_typmod_precision(old_typmod);
    1208         228 :             int32       new_precision = numeric_typmod_precision(new_typmod);
    1209             : 
    1210             :             /*
    1211             :              * If new_typmod is invalid, the destination is unconstrained;
    1212             :              * that's always OK.  If old_typmod is valid, the source is
    1213             :              * constrained, and we're OK if the scale is unchanged and the
    1214             :              * precision is not decreasing.  See further notes in function
    1215             :              * header comment.
    1216             :              */
    1217         456 :             if (!is_valid_numeric_typmod(new_typmod) ||
    1218         240 :                 (is_valid_numeric_typmod(old_typmod) &&
    1219           6 :                  new_scale == old_scale && new_precision >= old_precision))
    1220           6 :                 ret = relabel_to_typmod(source, new_typmod);
    1221             :         }
    1222             :     }
    1223             : 
    1224         516 :     PG_RETURN_POINTER(ret);
    1225             : }
    1226             : 
    1227             : /*
    1228             :  * numeric() -
    1229             :  *
    1230             :  *  This is a special function called by the Postgres database system
    1231             :  *  before a value is stored in a tuple's attribute. The precision and
    1232             :  *  scale of the attribute have to be applied on the value.
    1233             :  */
    1234             : Datum
    1235       11730 : numeric     (PG_FUNCTION_ARGS)
    1236             : {
    1237       11730 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1238       11730 :     int32       typmod = PG_GETARG_INT32(1);
    1239             :     Numeric     new;
    1240             :     int         precision;
    1241             :     int         scale;
    1242             :     int         ddigits;
    1243             :     int         maxdigits;
    1244             :     int         dscale;
    1245             :     NumericVar  var;
    1246             : 
    1247             :     /*
    1248             :      * Handle NaN and infinities: if apply_typmod_special doesn't complain,
    1249             :      * just return a copy of the input.
    1250             :      */
    1251       11730 :     if (NUMERIC_IS_SPECIAL(num))
    1252             :     {
    1253         210 :         (void) apply_typmod_special(num, typmod, NULL);
    1254         192 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1255             :     }
    1256             : 
    1257             :     /*
    1258             :      * If the value isn't a valid type modifier, simply return a copy of the
    1259             :      * input value
    1260             :      */
    1261       11520 :     if (!is_valid_numeric_typmod(typmod))
    1262           0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1263             : 
    1264             :     /*
    1265             :      * Get the precision and scale out of the typmod value
    1266             :      */
    1267       11520 :     precision = numeric_typmod_precision(typmod);
    1268       11520 :     scale = numeric_typmod_scale(typmod);
    1269       11520 :     maxdigits = precision - scale;
    1270             : 
    1271             :     /* The target display scale is non-negative */
    1272       11520 :     dscale = Max(scale, 0);
    1273             : 
    1274             :     /*
    1275             :      * If the number is certainly in bounds and due to the target scale no
    1276             :      * rounding could be necessary, just make a copy of the input and modify
    1277             :      * its scale fields, unless the larger scale forces us to abandon the
    1278             :      * short representation.  (Note we assume the existing dscale is
    1279             :      * honest...)
    1280             :      */
    1281       11520 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1282       11520 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
    1283        7134 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
    1284           0 :             || !NUMERIC_IS_SHORT(num)))
    1285             :     {
    1286        7134 :         new = duplicate_numeric(num);
    1287        7134 :         if (NUMERIC_IS_SHORT(num))
    1288        7134 :             new->choice.n_short.n_header =
    1289        7134 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
    1290        7134 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
    1291             :         else
    1292           0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
    1293           0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
    1294        7134 :         PG_RETURN_NUMERIC(new);
    1295             :     }
    1296             : 
    1297             :     /*
    1298             :      * We really need to fiddle with things - unpack the number into a
    1299             :      * variable and let apply_typmod() do it.
    1300             :      */
    1301        4386 :     init_var(&var);
    1302             : 
    1303        4386 :     set_var_from_num(num, &var);
    1304        4386 :     (void) apply_typmod(&var, typmod, NULL);
    1305        4326 :     new = make_result(&var);
    1306             : 
    1307        4326 :     free_var(&var);
    1308             : 
    1309        4326 :     PG_RETURN_NUMERIC(new);
    1310             : }
    1311             : 
    1312             : Datum
    1313        1936 : numerictypmodin(PG_FUNCTION_ARGS)
    1314             : {
    1315        1936 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1316             :     int32      *tl;
    1317             :     int         n;
    1318             :     int32       typmod;
    1319             : 
    1320        1936 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1321             : 
    1322        1936 :     if (n == 2)
    1323             :     {
    1324        1916 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1325          18 :             ereport(ERROR,
    1326             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1327             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1328             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1329        1898 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
    1330          12 :             ereport(ERROR,
    1331             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1332             :                      errmsg("NUMERIC scale %d must be between %d and %d",
    1333             :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
    1334        1886 :         typmod = make_numeric_typmod(tl[0], tl[1]);
    1335             :     }
    1336          20 :     else if (n == 1)
    1337             :     {
    1338           8 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1339           0 :             ereport(ERROR,
    1340             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1341             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1342             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1343             :         /* scale defaults to zero */
    1344           8 :         typmod = make_numeric_typmod(tl[0], 0);
    1345             :     }
    1346             :     else
    1347             :     {
    1348          12 :         ereport(ERROR,
    1349             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1350             :                  errmsg("invalid NUMERIC type modifier")));
    1351             :         typmod = 0;             /* keep compiler quiet */
    1352             :     }
    1353             : 
    1354        1894 :     PG_RETURN_INT32(typmod);
    1355             : }
    1356             : 
    1357             : Datum
    1358         376 : numerictypmodout(PG_FUNCTION_ARGS)
    1359             : {
    1360         376 :     int32       typmod = PG_GETARG_INT32(0);
    1361         376 :     char       *res = (char *) palloc(64);
    1362             : 
    1363         376 :     if (is_valid_numeric_typmod(typmod))
    1364         376 :         snprintf(res, 64, "(%d,%d)",
    1365             :                  numeric_typmod_precision(typmod),
    1366             :                  numeric_typmod_scale(typmod));
    1367             :     else
    1368           0 :         *res = '\0';
    1369             : 
    1370         376 :     PG_RETURN_CSTRING(res);
    1371             : }
    1372             : 
    1373             : 
    1374             : /* ----------------------------------------------------------------------
    1375             :  *
    1376             :  * Sign manipulation, rounding and the like
    1377             :  *
    1378             :  * ----------------------------------------------------------------------
    1379             :  */
    1380             : 
    1381             : Datum
    1382       19506 : numeric_abs(PG_FUNCTION_ARGS)
    1383             : {
    1384       19506 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1385             :     Numeric     res;
    1386             : 
    1387             :     /*
    1388             :      * Do it the easy way directly on the packed format
    1389             :      */
    1390       19506 :     res = duplicate_numeric(num);
    1391             : 
    1392       19506 :     if (NUMERIC_IS_SHORT(num))
    1393       19440 :         res->choice.n_short.n_header =
    1394       19440 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
    1395          66 :     else if (NUMERIC_IS_SPECIAL(num))
    1396             :     {
    1397             :         /* This changes -Inf to Inf, and doesn't affect NaN */
    1398          18 :         res->choice.n_short.n_header =
    1399          18 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
    1400             :     }
    1401             :     else
    1402          48 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
    1403             : 
    1404       19506 :     PG_RETURN_NUMERIC(res);
    1405             : }
    1406             : 
    1407             : 
    1408             : Datum
    1409         884 : numeric_uminus(PG_FUNCTION_ARGS)
    1410             : {
    1411         884 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1412             :     Numeric     res;
    1413             : 
    1414             :     /*
    1415             :      * Do it the easy way directly on the packed format
    1416             :      */
    1417         884 :     res = duplicate_numeric(num);
    1418             : 
    1419         884 :     if (NUMERIC_IS_SPECIAL(num))
    1420             :     {
    1421             :         /* Flip the sign, if it's Inf or -Inf */
    1422         126 :         if (!NUMERIC_IS_NAN(num))
    1423          84 :             res->choice.n_short.n_header =
    1424          84 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
    1425             :     }
    1426             : 
    1427             :     /*
    1428             :      * The packed format is known to be totally zero digit trimmed always. So
    1429             :      * once we've eliminated specials, we can identify a zero by the fact that
    1430             :      * there are no digits at all. Do nothing to a zero.
    1431             :      */
    1432         758 :     else if (NUMERIC_NDIGITS(num) != 0)
    1433             :     {
    1434             :         /* Else, flip the sign */
    1435         644 :         if (NUMERIC_IS_SHORT(num))
    1436         644 :             res->choice.n_short.n_header =
    1437         644 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
    1438           0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
    1439           0 :             res->choice.n_long.n_sign_dscale =
    1440           0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
    1441             :         else
    1442           0 :             res->choice.n_long.n_sign_dscale =
    1443           0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
    1444             :     }
    1445             : 
    1446         884 :     PG_RETURN_NUMERIC(res);
    1447             : }
    1448             : 
    1449             : 
    1450             : Datum
    1451         498 : numeric_uplus(PG_FUNCTION_ARGS)
    1452             : {
    1453         498 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1454             : 
    1455         498 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
    1456             : }
    1457             : 
    1458             : 
    1459             : /*
    1460             :  * numeric_sign_internal() -
    1461             :  *
    1462             :  * Returns -1 if the argument is less than 0, 0 if the argument is equal
    1463             :  * to 0, and 1 if the argument is greater than zero.  Caller must have
    1464             :  * taken care of the NaN case, but we can handle infinities here.
    1465             :  */
    1466             : static int
    1467        3570 : numeric_sign_internal(Numeric num)
    1468             : {
    1469        3570 :     if (NUMERIC_IS_SPECIAL(num))
    1470             :     {
    1471             :         Assert(!NUMERIC_IS_NAN(num));
    1472             :         /* Must be Inf or -Inf */
    1473         312 :         if (NUMERIC_IS_PINF(num))
    1474         186 :             return 1;
    1475             :         else
    1476         126 :             return -1;
    1477             :     }
    1478             : 
    1479             :     /*
    1480             :      * The packed format is known to be totally zero digit trimmed always. So
    1481             :      * once we've eliminated specials, we can identify a zero by the fact that
    1482             :      * there are no digits at all.
    1483             :      */
    1484        3258 :     else if (NUMERIC_NDIGITS(num) == 0)
    1485         228 :         return 0;
    1486        3030 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
    1487         732 :         return -1;
    1488             :     else
    1489        2298 :         return 1;
    1490             : }
    1491             : 
    1492             : /*
    1493             :  * numeric_sign() -
    1494             :  *
    1495             :  * returns -1 if the argument is less than 0, 0 if the argument is equal
    1496             :  * to 0, and 1 if the argument is greater than zero.
    1497             :  */
    1498             : Datum
    1499          48 : numeric_sign(PG_FUNCTION_ARGS)
    1500             : {
    1501          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1502             : 
    1503             :     /*
    1504             :      * Handle NaN (infinities can be handled normally)
    1505             :      */
    1506          48 :     if (NUMERIC_IS_NAN(num))
    1507           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    1508             : 
    1509          42 :     switch (numeric_sign_internal(num))
    1510             :     {
    1511           6 :         case 0:
    1512           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    1513          18 :         case 1:
    1514          18 :             PG_RETURN_NUMERIC(make_result(&const_one));
    1515          18 :         case -1:
    1516          18 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
    1517             :     }
    1518             : 
    1519             :     Assert(false);
    1520           0 :     return (Datum) 0;
    1521             : }
    1522             : 
    1523             : 
    1524             : /*
    1525             :  * numeric_round() -
    1526             :  *
    1527             :  *  Round a value to have 'scale' digits after the decimal point.
    1528             :  *  We allow negative 'scale', implying rounding before the decimal
    1529             :  *  point --- Oracle interprets rounding that way.
    1530             :  */
    1531             : Datum
    1532        7808 : numeric_round(PG_FUNCTION_ARGS)
    1533             : {
    1534        7808 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1535        7808 :     int32       scale = PG_GETARG_INT32(1);
    1536             :     Numeric     res;
    1537             :     NumericVar  arg;
    1538             : 
    1539             :     /*
    1540             :      * Handle NaN and infinities
    1541             :      */
    1542        7808 :     if (NUMERIC_IS_SPECIAL(num))
    1543          96 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1544             : 
    1545             :     /*
    1546             :      * Limit the scale value to avoid possible overflow in calculations.
    1547             :      *
    1548             :      * These limits are based on the maximum number of digits a Numeric value
    1549             :      * can have before and after the decimal point, but we must allow for one
    1550             :      * extra digit before the decimal point, in case the most significant
    1551             :      * digit rounds up; we must check if that causes Numeric overflow.
    1552             :      */
    1553        7712 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS - 1);
    1554        7712 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1555             : 
    1556             :     /*
    1557             :      * Unpack the argument and round it at the proper digit position
    1558             :      */
    1559        7712 :     init_var(&arg);
    1560        7712 :     set_var_from_num(num, &arg);
    1561             : 
    1562        7712 :     round_var(&arg, scale);
    1563             : 
    1564             :     /* We don't allow negative output dscale */
    1565        7712 :     if (scale < 0)
    1566         216 :         arg.dscale = 0;
    1567             : 
    1568             :     /*
    1569             :      * Return the rounded result
    1570             :      */
    1571        7712 :     res = make_result(&arg);
    1572             : 
    1573        7706 :     free_var(&arg);
    1574        7706 :     PG_RETURN_NUMERIC(res);
    1575             : }
    1576             : 
    1577             : 
    1578             : /*
    1579             :  * numeric_trunc() -
    1580             :  *
    1581             :  *  Truncate a value to have 'scale' digits after the decimal point.
    1582             :  *  We allow negative 'scale', implying a truncation before the decimal
    1583             :  *  point --- Oracle interprets truncation that way.
    1584             :  */
    1585             : Datum
    1586         626 : numeric_trunc(PG_FUNCTION_ARGS)
    1587             : {
    1588         626 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1589         626 :     int32       scale = PG_GETARG_INT32(1);
    1590             :     Numeric     res;
    1591             :     NumericVar  arg;
    1592             : 
    1593             :     /*
    1594             :      * Handle NaN and infinities
    1595             :      */
    1596         626 :     if (NUMERIC_IS_SPECIAL(num))
    1597          36 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1598             : 
    1599             :     /*
    1600             :      * Limit the scale value to avoid possible overflow in calculations.
    1601             :      *
    1602             :      * These limits are based on the maximum number of digits a Numeric value
    1603             :      * can have before and after the decimal point.
    1604             :      */
    1605         590 :     scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS);
    1606         590 :     scale = Min(scale, NUMERIC_DSCALE_MAX);
    1607             : 
    1608             :     /*
    1609             :      * Unpack the argument and truncate it at the proper digit position
    1610             :      */
    1611         590 :     init_var(&arg);
    1612         590 :     set_var_from_num(num, &arg);
    1613             : 
    1614         590 :     trunc_var(&arg, scale);
    1615             : 
    1616             :     /* We don't allow negative output dscale */
    1617         590 :     if (scale < 0)
    1618          24 :         arg.dscale = 0;
    1619             : 
    1620             :     /*
    1621             :      * Return the truncated result
    1622             :      */
    1623         590 :     res = make_result(&arg);
    1624             : 
    1625         590 :     free_var(&arg);
    1626         590 :     PG_RETURN_NUMERIC(res);
    1627             : }
    1628             : 
    1629             : 
    1630             : /*
    1631             :  * numeric_ceil() -
    1632             :  *
    1633             :  *  Return the smallest integer greater than or equal to the argument
    1634             :  */
    1635             : Datum
    1636         222 : numeric_ceil(PG_FUNCTION_ARGS)
    1637             : {
    1638         222 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1639             :     Numeric     res;
    1640             :     NumericVar  result;
    1641             : 
    1642             :     /*
    1643             :      * Handle NaN and infinities
    1644             :      */
    1645         222 :     if (NUMERIC_IS_SPECIAL(num))
    1646          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1647             : 
    1648         204 :     init_var_from_num(num, &result);
    1649         204 :     ceil_var(&result, &result);
    1650             : 
    1651         204 :     res = make_result(&result);
    1652         204 :     free_var(&result);
    1653             : 
    1654         204 :     PG_RETURN_NUMERIC(res);
    1655             : }
    1656             : 
    1657             : 
    1658             : /*
    1659             :  * numeric_floor() -
    1660             :  *
    1661             :  *  Return the largest integer equal to or less than the argument
    1662             :  */
    1663             : Datum
    1664         126 : numeric_floor(PG_FUNCTION_ARGS)
    1665             : {
    1666         126 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1667             :     Numeric     res;
    1668             :     NumericVar  result;
    1669             : 
    1670             :     /*
    1671             :      * Handle NaN and infinities
    1672             :      */
    1673         126 :     if (NUMERIC_IS_SPECIAL(num))
    1674          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1675             : 
    1676         108 :     init_var_from_num(num, &result);
    1677         108 :     floor_var(&result, &result);
    1678             : 
    1679         108 :     res = make_result(&result);
    1680         108 :     free_var(&result);
    1681             : 
    1682         108 :     PG_RETURN_NUMERIC(res);
    1683             : }
    1684             : 
    1685             : 
    1686             : /*
    1687             :  * generate_series_numeric() -
    1688             :  *
    1689             :  *  Generate series of numeric.
    1690             :  */
    1691             : Datum
    1692      120384 : generate_series_numeric(PG_FUNCTION_ARGS)
    1693             : {
    1694      120384 :     return generate_series_step_numeric(fcinfo);
    1695             : }
    1696             : 
    1697             : Datum
    1698      120834 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1699             : {
    1700             :     generate_series_numeric_fctx *fctx;
    1701             :     FuncCallContext *funcctx;
    1702             :     MemoryContext oldcontext;
    1703             : 
    1704      120834 :     if (SRF_IS_FIRSTCALL())
    1705             :     {
    1706         174 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1707         174 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1708         174 :         NumericVar  steploc = const_one;
    1709             : 
    1710             :         /* Reject NaN and infinities in start and stop values */
    1711         174 :         if (NUMERIC_IS_SPECIAL(start_num))
    1712             :         {
    1713          12 :             if (NUMERIC_IS_NAN(start_num))
    1714           6 :                 ereport(ERROR,
    1715             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1716             :                          errmsg("start value cannot be NaN")));
    1717             :             else
    1718           6 :                 ereport(ERROR,
    1719             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1720             :                          errmsg("start value cannot be infinity")));
    1721             :         }
    1722         162 :         if (NUMERIC_IS_SPECIAL(stop_num))
    1723             :         {
    1724          12 :             if (NUMERIC_IS_NAN(stop_num))
    1725           6 :                 ereport(ERROR,
    1726             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1727             :                          errmsg("stop value cannot be NaN")));
    1728             :             else
    1729           6 :                 ereport(ERROR,
    1730             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1731             :                          errmsg("stop value cannot be infinity")));
    1732             :         }
    1733             : 
    1734             :         /* see if we were given an explicit step size */
    1735         150 :         if (PG_NARGS() == 3)
    1736             :         {
    1737          72 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
    1738             : 
    1739          72 :             if (NUMERIC_IS_SPECIAL(step_num))
    1740             :             {
    1741          12 :                 if (NUMERIC_IS_NAN(step_num))
    1742           6 :                     ereport(ERROR,
    1743             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1744             :                              errmsg("step size cannot be NaN")));
    1745             :                 else
    1746           6 :                     ereport(ERROR,
    1747             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1748             :                              errmsg("step size cannot be infinity")));
    1749             :             }
    1750             : 
    1751          60 :             init_var_from_num(step_num, &steploc);
    1752             : 
    1753          60 :             if (cmp_var(&steploc, &const_zero) == 0)
    1754           6 :                 ereport(ERROR,
    1755             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1756             :                          errmsg("step size cannot equal zero")));
    1757             :         }
    1758             : 
    1759             :         /* create a function context for cross-call persistence */
    1760         132 :         funcctx = SRF_FIRSTCALL_INIT();
    1761             : 
    1762             :         /*
    1763             :          * Switch to memory context appropriate for multiple function calls.
    1764             :          */
    1765         132 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1766             : 
    1767             :         /* allocate memory for user context */
    1768             :         fctx = (generate_series_numeric_fctx *)
    1769         132 :             palloc(sizeof(generate_series_numeric_fctx));
    1770             : 
    1771             :         /*
    1772             :          * Use fctx to keep state from call to call. Seed current with the
    1773             :          * original start value. We must copy the start_num and stop_num
    1774             :          * values rather than pointing to them, since we may have detoasted
    1775             :          * them in the per-call context.
    1776             :          */
    1777         132 :         init_var(&fctx->current);
    1778         132 :         init_var(&fctx->stop);
    1779         132 :         init_var(&fctx->step);
    1780             : 
    1781         132 :         set_var_from_num(start_num, &fctx->current);
    1782         132 :         set_var_from_num(stop_num, &fctx->stop);
    1783         132 :         set_var_from_var(&steploc, &fctx->step);
    1784             : 
    1785         132 :         funcctx->user_fctx = fctx;
    1786         132 :         MemoryContextSwitchTo(oldcontext);
    1787             :     }
    1788             : 
    1789             :     /* stuff done on every call of the function */
    1790      120792 :     funcctx = SRF_PERCALL_SETUP();
    1791             : 
    1792             :     /*
    1793             :      * Get the saved state and use current state as the result of this
    1794             :      * iteration.
    1795             :      */
    1796      120792 :     fctx = funcctx->user_fctx;
    1797             : 
    1798      241404 :     if ((fctx->step.sign == NUMERIC_POS &&
    1799      120612 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1800         480 :         (fctx->step.sign == NUMERIC_NEG &&
    1801         180 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1802             :     {
    1803      120660 :         Numeric     result = make_result(&fctx->current);
    1804             : 
    1805             :         /* switch to memory context appropriate for iteration calculation */
    1806      120660 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1807             : 
    1808             :         /* increment current in preparation for next iteration */
    1809      120660 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1810      120660 :         MemoryContextSwitchTo(oldcontext);
    1811             : 
    1812             :         /* do when there is more left to send */
    1813      120660 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1814             :     }
    1815             :     else
    1816             :         /* do when there is no more left */
    1817         132 :         SRF_RETURN_DONE(funcctx);
    1818             : }
    1819             : 
    1820             : /*
    1821             :  * Planner support function for generate_series(numeric, numeric [, numeric])
    1822             :  */
    1823             : Datum
    1824         486 : generate_series_numeric_support(PG_FUNCTION_ARGS)
    1825             : {
    1826         486 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1827         486 :     Node       *ret = NULL;
    1828             : 
    1829         486 :     if (IsA(rawreq, SupportRequestRows))
    1830             :     {
    1831             :         /* Try to estimate the number of rows returned */
    1832         156 :         SupportRequestRows *req = (SupportRequestRows *) rawreq;
    1833             : 
    1834         156 :         if (is_funcclause(req->node))    /* be paranoid */
    1835             :         {
    1836         156 :             List       *args = ((FuncExpr *) req->node)->args;
    1837             :             Node       *arg1,
    1838             :                        *arg2,
    1839             :                        *arg3;
    1840             : 
    1841             :             /* We can use estimated argument values here */
    1842         156 :             arg1 = estimate_expression_value(req->root, linitial(args));
    1843         156 :             arg2 = estimate_expression_value(req->root, lsecond(args));
    1844         156 :             if (list_length(args) >= 3)
    1845         102 :                 arg3 = estimate_expression_value(req->root, lthird(args));
    1846             :             else
    1847          54 :                 arg3 = NULL;
    1848             : 
    1849             :             /*
    1850             :              * If any argument is constant NULL, we can safely assume that
    1851             :              * zero rows are returned.  Otherwise, if they're all non-NULL
    1852             :              * constants, we can calculate the number of rows that will be
    1853             :              * returned.
    1854             :              */
    1855         156 :             if ((IsA(arg1, Const) &&
    1856         150 :                  ((Const *) arg1)->constisnull) ||
    1857         156 :                 (IsA(arg2, Const) &&
    1858         156 :                  ((Const *) arg2)->constisnull) ||
    1859         102 :                 (arg3 != NULL && IsA(arg3, Const) &&
    1860          96 :                  ((Const *) arg3)->constisnull))
    1861             :             {
    1862           0 :                 req->rows = 0;
    1863           0 :                 ret = (Node *) req;
    1864             :             }
    1865         156 :             else if (IsA(arg1, Const) &&
    1866         150 :                      IsA(arg2, Const) &&
    1867         102 :                      (arg3 == NULL || IsA(arg3, Const)))
    1868             :             {
    1869             :                 Numeric     start_num;
    1870             :                 Numeric     stop_num;
    1871         138 :                 NumericVar  step = const_one;
    1872             : 
    1873             :                 /*
    1874             :                  * If any argument is NaN or infinity, generate_series() will
    1875             :                  * error out, so we needn't produce an estimate.
    1876             :                  */
    1877         138 :                 start_num = DatumGetNumeric(((Const *) arg1)->constvalue);
    1878         138 :                 stop_num = DatumGetNumeric(((Const *) arg2)->constvalue);
    1879             : 
    1880         138 :                 if (NUMERIC_IS_SPECIAL(start_num) ||
    1881         120 :                     NUMERIC_IS_SPECIAL(stop_num))
    1882          48 :                     PG_RETURN_POINTER(NULL);
    1883             : 
    1884         108 :                 if (arg3)
    1885             :                 {
    1886             :                     Numeric     step_num;
    1887             : 
    1888          66 :                     step_num = DatumGetNumeric(((Const *) arg3)->constvalue);
    1889             : 
    1890          66 :                     if (NUMERIC_IS_SPECIAL(step_num))
    1891          18 :                         PG_RETURN_POINTER(NULL);
    1892             : 
    1893          48 :                     init_var_from_num(step_num, &step);
    1894             :                 }
    1895             : 
    1896             :                 /*
    1897             :                  * The number of rows that will be returned is given by
    1898             :                  * floor((stop - start) / step) + 1, if the sign of step
    1899             :                  * matches the sign of stop - start.  Otherwise, no rows will
    1900             :                  * be returned.
    1901             :                  */
    1902          90 :                 if (cmp_var(&step, &const_zero) != 0)
    1903             :                 {
    1904             :                     NumericVar  start;
    1905             :                     NumericVar  stop;
    1906             :                     NumericVar  res;
    1907             : 
    1908          78 :                     init_var_from_num(start_num, &start);
    1909          78 :                     init_var_from_num(stop_num, &stop);
    1910             : 
    1911          78 :                     init_var(&res);
    1912          78 :                     sub_var(&stop, &start, &res);
    1913             : 
    1914          78 :                     if (step.sign != res.sign)
    1915             :                     {
    1916             :                         /* no rows will be returned */
    1917           6 :                         req->rows = 0;
    1918           6 :                         ret = (Node *) req;
    1919             :                     }
    1920             :                     else
    1921             :                     {
    1922          72 :                         if (arg3)
    1923          30 :                             div_var(&res, &step, &res, 0, false, false);
    1924             :                         else
    1925          42 :                             trunc_var(&res, 0); /* step = 1 */
    1926             : 
    1927          72 :                         req->rows = numericvar_to_double_no_overflow(&res) + 1;
    1928          72 :                         ret = (Node *) req;
    1929             :                     }
    1930             : 
    1931          78 :                     free_var(&res);
    1932             :                 }
    1933             :             }
    1934             :         }
    1935             :     }
    1936             : 
    1937         438 :     PG_RETURN_POINTER(ret);
    1938             : }
    1939             : 
    1940             : 
    1941             : /*
    1942             :  * Implements the numeric version of the width_bucket() function
    1943             :  * defined by SQL2003. See also width_bucket_float8().
    1944             :  *
    1945             :  * 'bound1' and 'bound2' are the lower and upper bounds of the
    1946             :  * histogram's range, respectively. 'count' is the number of buckets
    1947             :  * in the histogram. width_bucket() returns an integer indicating the
    1948             :  * bucket number that 'operand' belongs to in an equiwidth histogram
    1949             :  * with the specified characteristics. An operand smaller than the
    1950             :  * lower bound is assigned to bucket 0. An operand greater than or equal
    1951             :  * to the upper bound is assigned to an additional bucket (with number
    1952             :  * count+1). We don't allow the histogram bounds to be NaN or +/- infinity,
    1953             :  * but we do allow those values for the operand (taking NaN to be larger
    1954             :  * than any other value, as we do in comparisons).
    1955             :  */
    1956             : Datum
    1957         786 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1958             : {
    1959         786 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1960         786 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1961         786 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1962         786 :     int32       count = PG_GETARG_INT32(3);
    1963             :     NumericVar  count_var;
    1964             :     NumericVar  result_var;
    1965             :     int32       result;
    1966             : 
    1967         786 :     if (count <= 0)
    1968          12 :         ereport(ERROR,
    1969             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1970             :                  errmsg("count must be greater than zero")));
    1971             : 
    1972         774 :     if (NUMERIC_IS_SPECIAL(bound1) || NUMERIC_IS_SPECIAL(bound2))
    1973             :     {
    1974          24 :         if (NUMERIC_IS_NAN(bound1) || NUMERIC_IS_NAN(bound2))
    1975           6 :             ereport(ERROR,
    1976             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1977             :                      errmsg("lower and upper bounds cannot be NaN")));
    1978             : 
    1979          18 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1980          18 :             ereport(ERROR,
    1981             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1982             :                      errmsg("lower and upper bounds must be finite")));
    1983             :     }
    1984             : 
    1985         750 :     init_var(&result_var);
    1986         750 :     init_var(&count_var);
    1987             : 
    1988             :     /* Convert 'count' to a numeric, for ease of use later */
    1989         750 :     int64_to_numericvar((int64) count, &count_var);
    1990             : 
    1991         750 :     switch (cmp_numerics(bound1, bound2))
    1992             :     {
    1993           6 :         case 0:
    1994           6 :             ereport(ERROR,
    1995             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1996             :                      errmsg("lower bound cannot equal upper bound")));
    1997             :             break;
    1998             : 
    1999             :             /* bound1 < bound2 */
    2000         552 :         case -1:
    2001         552 :             if (cmp_numerics(operand, bound1) < 0)
    2002         114 :                 set_var_from_var(&const_zero, &result_var);
    2003         438 :             else if (cmp_numerics(operand, bound2) >= 0)
    2004         114 :                 add_var(&count_var, &const_one, &result_var);
    2005             :             else
    2006         324 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2007             :                                &result_var);
    2008         552 :             break;
    2009             : 
    2010             :             /* bound1 > bound2 */
    2011         192 :         case 1:
    2012         192 :             if (cmp_numerics(operand, bound1) > 0)
    2013          12 :                 set_var_from_var(&const_zero, &result_var);
    2014         180 :             else if (cmp_numerics(operand, bound2) <= 0)
    2015          24 :                 add_var(&count_var, &const_one, &result_var);
    2016             :             else
    2017         156 :                 compute_bucket(operand, bound1, bound2, &count_var,
    2018             :                                &result_var);
    2019         192 :             break;
    2020             :     }
    2021             : 
    2022             :     /* if result exceeds the range of a legal int4, we ereport here */
    2023         744 :     if (!numericvar_to_int32(&result_var, &result))
    2024           0 :         ereport(ERROR,
    2025             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    2026             :                  errmsg("integer out of range")));
    2027             : 
    2028         744 :     free_var(&count_var);
    2029         744 :     free_var(&result_var);
    2030             : 
    2031         744 :     PG_RETURN_INT32(result);
    2032             : }
    2033             : 
    2034             : /*
    2035             :  * 'operand' is inside the bucket range, so determine the correct
    2036             :  * bucket for it to go in. The calculations performed by this function
    2037             :  * are derived directly from the SQL2003 spec. Note however that we
    2038             :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    2039             :  */
    2040             : static void
    2041         480 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    2042             :                const NumericVar *count_var, NumericVar *result_var)
    2043             : {
    2044             :     NumericVar  bound1_var;
    2045             :     NumericVar  bound2_var;
    2046             :     NumericVar  operand_var;
    2047             : 
    2048         480 :     init_var_from_num(bound1, &bound1_var);
    2049         480 :     init_var_from_num(bound2, &bound2_var);
    2050         480 :     init_var_from_num(operand, &operand_var);
    2051             : 
    2052             :     /*
    2053             :      * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
    2054             :      * bound1 <= operand < bound2 or bound1 >= operand > bound2.  Either way,
    2055             :      * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
    2056             :      * where the quotient is computed using floor division (i.e., division to
    2057             :      * zero decimal places with truncation), which guarantees that the result
    2058             :      * is in the range [1, count].  Reversing the bounds doesn't affect the
    2059             :      * computation, because the signs cancel out when dividing.
    2060             :      */
    2061         480 :     sub_var(&operand_var, &bound1_var, &operand_var);
    2062         480 :     sub_var(&bound2_var, &bound1_var, &bound2_var);
    2063             : 
    2064         480 :     mul_var(&operand_var, count_var, &operand_var,
    2065         480 :             operand_var.dscale + count_var->dscale);
    2066         480 :     div_var(&operand_var, &bound2_var, result_var, 0, false, true);
    2067         480 :     add_var(result_var, &const_one, result_var);
    2068             : 
    2069         480 :     free_var(&bound1_var);
    2070         480 :     free_var(&bound2_var);
    2071         480 :     free_var(&operand_var);
    2072         480 : }
    2073             : 
    2074             : /* ----------------------------------------------------------------------
    2075             :  *
    2076             :  * Comparison functions
    2077             :  *
    2078             :  * Note: btree indexes need these routines not to leak memory; therefore,
    2079             :  * be careful to free working copies of toasted datums.  Most places don't
    2080             :  * need to be so careful.
    2081             :  *
    2082             :  * Sort support:
    2083             :  *
    2084             :  * We implement the sortsupport strategy routine in order to get the benefit of
    2085             :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    2086             :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    2087             :  * while this could be worked on itself, the abbreviation strategy gives more
    2088             :  * speedup in many common cases.
    2089             :  *
    2090             :  * The abbreviated format is an int64. The representation is negated relative
    2091             :  * to the original value, because we use the largest negative value for NaN,
    2092             :  * which sorts higher than other values. We convert the absolute value of the
    2093             :  * numeric to a 63-bit positive value, and then negate it if the original
    2094             :  * number was positive.
    2095             :  *
    2096             :  * We abort the abbreviation process if the abbreviation cardinality is below
    2097             :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    2098             :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    2099             :  * very small penalty), but we don't want to build up too many abbreviated
    2100             :  * values before first testing for abort, so we take the slightly pessimistic
    2101             :  * number.  We make no attempt to estimate the cardinality of the real values,
    2102             :  * since it plays no part in the cost model here (if the abbreviation is equal,
    2103             :  * the cost of comparing equal and unequal underlying values is comparable).
    2104             :  * We discontinue even checking for abort (saving us the hashing overhead) if
    2105             :  * the estimated cardinality gets to 100k; that would be enough to support many
    2106             :  * billions of rows while doing no worse than breaking even.
    2107             :  *
    2108             :  * ----------------------------------------------------------------------
    2109             :  */
    2110             : 
    2111             : /*
    2112             :  * Sort support strategy routine.
    2113             :  */
    2114             : Datum
    2115        1118 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2116             : {
    2117        1118 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2118             : 
    2119        1118 :     ssup->comparator = numeric_fast_cmp;
    2120             : 
    2121        1118 :     if (ssup->abbreviate)
    2122             :     {
    2123             :         NumericSortSupport *nss;
    2124         262 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2125             : 
    2126         262 :         nss = palloc(sizeof(NumericSortSupport));
    2127             : 
    2128             :         /*
    2129             :          * palloc a buffer for handling unaligned packed values in addition to
    2130             :          * the support struct
    2131             :          */
    2132         262 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2133             : 
    2134         262 :         nss->input_count = 0;
    2135         262 :         nss->estimating = true;
    2136         262 :         initHyperLogLog(&nss->abbr_card, 10);
    2137             : 
    2138         262 :         ssup->ssup_extra = nss;
    2139             : 
    2140         262 :         ssup->abbrev_full_comparator = ssup->comparator;
    2141         262 :         ssup->comparator = numeric_cmp_abbrev;
    2142         262 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2143         262 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2144             : 
    2145         262 :         MemoryContextSwitchTo(oldcontext);
    2146             :     }
    2147             : 
    2148        1118 :     PG_RETURN_VOID();
    2149             : }
    2150             : 
    2151             : /*
    2152             :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2153             :  * (must not leak memory!)
    2154             :  */
    2155             : static Datum
    2156       19168 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2157             : {
    2158       19168 :     NumericSortSupport *nss = ssup->ssup_extra;
    2159       19168 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2160             :     Numeric     value;
    2161             :     Datum       result;
    2162             : 
    2163       19168 :     nss->input_count += 1;
    2164             : 
    2165             :     /*
    2166             :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2167             :      * we keep and reuse a buffer large enough to handle any short datum.
    2168             :      */
    2169       19168 :     if (VARATT_IS_SHORT(original_varatt))
    2170             :     {
    2171        1026 :         void       *buf = nss->buf;
    2172        1026 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2173             : 
    2174             :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2175             : 
    2176        1026 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2177        1026 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2178             : 
    2179        1026 :         value = (Numeric) buf;
    2180             :     }
    2181             :     else
    2182       18142 :         value = (Numeric) original_varatt;
    2183             : 
    2184       19168 :     if (NUMERIC_IS_SPECIAL(value))
    2185             :     {
    2186         150 :         if (NUMERIC_IS_PINF(value))
    2187          48 :             result = NUMERIC_ABBREV_PINF;
    2188         102 :         else if (NUMERIC_IS_NINF(value))
    2189          48 :             result = NUMERIC_ABBREV_NINF;
    2190             :         else
    2191          54 :             result = NUMERIC_ABBREV_NAN;
    2192             :     }
    2193             :     else
    2194             :     {
    2195             :         NumericVar  var;
    2196             : 
    2197       19018 :         init_var_from_num(value, &var);
    2198             : 
    2199       19018 :         result = numeric_abbrev_convert_var(&var, nss);
    2200             :     }
    2201             : 
    2202             :     /* should happen only for external/compressed toasts */
    2203       19168 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
    2204           0 :         pfree(original_varatt);
    2205             : 
    2206       19168 :     return result;
    2207             : }
    2208             : 
    2209             : /*
    2210             :  * Consider whether to abort abbreviation.
    2211             :  *
    2212             :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2213             :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2214             :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2215             :  * whether the underlying values are also equal.
    2216             :  */
    2217             : static bool
    2218         144 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2219             : {
    2220         144 :     NumericSortSupport *nss = ssup->ssup_extra;
    2221             :     double      abbr_card;
    2222             : 
    2223         144 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2224         144 :         return false;
    2225             : 
    2226           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2227             : 
    2228             :     /*
    2229             :      * If we have >100k distinct values, then even if we were sorting many
    2230             :      * billion rows we'd likely still break even, and the penalty of undoing
    2231             :      * that many rows of abbrevs would probably not be worth it. Stop even
    2232             :      * counting at that point.
    2233             :      */
    2234           0 :     if (abbr_card > 100000.0)
    2235             :     {
    2236           0 :         if (trace_sort)
    2237           0 :             elog(LOG,
    2238             :                  "numeric_abbrev: estimation ends at cardinality %f"
    2239             :                  " after " INT64_FORMAT " values (%d rows)",
    2240             :                  abbr_card, nss->input_count, memtupcount);
    2241           0 :         nss->estimating = false;
    2242           0 :         return false;
    2243             :     }
    2244             : 
    2245             :     /*
    2246             :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2247             :      * break even point is somewhere between one per 100k rows, where
    2248             :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2249             :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2250             :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2251             :      * abort earlier on genuinely pathological data where we've had exactly
    2252             :      * one abbreviated value in the first 10k (non-null) rows.
    2253             :      */
    2254           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2255             :     {
    2256           0 :         if (trace_sort)
    2257           0 :             elog(LOG,
    2258             :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2259             :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2260             :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2261             :                  nss->input_count, memtupcount);
    2262           0 :         return true;
    2263             :     }
    2264             : 
    2265           0 :     if (trace_sort)
    2266           0 :         elog(LOG,
    2267             :              "numeric_abbrev: cardinality %f"
    2268             :              " after " INT64_FORMAT " values (%d rows)",
    2269             :              abbr_card, nss->input_count, memtupcount);
    2270             : 
    2271           0 :     return false;
    2272             : }
    2273             : 
    2274             : /*
    2275             :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2276             :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2277             :  * are, but it is a required part of the sort support API when abbreviations
    2278             :  * are performed.
    2279             :  *
    2280             :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2281             :  * aligning short-varlena inputs, but this has not so far been considered to
    2282             :  * be worth the effort.
    2283             :  */
    2284             : static int
    2285    17779098 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2286             : {
    2287    17779098 :     Numeric     nx = DatumGetNumeric(x);
    2288    17779098 :     Numeric     ny = DatumGetNumeric(y);
    2289             :     int         result;
    2290             : 
    2291    17779098 :     result = cmp_numerics(nx, ny);
    2292             : 
    2293    17779098 :     if ((Pointer) nx != DatumGetPointer(x))
    2294     5656170 :         pfree(nx);
    2295    17779098 :     if ((Pointer) ny != DatumGetPointer(y))
    2296     5656164 :         pfree(ny);
    2297             : 
    2298    17779098 :     return result;
    2299             : }
    2300             : 
    2301             : /*
    2302             :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2303             :  * values differ, but if the abbreviations differ, they must reflect the
    2304             :  * ordering of the true values.)
    2305             :  */
    2306             : static int
    2307      187846 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2308             : {
    2309             :     /*
    2310             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2311             :      * negated relative to the original value, to handle NaN/infinity cases.
    2312             :      */
    2313      187846 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2314       98322 :         return 1;
    2315       89524 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2316       89302 :         return -1;
    2317         222 :     return 0;
    2318             : }
    2319             : 
    2320             : /*
    2321             :  * Abbreviate a NumericVar into the 64-bit sortsupport size.
    2322             :  *
    2323             :  * The 31-bit value is constructed as:
    2324             :  *
    2325             :  *  0 + 7bits digit weight + 24 bits digit value
    2326             :  *
    2327             :  * where the digit weight is in single decimal digits, not digit words, and
    2328             :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2329             :  * significant decimal digits of the value converted to binary. Values whose
    2330             :  * weights would fall outside the representable range are rounded off to zero
    2331             :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2332             :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2333             :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2334             :  * to be a serious limitation, or when values are of the same magnitude and
    2335             :  * equal in the first 7 decimal digits, which is considered to be an
    2336             :  * unavoidable limitation given the available bits. (Stealing three more bits
    2337             :  * to compare another digit would narrow the range of representable weights by
    2338             :  * a factor of 8, which starts to look like a real limiting factor.)
    2339             :  *
    2340             :  * (The value 44 for the excess is essentially arbitrary)
    2341             :  *
    2342             :  * The 63-bit value is constructed as:
    2343             :  *
    2344             :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2345             :  *
    2346             :  * The weight in this case is again stored in excess-44, but this time it is
    2347             :  * the original weight in digit words (i.e. powers of 10000). The first four
    2348             :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2349             :  * are packed into 14 bits each to form the rest of the value. Again,
    2350             :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2351             :  * representable range in this case is 10^-176 to 10^332, which is considered
    2352             :  * to be good enough for all practical purposes, and comparison of 4 words
    2353             :  * means that at least 13 decimal digits are compared, which is considered to
    2354             :  * be a reasonable compromise between effectiveness and efficiency in computing
    2355             :  * the abbreviation.
    2356             :  *
    2357             :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2358             :  * to match the value used in the 31-bit case)
    2359             :  *
    2360             :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2361             :  * and then treated as unsigned, so the smallest representable value is stored
    2362             :  * with all bits zero. This allows simple comparisons to work on the composite
    2363             :  * value.
    2364             :  */
    2365             : static Datum
    2366       19018 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2367             : {
    2368       19018 :     int         ndigits = var->ndigits;
    2369       19018 :     int         weight = var->weight;
    2370             :     int64       result;
    2371             : 
    2372       19018 :     if (ndigits == 0 || weight < -44)
    2373             :     {
    2374          52 :         result = 0;
    2375             :     }
    2376       18966 :     else if (weight > 83)
    2377             :     {
    2378          12 :         result = PG_INT64_MAX;
    2379             :     }
    2380             :     else
    2381             :     {
    2382       18954 :         result = ((int64) (weight + 44) << 56);
    2383             : 
    2384       18954 :         switch (ndigits)
    2385             :         {
    2386           0 :             default:
    2387           0 :                 result |= ((int64) var->digits[3]);
    2388             :                 /* FALLTHROUGH */
    2389        6206 :             case 3:
    2390        6206 :                 result |= ((int64) var->digits[2]) << 14;
    2391             :                 /* FALLTHROUGH */
    2392       18332 :             case 2:
    2393       18332 :                 result |= ((int64) var->digits[1]) << 28;
    2394             :                 /* FALLTHROUGH */
    2395       18954 :             case 1:
    2396       18954 :                 result |= ((int64) var->digits[0]) << 42;
    2397       18954 :                 break;
    2398             :         }
    2399             :     }
    2400             : 
    2401             :     /* the abbrev is negated relative to the original */
    2402       19018 :     if (var->sign == NUMERIC_POS)
    2403       18920 :         result = -result;
    2404             : 
    2405       19018 :     if (nss->estimating)
    2406             :     {
    2407       19018 :         uint32      tmp = ((uint32) result
    2408       19018 :                            ^ (uint32) ((uint64) result >> 32));
    2409             : 
    2410       19018 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2411             :     }
    2412             : 
    2413       19018 :     return NumericAbbrevGetDatum(result);
    2414             : }
    2415             : 
    2416             : 
    2417             : /*
    2418             :  * Ordinary (non-sortsupport) comparisons follow.
    2419             :  */
    2420             : 
    2421             : Datum
    2422      750622 : numeric_cmp(PG_FUNCTION_ARGS)
    2423             : {
    2424      750622 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2425      750622 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2426             :     int         result;
    2427             : 
    2428      750622 :     result = cmp_numerics(num1, num2);
    2429             : 
    2430      750622 :     PG_FREE_IF_COPY(num1, 0);
    2431      750622 :     PG_FREE_IF_COPY(num2, 1);
    2432             : 
    2433      750622 :     PG_RETURN_INT32(result);
    2434             : }
    2435             : 
    2436             : 
    2437             : Datum
    2438      650394 : numeric_eq(PG_FUNCTION_ARGS)
    2439             : {
    2440      650394 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2441      650394 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2442             :     bool        result;
    2443             : 
    2444      650394 :     result = cmp_numerics(num1, num2) == 0;
    2445             : 
    2446      650394 :     PG_FREE_IF_COPY(num1, 0);
    2447      650394 :     PG_FREE_IF_COPY(num2, 1);
    2448             : 
    2449      650394 :     PG_RETURN_BOOL(result);
    2450             : }
    2451             : 
    2452             : Datum
    2453        5376 : numeric_ne(PG_FUNCTION_ARGS)
    2454             : {
    2455        5376 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2456        5376 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2457             :     bool        result;
    2458             : 
    2459        5376 :     result = cmp_numerics(num1, num2) != 0;
    2460             : 
    2461        5376 :     PG_FREE_IF_COPY(num1, 0);
    2462        5376 :     PG_FREE_IF_COPY(num2, 1);
    2463             : 
    2464        5376 :     PG_RETURN_BOOL(result);
    2465             : }
    2466             : 
    2467             : Datum
    2468       55694 : numeric_gt(PG_FUNCTION_ARGS)
    2469             : {
    2470       55694 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2471       55694 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2472             :     bool        result;
    2473             : 
    2474       55694 :     result = cmp_numerics(num1, num2) > 0;
    2475             : 
    2476       55694 :     PG_FREE_IF_COPY(num1, 0);
    2477       55694 :     PG_FREE_IF_COPY(num2, 1);
    2478             : 
    2479       55694 :     PG_RETURN_BOOL(result);
    2480             : }
    2481             : 
    2482             : Datum
    2483       15024 : numeric_ge(PG_FUNCTION_ARGS)
    2484             : {
    2485       15024 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2486       15024 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2487             :     bool        result;
    2488             : 
    2489       15024 :     result = cmp_numerics(num1, num2) >= 0;
    2490             : 
    2491       15024 :     PG_FREE_IF_COPY(num1, 0);
    2492       15024 :     PG_FREE_IF_COPY(num2, 1);
    2493             : 
    2494       15024 :     PG_RETURN_BOOL(result);
    2495             : }
    2496             : 
    2497             : Datum
    2498       59268 : numeric_lt(PG_FUNCTION_ARGS)
    2499             : {
    2500       59268 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2501       59268 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2502             :     bool        result;
    2503             : 
    2504       59268 :     result = cmp_numerics(num1, num2) < 0;
    2505             : 
    2506       59268 :     PG_FREE_IF_COPY(num1, 0);
    2507       59268 :     PG_FREE_IF_COPY(num2, 1);
    2508             : 
    2509       59268 :     PG_RETURN_BOOL(result);
    2510             : }
    2511             : 
    2512             : Datum
    2513       16888 : numeric_le(PG_FUNCTION_ARGS)
    2514             : {
    2515       16888 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2516       16888 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2517             :     bool        result;
    2518             : 
    2519       16888 :     result = cmp_numerics(num1, num2) <= 0;
    2520             : 
    2521       16888 :     PG_FREE_IF_COPY(num1, 0);
    2522       16888 :     PG_FREE_IF_COPY(num2, 1);
    2523             : 
    2524       16888 :     PG_RETURN_BOOL(result);
    2525             : }
    2526             : 
    2527             : static int
    2528    19353904 : cmp_numerics(Numeric num1, Numeric num2)
    2529             : {
    2530             :     int         result;
    2531             : 
    2532             :     /*
    2533             :      * We consider all NANs to be equal and larger than any non-NAN (including
    2534             :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2535             :      * a consistent sort order.
    2536             :      */
    2537    19353904 :     if (NUMERIC_IS_SPECIAL(num1))
    2538             :     {
    2539        5922 :         if (NUMERIC_IS_NAN(num1))
    2540             :         {
    2541        5832 :             if (NUMERIC_IS_NAN(num2))
    2542         584 :                 result = 0;     /* NAN = NAN */
    2543             :             else
    2544        5248 :                 result = 1;     /* NAN > non-NAN */
    2545             :         }
    2546          90 :         else if (NUMERIC_IS_PINF(num1))
    2547             :         {
    2548          72 :             if (NUMERIC_IS_NAN(num2))
    2549           0 :                 result = -1;    /* PINF < NAN */
    2550          72 :             else if (NUMERIC_IS_PINF(num2))
    2551           6 :                 result = 0;     /* PINF = PINF */
    2552             :             else
    2553          66 :                 result = 1;     /* PINF > anything else */
    2554             :         }
    2555             :         else                    /* num1 must be NINF */
    2556             :         {
    2557          18 :             if (NUMERIC_IS_NINF(num2))
    2558           6 :                 result = 0;     /* NINF = NINF */
    2559             :             else
    2560          12 :                 result = -1;    /* NINF < anything else */
    2561             :         }
    2562             :     }
    2563    19347982 :     else if (NUMERIC_IS_SPECIAL(num2))
    2564             :     {
    2565       11142 :         if (NUMERIC_IS_NINF(num2))
    2566          12 :             result = 1;         /* normal > NINF */
    2567             :         else
    2568       11130 :             result = -1;        /* normal < NAN or PINF */
    2569             :     }
    2570             :     else
    2571             :     {
    2572    38674708 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2573    19337142 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2574    19336840 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2575    19337566 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2576             :     }
    2577             : 
    2578    19353904 :     return result;
    2579             : }
    2580             : 
    2581             : /*
    2582             :  * in_range support function for numeric.
    2583             :  */
    2584             : Datum
    2585        1152 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2586             : {
    2587        1152 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2588        1152 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2589        1152 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2590        1152 :     bool        sub = PG_GETARG_BOOL(3);
    2591        1152 :     bool        less = PG_GETARG_BOOL(4);
    2592             :     bool        result;
    2593             : 
    2594             :     /*
    2595             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2596             :      * and NaN is because appropriate semantics for that seem non-obvious.
    2597             :      */
    2598        1152 :     if (NUMERIC_IS_NAN(offset) ||
    2599        1146 :         NUMERIC_IS_NINF(offset) ||
    2600        1146 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2601           6 :         ereport(ERROR,
    2602             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2603             :                  errmsg("invalid preceding or following size in window function")));
    2604             : 
    2605             :     /*
    2606             :      * Deal with cases where val and/or base is NaN, following the rule that
    2607             :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2608             :      * the conclusion.
    2609             :      */
    2610        1146 :     if (NUMERIC_IS_NAN(val))
    2611             :     {
    2612         186 :         if (NUMERIC_IS_NAN(base))
    2613          60 :             result = true;      /* NAN = NAN */
    2614             :         else
    2615         126 :             result = !less;     /* NAN > non-NAN */
    2616             :     }
    2617         960 :     else if (NUMERIC_IS_NAN(base))
    2618             :     {
    2619         126 :         result = less;          /* non-NAN < NAN */
    2620             :     }
    2621             : 
    2622             :     /*
    2623             :      * Deal with infinite offset (necessarily +Inf, at this point).
    2624             :      */
    2625         834 :     else if (NUMERIC_IS_SPECIAL(offset))
    2626             :     {
    2627             :         Assert(NUMERIC_IS_PINF(offset));
    2628         420 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2629             :         {
    2630             :             /*
    2631             :              * base +/- offset would produce NaN, so return true for any val
    2632             :              * (see in_range_float8_float8() for reasoning).
    2633             :              */
    2634         174 :             result = true;
    2635             :         }
    2636         246 :         else if (sub)
    2637             :         {
    2638             :             /* base - offset must be -inf */
    2639         150 :             if (less)
    2640          54 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2641             :             else
    2642          96 :                 result = true;  /* any val is >= sum */
    2643             :         }
    2644             :         else
    2645             :         {
    2646             :             /* base + offset must be +inf */
    2647          96 :             if (less)
    2648           0 :                 result = true;  /* any val is <= sum */
    2649             :             else
    2650          96 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2651             :         }
    2652             :     }
    2653             : 
    2654             :     /*
    2655             :      * Deal with cases where val and/or base is infinite.  The offset, being
    2656             :      * now known finite, cannot affect the conclusion.
    2657             :      */
    2658         414 :     else if (NUMERIC_IS_SPECIAL(val))
    2659             :     {
    2660          78 :         if (NUMERIC_IS_PINF(val))
    2661             :         {
    2662          36 :             if (NUMERIC_IS_PINF(base))
    2663          24 :                 result = true;  /* PINF = PINF */
    2664             :             else
    2665          12 :                 result = !less; /* PINF > any other non-NAN */
    2666             :         }
    2667             :         else                    /* val must be NINF */
    2668             :         {
    2669          42 :             if (NUMERIC_IS_NINF(base))
    2670          30 :                 result = true;  /* NINF = NINF */
    2671             :             else
    2672          12 :                 result = less;  /* NINF < anything else */
    2673             :         }
    2674             :     }
    2675         336 :     else if (NUMERIC_IS_SPECIAL(base))
    2676             :     {
    2677          24 :         if (NUMERIC_IS_NINF(base))
    2678          12 :             result = !less;     /* normal > NINF */
    2679             :         else
    2680          12 :             result = less;      /* normal < PINF */
    2681             :     }
    2682             :     else
    2683             :     {
    2684             :         /*
    2685             :          * Otherwise go ahead and compute base +/- offset.  While it's
    2686             :          * possible for this to overflow the numeric format, it's unlikely
    2687             :          * enough that we don't take measures to prevent it.
    2688             :          */
    2689             :         NumericVar  valv;
    2690             :         NumericVar  basev;
    2691             :         NumericVar  offsetv;
    2692             :         NumericVar  sum;
    2693             : 
    2694         312 :         init_var_from_num(val, &valv);
    2695         312 :         init_var_from_num(base, &basev);
    2696         312 :         init_var_from_num(offset, &offsetv);
    2697         312 :         init_var(&sum);
    2698             : 
    2699         312 :         if (sub)
    2700         156 :             sub_var(&basev, &offsetv, &sum);
    2701             :         else
    2702         156 :             add_var(&basev, &offsetv, &sum);
    2703             : 
    2704         312 :         if (less)
    2705         156 :             result = (cmp_var(&valv, &sum) <= 0);
    2706             :         else
    2707         156 :             result = (cmp_var(&valv, &sum) >= 0);
    2708             : 
    2709         312 :         free_var(&sum);
    2710             :     }
    2711             : 
    2712        1146 :     PG_FREE_IF_COPY(val, 0);
    2713        1146 :     PG_FREE_IF_COPY(base, 1);
    2714        1146 :     PG_FREE_IF_COPY(offset, 2);
    2715             : 
    2716        1146 :     PG_RETURN_BOOL(result);
    2717             : }
    2718             : 
    2719             : Datum
    2720      607536 : hash_numeric(PG_FUNCTION_ARGS)
    2721             : {
    2722      607536 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2723             :     Datum       digit_hash;
    2724             :     Datum       result;
    2725             :     int         weight;
    2726             :     int         start_offset;
    2727             :     int         end_offset;
    2728             :     int         i;
    2729             :     int         hash_len;
    2730             :     NumericDigit *digits;
    2731             : 
    2732             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2733      607536 :     if (NUMERIC_IS_SPECIAL(key))
    2734           0 :         PG_RETURN_UINT32(0);
    2735             : 
    2736      607536 :     weight = NUMERIC_WEIGHT(key);
    2737      607536 :     start_offset = 0;
    2738      607536 :     end_offset = 0;
    2739             : 
    2740             :     /*
    2741             :      * Omit any leading or trailing zeros from the input to the hash. The
    2742             :      * numeric implementation *should* guarantee that leading and trailing
    2743             :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2744             :      * starting and ending offsets in units of NumericDigits, not bytes.
    2745             :      */
    2746      607536 :     digits = NUMERIC_DIGITS(key);
    2747      607536 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2748             :     {
    2749      605876 :         if (digits[i] != (NumericDigit) 0)
    2750      605876 :             break;
    2751             : 
    2752           0 :         start_offset++;
    2753             : 
    2754             :         /*
    2755             :          * The weight is effectively the # of digits before the decimal point,
    2756             :          * so decrement it for each leading zero we skip.
    2757             :          */
    2758           0 :         weight--;
    2759             :     }
    2760             : 
    2761             :     /*
    2762             :      * If there are no non-zero digits, then the value of the number is zero,
    2763             :      * regardless of any other fields.
    2764             :      */
    2765      607536 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2766        1660 :         PG_RETURN_UINT32(-1);
    2767             : 
    2768      605876 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2769             :     {
    2770      605876 :         if (digits[i] != (NumericDigit) 0)
    2771      605876 :             break;
    2772             : 
    2773           0 :         end_offset++;
    2774             :     }
    2775             : 
    2776             :     /* If we get here, there should be at least one non-zero digit */
    2777             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2778             : 
    2779             :     /*
    2780             :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2781             :      * compare equal but have different scales. We also don't hash on the
    2782             :      * sign, although we could: since a sign difference implies inequality,
    2783             :      * this shouldn't affect correctness.
    2784             :      */
    2785      605876 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2786      605876 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2787             :                           hash_len * sizeof(NumericDigit));
    2788             : 
    2789             :     /* Mix in the weight, via XOR */
    2790      605876 :     result = digit_hash ^ weight;
    2791             : 
    2792      605876 :     PG_RETURN_DATUM(result);
    2793             : }
    2794             : 
    2795             : /*
    2796             :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2797             :  * Otherwise, similar to hash_numeric.
    2798             :  */
    2799             : Datum
    2800          84 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2801             : {
    2802          84 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2803          84 :     uint64      seed = PG_GETARG_INT64(1);
    2804             :     Datum       digit_hash;
    2805             :     Datum       result;
    2806             :     int         weight;
    2807             :     int         start_offset;
    2808             :     int         end_offset;
    2809             :     int         i;
    2810             :     int         hash_len;
    2811             :     NumericDigit *digits;
    2812             : 
    2813             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2814          84 :     if (NUMERIC_IS_SPECIAL(key))
    2815           0 :         PG_RETURN_UINT64(seed);
    2816             : 
    2817          84 :     weight = NUMERIC_WEIGHT(key);
    2818          84 :     start_offset = 0;
    2819          84 :     end_offset = 0;
    2820             : 
    2821          84 :     digits = NUMERIC_DIGITS(key);
    2822          84 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2823             :     {
    2824          72 :         if (digits[i] != (NumericDigit) 0)
    2825          72 :             break;
    2826             : 
    2827           0 :         start_offset++;
    2828             : 
    2829           0 :         weight--;
    2830             :     }
    2831             : 
    2832          84 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2833          12 :         PG_RETURN_UINT64(seed - 1);
    2834             : 
    2835          72 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2836             :     {
    2837          72 :         if (digits[i] != (NumericDigit) 0)
    2838          72 :             break;
    2839             : 
    2840           0 :         end_offset++;
    2841             :     }
    2842             : 
    2843             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2844             : 
    2845          72 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2846          72 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2847          72 :                                                       + start_offset),
    2848             :                                    hash_len * sizeof(NumericDigit),
    2849             :                                    seed);
    2850             : 
    2851          72 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2852             : 
    2853          72 :     PG_RETURN_DATUM(result);
    2854             : }
    2855             : 
    2856             : 
    2857             : /* ----------------------------------------------------------------------
    2858             :  *
    2859             :  * Basic arithmetic functions
    2860             :  *
    2861             :  * ----------------------------------------------------------------------
    2862             :  */
    2863             : 
    2864             : 
    2865             : /*
    2866             :  * numeric_add() -
    2867             :  *
    2868             :  *  Add two numerics
    2869             :  */
    2870             : Datum
    2871      252184 : numeric_add(PG_FUNCTION_ARGS)
    2872             : {
    2873      252184 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2874      252184 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2875             :     Numeric     res;
    2876             : 
    2877      252184 :     res = numeric_add_opt_error(num1, num2, NULL);
    2878             : 
    2879      252184 :     PG_RETURN_NUMERIC(res);
    2880             : }
    2881             : 
    2882             : /*
    2883             :  * numeric_add_opt_error() -
    2884             :  *
    2885             :  *  Internal version of numeric_add().  If "*have_error" flag is provided,
    2886             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2887             :  *  need to handle errors by itself.
    2888             :  */
    2889             : Numeric
    2890      253222 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2891             : {
    2892             :     NumericVar  arg1;
    2893             :     NumericVar  arg2;
    2894             :     NumericVar  result;
    2895             :     Numeric     res;
    2896             : 
    2897             :     /*
    2898             :      * Handle NaN and infinities
    2899             :      */
    2900      253222 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2901             :     {
    2902         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2903          78 :             return make_result(&const_nan);
    2904         120 :         if (NUMERIC_IS_PINF(num1))
    2905             :         {
    2906          36 :             if (NUMERIC_IS_NINF(num2))
    2907           6 :                 return make_result(&const_nan); /* Inf + -Inf */
    2908             :             else
    2909          30 :                 return make_result(&const_pinf);
    2910             :         }
    2911          84 :         if (NUMERIC_IS_NINF(num1))
    2912             :         {
    2913          36 :             if (NUMERIC_IS_PINF(num2))
    2914           6 :                 return make_result(&const_nan); /* -Inf + Inf */
    2915             :             else
    2916          30 :                 return make_result(&const_ninf);
    2917             :         }
    2918             :         /* by here, num1 must be finite, so num2 is not */
    2919          48 :         if (NUMERIC_IS_PINF(num2))
    2920          24 :             return make_result(&const_pinf);
    2921             :         Assert(NUMERIC_IS_NINF(num2));
    2922          24 :         return make_result(&const_ninf);
    2923             :     }
    2924             : 
    2925             :     /*
    2926             :      * Unpack the values, let add_var() compute the result and return it.
    2927             :      */
    2928      253024 :     init_var_from_num(num1, &arg1);
    2929      253024 :     init_var_from_num(num2, &arg2);
    2930             : 
    2931      253024 :     init_var(&result);
    2932      253024 :     add_var(&arg1, &arg2, &result);
    2933             : 
    2934      253024 :     res = make_result_opt_error(&result, have_error);
    2935             : 
    2936      253024 :     free_var(&result);
    2937             : 
    2938      253024 :     return res;
    2939             : }
    2940             : 
    2941             : 
    2942             : /*
    2943             :  * numeric_sub() -
    2944             :  *
    2945             :  *  Subtract one numeric from another
    2946             :  */
    2947             : Datum
    2948       75728 : numeric_sub(PG_FUNCTION_ARGS)
    2949             : {
    2950       75728 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2951       75728 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2952             :     Numeric     res;
    2953             : 
    2954       75728 :     res = numeric_sub_opt_error(num1, num2, NULL);
    2955             : 
    2956       75728 :     PG_RETURN_NUMERIC(res);
    2957             : }
    2958             : 
    2959             : 
    2960             : /*
    2961             :  * numeric_sub_opt_error() -
    2962             :  *
    2963             :  *  Internal version of numeric_sub().  If "*have_error" flag is provided,
    2964             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2965             :  *  need to handle errors by itself.
    2966             :  */
    2967             : Numeric
    2968       75878 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2969             : {
    2970             :     NumericVar  arg1;
    2971             :     NumericVar  arg2;
    2972             :     NumericVar  result;
    2973             :     Numeric     res;
    2974             : 
    2975             :     /*
    2976             :      * Handle NaN and infinities
    2977             :      */
    2978       75878 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2979             :     {
    2980         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2981          78 :             return make_result(&const_nan);
    2982         120 :         if (NUMERIC_IS_PINF(num1))
    2983             :         {
    2984          36 :             if (NUMERIC_IS_PINF(num2))
    2985           6 :                 return make_result(&const_nan); /* Inf - Inf */
    2986             :             else
    2987          30 :                 return make_result(&const_pinf);
    2988             :         }
    2989          84 :         if (NUMERIC_IS_NINF(num1))
    2990             :         {
    2991          36 :             if (NUMERIC_IS_NINF(num2))
    2992           6 :                 return make_result(&const_nan); /* -Inf - -Inf */
    2993             :             else
    2994          30 :                 return make_result(&const_ninf);
    2995             :         }
    2996             :         /* by here, num1 must be finite, so num2 is not */
    2997          48 :         if (NUMERIC_IS_PINF(num2))
    2998          24 :             return make_result(&const_ninf);
    2999             :         Assert(NUMERIC_IS_NINF(num2));
    3000          24 :         return make_result(&const_pinf);
    3001             :     }
    3002             : 
    3003             :     /*
    3004             :      * Unpack the values, let sub_var() compute the result and return it.
    3005             :      */
    3006       75680 :     init_var_from_num(num1, &arg1);
    3007       75680 :     init_var_from_num(num2, &arg2);
    3008             : 
    3009       75680 :     init_var(&result);
    3010       75680 :     sub_var(&arg1, &arg2, &result);
    3011             : 
    3012       75680 :     res = make_result_opt_error(&result, have_error);
    3013             : 
    3014       75680 :     free_var(&result);
    3015             : 
    3016       75680 :     return res;
    3017             : }
    3018             : 
    3019             : 
    3020             : /*
    3021             :  * numeric_mul() -
    3022             :  *
    3023             :  *  Calculate the product of two numerics
    3024             :  */
    3025             : Datum
    3026      489710 : numeric_mul(PG_FUNCTION_ARGS)
    3027             : {
    3028      489710 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3029      489710 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3030             :     Numeric     res;
    3031             : 
    3032      489710 :     res = numeric_mul_opt_error(num1, num2, NULL);
    3033             : 
    3034      489710 :     PG_RETURN_NUMERIC(res);
    3035             : }
    3036             : 
    3037             : 
    3038             : /*
    3039             :  * numeric_mul_opt_error() -
    3040             :  *
    3041             :  *  Internal version of numeric_mul().  If "*have_error" flag is provided,
    3042             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3043             :  *  need to handle errors by itself.
    3044             :  */
    3045             : Numeric
    3046      489746 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3047             : {
    3048             :     NumericVar  arg1;
    3049             :     NumericVar  arg2;
    3050             :     NumericVar  result;
    3051             :     Numeric     res;
    3052             : 
    3053             :     /*
    3054             :      * Handle NaN and infinities
    3055             :      */
    3056      489746 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3057             :     {
    3058         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3059          78 :             return make_result(&const_nan);
    3060         120 :         if (NUMERIC_IS_PINF(num1))
    3061             :         {
    3062          36 :             switch (numeric_sign_internal(num2))
    3063             :             {
    3064           6 :                 case 0:
    3065           6 :                     return make_result(&const_nan); /* Inf * 0 */
    3066          18 :                 case 1:
    3067          18 :                     return make_result(&const_pinf);
    3068          12 :                 case -1:
    3069          12 :                     return make_result(&const_ninf);
    3070             :             }
    3071             :             Assert(false);
    3072             :         }
    3073          84 :         if (NUMERIC_IS_NINF(num1))
    3074             :         {
    3075          36 :             switch (numeric_sign_internal(num2))
    3076             :             {
    3077           6 :                 case 0:
    3078           6 :                     return make_result(&const_nan); /* -Inf * 0 */
    3079          18 :                 case 1:
    3080          18 :                     return make_result(&const_ninf);
    3081          12 :                 case -1:
    3082          12 :                     return make_result(&const_pinf);
    3083             :             }
    3084             :             Assert(false);
    3085             :         }
    3086             :         /* by here, num1 must be finite, so num2 is not */
    3087          48 :         if (NUMERIC_IS_PINF(num2))
    3088             :         {
    3089          24 :             switch (numeric_sign_internal(num1))
    3090             :             {
    3091           6 :                 case 0:
    3092           6 :                     return make_result(&const_nan); /* 0 * Inf */
    3093          12 :                 case 1:
    3094          12 :                     return make_result(&const_pinf);
    3095           6 :                 case -1:
    3096           6 :                     return make_result(&const_ninf);
    3097             :             }
    3098             :             Assert(false);
    3099             :         }
    3100             :         Assert(NUMERIC_IS_NINF(num2));
    3101          24 :         switch (numeric_sign_internal(num1))
    3102             :         {
    3103           6 :             case 0:
    3104           6 :                 return make_result(&const_nan); /* 0 * -Inf */
    3105          12 :             case 1:
    3106          12 :                 return make_result(&const_ninf);
    3107           6 :             case -1:
    3108           6 :                 return make_result(&const_pinf);
    3109             :         }
    3110             :         Assert(false);
    3111             :     }
    3112             : 
    3113             :     /*
    3114             :      * Unpack the values, let mul_var() compute the result and return it.
    3115             :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3116             :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3117             :      * we request exact representation for the product (rscale = sum(dscale of
    3118             :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3119             :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3120             :      * after computing the exact result ensures that the final result is
    3121             :      * correctly rounded (rounding in mul_var() using a truncated product
    3122             :      * would not guarantee this).
    3123             :      */
    3124      489548 :     init_var_from_num(num1, &arg1);
    3125      489548 :     init_var_from_num(num2, &arg2);
    3126             : 
    3127      489548 :     init_var(&result);
    3128      489548 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3129             : 
    3130      489548 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3131           6 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3132             : 
    3133      489548 :     res = make_result_opt_error(&result, have_error);
    3134             : 
    3135      489548 :     free_var(&result);
    3136             : 
    3137      489548 :     return res;
    3138             : }
    3139             : 
    3140             : 
    3141             : /*
    3142             :  * numeric_div() -
    3143             :  *
    3144             :  *  Divide one numeric into another
    3145             :  */
    3146             : Datum
    3147      148258 : numeric_div(PG_FUNCTION_ARGS)
    3148             : {
    3149      148258 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3150      148258 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3151             :     Numeric     res;
    3152             : 
    3153      148258 :     res = numeric_div_opt_error(num1, num2, NULL);
    3154             : 
    3155      148226 :     PG_RETURN_NUMERIC(res);
    3156             : }
    3157             : 
    3158             : 
    3159             : /*
    3160             :  * numeric_div_opt_error() -
    3161             :  *
    3162             :  *  Internal version of numeric_div().  If "*have_error" flag is provided,
    3163             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3164             :  *  need to handle errors by itself.
    3165             :  */
    3166             : Numeric
    3167      149098 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3168             : {
    3169             :     NumericVar  arg1;
    3170             :     NumericVar  arg2;
    3171             :     NumericVar  result;
    3172             :     Numeric     res;
    3173             :     int         rscale;
    3174             : 
    3175      149098 :     if (have_error)
    3176          48 :         *have_error = false;
    3177             : 
    3178             :     /*
    3179             :      * Handle NaN and infinities
    3180             :      */
    3181      149098 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3182             :     {
    3183         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3184          78 :             return make_result(&const_nan);
    3185         120 :         if (NUMERIC_IS_PINF(num1))
    3186             :         {
    3187          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3188          12 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3189          24 :             switch (numeric_sign_internal(num2))
    3190             :             {
    3191           6 :                 case 0:
    3192           6 :                     if (have_error)
    3193             :                     {
    3194           0 :                         *have_error = true;
    3195           0 :                         return NULL;
    3196             :                     }
    3197           6 :                     ereport(ERROR,
    3198             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3199             :                              errmsg("division by zero")));
    3200             :                     break;
    3201          12 :                 case 1:
    3202          12 :                     return make_result(&const_pinf);
    3203           6 :                 case -1:
    3204           6 :                     return make_result(&const_ninf);
    3205             :             }
    3206             :             Assert(false);
    3207             :         }
    3208          84 :         if (NUMERIC_IS_NINF(num1))
    3209             :         {
    3210          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3211          12 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
    3212          24 :             switch (numeric_sign_internal(num2))
    3213             :             {
    3214           6 :                 case 0:
    3215           6 :                     if (have_error)
    3216             :                     {
    3217           0 :                         *have_error = true;
    3218           0 :                         return NULL;
    3219             :                     }
    3220           6 :                     ereport(ERROR,
    3221             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3222             :                              errmsg("division by zero")));
    3223             :                     break;
    3224          12 :                 case 1:
    3225          12 :                     return make_result(&const_ninf);
    3226           6 :                 case -1:
    3227           6 :                     return make_result(&const_pinf);
    3228             :             }
    3229             :             Assert(false);
    3230             :         }
    3231             :         /* by here, num1 must be finite, so num2 is not */
    3232             : 
    3233             :         /*
    3234             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3235             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3236             :          * really do underflow, so let's just return zero.
    3237             :          */
    3238          48 :         return make_result(&const_zero);
    3239             :     }
    3240             : 
    3241             :     /*
    3242             :      * Unpack the arguments
    3243             :      */
    3244      148900 :     init_var_from_num(num1, &arg1);
    3245      148900 :     init_var_from_num(num2, &arg2);
    3246             : 
    3247      148900 :     init_var(&result);
    3248             : 
    3249             :     /*
    3250             :      * Select scale for division result
    3251             :      */
    3252      148900 :     rscale = select_div_scale(&arg1, &arg2);
    3253             : 
    3254             :     /*
    3255             :      * If "have_error" is provided, check for division by zero here
    3256             :      */
    3257      148900 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3258             :     {
    3259          12 :         *have_error = true;
    3260          12 :         return NULL;
    3261             :     }
    3262             : 
    3263             :     /*
    3264             :      * Do the divide and return the result
    3265             :      */
    3266      148888 :     div_var(&arg1, &arg2, &result, rscale, true, true);
    3267             : 
    3268      148850 :     res = make_result_opt_error(&result, have_error);
    3269             : 
    3270      148850 :     free_var(&result);
    3271             : 
    3272      148850 :     return res;
    3273             : }
    3274             : 
    3275             : 
    3276             : /*
    3277             :  * numeric_div_trunc() -
    3278             :  *
    3279             :  *  Divide one numeric into another, truncating the result to an integer
    3280             :  */
    3281             : Datum
    3282        1218 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3283             : {
    3284        1218 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3285        1218 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3286             :     NumericVar  arg1;
    3287             :     NumericVar  arg2;
    3288             :     NumericVar  result;
    3289             :     Numeric     res;
    3290             : 
    3291             :     /*
    3292             :      * Handle NaN and infinities
    3293             :      */
    3294        1218 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3295             :     {
    3296         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3297          78 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3298         120 :         if (NUMERIC_IS_PINF(num1))
    3299             :         {
    3300          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3301          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3302          24 :             switch (numeric_sign_internal(num2))
    3303             :             {
    3304           6 :                 case 0:
    3305           6 :                     ereport(ERROR,
    3306             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3307             :                              errmsg("division by zero")));
    3308             :                     break;
    3309          12 :                 case 1:
    3310          12 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3311           6 :                 case -1:
    3312           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3313             :             }
    3314             :             Assert(false);
    3315             :         }
    3316          84 :         if (NUMERIC_IS_NINF(num1))
    3317             :         {
    3318          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3319          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3320          24 :             switch (numeric_sign_internal(num2))
    3321             :             {
    3322           6 :                 case 0:
    3323           6 :                     ereport(ERROR,
    3324             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3325             :                              errmsg("division by zero")));
    3326             :                     break;
    3327          12 :                 case 1:
    3328          12 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3329           6 :                 case -1:
    3330           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3331             :             }
    3332             :             Assert(false);
    3333             :         }
    3334             :         /* by here, num1 must be finite, so num2 is not */
    3335             : 
    3336             :         /*
    3337             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3338             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3339             :          * really do underflow, so let's just return zero.
    3340             :          */
    3341          48 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3342             :     }
    3343             : 
    3344             :     /*
    3345             :      * Unpack the arguments
    3346             :      */
    3347        1020 :     init_var_from_num(num1, &arg1);
    3348        1020 :     init_var_from_num(num2, &arg2);
    3349             : 
    3350        1020 :     init_var(&result);
    3351             : 
    3352             :     /*
    3353             :      * Do the divide and return the result
    3354             :      */
    3355        1020 :     div_var(&arg1, &arg2, &result, 0, false, true);
    3356             : 
    3357        1014 :     res = make_result(&result);
    3358             : 
    3359        1014 :     free_var(&result);
    3360             : 
    3361        1014 :     PG_RETURN_NUMERIC(res);
    3362             : }
    3363             : 
    3364             : 
    3365             : /*
    3366             :  * numeric_mod() -
    3367             :  *
    3368             :  *  Calculate the modulo of two numerics
    3369             :  */
    3370             : Datum
    3371      413366 : numeric_mod(PG_FUNCTION_ARGS)
    3372             : {
    3373      413366 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3374      413366 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3375             :     Numeric     res;
    3376             : 
    3377      413366 :     res = numeric_mod_opt_error(num1, num2, NULL);
    3378             : 
    3379      413348 :     PG_RETURN_NUMERIC(res);
    3380             : }
    3381             : 
    3382             : 
    3383             : /*
    3384             :  * numeric_mod_opt_error() -
    3385             :  *
    3386             :  *  Internal version of numeric_mod().  If "*have_error" flag is provided,
    3387             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3388             :  *  need to handle errors by itself.
    3389             :  */
    3390             : Numeric
    3391      413378 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3392             : {
    3393             :     Numeric     res;
    3394             :     NumericVar  arg1;
    3395             :     NumericVar  arg2;
    3396             :     NumericVar  result;
    3397             : 
    3398      413378 :     if (have_error)
    3399           0 :         *have_error = false;
    3400             : 
    3401             :     /*
    3402             :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3403             :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3404             :      * returning NaN.  We choose to throw error only for y-is-zero.
    3405             :      */
    3406      413378 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3407             :     {
    3408         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3409          78 :             return make_result(&const_nan);
    3410         120 :         if (NUMERIC_IS_INF(num1))
    3411             :         {
    3412          72 :             if (numeric_sign_internal(num2) == 0)
    3413             :             {
    3414          12 :                 if (have_error)
    3415             :                 {
    3416           0 :                     *have_error = true;
    3417           0 :                     return NULL;
    3418             :                 }
    3419          12 :                 ereport(ERROR,
    3420             :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
    3421             :                          errmsg("division by zero")));
    3422             :             }
    3423             :             /* Inf % any nonzero = NaN */
    3424          60 :             return make_result(&const_nan);
    3425             :         }
    3426             :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3427          48 :         return duplicate_numeric(num1);
    3428             :     }
    3429             : 
    3430      413180 :     init_var_from_num(num1, &arg1);
    3431      413180 :     init_var_from_num(num2, &arg2);
    3432             : 
    3433      413180 :     init_var(&result);
    3434             : 
    3435             :     /*
    3436             :      * If "have_error" is provided, check for division by zero here
    3437             :      */
    3438      413180 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3439             :     {
    3440           0 :         *have_error = true;
    3441           0 :         return NULL;
    3442             :     }
    3443             : 
    3444      413180 :     mod_var(&arg1, &arg2, &result);
    3445             : 
    3446      413168 :     res = make_result_opt_error(&result, NULL);
    3447             : 
    3448      413168 :     free_var(&result);
    3449             : 
    3450      413168 :     return res;
    3451             : }
    3452             : 
    3453             : 
    3454             : /*
    3455             :  * numeric_inc() -
    3456             :  *
    3457             :  *  Increment a number by one
    3458             :  */
    3459             : Datum
    3460          48 : numeric_inc(PG_FUNCTION_ARGS)
    3461             : {
    3462          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3463             :     NumericVar  arg;
    3464             :     Numeric     res;
    3465             : 
    3466             :     /*
    3467             :      * Handle NaN and infinities
    3468             :      */
    3469          48 :     if (NUMERIC_IS_SPECIAL(num))
    3470          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3471             : 
    3472             :     /*
    3473             :      * Compute the result and return it
    3474             :      */
    3475          30 :     init_var_from_num(num, &arg);
    3476             : 
    3477          30 :     add_var(&arg, &const_one, &arg);
    3478             : 
    3479          30 :     res = make_result(&arg);
    3480             : 
    3481          30 :     free_var(&arg);
    3482             : 
    3483          30 :     PG_RETURN_NUMERIC(res);
    3484             : }
    3485             : 
    3486             : 
    3487             : /*
    3488             :  * numeric_smaller() -
    3489             :  *
    3490             :  *  Return the smaller of two numbers
    3491             :  */
    3492             : Datum
    3493         798 : numeric_smaller(PG_FUNCTION_ARGS)
    3494             : {
    3495         798 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3496         798 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3497             : 
    3498             :     /*
    3499             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3500             :      * particularly as regards comparisons involving NaN.
    3501             :      */
    3502         798 :     if (cmp_numerics(num1, num2) < 0)
    3503         646 :         PG_RETURN_NUMERIC(num1);
    3504             :     else
    3505         152 :         PG_RETURN_NUMERIC(num2);
    3506             : }
    3507             : 
    3508             : 
    3509             : /*
    3510             :  * numeric_larger() -
    3511             :  *
    3512             :  *  Return the larger of two numbers
    3513             :  */
    3514             : Datum
    3515       18630 : numeric_larger(PG_FUNCTION_ARGS)
    3516             : {
    3517       18630 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3518       18630 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3519             : 
    3520             :     /*
    3521             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3522             :      * particularly as regards comparisons involving NaN.
    3523             :      */
    3524       18630 :     if (cmp_numerics(num1, num2) > 0)
    3525       17890 :         PG_RETURN_NUMERIC(num1);
    3526             :     else
    3527         740 :         PG_RETURN_NUMERIC(num2);
    3528             : }
    3529             : 
    3530             : 
    3531             : /* ----------------------------------------------------------------------
    3532             :  *
    3533             :  * Advanced math functions
    3534             :  *
    3535             :  * ----------------------------------------------------------------------
    3536             :  */
    3537             : 
    3538             : /*
    3539             :  * numeric_gcd() -
    3540             :  *
    3541             :  *  Calculate the greatest common divisor of two numerics
    3542             :  */
    3543             : Datum
    3544         216 : numeric_gcd(PG_FUNCTION_ARGS)
    3545             : {
    3546         216 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3547         216 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3548             :     NumericVar  arg1;
    3549             :     NumericVar  arg2;
    3550             :     NumericVar  result;
    3551             :     Numeric     res;
    3552             : 
    3553             :     /*
    3554             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3555             :      * cases.
    3556             :      */
    3557         216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3558          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3559             : 
    3560             :     /*
    3561             :      * Unpack the arguments
    3562             :      */
    3563         120 :     init_var_from_num(num1, &arg1);
    3564         120 :     init_var_from_num(num2, &arg2);
    3565             : 
    3566         120 :     init_var(&result);
    3567             : 
    3568             :     /*
    3569             :      * Find the GCD and return the result
    3570             :      */
    3571         120 :     gcd_var(&arg1, &arg2, &result);
    3572             : 
    3573         120 :     res = make_result(&result);
    3574             : 
    3575         120 :     free_var(&result);
    3576             : 
    3577         120 :     PG_RETURN_NUMERIC(res);
    3578             : }
    3579             : 
    3580             : 
    3581             : /*
    3582             :  * numeric_lcm() -
    3583             :  *
    3584             :  *  Calculate the least common multiple of two numerics
    3585             :  */
    3586             : Datum
    3587         246 : numeric_lcm(PG_FUNCTION_ARGS)
    3588             : {
    3589         246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3590         246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3591             :     NumericVar  arg1;
    3592             :     NumericVar  arg2;
    3593             :     NumericVar  result;
    3594             :     Numeric     res;
    3595             : 
    3596             :     /*
    3597             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3598             :      * cases.
    3599             :      */
    3600         246 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3601          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3602             : 
    3603             :     /*
    3604             :      * Unpack the arguments
    3605             :      */
    3606         150 :     init_var_from_num(num1, &arg1);
    3607         150 :     init_var_from_num(num2, &arg2);
    3608             : 
    3609         150 :     init_var(&result);
    3610             : 
    3611             :     /*
    3612             :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3613             :      * zero if either input is zero.
    3614             :      *
    3615             :      * Note that the division is guaranteed to be exact, returning an integer
    3616             :      * result, so the LCM is an integral multiple of both x and y.  A display
    3617             :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3618             :      * but as with other numeric functions, we choose to return a result whose
    3619             :      * display scale is no smaller than either input.
    3620             :      */
    3621         150 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3622          48 :         set_var_from_var(&const_zero, &result);
    3623             :     else
    3624             :     {
    3625         102 :         gcd_var(&arg1, &arg2, &result);
    3626         102 :         div_var(&arg1, &result, &result, 0, false, true);
    3627         102 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3628         102 :         result.sign = NUMERIC_POS;
    3629             :     }
    3630             : 
    3631         150 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3632             : 
    3633         150 :     res = make_result(&result);
    3634             : 
    3635         144 :     free_var(&result);
    3636             : 
    3637         144 :     PG_RETURN_NUMERIC(res);
    3638             : }
    3639             : 
    3640             : 
    3641             : /*
    3642             :  * numeric_fac()
    3643             :  *
    3644             :  * Compute factorial
    3645             :  */
    3646             : Datum
    3647          42 : numeric_fac(PG_FUNCTION_ARGS)
    3648             : {
    3649          42 :     int64       num = PG_GETARG_INT64(0);
    3650             :     Numeric     res;
    3651             :     NumericVar  fact;
    3652             :     NumericVar  result;
    3653             : 
    3654          42 :     if (num < 0)
    3655           6 :         ereport(ERROR,
    3656             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3657             :                  errmsg("factorial of a negative number is undefined")));
    3658          36 :     if (num <= 1)
    3659             :     {
    3660           6 :         res = make_result(&const_one);
    3661           6 :         PG_RETURN_NUMERIC(res);
    3662             :     }
    3663             :     /* Fail immediately if the result would overflow */
    3664          30 :     if (num > 32177)
    3665           6 :         ereport(ERROR,
    3666             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3667             :                  errmsg("value overflows numeric format")));
    3668             : 
    3669          24 :     init_var(&fact);
    3670          24 :     init_var(&result);
    3671             : 
    3672          24 :     int64_to_numericvar(num, &result);
    3673             : 
    3674         294 :     for (num = num - 1; num > 1; num--)
    3675             :     {
    3676             :         /* this loop can take awhile, so allow it to be interrupted */
    3677         270 :         CHECK_FOR_INTERRUPTS();
    3678             : 
    3679         270 :         int64_to_numericvar(num, &fact);
    3680             : 
    3681         270 :         mul_var(&result, &fact, &result, 0);
    3682             :     }
    3683             : 
    3684          24 :     res = make_result(&result);
    3685             : 
    3686          24 :     free_var(&fact);
    3687          24 :     free_var(&result);
    3688             : 
    3689          24 :     PG_RETURN_NUMERIC(res);
    3690             : }
    3691             : 
    3692             : 
    3693             : /*
    3694             :  * numeric_sqrt() -
    3695             :  *
    3696             :  *  Compute the square root of a numeric.
    3697             :  */
    3698             : Datum
    3699         150 : numeric_sqrt(PG_FUNCTION_ARGS)
    3700             : {
    3701         150 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3702             :     Numeric     res;
    3703             :     NumericVar  arg;
    3704             :     NumericVar  result;
    3705             :     int         sweight;
    3706             :     int         rscale;
    3707             : 
    3708             :     /*
    3709             :      * Handle NaN and infinities
    3710             :      */
    3711         150 :     if (NUMERIC_IS_SPECIAL(num))
    3712             :     {
    3713             :         /* error should match that in sqrt_var() */
    3714          18 :         if (NUMERIC_IS_NINF(num))
    3715           6 :             ereport(ERROR,
    3716             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3717             :                      errmsg("cannot take square root of a negative number")));
    3718             :         /* For NAN or PINF, just duplicate the input */
    3719          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3720             :     }
    3721             : 
    3722             :     /*
    3723             :      * Unpack the argument and determine the result scale.  We choose a scale
    3724             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3725             :      * case not less than the input's dscale.
    3726             :      */
    3727         132 :     init_var_from_num(num, &arg);
    3728             : 
    3729         132 :     init_var(&result);
    3730             : 
    3731             :     /*
    3732             :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3733             :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3734             :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3735             :      * a few cycles, since the division is exact and there is no need to round
    3736             :      * towards negative infinity.
    3737             :      */
    3738             : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3739         132 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3740             : #else
    3741             :     if (arg.weight >= 0)
    3742             :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3743             :     else
    3744             :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3745             : #endif
    3746             : 
    3747         132 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3748         132 :     rscale = Max(rscale, arg.dscale);
    3749         132 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3750         132 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3751             : 
    3752             :     /*
    3753             :      * Let sqrt_var() do the calculation and return the result.
    3754             :      */
    3755         132 :     sqrt_var(&arg, &result, rscale);
    3756             : 
    3757         126 :     res = make_result(&result);
    3758             : 
    3759         126 :     free_var(&result);
    3760             : 
    3761         126 :     PG_RETURN_NUMERIC(res);
    3762             : }
    3763             : 
    3764             : 
    3765             : /*
    3766             :  * numeric_exp() -
    3767             :  *
    3768             :  *  Raise e to the power of x
    3769             :  */
    3770             : Datum
    3771          78 : numeric_exp(PG_FUNCTION_ARGS)
    3772             : {
    3773          78 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3774             :     Numeric     res;
    3775             :     NumericVar  arg;
    3776             :     NumericVar  result;
    3777             :     int         rscale;
    3778             :     double      val;
    3779             : 
    3780             :     /*
    3781             :      * Handle NaN and infinities
    3782             :      */
    3783          78 :     if (NUMERIC_IS_SPECIAL(num))
    3784             :     {
    3785             :         /* Per POSIX, exp(-Inf) is zero */
    3786          18 :         if (NUMERIC_IS_NINF(num))
    3787           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3788             :         /* For NAN or PINF, just duplicate the input */
    3789          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3790             :     }
    3791             : 
    3792             :     /*
    3793             :      * Unpack the argument and determine the result scale.  We choose a scale
    3794             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3795             :      * case not less than the input's dscale.
    3796             :      */
    3797          60 :     init_var_from_num(num, &arg);
    3798             : 
    3799          60 :     init_var(&result);
    3800             : 
    3801             :     /* convert input to float8, ignoring overflow */
    3802          60 :     val = numericvar_to_double_no_overflow(&arg);
    3803             : 
    3804             :     /*
    3805             :      * log10(result) = num * log10(e), so this is approximately the decimal
    3806             :      * weight of the result:
    3807             :      */
    3808          60 :     val *= 0.434294481903252;
    3809             : 
    3810             :     /* limit to something that won't cause integer overflow */
    3811          60 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3812          60 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3813             : 
    3814          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3815          60 :     rscale = Max(rscale, arg.dscale);
    3816          60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3817          60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3818             : 
    3819             :     /*
    3820             :      * Let exp_var() do the calculation and return the result.
    3821             :      */
    3822          60 :     exp_var(&arg, &result, rscale);
    3823             : 
    3824          60 :     res = make_result(&result);
    3825             : 
    3826          60 :     free_var(&result);
    3827             : 
    3828          60 :     PG_RETURN_NUMERIC(res);
    3829             : }
    3830             : 
    3831             : 
    3832             : /*
    3833             :  * numeric_ln() -
    3834             :  *
    3835             :  *  Compute the natural logarithm of x
    3836             :  */
    3837             : Datum
    3838         198 : numeric_ln(PG_FUNCTION_ARGS)
    3839             : {
    3840         198 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3841             :     Numeric     res;
    3842             :     NumericVar  arg;
    3843             :     NumericVar  result;
    3844             :     int         ln_dweight;
    3845             :     int         rscale;
    3846             : 
    3847             :     /*
    3848             :      * Handle NaN and infinities
    3849             :      */
    3850         198 :     if (NUMERIC_IS_SPECIAL(num))
    3851             :     {
    3852          18 :         if (NUMERIC_IS_NINF(num))
    3853           6 :             ereport(ERROR,
    3854             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3855             :                      errmsg("cannot take logarithm of a negative number")));
    3856             :         /* For NAN or PINF, just duplicate the input */
    3857          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3858             :     }
    3859             : 
    3860         180 :     init_var_from_num(num, &arg);
    3861         180 :     init_var(&result);
    3862             : 
    3863             :     /* Estimated dweight of logarithm */
    3864         180 :     ln_dweight = estimate_ln_dweight(&arg);
    3865             : 
    3866         180 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3867         180 :     rscale = Max(rscale, arg.dscale);
    3868         180 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3869         180 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3870             : 
    3871         180 :     ln_var(&arg, &result, rscale);
    3872             : 
    3873         156 :     res = make_result(&result);
    3874             : 
    3875         156 :     free_var(&result);
    3876             : 
    3877         156 :     PG_RETURN_NUMERIC(res);
    3878             : }
    3879             : 
    3880             : 
    3881             : /*
    3882             :  * numeric_log() -
    3883             :  *
    3884             :  *  Compute the logarithm of x in a given base
    3885             :  */
    3886             : Datum
    3887         342 : numeric_log(PG_FUNCTION_ARGS)
    3888             : {
    3889         342 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3890         342 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3891             :     Numeric     res;
    3892             :     NumericVar  arg1;
    3893             :     NumericVar  arg2;
    3894             :     NumericVar  result;
    3895             : 
    3896             :     /*
    3897             :      * Handle NaN and infinities
    3898             :      */
    3899         342 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3900             :     {
    3901             :         int         sign1,
    3902             :                     sign2;
    3903             : 
    3904         126 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3905          54 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3906             :         /* fail on negative inputs including -Inf, as log_var would */
    3907          72 :         sign1 = numeric_sign_internal(num1);
    3908          72 :         sign2 = numeric_sign_internal(num2);
    3909          72 :         if (sign1 < 0 || sign2 < 0)
    3910          24 :             ereport(ERROR,
    3911             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3912             :                      errmsg("cannot take logarithm of a negative number")));
    3913             :         /* fail on zero inputs, as log_var would */
    3914          48 :         if (sign1 == 0 || sign2 == 0)
    3915           6 :             ereport(ERROR,
    3916             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3917             :                      errmsg("cannot take logarithm of zero")));
    3918          42 :         if (NUMERIC_IS_PINF(num1))
    3919             :         {
    3920             :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    3921          18 :             if (NUMERIC_IS_PINF(num2))
    3922           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    3923             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    3924          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3925             :         }
    3926             :         Assert(NUMERIC_IS_PINF(num2));
    3927             :         /* log(finite-positive, Inf) is Inf */
    3928          24 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    3929             :     }
    3930             : 
    3931             :     /*
    3932             :      * Initialize things
    3933             :      */
    3934         216 :     init_var_from_num(num1, &arg1);
    3935         216 :     init_var_from_num(num2, &arg2);
    3936         216 :     init_var(&result);
    3937             : 
    3938             :     /*
    3939             :      * Call log_var() to compute and return the result; note it handles scale
    3940             :      * selection itself.
    3941             :      */
    3942         216 :     log_var(&arg1, &arg2, &result);
    3943             : 
    3944         156 :     res = make_result(&result);
    3945             : 
    3946         156 :     free_var(&result);
    3947             : 
    3948         156 :     PG_RETURN_NUMERIC(res);
    3949             : }
    3950             : 
    3951             : 
    3952             : /*
    3953             :  * numeric_power() -
    3954             :  *
    3955             :  *  Raise x to the power of y
    3956             :  */
    3957             : Datum
    3958        1644 : numeric_power(PG_FUNCTION_ARGS)
    3959             : {
    3960        1644 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3961        1644 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3962             :     Numeric     res;
    3963             :     NumericVar  arg1;
    3964             :     NumericVar  arg2;
    3965             :     NumericVar  result;
    3966             :     int         sign1,
    3967             :                 sign2;
    3968             : 
    3969             :     /*
    3970             :      * Handle NaN and infinities
    3971             :      */
    3972        1644 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3973             :     {
    3974             :         /*
    3975             :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    3976             :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    3977             :          * (with no error).
    3978             :          */
    3979         234 :         if (NUMERIC_IS_NAN(num1))
    3980             :         {
    3981          54 :             if (!NUMERIC_IS_SPECIAL(num2))
    3982             :             {
    3983          36 :                 init_var_from_num(num2, &arg2);
    3984          36 :                 if (cmp_var(&arg2, &const_zero) == 0)
    3985          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3986             :             }
    3987          42 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3988             :         }
    3989         180 :         if (NUMERIC_IS_NAN(num2))
    3990             :         {
    3991          42 :             if (!NUMERIC_IS_SPECIAL(num1))
    3992             :             {
    3993          36 :                 init_var_from_num(num1, &arg1);
    3994          36 :                 if (cmp_var(&arg1, &const_one) == 0)
    3995          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3996             :             }
    3997          30 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3998             :         }
    3999             :         /* At least one input is infinite, but error rules still apply */
    4000         138 :         sign1 = numeric_sign_internal(num1);
    4001         138 :         sign2 = numeric_sign_internal(num2);
    4002         138 :         if (sign1 == 0 && sign2 < 0)
    4003           6 :             ereport(ERROR,
    4004             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4005             :                      errmsg("zero raised to a negative power is undefined")));
    4006         132 :         if (sign1 < 0 && !numeric_is_integral(num2))
    4007           6 :             ereport(ERROR,
    4008             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4009             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    4010             : 
    4011             :         /*
    4012             :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    4013             :          *
    4014             :          * For any value of y, if x is +1, 1.0 shall be returned.
    4015             :          */
    4016         126 :         if (!NUMERIC_IS_SPECIAL(num1))
    4017             :         {
    4018          42 :             init_var_from_num(num1, &arg1);
    4019          42 :             if (cmp_var(&arg1, &const_one) == 0)
    4020           6 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    4021             :         }
    4022             : 
    4023             :         /*
    4024             :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    4025             :          */
    4026         120 :         if (sign2 == 0)
    4027          12 :             PG_RETURN_NUMERIC(make_result(&const_one));
    4028             : 
    4029             :         /*
    4030             :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    4031             :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    4032             :          * be returned.  (Since we don't deal in minus zero, we need not
    4033             :          * distinguish these two cases.)
    4034             :          */
    4035         108 :         if (sign1 == 0 && sign2 > 0)
    4036           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4037             : 
    4038             :         /*
    4039             :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    4040             :          *
    4041             :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4042             :          *
    4043             :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4044             :          *
    4045             :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4046             :          *
    4047             :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4048             :          */
    4049         102 :         if (NUMERIC_IS_INF(num2))
    4050             :         {
    4051             :             bool        abs_x_gt_one;
    4052             : 
    4053          54 :             if (NUMERIC_IS_SPECIAL(num1))
    4054          24 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4055             :             else
    4056             :             {
    4057          30 :                 init_var_from_num(num1, &arg1);
    4058          30 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4059           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4060          24 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4061          24 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4062             :             }
    4063          48 :             if (abs_x_gt_one == (sign2 > 0))
    4064          30 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4065             :             else
    4066          18 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4067             :         }
    4068             : 
    4069             :         /*
    4070             :          * For y < 0, if x is +Inf, +0 shall be returned.
    4071             :          *
    4072             :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4073             :          */
    4074          48 :         if (NUMERIC_IS_PINF(num1))
    4075             :         {
    4076          24 :             if (sign2 > 0)
    4077          18 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4078             :             else
    4079           6 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4080             :         }
    4081             : 
    4082             :         Assert(NUMERIC_IS_NINF(num1));
    4083             : 
    4084             :         /*
    4085             :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4086             :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4087             :          * (Again, we need not distinguish these two cases.)
    4088             :          */
    4089          24 :         if (sign2 < 0)
    4090          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4091             : 
    4092             :         /*
    4093             :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4094             :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4095             :          */
    4096          12 :         init_var_from_num(num2, &arg2);
    4097          12 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4098          12 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4099           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4100             :         else
    4101           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4102             :     }
    4103             : 
    4104             :     /*
    4105             :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4106             :      * certain error conditions.  Specifically, we don't return a
    4107             :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4108             :      * non-integer power must produce the same error code, but that case is
    4109             :      * handled in power_var().
    4110             :      */
    4111        1410 :     sign1 = numeric_sign_internal(num1);
    4112        1410 :     sign2 = numeric_sign_internal(num2);
    4113             : 
    4114        1410 :     if (sign1 == 0 && sign2 < 0)
    4115          12 :         ereport(ERROR,
    4116             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4117             :                  errmsg("zero raised to a negative power is undefined")));
    4118             : 
    4119             :     /*
    4120             :      * Initialize things
    4121             :      */
    4122        1398 :     init_var(&result);
    4123        1398 :     init_var_from_num(num1, &arg1);
    4124        1398 :     init_var_from_num(num2, &arg2);
    4125             : 
    4126             :     /*
    4127             :      * Call power_var() to compute and return the result; note it handles
    4128             :      * scale selection itself.
    4129             :      */
    4130        1398 :     power_var(&arg1, &arg2, &result);
    4131             : 
    4132        1368 :     res = make_result(&result);
    4133             : 
    4134        1368 :     free_var(&result);
    4135             : 
    4136        1368 :     PG_RETURN_NUMERIC(res);
    4137             : }
    4138             : 
    4139             : /*
    4140             :  * numeric_scale() -
    4141             :  *
    4142             :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4143             :  */
    4144             : Datum
    4145         108 : numeric_scale(PG_FUNCTION_ARGS)
    4146             : {
    4147         108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4148             : 
    4149         108 :     if (NUMERIC_IS_SPECIAL(num))
    4150          18 :         PG_RETURN_NULL();
    4151             : 
    4152          90 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4153             : }
    4154             : 
    4155             : /*
    4156             :  * Calculate minimum scale for value.
    4157             :  */
    4158             : static int
    4159         372 : get_min_scale(NumericVar *var)
    4160             : {
    4161             :     int         min_scale;
    4162             :     int         last_digit_pos;
    4163             : 
    4164             :     /*
    4165             :      * Ordinarily, the input value will be "stripped" so that the last
    4166             :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4167             :      * loop if it isn't, so explicitly find the last nonzero digit.
    4168             :      */
    4169         372 :     last_digit_pos = var->ndigits - 1;
    4170         372 :     while (last_digit_pos >= 0 &&
    4171         342 :            var->digits[last_digit_pos] == 0)
    4172           0 :         last_digit_pos--;
    4173             : 
    4174         372 :     if (last_digit_pos >= 0)
    4175             :     {
    4176             :         /* compute min_scale assuming that last ndigit has no zeroes */
    4177         342 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4178             : 
    4179             :         /*
    4180             :          * We could get a negative result if there are no digits after the
    4181             :          * decimal point.  In this case the min_scale must be zero.
    4182             :          */
    4183         342 :         if (min_scale > 0)
    4184             :         {
    4185             :             /*
    4186             :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4187             :              * zero.
    4188             :              */
    4189         186 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4190             : 
    4191         498 :             while (last_digit % 10 == 0)
    4192             :             {
    4193         312 :                 min_scale--;
    4194         312 :                 last_digit /= 10;
    4195             :             }
    4196             :         }
    4197             :         else
    4198         156 :             min_scale = 0;
    4199             :     }
    4200             :     else
    4201          30 :         min_scale = 0;          /* result if input is zero */
    4202             : 
    4203         372 :     return min_scale;
    4204             : }
    4205             : 
    4206             : /*
    4207             :  * Returns minimum scale required to represent supplied value without loss.
    4208             :  */
    4209             : Datum
    4210          72 : numeric_min_scale(PG_FUNCTION_ARGS)
    4211             : {
    4212          72 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4213             :     NumericVar  arg;
    4214             :     int         min_scale;
    4215             : 
    4216          72 :     if (NUMERIC_IS_SPECIAL(num))
    4217          12 :         PG_RETURN_NULL();
    4218             : 
    4219          60 :     init_var_from_num(num, &arg);
    4220          60 :     min_scale = get_min_scale(&arg);
    4221          60 :     free_var(&arg);
    4222             : 
    4223          60 :     PG_RETURN_INT32(min_scale);
    4224             : }
    4225             : 
    4226             : /*
    4227             :  * Reduce scale of numeric value to represent supplied value without loss.
    4228             :  */
    4229             : Datum
    4230         324 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4231             : {
    4232         324 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4233             :     Numeric     res;
    4234             :     NumericVar  result;
    4235             : 
    4236         324 :     if (NUMERIC_IS_SPECIAL(num))
    4237          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4238             : 
    4239         312 :     init_var_from_num(num, &result);
    4240         312 :     result.dscale = get_min_scale(&result);
    4241         312 :     res = make_result(&result);
    4242         312 :     free_var(&result);
    4243             : 
    4244         312 :     PG_RETURN_NUMERIC(res);
    4245             : }
    4246             : 
    4247             : /*
    4248             :  * Return a random numeric value in the range [rmin, rmax].
    4249             :  */
    4250             : Numeric
    4251       33462 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
    4252             : {
    4253             :     NumericVar  rmin_var;
    4254             :     NumericVar  rmax_var;
    4255             :     NumericVar  result;
    4256             :     Numeric     res;
    4257             : 
    4258             :     /* Range bounds must not be NaN/infinity */
    4259       33462 :     if (NUMERIC_IS_SPECIAL(rmin))
    4260             :     {
    4261          12 :         if (NUMERIC_IS_NAN(rmin))
    4262           6 :             ereport(ERROR,
    4263             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4264             :                     errmsg("lower bound cannot be NaN"));
    4265             :         else
    4266           6 :             ereport(ERROR,
    4267             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4268             :                     errmsg("lower bound cannot be infinity"));
    4269             :     }
    4270       33450 :     if (NUMERIC_IS_SPECIAL(rmax))
    4271             :     {
    4272          12 :         if (NUMERIC_IS_NAN(rmax))
    4273           6 :             ereport(ERROR,
    4274             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4275             :                     errmsg("upper bound cannot be NaN"));
    4276             :         else
    4277           6 :             ereport(ERROR,
    4278             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4279             :                     errmsg("upper bound cannot be infinity"));
    4280             :     }
    4281             : 
    4282             :     /* Return a random value in the range [rmin, rmax] */
    4283       33438 :     init_var_from_num(rmin, &rmin_var);
    4284       33438 :     init_var_from_num(rmax, &rmax_var);
    4285             : 
    4286       33438 :     init_var(&result);
    4287             : 
    4288       33438 :     random_var(state, &rmin_var, &rmax_var, &result);
    4289             : 
    4290       33432 :     res = make_result(&result);
    4291             : 
    4292       33432 :     free_var(&result);
    4293             : 
    4294       33432 :     return res;
    4295             : }
    4296             : 
    4297             : 
    4298             : /* ----------------------------------------------------------------------
    4299             :  *
    4300             :  * Type conversion functions
    4301             :  *
    4302             :  * ----------------------------------------------------------------------
    4303             :  */
    4304             : 
    4305             : Numeric
    4306     1868506 : int64_to_numeric(int64 val)
    4307             : {
    4308             :     Numeric     res;
    4309             :     NumericVar  result;
    4310             : 
    4311     1868506 :     init_var(&result);
    4312             : 
    4313     1868506 :     int64_to_numericvar(val, &result);
    4314             : 
    4315     1868506 :     res = make_result(&result);
    4316             : 
    4317     1868506 :     free_var(&result);
    4318             : 
    4319     1868506 :     return res;
    4320             : }
    4321             : 
    4322             : /*
    4323             :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4324             :  * numeric division.
    4325             :  */
    4326             : Numeric
    4327       29380 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4328             : {
    4329             :     Numeric     res;
    4330             :     NumericVar  result;
    4331             :     int         rscale;
    4332             :     int         w;
    4333             :     int         m;
    4334             : 
    4335       29380 :     init_var(&result);
    4336             : 
    4337             :     /* result scale */
    4338       29380 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4339             : 
    4340             :     /* how much to decrease the weight by */
    4341       29380 :     w = log10val2 / DEC_DIGITS;
    4342             :     /* how much is left to divide by */
    4343       29380 :     m = log10val2 % DEC_DIGITS;
    4344       29380 :     if (m < 0)
    4345             :     {
    4346           0 :         m += DEC_DIGITS;
    4347           0 :         w--;
    4348             :     }
    4349             : 
    4350             :     /*
    4351             :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4352             :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4353             :      * one more.
    4354             :      */
    4355       29380 :     if (m > 0)
    4356             :     {
    4357             : #if DEC_DIGITS == 4
    4358             :         static const int pow10[] = {1, 10, 100, 1000};
    4359             : #elif DEC_DIGITS == 2
    4360             :         static const int pow10[] = {1, 10};
    4361             : #elif DEC_DIGITS == 1
    4362             :         static const int pow10[] = {1};
    4363             : #else
    4364             : #error unsupported NBASE
    4365             : #endif
    4366       29380 :         int64       factor = pow10[DEC_DIGITS - m];
    4367             :         int64       new_val1;
    4368             : 
    4369             :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4370             : 
    4371       29380 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4372             :         {
    4373             :             /* do the multiplication using 128-bit integers */
    4374             :             INT128      tmp;
    4375             : 
    4376          12 :             tmp = int64_to_int128(0);
    4377          12 :             int128_add_int64_mul_int64(&tmp, val1, factor);
    4378             : 
    4379          12 :             int128_to_numericvar(tmp, &result);
    4380             :         }
    4381             :         else
    4382       29368 :             int64_to_numericvar(new_val1, &result);
    4383             : 
    4384       29380 :         w++;
    4385             :     }
    4386             :     else
    4387           0 :         int64_to_numericvar(val1, &result);
    4388             : 
    4389       29380 :     result.weight -= w;
    4390       29380 :     result.dscale = rscale;
    4391             : 
    4392       29380 :     res = make_result(&result);
    4393             : 
    4394       29380 :     free_var(&result);
    4395             : 
    4396       29380 :     return res;
    4397             : }
    4398             : 
    4399             : Datum
    4400     1554994 : int4_numeric(PG_FUNCTION_ARGS)
    4401             : {
    4402     1554994 :     int32       val = PG_GETARG_INT32(0);
    4403             : 
    4404     1554994 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4405             : }
    4406             : 
    4407             : int32
    4408        7752 : numeric_int4_opt_error(Numeric num, bool *have_error)
    4409             : {
    4410             :     NumericVar  x;
    4411             :     int32       result;
    4412             : 
    4413        7752 :     if (have_error)
    4414        1584 :         *have_error = false;
    4415             : 
    4416        7752 :     if (NUMERIC_IS_SPECIAL(num))
    4417             :     {
    4418          18 :         if (have_error)
    4419             :         {
    4420           0 :             *have_error = true;
    4421           0 :             return 0;
    4422             :         }
    4423             :         else
    4424             :         {
    4425          18 :             if (NUMERIC_IS_NAN(num))
    4426           6 :                 ereport(ERROR,
    4427             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4428             :                          errmsg("cannot convert NaN to %s", "integer")));
    4429             :             else
    4430          12 :                 ereport(ERROR,
    4431             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4432             :                          errmsg("cannot convert infinity to %s", "integer")));
    4433             :         }
    4434             :     }
    4435             : 
    4436             :     /* Convert to variable format, then convert to int4 */
    4437        7734 :     init_var_from_num(num, &x);
    4438             : 
    4439        7734 :     if (!numericvar_to_int32(&x, &result))
    4440             :     {
    4441          90 :         if (have_error)
    4442             :         {
    4443          78 :             *have_error = true;
    4444          78 :             return 0;
    4445             :         }
    4446             :         else
    4447             :         {
    4448          12 :             ereport(ERROR,
    4449             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4450             :                      errmsg("integer out of range")));
    4451             :         }
    4452             :     }
    4453             : 
    4454        7644 :     return result;
    4455             : }
    4456             : 
    4457             : Datum
    4458        6168 : numeric_int4(PG_FUNCTION_ARGS)
    4459             : {
    4460        6168 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4461             : 
    4462        6168 :     PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
    4463             : }
    4464             : 
    4465             : /*
    4466             :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4467             :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4468             :  * The input NumericVar is *not* free'd.
    4469             :  */
    4470             : static bool
    4471        8478 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4472             : {
    4473             :     int64       val;
    4474             : 
    4475        8478 :     if (!numericvar_to_int64(var, &val))
    4476           6 :         return false;
    4477             : 
    4478        8472 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4479          84 :         return false;
    4480             : 
    4481             :     /* Down-convert to int4 */
    4482        8388 :     *result = (int32) val;
    4483             : 
    4484        8388 :     return true;
    4485             : }
    4486             : 
    4487             : Datum
    4488       36850 : int8_numeric(PG_FUNCTION_ARGS)
    4489             : {
    4490       36850 :     int64       val = PG_GETARG_INT64(0);
    4491             : 
    4492       36850 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4493             : }
    4494             : 
    4495             : int64
    4496         570 : numeric_int8_opt_error(Numeric num, bool *have_error)
    4497             : {
    4498             :     NumericVar  x;
    4499             :     int64       result;
    4500             : 
    4501         570 :     if (have_error)
    4502          48 :         *have_error = false;
    4503             : 
    4504         570 :     if (NUMERIC_IS_SPECIAL(num))
    4505             :     {
    4506          18 :         if (have_error)
    4507             :         {
    4508           0 :             *have_error = true;
    4509           0 :             return 0;
    4510             :         }
    4511             :         else
    4512             :         {
    4513          18 :             if (NUMERIC_IS_NAN(num))
    4514           6 :                 ereport(ERROR,
    4515             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4516             :                          errmsg("cannot convert NaN to %s", "bigint")));
    4517             :             else
    4518          12 :                 ereport(ERROR,
    4519             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4520             :                          errmsg("cannot convert infinity to %s", "bigint")));
    4521             :         }
    4522             :     }
    4523             : 
    4524             :     /* Convert to variable format, then convert to int8 */
    4525         552 :     init_var_from_num(num, &x);
    4526             : 
    4527         552 :     if (!numericvar_to_int64(&x, &result))
    4528             :     {
    4529          60 :         if (have_error)
    4530             :         {
    4531          12 :             *have_error = true;
    4532          12 :             return 0;
    4533             :         }
    4534             :         else
    4535             :         {
    4536          48 :             ereport(ERROR,
    4537             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4538             :                      errmsg("bigint out of range")));
    4539             :         }
    4540             :     }
    4541             : 
    4542         492 :     return result;
    4543             : }
    4544             : 
    4545             : Datum
    4546         522 : numeric_int8(PG_FUNCTION_ARGS)
    4547             : {
    4548         522 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4549             : 
    4550         522 :     PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
    4551             : }
    4552             : 
    4553             : 
    4554             : Datum
    4555           6 : int2_numeric(PG_FUNCTION_ARGS)
    4556             : {
    4557           6 :     int16       val = PG_GETARG_INT16(0);
    4558             : 
    4559           6 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4560             : }
    4561             : 
    4562             : 
    4563             : Datum
    4564         102 : numeric_int2(PG_FUNCTION_ARGS)
    4565             : {
    4566         102 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4567             :     NumericVar  x;
    4568             :     int64       val;
    4569             :     int16       result;
    4570             : 
    4571         102 :     if (NUMERIC_IS_SPECIAL(num))
    4572             :     {
    4573          18 :         if (NUMERIC_IS_NAN(num))
    4574           6 :             ereport(ERROR,
    4575             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4576             :                      errmsg("cannot convert NaN to %s", "smallint")));
    4577             :         else
    4578          12 :             ereport(ERROR,
    4579             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4580             :                      errmsg("cannot convert infinity to %s", "smallint")));
    4581             :     }
    4582             : 
    4583             :     /* Convert to variable format and thence to int8 */
    4584          84 :     init_var_from_num(num, &x);
    4585             : 
    4586          84 :     if (!numericvar_to_int64(&x, &val))
    4587           0 :         ereport(ERROR,
    4588             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4589             :                  errmsg("smallint out of range")));
    4590             : 
    4591          84 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4592          12 :         ereport(ERROR,
    4593             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4594             :                  errmsg("smallint out of range")));
    4595             : 
    4596             :     /* Down-convert to int2 */
    4597          72 :     result = (int16) val;
    4598             : 
    4599          72 :     PG_RETURN_INT16(result);
    4600             : }
    4601             : 
    4602             : 
    4603             : Datum
    4604        1074 : float8_numeric(PG_FUNCTION_ARGS)
    4605             : {
    4606        1074 :     float8      val = PG_GETARG_FLOAT8(0);
    4607             :     Numeric     res;
    4608             :     NumericVar  result;
    4609             :     char        buf[DBL_DIG + 100];
    4610             :     const char *endptr;
    4611             : 
    4612        1074 :     if (isnan(val))
    4613           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4614             : 
    4615        1068 :     if (isinf(val))
    4616             :     {
    4617          12 :         if (val < 0)
    4618           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4619             :         else
    4620           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4621             :     }
    4622             : 
    4623        1056 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4624             : 
    4625        1056 :     init_var(&result);
    4626             : 
    4627             :     /* Assume we need not worry about leading/trailing spaces */
    4628        1056 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4629             : 
    4630        1056 :     res = make_result(&result);
    4631             : 
    4632        1056 :     free_var(&result);
    4633             : 
    4634        1056 :     PG_RETURN_NUMERIC(res);
    4635             : }
    4636             : 
    4637             : 
    4638             : Datum
    4639      519988 : numeric_float8(PG_FUNCTION_ARGS)
    4640             : {
    4641      519988 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4642             :     char       *tmp;
    4643             :     Datum       result;
    4644             : 
    4645      519988 :     if (NUMERIC_IS_SPECIAL(num))
    4646             :     {
    4647          78 :         if (NUMERIC_IS_PINF(num))
    4648          24 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4649          54 :         else if (NUMERIC_IS_NINF(num))
    4650          24 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4651             :         else
    4652          30 :             PG_RETURN_FLOAT8(get_float8_nan());
    4653             :     }
    4654             : 
    4655      519910 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4656             :                                               NumericGetDatum(num)));
    4657             : 
    4658      519910 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
    4659             : 
    4660      519910 :     pfree(tmp);
    4661             : 
    4662      519910 :     PG_RETURN_DATUM(result);
    4663             : }
    4664             : 
    4665             : 
    4666             : /*
    4667             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4668             :  *
    4669             :  * (internal helper function, not directly callable from SQL)
    4670             :  */
    4671             : Datum
    4672          28 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4673             : {
    4674          28 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4675             :     double      val;
    4676             : 
    4677          28 :     if (NUMERIC_IS_SPECIAL(num))
    4678             :     {
    4679           0 :         if (NUMERIC_IS_PINF(num))
    4680           0 :             val = HUGE_VAL;
    4681           0 :         else if (NUMERIC_IS_NINF(num))
    4682           0 :             val = -HUGE_VAL;
    4683             :         else
    4684           0 :             val = get_float8_nan();
    4685             :     }
    4686             :     else
    4687             :     {
    4688             :         NumericVar  x;
    4689             : 
    4690          28 :         init_var_from_num(num, &x);
    4691          28 :         val = numericvar_to_double_no_overflow(&x);
    4692             :     }
    4693             : 
    4694          28 :     PG_RETURN_FLOAT8(val);
    4695             : }
    4696             : 
    4697             : Datum
    4698       22406 : float4_numeric(PG_FUNCTION_ARGS)
    4699             : {
    4700       22406 :     float4      val = PG_GETARG_FLOAT4(0);
    4701             :     Numeric     res;
    4702             :     NumericVar  result;
    4703             :     char        buf[FLT_DIG + 100];
    4704             :     const char *endptr;
    4705             : 
    4706       22406 :     if (isnan(val))
    4707           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4708             : 
    4709       22400 :     if (isinf(val))
    4710             :     {
    4711          12 :         if (val < 0)
    4712           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4713             :         else
    4714           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4715             :     }
    4716             : 
    4717       22388 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4718             : 
    4719       22388 :     init_var(&result);
    4720             : 
    4721             :     /* Assume we need not worry about leading/trailing spaces */
    4722       22388 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4723             : 
    4724       22388 :     res = make_result(&result);
    4725             : 
    4726       22388 :     free_var(&result);
    4727             : 
    4728       22388 :     PG_RETURN_NUMERIC(res);
    4729             : }
    4730             : 
    4731             : 
    4732             : Datum
    4733        2456 : numeric_float4(PG_FUNCTION_ARGS)
    4734             : {
    4735        2456 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4736             :     char       *tmp;
    4737             :     Datum       result;
    4738             : 
    4739        2456 :     if (NUMERIC_IS_SPECIAL(num))
    4740             :     {
    4741          78 :         if (NUMERIC_IS_PINF(num))
    4742          24 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4743          54 :         else if (NUMERIC_IS_NINF(num))
    4744          24 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4745             :         else
    4746          30 :             PG_RETURN_FLOAT4(get_float4_nan());
    4747             :     }
    4748             : 
    4749        2378 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4750             :                                               NumericGetDatum(num)));
    4751             : 
    4752        2378 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
    4753             : 
    4754        2378 :     pfree(tmp);
    4755             : 
    4756        2378 :     PG_RETURN_DATUM(result);
    4757             : }
    4758             : 
    4759             : 
    4760             : Datum
    4761         120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4762             : {
    4763         120 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4764             :     NumericVar  x;
    4765             :     XLogRecPtr  result;
    4766             : 
    4767         120 :     if (NUMERIC_IS_SPECIAL(num))
    4768             :     {
    4769           6 :         if (NUMERIC_IS_NAN(num))
    4770           6 :             ereport(ERROR,
    4771             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4772             :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4773             :         else
    4774           0 :             ereport(ERROR,
    4775             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4776             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4777             :     }
    4778             : 
    4779             :     /* Convert to variable format and thence to pg_lsn */
    4780         114 :     init_var_from_num(num, &x);
    4781             : 
    4782         114 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4783          24 :         ereport(ERROR,
    4784             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4785             :                  errmsg("pg_lsn out of range")));
    4786             : 
    4787          90 :     PG_RETURN_LSN(result);
    4788             : }
    4789             : 
    4790             : 
    4791             : /* ----------------------------------------------------------------------
    4792             :  *
    4793             :  * Aggregate functions
    4794             :  *
    4795             :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4796             :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4797             :  * context.  The digit buffers for the NumericVars will be there too.
    4798             :  *
    4799             :  * For integer inputs, some aggregates use special-purpose 64-bit or 128-bit
    4800             :  * integer based transition datatypes to speed up calculations.
    4801             :  *
    4802             :  * ----------------------------------------------------------------------
    4803             :  */
    4804             : 
    4805             : typedef struct NumericAggState
    4806             : {
    4807             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4808             :     MemoryContext agg_context;  /* context we're calculating in */
    4809             :     int64       N;              /* count of processed numbers */
    4810             :     NumericSumAccum sumX;       /* sum of processed numbers */
    4811             :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4812             :     int         maxScale;       /* maximum scale seen so far */
    4813             :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4814             :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4815             :     int64       NaNcount;       /* count of NaN values */
    4816             :     int64       pInfcount;      /* count of +Inf values */
    4817             :     int64       nInfcount;      /* count of -Inf values */
    4818             : } NumericAggState;
    4819             : 
    4820             : #define NA_TOTAL_COUNT(na) \
    4821             :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4822             : 
    4823             : /*
    4824             :  * Prepare state data for a numeric aggregate function that needs to compute
    4825             :  * sum, count and optionally sum of squares of the input.
    4826             :  */
    4827             : static NumericAggState *
    4828      171136 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4829             : {
    4830             :     NumericAggState *state;
    4831             :     MemoryContext agg_context;
    4832             :     MemoryContext old_context;
    4833             : 
    4834      171136 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4835           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4836             : 
    4837      171136 :     old_context = MemoryContextSwitchTo(agg_context);
    4838             : 
    4839      171136 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4840      171136 :     state->calcSumX2 = calcSumX2;
    4841      171136 :     state->agg_context = agg_context;
    4842             : 
    4843      171136 :     MemoryContextSwitchTo(old_context);
    4844             : 
    4845      171136 :     return state;
    4846             : }
    4847             : 
    4848             : /*
    4849             :  * Like makeNumericAggState(), but allocate the state in the current memory
    4850             :  * context.
    4851             :  */
    4852             : static NumericAggState *
    4853          80 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4854             : {
    4855             :     NumericAggState *state;
    4856             : 
    4857          80 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4858          80 :     state->calcSumX2 = calcSumX2;
    4859          80 :     state->agg_context = CurrentMemoryContext;
    4860             : 
    4861          80 :     return state;
    4862             : }
    4863             : 
    4864             : /*
    4865             :  * Accumulate a new input value for numeric aggregate functions.
    4866             :  */
    4867             : static void
    4868     2113552 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4869             : {
    4870             :     NumericVar  X;
    4871             :     NumericVar  X2;
    4872             :     MemoryContext old_context;
    4873             : 
    4874             :     /* Count NaN/infinity inputs separately from all else */
    4875     2113552 :     if (NUMERIC_IS_SPECIAL(newval))
    4876             :     {
    4877         162 :         if (NUMERIC_IS_PINF(newval))
    4878          72 :             state->pInfcount++;
    4879          90 :         else if (NUMERIC_IS_NINF(newval))
    4880          36 :             state->nInfcount++;
    4881             :         else
    4882          54 :             state->NaNcount++;
    4883         162 :         return;
    4884             :     }
    4885             : 
    4886             :     /* load processed number in short-lived context */
    4887     2113390 :     init_var_from_num(newval, &X);
    4888             : 
    4889             :     /*
    4890             :      * Track the highest input dscale that we've seen, to support inverse
    4891             :      * transitions (see do_numeric_discard).
    4892             :      */
    4893     2113390 :     if (X.dscale > state->maxScale)
    4894             :     {
    4895         156 :         state->maxScale = X.dscale;
    4896         156 :         state->maxScaleCount = 1;
    4897             :     }
    4898     2113234 :     else if (X.dscale == state->maxScale)
    4899     2113198 :         state->maxScaleCount++;
    4900             : 
    4901             :     /* if we need X^2, calculate that in short-lived context */
    4902     2113390 :     if (state->calcSumX2)
    4903             :     {
    4904      240732 :         init_var(&X2);
    4905      240732 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4906             :     }
    4907             : 
    4908             :     /* The rest of this needs to work in the aggregate context */
    4909     2113390 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4910             : 
    4911     2113390 :     state->N++;
    4912             : 
    4913             :     /* Accumulate sums */
    4914     2113390 :     accum_sum_add(&(state->sumX), &X);
    4915             : 
    4916     2113390 :     if (state->calcSumX2)
    4917      240732 :         accum_sum_add(&(state->sumX2), &X2);
    4918             : 
    4919     2113390 :     MemoryContextSwitchTo(old_context);
    4920             : }
    4921             : 
    4922             : /*
    4923             :  * Attempt to remove an input value from the aggregated state.
    4924             :  *
    4925             :  * If the value cannot be removed then the function will return false; the
    4926             :  * possible reasons for failing are described below.
    4927             :  *
    4928             :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    4929             :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    4930             :  * won't be able to tell what the new aggregated value's dscale should be.
    4931             :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    4932             :  * have been zero if we'd really aggregated only 2.
    4933             :  *
    4934             :  * Note: alternatively, we could count the number of inputs with each possible
    4935             :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    4936             :  */
    4937             : static bool
    4938         342 : do_numeric_discard(NumericAggState *state, Numeric newval)
    4939             : {
    4940             :     NumericVar  X;
    4941             :     NumericVar  X2;
    4942             :     MemoryContext old_context;
    4943             : 
    4944             :     /* Count NaN/infinity inputs separately from all else */
    4945         342 :     if (NUMERIC_IS_SPECIAL(newval))
    4946             :     {
    4947           6 :         if (NUMERIC_IS_PINF(newval))
    4948           0 :             state->pInfcount--;
    4949           6 :         else if (NUMERIC_IS_NINF(newval))
    4950           0 :             state->nInfcount--;
    4951             :         else
    4952           6 :             state->NaNcount--;
    4953           6 :         return true;
    4954             :     }
    4955             : 
    4956             :     /* load processed number in short-lived context */
    4957         336 :     init_var_from_num(newval, &X);
    4958             : 
    4959             :     /*
    4960             :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    4961             :      * Removing the last input with that dscale would require us to recompute
    4962             :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    4963             :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    4964             :      * and force the aggregation to be redone from scratch.
    4965             :      */
    4966         336 :     if (X.dscale == state->maxScale)
    4967             :     {
    4968         336 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    4969             :         {
    4970             :             /*
    4971             :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    4972             :              * above zero anyway
    4973             :              */
    4974         318 :             state->maxScaleCount--;
    4975             :         }
    4976          18 :         else if (state->N == 1)
    4977             :         {
    4978             :             /* No remaining non-NaN inputs at all, so reset maxScale */
    4979          12 :             state->maxScale = 0;
    4980          12 :             state->maxScaleCount = 0;
    4981             :         }
    4982             :         else
    4983             :         {
    4984             :             /* Correct new maxScale is uncertain, must fail */
    4985           6 :             return false;
    4986             :         }
    4987             :     }
    4988             : 
    4989             :     /* if we need X^2, calculate that in short-lived context */
    4990         330 :     if (state->calcSumX2)
    4991             :     {
    4992         288 :         init_var(&X2);
    4993         288 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4994             :     }
    4995             : 
    4996             :     /* The rest of this needs to work in the aggregate context */
    4997         330 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4998             : 
    4999         330 :     if (state->N-- > 1)
    5000             :     {
    5001             :         /* Negate X, to subtract it from the sum */
    5002         312 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    5003         312 :         accum_sum_add(&(state->sumX), &X);
    5004             : 
    5005         312 :         if (state->calcSumX2)
    5006             :         {
    5007             :             /* Negate X^2. X^2 is always positive */
    5008         288 :             X2.sign = NUMERIC_NEG;
    5009         288 :             accum_sum_add(&(state->sumX2), &X2);
    5010             :         }
    5011             :     }
    5012             :     else
    5013             :     {
    5014             :         /* Zero the sums */
    5015             :         Assert(state->N == 0);
    5016             : 
    5017          18 :         accum_sum_reset(&state->sumX);
    5018          18 :         if (state->calcSumX2)
    5019           0 :             accum_sum_reset(&state->sumX2);
    5020             :     }
    5021             : 
    5022         330 :     MemoryContextSwitchTo(old_context);
    5023             : 
    5024         330 :     return true;
    5025             : }
    5026             : 
    5027             : /*
    5028             :  * Generic transition function for numeric aggregates that require sumX2.
    5029             :  */
    5030             : Datum
    5031         642 : numeric_accum(PG_FUNCTION_ARGS)
    5032             : {
    5033             :     NumericAggState *state;
    5034             : 
    5035         642 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5036             : 
    5037             :     /* Create the state data on the first call */
    5038         642 :     if (state == NULL)
    5039         174 :         state = makeNumericAggState(fcinfo, true);
    5040             : 
    5041         642 :     if (!PG_ARGISNULL(1))
    5042         624 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5043             : 
    5044         642 :     PG_RETURN_POINTER(state);
    5045             : }
    5046             : 
    5047             : /*
    5048             :  * Generic combine function for numeric aggregates which require sumX2
    5049             :  */
    5050             : Datum
    5051          34 : numeric_combine(PG_FUNCTION_ARGS)
    5052             : {
    5053             :     NumericAggState *state1;
    5054             :     NumericAggState *state2;
    5055             :     MemoryContext agg_context;
    5056             :     MemoryContext old_context;
    5057             : 
    5058          34 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5059           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5060             : 
    5061          34 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5062          34 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5063             : 
    5064          34 :     if (state2 == NULL)
    5065           0 :         PG_RETURN_POINTER(state1);
    5066             : 
    5067             :     /* manually copy all fields from state2 to state1 */
    5068          34 :     if (state1 == NULL)
    5069             :     {
    5070          18 :         old_context = MemoryContextSwitchTo(agg_context);
    5071             : 
    5072          18 :         state1 = makeNumericAggStateCurrentContext(true);
    5073          18 :         state1->N = state2->N;
    5074          18 :         state1->NaNcount = state2->NaNcount;
    5075          18 :         state1->pInfcount = state2->pInfcount;
    5076          18 :         state1->nInfcount = state2->nInfcount;
    5077          18 :         state1->maxScale = state2->maxScale;
    5078          18 :         state1->maxScaleCount = state2->maxScaleCount;
    5079             : 
    5080          18 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5081          18 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5082             : 
    5083          18 :         MemoryContextSwitchTo(old_context);
    5084             : 
    5085          18 :         PG_RETURN_POINTER(state1);
    5086             :     }
    5087             : 
    5088          16 :     state1->N += state2->N;
    5089          16 :     state1->NaNcount += state2->NaNcount;
    5090          16 :     state1->pInfcount += state2->pInfcount;
    5091          16 :     state1->nInfcount += state2->nInfcount;
    5092             : 
    5093          16 :     if (state2->N > 0)
    5094             :     {
    5095             :         /*
    5096             :          * These are currently only needed for moving aggregates, but let's do
    5097             :          * the right thing anyway...
    5098             :          */
    5099          16 :         if (state2->maxScale > state1->maxScale)
    5100             :         {
    5101           0 :             state1->maxScale = state2->maxScale;
    5102           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5103             :         }
    5104          16 :         else if (state2->maxScale == state1->maxScale)
    5105          16 :             state1->maxScaleCount += state2->maxScaleCount;
    5106             : 
    5107             :         /* The rest of this needs to work in the aggregate context */
    5108          16 :         old_context = MemoryContextSwitchTo(agg_context);
    5109             : 
    5110             :         /* Accumulate sums */
    5111          16 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5112          16 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5113             : 
    5114          16 :         MemoryContextSwitchTo(old_context);
    5115             :     }
    5116          16 :     PG_RETURN_POINTER(state1);
    5117             : }
    5118             : 
    5119             : /*
    5120             :  * Generic transition function for numeric aggregates that don't require sumX2.
    5121             :  */
    5122             : Datum
    5123     1872808 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5124             : {
    5125             :     NumericAggState *state;
    5126             : 
    5127     1872808 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5128             : 
    5129             :     /* Create the state data on the first call */
    5130     1872808 :     if (state == NULL)
    5131      170904 :         state = makeNumericAggState(fcinfo, false);
    5132             : 
    5133     1872808 :     if (!PG_ARGISNULL(1))
    5134     1872748 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5135             : 
    5136     1872808 :     PG_RETURN_POINTER(state);
    5137             : }
    5138             : 
    5139             : /*
    5140             :  * Combine function for numeric aggregates which don't require sumX2
    5141             :  */
    5142             : Datum
    5143          22 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5144             : {
    5145             :     NumericAggState *state1;
    5146             :     NumericAggState *state2;
    5147             :     MemoryContext agg_context;
    5148             :     MemoryContext old_context;
    5149             : 
    5150          22 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5151           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5152             : 
    5153          22 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5154          22 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5155             : 
    5156          22 :     if (state2 == NULL)
    5157           0 :         PG_RETURN_POINTER(state1);
    5158             : 
    5159             :     /* manually copy all fields from state2 to state1 */
    5160          22 :     if (state1 == NULL)
    5161             :     {
    5162           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5163             : 
    5164           6 :         state1 = makeNumericAggStateCurrentContext(false);
    5165           6 :         state1->N = state2->N;
    5166           6 :         state1->NaNcount = state2->NaNcount;
    5167           6 :         state1->pInfcount = state2->pInfcount;
    5168           6 :         state1->nInfcount = state2->nInfcount;
    5169           6 :         state1->maxScale = state2->maxScale;
    5170           6 :         state1->maxScaleCount = state2->maxScaleCount;
    5171             : 
    5172           6 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5173             : 
    5174           6 :         MemoryContextSwitchTo(old_context);
    5175             : 
    5176           6 :         PG_RETURN_POINTER(state1);
    5177             :     }
    5178             : 
    5179          16 :     state1->N += state2->N;
    5180          16 :     state1->NaNcount += state2->NaNcount;
    5181          16 :     state1->pInfcount += state2->pInfcount;
    5182          16 :     state1->nInfcount += state2->nInfcount;
    5183             : 
    5184          16 :     if (state2->N > 0)
    5185             :     {
    5186             :         /*
    5187             :          * These are currently only needed for moving aggregates, but let's do
    5188             :          * the right thing anyway...
    5189             :          */
    5190          16 :         if (state2->maxScale > state1->maxScale)
    5191             :         {
    5192           0 :             state1->maxScale = state2->maxScale;
    5193           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5194             :         }
    5195          16 :         else if (state2->maxScale == state1->maxScale)
    5196          16 :             state1->maxScaleCount += state2->maxScaleCount;
    5197             : 
    5198             :         /* The rest of this needs to work in the aggregate context */
    5199          16 :         old_context = MemoryContextSwitchTo(agg_context);
    5200             : 
    5201             :         /* Accumulate sums */
    5202          16 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5203             : 
    5204          16 :         MemoryContextSwitchTo(old_context);
    5205             :     }
    5206          16 :     PG_RETURN_POINTER(state1);
    5207             : }
    5208             : 
    5209             : /*
    5210             :  * numeric_avg_serialize
    5211             :  *      Serialize NumericAggState for numeric aggregates that don't require
    5212             :  *      sumX2.
    5213             :  */
    5214             : Datum
    5215          22 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5216             : {
    5217             :     NumericAggState *state;
    5218             :     StringInfoData buf;
    5219             :     bytea      *result;
    5220             :     NumericVar  tmp_var;
    5221             : 
    5222             :     /* Ensure we disallow calling when not in aggregate context */
    5223          22 :     if (!AggCheckCallContext(fcinfo, NULL))
    5224           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5225             : 
    5226          22 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5227             : 
    5228          22 :     init_var(&tmp_var);
    5229             : 
    5230          22 :     pq_begintypsend(&buf);
    5231             : 
    5232             :     /* N */
    5233          22 :     pq_sendint64(&buf, state->N);
    5234             : 
    5235             :     /* sumX */
    5236          22 :     accum_sum_final(&state->sumX, &tmp_var);
    5237          22 :     numericvar_serialize(&buf, &tmp_var);
    5238             : 
    5239             :     /* maxScale */
    5240          22 :     pq_sendint32(&buf, state->maxScale);
    5241             : 
    5242             :     /* maxScaleCount */
    5243          22 :     pq_sendint64(&buf, state->maxScaleCount);
    5244             : 
    5245             :     /* NaNcount */
    5246          22 :     pq_sendint64(&buf, state->NaNcount);
    5247             : 
    5248             :     /* pInfcount */
    5249          22 :     pq_sendint64(&buf, state->pInfcount);
    5250             : 
    5251             :     /* nInfcount */
    5252          22 :     pq_sendint64(&buf, state->nInfcount);
    5253             : 
    5254          22 :     result = pq_endtypsend(&buf);
    5255             : 
    5256          22 :     free_var(&tmp_var);
    5257             : 
    5258          22 :     PG_RETURN_BYTEA_P(result);
    5259             : }
    5260             : 
    5261             : /*
    5262             :  * numeric_avg_deserialize
    5263             :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5264             :  *      don't require sumX2.
    5265             :  */
    5266             : Datum
    5267          22 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5268             : {
    5269             :     bytea      *sstate;
    5270             :     NumericAggState *result;
    5271             :     StringInfoData buf;
    5272             :     NumericVar  tmp_var;
    5273             : 
    5274          22 :     if (!AggCheckCallContext(fcinfo, NULL))
    5275           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5276             : 
    5277          22 :     sstate = PG_GETARG_BYTEA_PP(0);
    5278             : 
    5279          22 :     init_var(&tmp_var);
    5280             : 
    5281             :     /*
    5282             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5283             :      * recv-function infrastructure.
    5284             :      */
    5285          22 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5286          22 :                            VARSIZE_ANY_EXHDR(sstate));
    5287             : 
    5288          22 :     result = makeNumericAggStateCurrentContext(false);
    5289             : 
    5290             :     /* N */
    5291          22 :     result->N = pq_getmsgint64(&buf);
    5292             : 
    5293             :     /* sumX */
    5294          22 :     numericvar_deserialize(&buf, &tmp_var);
    5295          22 :     accum_sum_add(&(result->sumX), &tmp_var);
    5296             : 
    5297             :     /* maxScale */
    5298          22 :     result->maxScale = pq_getmsgint(&buf, 4);
    5299             : 
    5300             :     /* maxScaleCount */
    5301          22 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5302             : 
    5303             :     /* NaNcount */
    5304          22 :     result->NaNcount = pq_getmsgint64(&buf);
    5305             : 
    5306             :     /* pInfcount */
    5307          22 :     result->pInfcount = pq_getmsgint64(&buf);
    5308             : 
    5309             :     /* nInfcount */
    5310          22 :     result->nInfcount = pq_getmsgint64(&buf);
    5311             : 
    5312          22 :     pq_getmsgend(&buf);
    5313             : 
    5314          22 :     free_var(&tmp_var);
    5315             : 
    5316          22 :     PG_RETURN_POINTER(result);
    5317             : }
    5318             : 
    5319             : /*
    5320             :  * numeric_serialize
    5321             :  *      Serialization function for NumericAggState for numeric aggregates that
    5322             :  *      require sumX2.
    5323             :  */
    5324             : Datum
    5325          34 : numeric_serialize(PG_FUNCTION_ARGS)
    5326             : {
    5327             :     NumericAggState *state;
    5328             :     StringInfoData buf;
    5329             :     bytea      *result;
    5330             :     NumericVar  tmp_var;
    5331             : 
    5332             :     /* Ensure we disallow calling when not in aggregate context */
    5333          34 :     if (!AggCheckCallContext(fcinfo, NULL))
    5334           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5335             : 
    5336          34 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5337             : 
    5338          34 :     init_var(&tmp_var);
    5339             : 
    5340          34 :     pq_begintypsend(&buf);
    5341             : 
    5342             :     /* N */
    5343          34 :     pq_sendint64(&buf, state->N);
    5344             : 
    5345             :     /* sumX */
    5346          34 :     accum_sum_final(&state->sumX, &tmp_var);
    5347          34 :     numericvar_serialize(&buf, &tmp_var);
    5348             : 
    5349             :     /* sumX2 */
    5350          34 :     accum_sum_final(&state->sumX2, &tmp_var);
    5351          34 :     numericvar_serialize(&buf, &tmp_var);
    5352             : 
    5353             :     /* maxScale */
    5354          34 :     pq_sendint32(&buf, state->maxScale);
    5355             : 
    5356             :     /* maxScaleCount */
    5357          34 :     pq_sendint64(&buf, state->maxScaleCount);
    5358             : 
    5359             :     /* NaNcount */
    5360          34 :     pq_sendint64(&buf, state->NaNcount);
    5361             : 
    5362             :     /* pInfcount */
    5363          34 :     pq_sendint64(&buf, state->pInfcount);
    5364             : 
    5365             :     /* nInfcount */
    5366          34 :     pq_sendint64(&buf, state->nInfcount);
    5367             : 
    5368          34 :     result = pq_endtypsend(&buf);
    5369             : 
    5370          34 :     free_var(&tmp_var);
    5371             : 
    5372          34 :     PG_RETURN_BYTEA_P(result);
    5373             : }
    5374             : 
    5375             : /*
    5376             :  * numeric_deserialize
    5377             :  *      Deserialization function for NumericAggState for numeric aggregates that
    5378             :  *      require sumX2.
    5379             :  */
    5380             : Datum
    5381          34 : numeric_deserialize(PG_FUNCTION_ARGS)
    5382             : {
    5383             :     bytea      *sstate;
    5384             :     NumericAggState *result;
    5385             :     StringInfoData buf;
    5386             :     NumericVar  tmp_var;
    5387             : 
    5388          34 :     if (!AggCheckCallContext(fcinfo, NULL))
    5389           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5390             : 
    5391          34 :     sstate = PG_GETARG_BYTEA_PP(0);
    5392             : 
    5393          34 :     init_var(&tmp_var);
    5394             : 
    5395             :     /*
    5396             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5397             :      * recv-function infrastructure.
    5398             :      */
    5399          34 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5400          34 :                            VARSIZE_ANY_EXHDR(sstate));
    5401             : 
    5402          34 :     result = makeNumericAggStateCurrentContext(false);
    5403             : 
    5404             :     /* N */
    5405          34 :     result->N = pq_getmsgint64(&buf);
    5406             : 
    5407             :     /* sumX */
    5408          34 :     numericvar_deserialize(&buf, &tmp_var);
    5409          34 :     accum_sum_add(&(result->sumX), &tmp_var);
    5410             : 
    5411             :     /* sumX2 */
    5412          34 :     numericvar_deserialize(&buf, &tmp_var);
    5413          34 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5414             : 
    5415             :     /* maxScale */
    5416          34 :     result->maxScale = pq_getmsgint(&buf, 4);
    5417             : 
    5418             :     /* maxScaleCount */
    5419          34 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5420             : 
    5421             :     /* NaNcount */
    5422          34 :     result->NaNcount = pq_getmsgint64(&buf);
    5423             : 
    5424             :     /* pInfcount */
    5425          34 :     result->pInfcount = pq_getmsgint64(&buf);
    5426             : 
    5427             :     /* nInfcount */
    5428          34 :     result->nInfcount = pq_getmsgint64(&buf);
    5429             : 
    5430          34 :     pq_getmsgend(&buf);
    5431             : 
    5432          34 :     free_var(&tmp_var);
    5433             : 
    5434          34 :     PG_RETURN_POINTER(result);
    5435             : }
    5436             : 
    5437             : /*
    5438             :  * Generic inverse transition function for numeric aggregates
    5439             :  * (with or without requirement for X^2).
    5440             :  */
    5441             : Datum
    5442         228 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5443             : {
    5444             :     NumericAggState *state;
    5445             : 
    5446         228 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5447             : 
    5448             :     /* Should not get here with no state */
    5449         228 :     if (state == NULL)
    5450           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5451             : 
    5452         228 :     if (!PG_ARGISNULL(1))
    5453             :     {
    5454             :         /* If we fail to perform the inverse transition, return NULL */
    5455         198 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5456           6 :             PG_RETURN_NULL();
    5457             :     }
    5458             : 
    5459         222 :     PG_RETURN_POINTER(state);
    5460             : }
    5461             : 
    5462             : 
    5463             : /*
    5464             :  * Integer data types in general use Numeric accumulators to share code and
    5465             :  * avoid risk of overflow.  However for performance reasons optimized
    5466             :  * special-purpose accumulator routines are used when possible:
    5467             :  *
    5468             :  * For 16-bit and 32-bit inputs, N and sum(X) fit into 64-bit, so 64-bit
    5469             :  * accumulators are used for SUM and AVG of these data types.
    5470             :  *
    5471             :  * For 16-bit and 32-bit inputs, sum(X^2) fits into 128-bit, so 128-bit
    5472             :  * accumulators are used for STDDEV_POP, STDDEV_SAMP, VAR_POP, and VAR_SAMP of
    5473             :  * these data types.
    5474             :  *
    5475             :  * For 64-bit inputs, sum(X) fits into 128-bit, so a 128-bit accumulator is
    5476             :  * used for SUM(int8) and AVG(int8).
    5477             :  */
    5478             : 
    5479             : typedef struct Int128AggState
    5480             : {
    5481             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5482             :     int64       N;              /* count of processed numbers */
    5483             :     INT128      sumX;           /* sum of processed numbers */
    5484             :     INT128      sumX2;          /* sum of squares of processed numbers */
    5485             : } Int128AggState;
    5486             : 
    5487             : /*
    5488             :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5489             :  * sum, count and optionally sum of squares of the input.
    5490             :  */
    5491             : static Int128AggState *
    5492         966 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5493             : {
    5494             :     Int128AggState *state;
    5495             :     MemoryContext agg_context;
    5496             :     MemoryContext old_context;
    5497             : 
    5498         966 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5499           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5500             : 
    5501         966 :     old_context = MemoryContextSwitchTo(agg_context);
    5502             : 
    5503         966 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5504         966 :     state->calcSumX2 = calcSumX2;
    5505             : 
    5506         966 :     MemoryContextSwitchTo(old_context);
    5507             : 
    5508         966 :     return state;
    5509             : }
    5510             : 
    5511             : /*
    5512             :  * Like makeInt128AggState(), but allocate the state in the current memory
    5513             :  * context.
    5514             :  */
    5515             : static Int128AggState *
    5516          50 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5517             : {
    5518             :     Int128AggState *state;
    5519             : 
    5520          50 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5521          50 :     state->calcSumX2 = calcSumX2;
    5522             : 
    5523          50 :     return state;
    5524             : }
    5525             : 
    5526             : /*
    5527             :  * Accumulate a new input value for 128-bit aggregate functions.
    5528             :  */
    5529             : static void
    5530      557482 : do_int128_accum(Int128AggState *state, int64 newval)
    5531             : {
    5532      557482 :     if (state->calcSumX2)
    5533      242360 :         int128_add_int64_mul_int64(&state->sumX2, newval, newval);
    5534             : 
    5535      557482 :     int128_add_int64(&state->sumX, newval);
    5536      557482 :     state->N++;
    5537      557482 : }
    5538             : 
    5539             : /*
    5540             :  * Remove an input value from the aggregated state.
    5541             :  */
    5542             : static void
    5543         312 : do_int128_discard(Int128AggState *state, int64 newval)
    5544             : {
    5545         312 :     if (state->calcSumX2)
    5546         288 :         int128_sub_int64_mul_int64(&state->sumX2, newval, newval);
    5547             : 
    5548         312 :     int128_sub_int64(&state->sumX, newval);
    5549         312 :     state->N--;
    5550         312 : }
    5551             : 
    5552             : Datum
    5553         198 : int2_accum(PG_FUNCTION_ARGS)
    5554             : {
    5555             :     Int128AggState *state;
    5556             : 
    5557         198 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5558             : 
    5559             :     /* Create the state data on the first call */
    5560         198 :     if (state == NULL)
    5561          36 :         state = makeInt128AggState(fcinfo, true);
    5562             : 
    5563         198 :     if (!PG_ARGISNULL(1))
    5564         180 :         do_int128_accum(state, PG_GETARG_INT16(1));
    5565             : 
    5566         198 :     PG_RETURN_POINTER(state);
    5567             : }
    5568             : 
    5569             : Datum
    5570      242198 : int4_accum(PG_FUNCTION_ARGS)
    5571             : {
    5572             :     Int128AggState *state;
    5573             : 
    5574      242198 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5575             : 
    5576             :     /* Create the state data on the first call */
    5577      242198 :     if (state == NULL)
    5578          78 :         state = makeInt128AggState(fcinfo, true);
    5579             : 
    5580      242198 :     if (!PG_ARGISNULL(1))
    5581      242180 :         do_int128_accum(state, PG_GETARG_INT32(1));
    5582             : 
    5583      242198 :     PG_RETURN_POINTER(state);
    5584             : }
    5585             : 
    5586             : Datum
    5587      240198 : int8_accum(PG_FUNCTION_ARGS)
    5588             : {
    5589             :     NumericAggState *state;
    5590             : 
    5591      240198 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5592             : 
    5593             :     /* Create the state data on the first call */
    5594      240198 :     if (state == NULL)
    5595          58 :         state = makeNumericAggState(fcinfo, true);
    5596             : 
    5597      240198 :     if (!PG_ARGISNULL(1))
    5598      240180 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5599             : 
    5600      240198 :     PG_RETURN_POINTER(state);
    5601             : }
    5602             : 
    5603             : /*
    5604             :  * Combine function for Int128AggState for aggregates which require sumX2
    5605             :  */
    5606             : Datum
    5607          22 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5608             : {
    5609             :     Int128AggState *state1;
    5610             :     Int128AggState *state2;
    5611             :     MemoryContext agg_context;
    5612             :     MemoryContext old_context;
    5613             : 
    5614          22 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5615           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5616             : 
    5617          22 :     state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5618          22 :     state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
    5619             : 
    5620          22 :     if (state2 == NULL)
    5621           0 :         PG_RETURN_POINTER(state1);
    5622             : 
    5623             :     /* manually copy all fields from state2 to state1 */
    5624          22 :     if (state1 == NULL)
    5625             :     {
    5626           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5627             : 
    5628           6 :         state1 = makeInt128AggState(fcinfo, true);
    5629           6 :         state1->N = state2->N;
    5630           6 :         state1->sumX = state2->sumX;
    5631           6 :         state1->sumX2 = state2->sumX2;
    5632             : 
    5633           6 :         MemoryContextSwitchTo(old_context);
    5634             : 
    5635           6 :         PG_RETURN_POINTER(state1);
    5636             :     }
    5637             : 
    5638          16 :     if (state2->N > 0)
    5639             :     {
    5640          16 :         state1->N += state2->N;
    5641          16 :         int128_add_int128(&state1->sumX, state2->sumX);
    5642          16 :         int128_add_int128(&state1->sumX2, state2->sumX2);
    5643             :     }
    5644          16 :     PG_RETURN_POINTER(state1);
    5645             : }
    5646             : 
    5647             : /*
    5648             :  * int128_serialize - serialize a 128-bit integer to binary format
    5649             :  */
    5650             : static inline void
    5651          72 : int128_serialize(StringInfo buf, INT128 val)
    5652             : {
    5653          72 :     pq_sendint64(buf, PG_INT128_HI_INT64(val));
    5654          72 :     pq_sendint64(buf, PG_INT128_LO_UINT64(val));
    5655          72 : }
    5656             : 
    5657             : /*
    5658             :  * int128_deserialize - deserialize binary format to a 128-bit integer.
    5659             :  */
    5660             : static inline INT128
    5661          72 : int128_deserialize(StringInfo buf)
    5662             : {
    5663          72 :     int64       hi = pq_getmsgint64(buf);
    5664          72 :     uint64      lo = pq_getmsgint64(buf);
    5665             : 
    5666          72 :     return make_int128(hi, lo);
    5667             : }
    5668             : 
    5669             : /*
    5670             :  * numeric_poly_serialize
    5671             :  *      Serialize Int128AggState into bytea for aggregate functions which
    5672             :  *      require sumX2.
    5673             :  */
    5674             : Datum
    5675          22 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5676             : {
    5677             :     Int128AggState *state;
    5678             :     StringInfoData buf;
    5679             :     bytea      *result;
    5680             : 
    5681             :     /* Ensure we disallow calling when not in aggregate context */
    5682          22 :     if (!AggCheckCallContext(fcinfo, NULL))
    5683           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5684             : 
    5685          22 :     state = (Int128AggState *) PG_GETARG_POINTER(0);
    5686             : 
    5687          22 :     pq_begintypsend(&buf);
    5688             : 
    5689             :     /* N */
    5690          22 :     pq_sendint64(&buf, state->N);
    5691             : 
    5692             :     /* sumX */
    5693          22 :     int128_serialize(&buf, state->sumX);
    5694             : 
    5695             :     /* sumX2 */
    5696          22 :     int128_serialize(&buf, state->sumX2);
    5697             : 
    5698          22 :     result = pq_endtypsend(&buf);
    5699             : 
    5700          22 :     PG_RETURN_BYTEA_P(result);
    5701             : }
    5702             : 
    5703             : /*
    5704             :  * numeric_poly_deserialize
    5705             :  *      Deserialize Int128AggState from bytea for aggregate functions which
    5706             :  *      require sumX2.
    5707             :  */
    5708             : Datum
    5709          22 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5710             : {
    5711             :     bytea      *sstate;
    5712             :     Int128AggState *result;
    5713             :     StringInfoData buf;
    5714             : 
    5715          22 :     if (!AggCheckCallContext(fcinfo, NULL))
    5716           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5717             : 
    5718          22 :     sstate = PG_GETARG_BYTEA_PP(0);
    5719             : 
    5720             :     /*
    5721             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5722             :      * recv-function infrastructure.
    5723             :      */
    5724          22 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5725          22 :                            VARSIZE_ANY_EXHDR(sstate));
    5726             : 
    5727          22 :     result = makeInt128AggStateCurrentContext(false);
    5728             : 
    5729             :     /* N */
    5730          22 :     result->N = pq_getmsgint64(&buf);
    5731             : 
    5732             :     /* sumX */
    5733          22 :     result->sumX = int128_deserialize(&buf);
    5734             : 
    5735             :     /* sumX2 */
    5736          22 :     result->sumX2 = int128_deserialize(&buf);
    5737             : 
    5738          22 :     pq_getmsgend(&buf);
    5739             : 
    5740          22 :     PG_RETURN_POINTER(result);
    5741             : }
    5742             : 
    5743             : /*
    5744             :  * Transition function for int8 input when we don't need sumX2.
    5745             :  */
    5746             : Datum
    5747      318920 : int8_avg_accum(PG_FUNCTION_ARGS)
    5748             : {
    5749             :     Int128AggState *state;
    5750             : 
    5751      318920 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5752             : 
    5753             :     /* Create the state data on the first call */
    5754      318920 :     if (state == NULL)
    5755         834 :         state = makeInt128AggState(fcinfo, false);
    5756             : 
    5757      318920 :     if (!PG_ARGISNULL(1))
    5758      315122 :         do_int128_accum(state, PG_GETARG_INT64(1));
    5759             : 
    5760      318920 :     PG_RETURN_POINTER(state);
    5761             : }
    5762             : 
    5763             : /*
    5764             :  * Combine function for Int128AggState for aggregates which don't require
    5765             :  * sumX2
    5766             :  */
    5767             : Datum
    5768          28 : int8_avg_combine(PG_FUNCTION_ARGS)
    5769             : {
    5770             :     Int128AggState *state1;
    5771             :     Int128AggState *state2;
    5772             :     MemoryContext agg_context;
    5773             :     MemoryContext old_context;
    5774             : 
    5775          28 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5776           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5777             : 
    5778          28 :     state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5779          28 :     state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
    5780             : 
    5781          28 :     if (state2 == NULL)
    5782           0 :         PG_RETURN_POINTER(state1);
    5783             : 
    5784             :     /* manually copy all fields from state2 to state1 */
    5785          28 :     if (state1 == NULL)
    5786             :     {
    5787          12 :         old_context = MemoryContextSwitchTo(agg_context);
    5788             : 
    5789          12 :         state1 = makeInt128AggState(fcinfo, false);
    5790          12 :         state1->N = state2->N;
    5791          12 :         state1->sumX = state2->sumX;
    5792             : 
    5793          12 :         MemoryContextSwitchTo(old_context);
    5794             : 
    5795          12 :         PG_RETURN_POINTER(state1);
    5796             :     }
    5797             : 
    5798          16 :     if (state2->N > 0)
    5799             :     {
    5800          16 :         state1->N += state2->N;
    5801          16 :         int128_add_int128(&state1->sumX, state2->sumX);
    5802             :     }
    5803          16 :     PG_RETURN_POINTER(state1);
    5804             : }
    5805             : 
    5806             : /*
    5807             :  * int8_avg_serialize
    5808             :  *      Serialize Int128AggState into bytea for aggregate functions which
    5809             :  *      don't require sumX2.
    5810             :  */
    5811             : Datum
    5812          28 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5813             : {
    5814             :     Int128AggState *state;
    5815             :     StringInfoData buf;
    5816             :     bytea      *result;
    5817             : 
    5818             :     /* Ensure we disallow calling when not in aggregate context */
    5819          28 :     if (!AggCheckCallContext(fcinfo, NULL))
    5820           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5821             : 
    5822          28 :     state = (Int128AggState *) PG_GETARG_POINTER(0);
    5823             : 
    5824          28 :     pq_begintypsend(&buf);
    5825             : 
    5826             :     /* N */
    5827          28 :     pq_sendint64(&buf, state->N);
    5828             : 
    5829             :     /* sumX */
    5830          28 :     int128_serialize(&buf, state->sumX);
    5831             : 
    5832          28 :     result = pq_endtypsend(&buf);
    5833             : 
    5834          28 :     PG_RETURN_BYTEA_P(result);
    5835             : }
    5836             : 
    5837             : /*
    5838             :  * int8_avg_deserialize
    5839             :  *      Deserialize Int128AggState from bytea for aggregate functions which
    5840             :  *      don't require sumX2.
    5841             :  */
    5842             : Datum
    5843          28 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    5844             : {
    5845             :     bytea      *sstate;
    5846             :     Int128AggState *result;
    5847             :     StringInfoData buf;
    5848             : 
    5849          28 :     if (!AggCheckCallContext(fcinfo, NULL))
    5850           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5851             : 
    5852          28 :     sstate = PG_GETARG_BYTEA_PP(0);
    5853             : 
    5854             :     /*
    5855             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5856             :      * recv-function infrastructure.
    5857             :      */
    5858          28 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5859          28 :                            VARSIZE_ANY_EXHDR(sstate));
    5860             : 
    5861          28 :     result = makeInt128AggStateCurrentContext(false);
    5862             : 
    5863             :     /* N */
    5864          28 :     result->N = pq_getmsgint64(&buf);
    5865             : 
    5866             :     /* sumX */
    5867          28 :     result->sumX = int128_deserialize(&buf);
    5868             : 
    5869          28 :     pq_getmsgend(&buf);
    5870             : 
    5871          28 :     PG_RETURN_POINTER(result);
    5872             : }
    5873             : 
    5874             : /*
    5875             :  * Inverse transition functions to go with the above.
    5876             :  */
    5877             : 
    5878             : Datum
    5879         162 : int2_accum_inv(PG_FUNCTION_ARGS)
    5880             : {
    5881             :     Int128AggState *state;
    5882             : 
    5883         162 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5884             : 
    5885             :     /* Should not get here with no state */
    5886         162 :     if (state == NULL)
    5887           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    5888             : 
    5889         162 :     if (!PG_ARGISNULL(1))
    5890         144 :         do_int128_discard(state, PG_GETARG_INT16(1));
    5891             : 
    5892         162 :     PG_RETURN_POINTER(state);
    5893             : }
    5894             : 
    5895             : Datum
    5896         162 : int4_accum_inv(PG_FUNCTION_ARGS)
    5897             : {
    5898             :     Int128AggState *state;
    5899             : 
    5900         162 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5901             : 
    5902             :     /* Should not get here with no state */
    5903         162 :     if (state == NULL)
    5904           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    5905             : 
    5906         162 :     if (!PG_ARGISNULL(1))
    5907         144 :         do_int128_discard(state, PG_GETARG_INT32(1));
    5908             : 
    5909         162 :     PG_RETURN_POINTER(state);
    5910             : }
    5911             : 
    5912             : Datum
    5913         162 : int8_accum_inv(PG_FUNCTION_ARGS)
    5914             : {
    5915             :     NumericAggState *state;
    5916             : 
    5917         162 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5918             : 
    5919             :     /* Should not get here with no state */
    5920         162 :     if (state == NULL)
    5921           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    5922             : 
    5923         162 :     if (!PG_ARGISNULL(1))
    5924             :     {
    5925             :         /* Should never fail, all inputs have dscale 0 */
    5926         144 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    5927           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5928             :     }
    5929             : 
    5930         162 :     PG_RETURN_POINTER(state);
    5931             : }
    5932             : 
    5933             : Datum
    5934          36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    5935             : {
    5936             :     Int128AggState *state;
    5937             : 
    5938          36 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5939             : 
    5940             :     /* Should not get here with no state */
    5941          36 :     if (state == NULL)
    5942           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    5943             : 
    5944          36 :     if (!PG_ARGISNULL(1))
    5945          24 :         do_int128_discard(state, PG_GETARG_INT64(1));
    5946             : 
    5947          36 :     PG_RETURN_POINTER(state);
    5948             : }
    5949             : 
    5950             : Datum
    5951        1052 : numeric_poly_sum(PG_FUNCTION_ARGS)
    5952             : {
    5953             :     Int128AggState *state;
    5954             :     Numeric     res;
    5955             :     NumericVar  result;
    5956             : 
    5957        1052 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5958             : 
    5959             :     /* If there were no non-null inputs, return NULL */
    5960        1052 :     if (state == NULL || state->N == 0)
    5961          24 :         PG_RETURN_NULL();
    5962             : 
    5963        1028 :     init_var(&result);
    5964             : 
    5965        1028 :     int128_to_numericvar(state->sumX, &result);
    5966             : 
    5967        1028 :     res = make_result(&result);
    5968             : 
    5969        1028 :     free_var(&result);
    5970             : 
    5971        1028 :     PG_RETURN_NUMERIC(res);
    5972             : }
    5973             : 
    5974             : Datum
    5975          36 : numeric_poly_avg(PG_FUNCTION_ARGS)
    5976             : {
    5977             :     Int128AggState *state;
    5978             :     NumericVar  result;
    5979             :     Datum       countd,
    5980             :                 sumd;
    5981             : 
    5982          36 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    5983             : 
    5984             :     /* If there were no non-null inputs, return NULL */
    5985          36 :     if (state == NULL || state->N == 0)
    5986          18 :         PG_RETURN_NULL();
    5987             : 
    5988          18 :     init_var(&result);
    5989             : 
    5990          18 :     int128_to_numericvar(state->sumX, &result);
    5991             : 
    5992          18 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    5993          18 :     sumd = NumericGetDatum(make_result(&result));
    5994             : 
    5995          18 :     free_var(&result);
    5996             : 
    5997          18 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    5998             : }
    5999             : 
    6000             : Datum
    6001          78 : numeric_avg(PG_FUNCTION_ARGS)
    6002             : {
    6003             :     NumericAggState *state;
    6004             :     Datum       N_datum;
    6005             :     Datum       sumX_datum;
    6006             :     NumericVar  sumX_var;
    6007             : 
    6008          78 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6009             : 
    6010             :     /* If there were no non-null inputs, return NULL */
    6011          78 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6012          18 :         PG_RETURN_NULL();
    6013             : 
    6014          60 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6015           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6016             : 
    6017             :     /* adding plus and minus infinities gives NaN */
    6018          54 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6019           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6020          48 :     if (state->pInfcount > 0)
    6021          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6022          30 :     if (state->nInfcount > 0)
    6023           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6024             : 
    6025          24 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    6026             : 
    6027          24 :     init_var(&sumX_var);
    6028          24 :     accum_sum_final(&state->sumX, &sumX_var);
    6029          24 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    6030          24 :     free_var(&sumX_var);
    6031             : 
    6032          24 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    6033             : }
    6034             : 
    6035             : Datum
    6036      170906 : numeric_sum(PG_FUNCTION_ARGS)
    6037             : {
    6038             :     NumericAggState *state;
    6039             :     NumericVar  sumX_var;
    6040             :     Numeric     result;
    6041             : 
    6042      170906 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6043             : 
    6044             :     /* If there were no non-null inputs, return NULL */
    6045      170906 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6046          18 :         PG_RETURN_NULL();
    6047             : 
    6048      170888 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6049          18 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6050             : 
    6051             :     /* adding plus and minus infinities gives NaN */
    6052      170870 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6053           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6054      170864 :     if (state->pInfcount > 0)
    6055          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6056      170846 :     if (state->nInfcount > 0)
    6057           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6058             : 
    6059      170840 :     init_var(&sumX_var);
    6060      170840 :     accum_sum_final(&state->sumX, &sumX_var);
    6061      170840 :     result = make_result(&sumX_var);
    6062      170840 :     free_var(&sumX_var);
    6063             : 
    6064      170840 :     PG_RETURN_NUMERIC(result);
    6065             : }
    6066             : 
    6067             : /*
    6068             :  * Workhorse routine for the standard deviance and variance
    6069             :  * aggregates. 'state' is aggregate's transition state.
    6070             :  * 'variance' specifies whether we should calculate the
    6071             :  * variance or the standard deviation. 'sample' indicates whether the
    6072             :  * caller is interested in the sample or the population
    6073             :  * variance/stddev.
    6074             :  *
    6075             :  * If appropriate variance statistic is undefined for the input,
    6076             :  * *is_null is set to true and NULL is returned.
    6077             :  */
    6078             : static Numeric
    6079         986 : numeric_stddev_internal(NumericAggState *state,
    6080             :                         bool variance, bool sample,
    6081             :                         bool *is_null)
    6082             : {
    6083             :     Numeric     res;
    6084             :     NumericVar  vN,
    6085             :                 vsumX,
    6086             :                 vsumX2,
    6087             :                 vNminus1;
    6088             :     int64       totCount;
    6089             :     int         rscale;
    6090             : 
    6091             :     /*
    6092             :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6093             :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6094             :      * and infinities count as normal inputs for this purpose).
    6095             :      */
    6096         986 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6097             :     {
    6098           0 :         *is_null = true;
    6099           0 :         return NULL;
    6100             :     }
    6101             : 
    6102         986 :     if (sample && totCount <= 1)
    6103             :     {
    6104         132 :         *is_null = true;
    6105         132 :         return NULL;
    6106             :     }
    6107             : 
    6108         854 :     *is_null = false;
    6109             : 
    6110             :     /*
    6111             :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6112             :      * float8 functions, any infinity input produces NaN output.
    6113             :      */
    6114         854 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6115          54 :         return make_result(&const_nan);
    6116             : 
    6117             :     /* OK, normal calculation applies */
    6118         800 :     init_var(&vN);
    6119         800 :     init_var(&vsumX);
    6120         800 :     init_var(&vsumX2);
    6121             : 
    6122         800 :     int64_to_numericvar(state->N, &vN);
    6123         800 :     accum_sum_final(&(state->sumX), &vsumX);
    6124         800 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6125             : 
    6126         800 :     init_var(&vNminus1);
    6127         800 :     sub_var(&vN, &const_one, &vNminus1);
    6128             : 
    6129             :     /* compute rscale for mul_var calls */
    6130         800 :     rscale = vsumX.dscale * 2;
    6131             : 
    6132         800 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6133         800 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6134         800 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6135             : 
    6136         800 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6137             :     {
    6138             :         /* Watch out for roundoff error producing a negative numerator */
    6139          80 :         res = make_result(&const_zero);
    6140             :     }
    6141             :     else
    6142             :     {
    6143         720 :         if (sample)
    6144         492 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6145             :         else
    6146         228 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6147         720 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6148         720 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true);    /* variance */
    6149         720 :         if (!variance)
    6150         378 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6151             : 
    6152         720 :         res = make_result(&vsumX);
    6153             :     }
    6154             : 
    6155         800 :     free_var(&vNminus1);
    6156         800 :     free_var(&vsumX);
    6157         800 :     free_var(&vsumX2);
    6158             : 
    6159         800 :     return res;
    6160             : }
    6161             : 
    6162             : Datum
    6163         180 : numeric_var_samp(PG_FUNCTION_ARGS)
    6164             : {
    6165             :     NumericAggState *state;
    6166             :     Numeric     res;
    6167             :     bool        is_null;
    6168             : 
    6169         180 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6170             : 
    6171         180 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6172             : 
    6173         180 :     if (is_null)
    6174          42 :         PG_RETURN_NULL();
    6175             :     else
    6176         138 :         PG_RETURN_NUMERIC(res);
    6177             : }
    6178             : 
    6179             : Datum
    6180         174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6181             : {
    6182             :     NumericAggState *state;
    6183             :     Numeric     res;
    6184             :     bool        is_null;
    6185             : 
    6186         174 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6187             : 
    6188         174 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6189             : 
    6190         174 :     if (is_null)
    6191          42 :         PG_RETURN_NULL();
    6192             :     else
    6193         132 :         PG_RETURN_NUMERIC(res);
    6194             : }
    6195             : 
    6196             : Datum
    6197         114 : numeric_var_pop(PG_FUNCTION_ARGS)
    6198             : {
    6199             :     NumericAggState *state;
    6200             :     Numeric     res;
    6201             :     bool        is_null;
    6202             : 
    6203         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6204             : 
    6205         114 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6206             : 
    6207         114 :     if (is_null)
    6208           0 :         PG_RETURN_NULL();
    6209             :     else
    6210         114 :         PG_RETURN_NUMERIC(res);
    6211             : }
    6212             : 
    6213             : Datum
    6214          96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6215             : {
    6216             :     NumericAggState *state;
    6217             :     Numeric     res;
    6218             :     bool        is_null;
    6219             : 
    6220          96 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6221             : 
    6222          96 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6223             : 
    6224          96 :     if (is_null)
    6225           0 :         PG_RETURN_NULL();
    6226             :     else
    6227          96 :         PG_RETURN_NUMERIC(res);
    6228             : }
    6229             : 
    6230             : static Numeric
    6231         422 : numeric_poly_stddev_internal(Int128AggState *state,
    6232             :                              bool variance, bool sample,
    6233             :                              bool *is_null)
    6234             : {
    6235             :     NumericAggState numstate;
    6236             :     Numeric     res;
    6237             : 
    6238             :     /* Initialize an empty agg state */
    6239         422 :     memset(&numstate, 0, sizeof(NumericAggState));
    6240             : 
    6241         422 :     if (state)
    6242             :     {
    6243             :         NumericVar  tmp_var;
    6244             : 
    6245         422 :         numstate.N = state->N;
    6246             : 
    6247         422 :         init_var(&tmp_var);
    6248             : 
    6249         422 :         int128_to_numericvar(state->sumX, &tmp_var);
    6250         422 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6251             : 
    6252         422 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6253         422 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6254             : 
    6255         422 :         free_var(&tmp_var);
    6256             :     }
    6257             : 
    6258         422 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6259             : 
    6260         422 :     if (numstate.sumX.ndigits > 0)
    6261             :     {
    6262         422 :         pfree(numstate.sumX.pos_digits);
    6263         422 :         pfree(numstate.sumX.neg_digits);
    6264             :     }
    6265         422 :     if (numstate.sumX2.ndigits > 0)
    6266             :     {
    6267         422 :         pfree(numstate.sumX2.pos_digits);
    6268         422 :         pfree(numstate.sumX2.neg_digits);
    6269             :     }
    6270             : 
    6271         422 :     return res;
    6272             : }
    6273             : 
    6274             : Datum
    6275         126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6276             : {
    6277             :     Int128AggState *state;
    6278             :     Numeric     res;
    6279             :     bool        is_null;
    6280             : 
    6281         126 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6282             : 
    6283         126 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6284             : 
    6285         126 :     if (is_null)
    6286          24 :         PG_RETURN_NULL();
    6287             :     else
    6288         102 :         PG_RETURN_NUMERIC(res);
    6289             : }
    6290             : 
    6291             : Datum
    6292         164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6293             : {
    6294             :     Int128AggState *state;
    6295             :     Numeric     res;
    6296             :     bool        is_null;
    6297             : 
    6298         164 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6299             : 
    6300         164 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6301             : 
    6302         164 :     if (is_null)
    6303          24 :         PG_RETURN_NULL();
    6304             :     else
    6305         140 :         PG_RETURN_NUMERIC(res);
    6306             : }
    6307             : 
    6308             : Datum
    6309          60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6310             : {
    6311             :     Int128AggState *state;
    6312             :     Numeric     res;
    6313             :     bool        is_null;
    6314             : 
    6315          60 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6316             : 
    6317          60 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6318             : 
    6319          60 :     if (is_null)
    6320           0 :         PG_RETURN_NULL();
    6321             :     else
    6322          60 :         PG_RETURN_NUMERIC(res);
    6323             : }
    6324             : 
    6325             : Datum
    6326          72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6327             : {
    6328             :     Int128AggState *state;
    6329             :     Numeric     res;
    6330             :     bool        is_null;
    6331             : 
    6332          72 :     state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
    6333             : 
    6334          72 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6335             : 
    6336          72 :     if (is_null)
    6337           0 :         PG_RETURN_NULL();
    6338             :     else
    6339          72 :         PG_RETURN_NUMERIC(res);
    6340             : }
    6341             : 
    6342             : /*
    6343             :  * SUM transition functions for integer datatypes.
    6344             :  *
    6345             :  * To avoid overflow, we use accumulators wider than the input datatype.
    6346             :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6347             :  * inputs, we use int8 accumulators which should be sufficient for practical
    6348             :  * purposes.  (The latter two therefore don't really belong in this file,
    6349             :  * but we keep them here anyway.)
    6350             :  *
    6351             :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6352             :  * the initial condition of the transition data value needs to be NULL. This
    6353             :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6354             :  * data value into the transition data: it doesn't know how to do the type
    6355             :  * conversion.  The upshot is that these routines have to be marked non-strict
    6356             :  * and handle substitution of the first non-null input themselves.
    6357             :  *
    6358             :  * Note: these functions are used only in plain aggregation mode.
    6359             :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6360             :  */
    6361             : 
    6362             : Datum
    6363          24 : int2_sum(PG_FUNCTION_ARGS)
    6364             : {
    6365             :     int64       oldsum;
    6366             :     int64       newval;
    6367             : 
    6368          24 :     if (PG_ARGISNULL(0))
    6369             :     {
    6370             :         /* No non-null input seen so far... */
    6371           6 :         if (PG_ARGISNULL(1))
    6372           0 :             PG_RETURN_NULL();   /* still no non-null */
    6373             :         /* This is the first non-null input. */
    6374           6 :         newval = (int64) PG_GETARG_INT16(1);
    6375           6 :         PG_RETURN_INT64(newval);
    6376             :     }
    6377             : 
    6378          18 :     oldsum = PG_GETARG_INT64(0);
    6379             : 
    6380             :     /* Leave sum unchanged if new input is null. */
    6381          18 :     if (PG_ARGISNULL(1))
    6382           0 :         PG_RETURN_INT64(oldsum);
    6383             : 
    6384             :     /* OK to do the addition. */
    6385          18 :     newval = oldsum + (int64) PG_GETARG_INT16(1);
    6386             : 
    6387          18 :     PG_RETURN_INT64(newval);
    6388             : }
    6389             : 
    6390             : Datum
    6391     3698156 : int4_sum(PG_FUNCTION_ARGS)
    6392             : {
    6393             :     int64       oldsum;
    6394             :     int64       newval;
    6395             : 
    6396     3698156 :     if (PG_ARGISNULL(0))
    6397             :     {
    6398             :         /* No non-null input seen so far... */
    6399      207124 :         if (PG_ARGISNULL(1))
    6400         986 :             PG_RETURN_NULL();   /* still no non-null */
    6401             :         /* This is the first non-null input. */
    6402      206138 :         newval = (int64) PG_GETARG_INT32(1);
    6403      206138 :         PG_RETURN_INT64(newval);
    6404             :     }
    6405             : 
    6406     3491032 :     oldsum = PG_GETARG_INT64(0);
    6407             : 
    6408             :     /* Leave sum unchanged if new input is null. */
    6409     3491032 :     if (PG_ARGISNULL(1))
    6410       30874 :         PG_RETURN_INT64(oldsum);
    6411             : 
    6412             :     /* OK to do the addition. */
    6413     3460158 :     newval = oldsum + (int64) PG_GETARG_INT32(1);
    6414             : 
    6415     3460158 :     PG_RETURN_INT64(newval);
    6416             : }
    6417             : 
    6418             : /*
    6419             :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6420             :  */
    6421             : Datum
    6422           0 : int8_sum(PG_FUNCTION_ARGS)
    6423             : {
    6424             :     Numeric     oldsum;
    6425             : 
    6426           0 :     if (PG_ARGISNULL(0))
    6427             :     {
    6428             :         /* No non-null input seen so far... */
    6429           0 :         if (PG_ARGISNULL(1))
    6430           0 :             PG_RETURN_NULL();   /* still no non-null */
    6431             :         /* This is the first non-null input. */
    6432           0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6433             :     }
    6434             : 
    6435             :     /*
    6436             :      * Note that we cannot special-case the aggregate case here, as we do for
    6437             :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6438             :      * our first parameter in-place.
    6439             :      */
    6440             : 
    6441           0 :     oldsum = PG_GETARG_NUMERIC(0);
    6442             : 
    6443             :     /* Leave sum unchanged if new input is null. */
    6444           0 :     if (PG_ARGISNULL(1))
    6445           0 :         PG_RETURN_NUMERIC(oldsum);
    6446             : 
    6447             :     /* OK to do the addition. */
    6448           0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6449             :                                         NumericGetDatum(oldsum),
    6450             :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6451             : }
    6452             : 
    6453             : 
    6454             : /*
    6455             :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6456             :  * is a two-element int8 array, holding count and sum.
    6457             :  *
    6458             :  * These functions are also used for sum(int2) and sum(int4) when
    6459             :  * operating in moving-aggregate mode, since for correct inverse transitions
    6460             :  * we need to count the inputs.
    6461             :  */
    6462             : 
    6463             : typedef struct Int8TransTypeData
    6464             : {
    6465             :     int64       count;
    6466             :     int64       sum;
    6467             : } Int8TransTypeData;
    6468             : 
    6469             : Datum
    6470          42 : int2_avg_accum(PG_FUNCTION_ARGS)
    6471             : {
    6472             :     ArrayType  *transarray;
    6473          42 :     int16       newval = PG_GETARG_INT16(1);
    6474             :     Int8TransTypeData *transdata;
    6475             : 
    6476             :     /*
    6477             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6478             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6479             :      * a copy of it before scribbling on it.
    6480             :      */
    6481          42 :     if (AggCheckCallContext(fcinfo, NULL))
    6482          42 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6483             :     else
    6484           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6485             : 
    6486          84 :     if (ARR_HASNULL(transarray) ||
    6487          42 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6488           0 :         elog(ERROR, "expected 2-element int8 array");
    6489             : 
    6490          42 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6491          42 :     transdata->count++;
    6492          42 :     transdata->sum += newval;
    6493             : 
    6494          42 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6495             : }
    6496             : 
    6497             : Datum
    6498     2620302 : int4_avg_accum(PG_FUNCTION_ARGS)
    6499             : {
    6500             :     ArrayType  *transarray;
    6501     2620302 :     int32       newval = PG_GETARG_INT32(1);
    6502             :     Int8TransTypeData *transdata;
    6503             : 
    6504             :     /*
    6505             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6506             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6507             :      * a copy of it before scribbling on it.
    6508             :      */
    6509     2620302 :     if (AggCheckCallContext(fcinfo, NULL))
    6510     2620302 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6511             :     else
    6512           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6513             : 
    6514     5240604 :     if (ARR_HASNULL(transarray) ||
    6515     2620302 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6516           0 :         elog(ERROR, "expected 2-element int8 array");
    6517             : 
    6518     2620302 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6519     2620302 :     transdata->count++;
    6520     2620302 :     transdata->sum += newval;
    6521             : 
    6522     2620302 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6523             : }
    6524             : 
    6525             : Datum
    6526        4028 : int4_avg_combine(PG_FUNCTION_ARGS)
    6527             : {
    6528             :     ArrayType  *transarray1;
    6529             :     ArrayType  *transarray2;
    6530             :     Int8TransTypeData *state1;
    6531             :     Int8TransTypeData *state2;
    6532             : 
    6533        4028 :     if (!AggCheckCallContext(fcinfo, NULL))
    6534           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6535             : 
    6536        4028 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6537        4028 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6538             : 
    6539        8056 :     if (ARR_HASNULL(transarray1) ||
    6540        4028 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6541           0 :         elog(ERROR, "expected 2-element int8 array");
    6542             : 
    6543        8056 :     if (ARR_HASNULL(transarray2) ||
    6544        4028 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6545           0 :         elog(ERROR, "expected 2-element int8 array");
    6546             : 
    6547        4028 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6548        4028 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6549             : 
    6550        4028 :     state1->count += state2->count;
    6551        4028 :     state1->sum += state2->sum;
    6552             : 
    6553        4028 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6554             : }
    6555             : 
    6556             : Datum
    6557          12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6558             : {
    6559             :     ArrayType  *transarray;
    6560          12 :     int16       newval = PG_GETARG_INT16(1);
    6561             :     Int8TransTypeData *transdata;
    6562             : 
    6563             :     /*
    6564             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6565             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6566             :      * a copy of it before scribbling on it.
    6567             :      */
    6568          12 :     if (AggCheckCallContext(fcinfo, NULL))
    6569          12 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6570             :     else
    6571           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6572             : 
    6573          24 :     if (ARR_HASNULL(transarray) ||
    6574          12 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6575           0 :         elog(ERROR, "expected 2-element int8 array");
    6576             : 
    6577          12 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6578          12 :     transdata->count--;
    6579          12 :     transdata->sum -= newval;
    6580             : 
    6581          12 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6582             : }
    6583             : 
    6584             : Datum
    6585        1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6586             : {
    6587             :     ArrayType  *transarray;
    6588        1452 :     int32       newval = PG_GETARG_INT32(1);
    6589             :     Int8TransTypeData *transdata;
    6590             : 
    6591             :     /*
    6592             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6593             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6594             :      * a copy of it before scribbling on it.
    6595             :      */
    6596        1452 :     if (AggCheckCallContext(fcinfo, NULL))
    6597        1452 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6598             :     else
    6599           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6600             : 
    6601        2904 :     if (ARR_HASNULL(transarray) ||
    6602        1452 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6603           0 :         elog(ERROR, "expected 2-element int8 array");
    6604             : 
    6605        1452 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6606        1452 :     transdata->count--;
    6607        1452 :     transdata->sum -= newval;
    6608             : 
    6609        1452 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6610             : }
    6611             : 
    6612             : Datum
    6613       10774 : int8_avg(PG_FUNCTION_ARGS)
    6614             : {
    6615       10774 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6616             :     Int8TransTypeData *transdata;
    6617             :     Datum       countd,
    6618             :                 sumd;
    6619             : 
    6620       21548 :     if (ARR_HASNULL(transarray) ||
    6621       10774 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6622           0 :         elog(ERROR, "expected 2-element int8 array");
    6623       10774 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6624             : 
    6625             :     /* SQL defines AVG of no values to be NULL */
    6626       10774 :     if (transdata->count == 0)
    6627         118 :         PG_RETURN_NULL();
    6628             : 
    6629       10656 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6630       10656 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6631             : 
    6632       10656 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6633             : }
    6634             : 
    6635             : /*
    6636             :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6637             :  * final function for both.
    6638             :  */
    6639             : Datum
    6640        3834 : int2int4_sum(PG_FUNCTION_ARGS)
    6641             : {
    6642        3834 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6643             :     Int8TransTypeData *transdata;
    6644             : 
    6645        7668 :     if (ARR_HASNULL(transarray) ||
    6646        3834 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6647           0 :         elog(ERROR, "expected 2-element int8 array");
    6648        3834 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6649             : 
    6650             :     /* SQL defines SUM of no values to be NULL */
    6651        3834 :     if (transdata->count == 0)
    6652         480 :         PG_RETURN_NULL();
    6653             : 
    6654        3354 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6655             : }
    6656             : 
    6657             : 
    6658             : /* ----------------------------------------------------------------------
    6659             :  *
    6660             :  * Debug support
    6661             :  *
    6662             :  * ----------------------------------------------------------------------
    6663             :  */
    6664             : 
    6665             : #ifdef NUMERIC_DEBUG
    6666             : 
    6667             : /*
    6668             :  * dump_numeric() - Dump a value in the db storage format for debugging
    6669             :  */
    6670             : static void
    6671             : dump_numeric(const char *str, Numeric num)
    6672             : {
    6673             :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6674             :     int         ndigits;
    6675             :     int         i;
    6676             : 
    6677             :     ndigits = NUMERIC_NDIGITS(num);
    6678             : 
    6679             :     printf("%s: NUMERIC w=%d d=%d ", str,
    6680             :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6681             :     switch (NUMERIC_SIGN(num))
    6682             :     {
    6683             :         case NUMERIC_POS:
    6684             :             printf("POS");
    6685             :             break;
    6686             :         case NUMERIC_NEG:
    6687             :             printf("NEG");
    6688             :             break;
    6689             :         case NUMERIC_NAN:
    6690             :             printf("NaN");
    6691             :             break;
    6692             :         case NUMERIC_PINF:
    6693             :             printf("Infinity");
    6694             :             break;
    6695             :         case NUMERIC_NINF:
    6696             :             printf("-Infinity");
    6697             :             break;
    6698             :         default:
    6699             :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    6700             :             break;
    6701             :     }
    6702             : 
    6703             :     for (i = 0; i < ndigits; i++)
    6704             :         printf(" %0*d", DEC_DIGITS, digits[i]);
    6705             :     printf("\n");
    6706             : }
    6707             : 
    6708             : 
    6709             : /*
    6710             :  * dump_var() - Dump a value in the variable format for debugging
    6711             :  */
    6712             : static void
    6713             : dump_var(const char *str, NumericVar *var)
    6714             : {
    6715             :     int         i;
    6716             : 
    6717             :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    6718             :     switch (var->sign)
    6719             :     {
    6720             :         case NUMERIC_POS:
    6721             :             printf("POS");
    6722             :             break;
    6723             :         case NUMERIC_NEG:
    6724             :             printf("NEG");
    6725             :             break;
    6726             :         case NUMERIC_NAN:
    6727             :             printf("NaN");
    6728             :             break;
    6729             :         case NUMERIC_PINF:
    6730             :             printf("Infinity");
    6731             :             break;
    6732             :         case NUMERIC_NINF:
    6733             :             printf("-Infinity");
    6734             :             break;
    6735             :         default:
    6736             :             printf("SIGN=0x%x", var->sign);
    6737             :             break;
    6738             :     }
    6739             : 
    6740             :     for (i = 0; i < var->ndigits; i++)
    6741             :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    6742             : 
    6743             :     printf("\n");
    6744             : }
    6745             : #endif                          /* NUMERIC_DEBUG */
    6746             : 
    6747             : 
    6748             : /* ----------------------------------------------------------------------
    6749             :  *
    6750             :  * Local functions follow
    6751             :  *
    6752             :  * In general, these do not support "special" (NaN or infinity) inputs;
    6753             :  * callers should handle those possibilities first.
    6754             :  * (There are one or two exceptions, noted in their header comments.)
    6755             :  *
    6756             :  * ----------------------------------------------------------------------
    6757             :  */
    6758             : 
    6759             : 
    6760             : /*
    6761             :  * alloc_var() -
    6762             :  *
    6763             :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    6764             :  */
    6765             : static void
    6766     2177376 : alloc_var(NumericVar *var, int ndigits)
    6767             : {
    6768     2177376 :     digitbuf_free(var->buf);
    6769     2177376 :     var->buf = digitbuf_alloc(ndigits + 1);
    6770     2177376 :     var->buf[0] = 0;         /* spare digit for rounding */
    6771     2177376 :     var->digits = var->buf + 1;
    6772     2177376 :     var->ndigits = ndigits;
    6773     2177376 : }
    6774             : 
    6775             : 
    6776             : /*
    6777             :  * free_var() -
    6778             :  *
    6779             :  *  Return the digit buffer of a variable to the free pool
    6780             :  */
    6781             : static void
    6782     4189276 : free_var(NumericVar *var)
    6783             : {
    6784     4189276 :     digitbuf_free(var->buf);
    6785     4189276 :     var->buf = NULL;
    6786     4189276 :     var->digits = NULL;
    6787     4189276 :     var->sign = NUMERIC_NAN;
    6788     4189276 : }
    6789             : 
    6790             : 
    6791             : /*
    6792             :  * zero_var() -
    6793             :  *
    6794             :  *  Set a variable to ZERO.
    6795             :  *  Note: its dscale is not touched.
    6796             :  */
    6797             : static void
    6798       61068 : zero_var(NumericVar *var)
    6799             : {
    6800       61068 :     digitbuf_free(var->buf);
    6801       61068 :     var->buf = NULL;
    6802       61068 :     var->digits = NULL;
    6803       61068 :     var->ndigits = 0;
    6804       61068 :     var->weight = 0;         /* by convention; doesn't really matter */
    6805       61068 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    6806       61068 : }
    6807             : 
    6808             : 
    6809             : /*
    6810             :  * set_var_from_str()
    6811             :  *
    6812             :  *  Parse a string and put the number into a variable
    6813             :  *
    6814             :  * This function does not handle leading or trailing spaces.  It returns
    6815             :  * the end+1 position parsed into *endptr, so that caller can check for
    6816             :  * trailing spaces/garbage if deemed necessary.
    6817             :  *
    6818             :  * cp is the place to actually start parsing; str is what to use in error
    6819             :  * reports.  (Typically cp would be the same except advanced over spaces.)
    6820             :  *
    6821             :  * Returns true on success, false on failure (if escontext points to an
    6822             :  * ErrorSaveContext; otherwise errors are thrown).
    6823             :  */
    6824             : static bool
    6825      185008 : set_var_from_str(const char *str, const char *cp,
    6826             :                  NumericVar *dest, const char **endptr,
    6827             :                  Node *escontext)
    6828             : {
    6829      185008 :     bool        have_dp = false;
    6830             :     int         i;
    6831             :     unsigned char *decdigits;
    6832      185008 :     int         sign = NUMERIC_POS;
    6833      185008 :     int         dweight = -1;
    6834             :     int         ddigits;
    6835      185008 :     int         dscale = 0;
    6836             :     int         weight;
    6837             :     int         ndigits;
    6838             :     int         offset;
    6839             :     NumericDigit *digits;
    6840             : 
    6841             :     /*
    6842             :      * We first parse the string to extract decimal digits and determine the
    6843             :      * correct decimal weight.  Then convert to NBASE representation.
    6844             :      */
    6845      185008 :     switch (*cp)
    6846             :     {
    6847           0 :         case '+':
    6848           0 :             sign = NUMERIC_POS;
    6849           0 :             cp++;
    6850           0 :             break;
    6851             : 
    6852         300 :         case '-':
    6853         300 :             sign = NUMERIC_NEG;
    6854         300 :             cp++;
    6855         300 :             break;
    6856             :     }
    6857             : 
    6858      185008 :     if (*cp == '.')
    6859             :     {
    6860         384 :         have_dp = true;
    6861         384 :         cp++;
    6862             :     }
    6863             : 
    6864      185008 :     if (!isdigit((unsigned char) *cp))
    6865           0 :         goto invalid_syntax;
    6866             : 
    6867      185008 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    6868             : 
    6869             :     /* leading padding for digit alignment later */
    6870      185008 :     memset(decdigits, 0, DEC_DIGITS);
    6871      185008 :     i = DEC_DIGITS;
    6872             : 
    6873      797030 :     while (*cp)
    6874             :     {
    6875      613386 :         if (isdigit((unsigned char) *cp))
    6876             :         {
    6877      593974 :             decdigits[i++] = *cp++ - '0';
    6878      593974 :             if (!have_dp)
    6879      509334 :                 dweight++;
    6880             :             else
    6881       84640 :                 dscale++;
    6882             :         }
    6883       19412 :         else if (*cp == '.')
    6884             :         {
    6885       17886 :             if (have_dp)
    6886           0 :                 goto invalid_syntax;
    6887       17886 :             have_dp = true;
    6888       17886 :             cp++;
    6889             :             /* decimal point must not be followed by underscore */
    6890       17886 :             if (*cp == '_')
    6891           6 :                 goto invalid_syntax;
    6892             :         }
    6893        1526 :         else if (*cp == '_')
    6894             :         {
    6895             :             /* underscore must be followed by more digits */
    6896         186 :             cp++;
    6897         186 :             if (!isdigit((unsigned char) *cp))
    6898          18 :                 goto invalid_syntax;
    6899             :         }
    6900             :         else
    6901        1340 :             break;
    6902             :     }
    6903             : 
    6904      184984 :     ddigits = i - DEC_DIGITS;
    6905             :     /* trailing padding for digit alignment later */
    6906      184984 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    6907             : 
    6908             :     /* Handle exponent, if any */
    6909      184984 :     if (*cp == 'e' || *cp == 'E')
    6910             :     {
    6911        1292 :         int64       exponent = 0;
    6912        1292 :         bool        neg = false;
    6913             : 
    6914             :         /*
    6915             :          * At this point, dweight and dscale can't be more than about
    6916             :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    6917             :          * constraining the exponent similarly should be enough to prevent
    6918             :          * integer overflow in this function.  If the value is too large to
    6919             :          * fit in storage format, make_result() will complain about it later;
    6920             :          * for consistency use the same ereport errcode/text as make_result().
    6921             :          */
    6922             : 
    6923             :         /* exponent sign */
    6924        1292 :         cp++;
    6925        1292 :         if (*cp == '+')
    6926         154 :             cp++;
    6927        1138 :         else if (*cp == '-')
    6928             :         {
    6929         490 :             neg = true;
    6930         490 :             cp++;
    6931             :         }
    6932             : 
    6933             :         /* exponent digits */
    6934        1292 :         if (!isdigit((unsigned char) *cp))
    6935           6 :             goto invalid_syntax;
    6936             : 
    6937        4544 :         while (*cp)
    6938             :         {
    6939        3276 :             if (isdigit((unsigned char) *cp))
    6940             :             {
    6941        3234 :                 exponent = exponent * 10 + (*cp++ - '0');
    6942        3234 :                 if (exponent > PG_INT32_MAX / 2)
    6943           6 :                     goto out_of_range;
    6944             :             }
    6945          42 :             else if (*cp == '_')
    6946             :             {
    6947             :                 /* underscore must be followed by more digits */
    6948          42 :                 cp++;
    6949          42 :                 if (!isdigit((unsigned char) *cp))
    6950          12 :                     goto invalid_syntax;
    6951             :             }
    6952             :             else
    6953           0 :                 break;
    6954             :         }
    6955             : 
    6956        1268 :         if (neg)
    6957         490 :             exponent = -exponent;
    6958             : 
    6959        1268 :         dweight += (int) exponent;
    6960        1268 :         dscale -= (int) exponent;
    6961        1268 :         if (dscale < 0)
    6962         574 :             dscale = 0;
    6963             :     }
    6964             : 
    6965             :     /*
    6966             :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    6967             :      * to determine the converted weight and ndigits.  offset is the number of
    6968             :      * decimal zeroes to insert before the first given digit to have a
    6969             :      * correctly aligned first NBASE digit.
    6970             :      */
    6971      184960 :     if (dweight >= 0)
    6972      184188 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    6973             :     else
    6974         772 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    6975      184960 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    6976      184960 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    6977             : 
    6978      184960 :     alloc_var(dest, ndigits);
    6979      184960 :     dest->sign = sign;
    6980      184960 :     dest->weight = weight;
    6981      184960 :     dest->dscale = dscale;
    6982             : 
    6983      184960 :     i = DEC_DIGITS - offset;
    6984      184960 :     digits = dest->digits;
    6985             : 
    6986      444360 :     while (ndigits-- > 0)
    6987             :     {
    6988             : #if DEC_DIGITS == 4
    6989      259400 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    6990      259400 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    6991             : #elif DEC_DIGITS == 2
    6992             :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    6993             : #elif DEC_DIGITS == 1
    6994             :         *digits++ = decdigits[i];
    6995             : #else
    6996             : #error unsupported NBASE
    6997             : #endif
    6998      259400 :         i += DEC_DIGITS;
    6999             :     }
    7000             : 
    7001      184960 :     pfree(decdigits);
    7002             : 
    7003             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    7004      184960 :     strip_var(dest);
    7005             : 
    7006             :     /* Return end+1 position for caller */
    7007      184960 :     *endptr = cp;
    7008             : 
    7009      184960 :     return true;
    7010             : 
    7011           6 : out_of_range:
    7012           6 :     ereturn(escontext, false,
    7013             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7014             :              errmsg("value overflows numeric format")));
    7015             : 
    7016          42 : invalid_syntax:
    7017          42 :     ereturn(escontext, false,
    7018             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7019             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7020             :                     "numeric", str)));
    7021             : }
    7022             : 
    7023             : 
    7024             : /*
    7025             :  * Return the numeric value of a single hex digit.
    7026             :  */
    7027             : static inline int
    7028         708 : xdigit_value(char dig)
    7029             : {
    7030         894 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    7031         294 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    7032         108 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    7033             : }
    7034             : 
    7035             : /*
    7036             :  * set_var_from_non_decimal_integer_str()
    7037             :  *
    7038             :  *  Parse a string containing a non-decimal integer
    7039             :  *
    7040             :  * This function does not handle leading or trailing spaces.  It returns
    7041             :  * the end+1 position parsed into *endptr, so that caller can check for
    7042             :  * trailing spaces/garbage if deemed necessary.
    7043             :  *
    7044             :  * cp is the place to actually start parsing; str is what to use in error
    7045             :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    7046             :  * assumed to have already been parsed, so cp should point to the number's
    7047             :  * first digit in the base specified.
    7048             :  *
    7049             :  * base is expected to be 2, 8 or 16.
    7050             :  *
    7051             :  * Returns true on success, false on failure (if escontext points to an
    7052             :  * ErrorSaveContext; otherwise errors are thrown).
    7053             :  */
    7054             : static bool
    7055         156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7056             :                                      int base, NumericVar *dest,
    7057             :                                      const char **endptr, Node *escontext)
    7058             : {
    7059         156 :     const char *firstdigit = cp;
    7060             :     int64       tmp;
    7061             :     int64       mul;
    7062             :     NumericVar  tmp_var;
    7063             : 
    7064         156 :     init_var(&tmp_var);
    7065             : 
    7066         156 :     zero_var(dest);
    7067             : 
    7068             :     /*
    7069             :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7070             :      * value of the digits in the group, and "mul" is base^n, where n is the
    7071             :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7072             :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7073             :      */
    7074         156 :     tmp = 0;
    7075         156 :     mul = 1;
    7076             : 
    7077         156 :     if (base == 16)
    7078             :     {
    7079         828 :         while (*cp)
    7080             :         {
    7081         798 :             if (isxdigit((unsigned char) *cp))
    7082             :             {
    7083         708 :                 if (mul > PG_INT64_MAX / 16)
    7084             :                 {
    7085             :                     /* Add the contribution from this group of digits */
    7086          30 :                     int64_to_numericvar(mul, &tmp_var);
    7087          30 :                     mul_var(dest, &tmp_var, dest, 0);
    7088          30 :                     int64_to_numericvar(tmp, &tmp_var);
    7089          30 :                     add_var(dest, &tmp_var, dest);
    7090             : 
    7091             :                     /* Result will overflow if weight overflows int16 */
    7092          30 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7093           0 :                         goto out_of_range;
    7094             : 
    7095             :                     /* Begin a new group */
    7096          30 :                     tmp = 0;
    7097          30 :                     mul = 1;
    7098             :                 }
    7099             : 
    7100         708 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7101         708 :                 mul = mul * 16;
    7102             :             }
    7103          90 :             else if (*cp == '_')
    7104             :             {
    7105             :                 /* Underscore must be followed by more digits */
    7106          66 :                 cp++;
    7107          66 :                 if (!isxdigit((unsigned char) *cp))
    7108          18 :                     goto invalid_syntax;
    7109             :             }
    7110             :             else
    7111          24 :                 break;
    7112             :         }
    7113             :     }
    7114          84 :     else if (base == 8)
    7115             :     {
    7116         636 :         while (*cp)
    7117             :         {
    7118         606 :             if (*cp >= '0' && *cp <= '7')
    7119             :             {
    7120         558 :                 if (mul > PG_INT64_MAX / 8)
    7121             :                 {
    7122             :                     /* Add the contribution from this group of digits */
    7123          18 :                     int64_to_numericvar(mul, &tmp_var);
    7124          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7125          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7126          18 :                     add_var(dest, &tmp_var, dest);
    7127             : 
    7128             :                     /* Result will overflow if weight overflows int16 */
    7129          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7130           0 :                         goto out_of_range;
    7131             : 
    7132             :                     /* Begin a new group */
    7133          18 :                     tmp = 0;
    7134          18 :                     mul = 1;
    7135             :                 }
    7136             : 
    7137         558 :                 tmp = tmp * 8 + (*cp++ - '0');
    7138         558 :                 mul = mul * 8;
    7139             :             }
    7140          48 :             else if (*cp == '_')
    7141             :             {
    7142             :                 /* Underscore must be followed by more digits */
    7143          36 :                 cp++;
    7144          36 :                 if (*cp < '0' || *cp > '7')
    7145           0 :                     goto invalid_syntax;
    7146             :             }
    7147             :             else
    7148          12 :                 break;
    7149             :         }
    7150             :     }
    7151          42 :     else if (base == 2)
    7152             :     {
    7153        1560 :         while (*cp)
    7154             :         {
    7155        1530 :             if (*cp >= '0' && *cp <= '1')
    7156             :             {
    7157        1416 :                 if (mul > PG_INT64_MAX / 2)
    7158             :                 {
    7159             :                     /* Add the contribution from this group of digits */
    7160          18 :                     int64_to_numericvar(mul, &tmp_var);
    7161          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7162          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7163          18 :                     add_var(dest, &tmp_var, dest);
    7164             : 
    7165             :                     /* Result will overflow if weight overflows int16 */
    7166          18 :                     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7167           0 :                         goto out_of_range;
    7168             : 
    7169             :                     /* Begin a new group */
    7170          18 :                     tmp = 0;
    7171          18 :                     mul = 1;
    7172             :                 }
    7173             : 
    7174        1416 :                 tmp = tmp * 2 + (*cp++ - '0');
    7175        1416 :                 mul = mul * 2;
    7176             :             }
    7177         114 :             else if (*cp == '_')
    7178             :             {
    7179             :                 /* Underscore must be followed by more digits */
    7180         102 :                 cp++;
    7181         102 :                 if (*cp < '0' || *cp > '1')
    7182           0 :                     goto invalid_syntax;
    7183             :             }
    7184             :             else
    7185          12 :                 break;
    7186             :         }
    7187             :     }
    7188             :     else
    7189             :         /* Should never happen; treat as invalid input */
    7190           0 :         goto invalid_syntax;
    7191             : 
    7192             :     /* Check that we got at least one digit */
    7193         138 :     if (unlikely(cp == firstdigit))
    7194           0 :         goto invalid_syntax;
    7195             : 
    7196             :     /* Add the contribution from the final group of digits */
    7197         138 :     int64_to_numericvar(mul, &tmp_var);
    7198         138 :     mul_var(dest, &tmp_var, dest, 0);
    7199         138 :     int64_to_numericvar(tmp, &tmp_var);
    7200         138 :     add_var(dest, &tmp_var, dest);
    7201             : 
    7202         138 :     if (dest->weight > NUMERIC_WEIGHT_MAX)
    7203           0 :         goto out_of_range;
    7204             : 
    7205         138 :     dest->sign = sign;
    7206             : 
    7207         138 :     free_var(&tmp_var);
    7208             : 
    7209             :     /* Return end+1 position for caller */
    7210         138 :     *endptr = cp;
    7211             : 
    7212         138 :     return true;
    7213             : 
    7214           0 : out_of_range:
    7215           0 :     ereturn(escontext, false,
    7216             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7217             :              errmsg("value overflows numeric format")));
    7218             : 
    7219          18 : invalid_syntax:
    7220          18 :     ereturn(escontext, false,
    7221             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7222             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7223             :                     "numeric", str)));
    7224             : }
    7225             : 
    7226             : 
    7227             : /*
    7228             :  * set_var_from_num() -
    7229             :  *
    7230             :  *  Convert the packed db format into a variable
    7231             :  */
    7232             : static void
    7233       12952 : set_var_from_num(Numeric num, NumericVar *dest)
    7234             : {
    7235             :     int         ndigits;
    7236             : 
    7237       12952 :     ndigits = NUMERIC_NDIGITS(num);
    7238             : 
    7239       12952 :     alloc_var(dest, ndigits);
    7240             : 
    7241       12952 :     dest->weight = NUMERIC_WEIGHT(num);
    7242       12952 :     dest->sign = NUMERIC_SIGN(num);
    7243       12952 :     dest->dscale = NUMERIC_DSCALE(num);
    7244             : 
    7245       12952 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7246       12952 : }
    7247             : 
    7248             : 
    7249             : /*
    7250             :  * init_var_from_num() -
    7251             :  *
    7252             :  *  Initialize a variable from packed db format. The digits array is not
    7253             :  *  copied, which saves some cycles when the resulting var is not modified.
    7254             :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7255             :  *  other value to it (with set_var_* functions, or by using the var as the
    7256             :  *  destination of a function like add_var())
    7257             :  *
    7258             :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7259             :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7260             :  *  propagate to the original Numeric! It's OK to use it as the destination
    7261             :  *  argument of one of the calculational functions, though.
    7262             :  */
    7263             : static void
    7264     5862976 : init_var_from_num(Numeric num, NumericVar *dest)
    7265             : {
    7266     5862976 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7267     5862976 :     dest->weight = NUMERIC_WEIGHT(num);
    7268     5862976 :     dest->sign = NUMERIC_SIGN(num);
    7269     5862976 :     dest->dscale = NUMERIC_DSCALE(num);
    7270     5862976 :     dest->digits = NUMERIC_DIGITS(num);
    7271     5862976 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7272     5862976 : }
    7273             : 
    7274             : 
    7275             : /*
    7276             :  * set_var_from_var() -
    7277             :  *
    7278             :  *  Copy one variable into another
    7279             :  */
    7280             : static void
    7281       35262 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7282             : {
    7283             :     NumericDigit *newbuf;
    7284             : 
    7285       35262 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7286       35262 :     newbuf[0] = 0;              /* spare digit for rounding */
    7287       35262 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7288       34316 :         memcpy(newbuf + 1, value->digits,
    7289       34316 :                value->ndigits * sizeof(NumericDigit));
    7290             : 
    7291       35262 :     digitbuf_free(dest->buf);
    7292             : 
    7293       35262 :     memmove(dest, value, sizeof(NumericVar));
    7294       35262 :     dest->buf = newbuf;
    7295       35262 :     dest->digits = newbuf + 1;
    7296       35262 : }
    7297             : 
    7298             : 
    7299             : /*
    7300             :  * get_str_from_var() -
    7301             :  *
    7302             :  *  Convert a var to text representation (guts of numeric_out).
    7303             :  *  The var is displayed to the number of digits indicated by its dscale.
    7304             :  *  Returns a palloc'd string.
    7305             :  */
    7306             : static char *
    7307      884850 : get_str_from_var(const NumericVar *var)
    7308             : {
    7309             :     int         dscale;
    7310             :     char       *str;
    7311             :     char       *cp;
    7312             :     char       *endcp;
    7313             :     int         i;
    7314             :     int         d;
    7315             :     NumericDigit dig;
    7316             : 
    7317             : #if DEC_DIGITS > 1
    7318             :     NumericDigit d1;
    7319             : #endif
    7320             : 
    7321      884850 :     dscale = var->dscale;
    7322             : 
    7323             :     /*
    7324             :      * Allocate space for the result.
    7325             :      *
    7326             :      * i is set to the # of decimal digits before decimal point. dscale is the
    7327             :      * # of decimal digits we will print after decimal point. We may generate
    7328             :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7329             :      * need room for sign, decimal point, null terminator.
    7330             :      */
    7331      884850 :     i = (var->weight + 1) * DEC_DIGITS;
    7332      884850 :     if (i <= 0)
    7333      137660 :         i = 1;
    7334             : 
    7335      884850 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7336      884850 :     cp = str;
    7337             : 
    7338             :     /*
    7339             :      * Output a dash for negative values
    7340             :      */
    7341      884850 :     if (var->sign == NUMERIC_NEG)
    7342        7330 :         *cp++ = '-';
    7343             : 
    7344             :     /*
    7345             :      * Output all digits before the decimal point
    7346             :      */
    7347      884850 :     if (var->weight < 0)
    7348             :     {
    7349      137660 :         d = var->weight + 1;
    7350      137660 :         *cp++ = '0';
    7351             :     }
    7352             :     else
    7353             :     {
    7354     1601810 :         for (d = 0; d <= var->weight; d++)
    7355             :         {
    7356      854620 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7357             :             /* In the first digit, suppress extra leading decimal zeroes */
    7358             : #if DEC_DIGITS == 4
    7359             :             {
    7360      854620 :                 bool        putit = (d > 0);
    7361             : 
    7362      854620 :                 d1 = dig / 1000;
    7363      854620 :                 dig -= d1 * 1000;
    7364      854620 :                 putit |= (d1 > 0);
    7365      854620 :                 if (putit)
    7366      169122 :                     *cp++ = d1 + '0';
    7367      854620 :                 d1 = dig / 100;
    7368      854620 :                 dig -= d1 * 100;
    7369      854620 :                 putit |= (d1 > 0);
    7370      854620 :                 if (putit)
    7371      580018 :                     *cp++ = d1 + '0';
    7372      854620 :                 d1 = dig / 10;
    7373      854620 :                 dig -= d1 * 10;
    7374      854620 :                 putit |= (d1 > 0);
    7375      854620 :                 if (putit)
    7376      712304 :                     *cp++ = d1 + '0';
    7377      854620 :                 *cp++ = dig + '0';
    7378             :             }
    7379             : #elif DEC_DIGITS == 2
    7380             :             d1 = dig / 10;
    7381             :             dig -= d1 * 10;
    7382             :             if (d1 > 0 || d > 0)
    7383             :                 *cp++ = d1 + '0';
    7384             :             *cp++ = dig + '0';
    7385             : #elif DEC_DIGITS == 1
    7386             :             *cp++ = dig + '0';
    7387             : #else
    7388             : #error unsupported NBASE
    7389             : #endif
    7390             :         }
    7391             :     }
    7392             : 
    7393             :     /*
    7394             :      * If requested, output a decimal point and all the digits that follow it.
    7395             :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7396             :      * needed.
    7397             :      */
    7398      884850 :     if (dscale > 0)
    7399             :     {
    7400      644678 :         *cp++ = '.';
    7401      644678 :         endcp = cp + dscale;
    7402     1901332 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7403             :         {
    7404     1256654 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7405             : #if DEC_DIGITS == 4
    7406     1256654 :             d1 = dig / 1000;
    7407     1256654 :             dig -= d1 * 1000;
    7408     1256654 :             *cp++ = d1 + '0';
    7409     1256654 :             d1 = dig / 100;
    7410     1256654 :             dig -= d1 * 100;
    7411     1256654 :             *cp++ = d1 + '0';
    7412     1256654 :             d1 = dig / 10;
    7413     1256654 :             dig -= d1 * 10;
    7414     1256654 :             *cp++ = d1 + '0';
    7415     1256654 :             *cp++ = dig + '0';
    7416             : #elif DEC_DIGITS == 2
    7417             :             d1 = dig / 10;
    7418             :             dig -= d1 * 10;
    7419             :             *cp++ = d1 + '0';
    7420             :             *cp++ = dig + '0';
    7421             : #elif DEC_DIGITS == 1
    7422             :             *cp++ = dig + '0';
    7423             : #else
    7424             : #error unsupported NBASE
    7425             : #endif
    7426             :         }
    7427      644678 :         cp = endcp;
    7428             :     }
    7429             : 
    7430             :     /*
    7431             :      * terminate the string and return it
    7432             :      */
    7433      884850 :     *cp = '\0';
    7434      884850 :     return str;
    7435             : }
    7436             : 
    7437             : /*
    7438             :  * get_str_from_var_sci() -
    7439             :  *
    7440             :  *  Convert a var to a normalised scientific notation text representation.
    7441             :  *  This function does the heavy lifting for numeric_out_sci().
    7442             :  *
    7443             :  *  This notation has the general form a * 10^b, where a is known as the
    7444             :  *  "significand" and b is known as the "exponent".
    7445             :  *
    7446             :  *  Because we can't do superscript in ASCII (and because we want to copy
    7447             :  *  printf's behaviour) we display the exponent using E notation, with a
    7448             :  *  minimum of two exponent digits.
    7449             :  *
    7450             :  *  For example, the value 1234 could be output as 1.2e+03.
    7451             :  *
    7452             :  *  We assume that the exponent can fit into an int32.
    7453             :  *
    7454             :  *  rscale is the number of decimal digits desired after the decimal point in
    7455             :  *  the output, negative values will be treated as meaning zero.
    7456             :  *
    7457             :  *  Returns a palloc'd string.
    7458             :  */
    7459             : static char *
    7460         228 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7461             : {
    7462             :     int32       exponent;
    7463             :     NumericVar  tmp_var;
    7464             :     size_t      len;
    7465             :     char       *str;
    7466             :     char       *sig_out;
    7467             : 
    7468         228 :     if (rscale < 0)
    7469           0 :         rscale = 0;
    7470             : 
    7471             :     /*
    7472             :      * Determine the exponent of this number in normalised form.
    7473             :      *
    7474             :      * This is the exponent required to represent the number with only one
    7475             :      * significant digit before the decimal place.
    7476             :      */
    7477         228 :     if (var->ndigits > 0)
    7478             :     {
    7479         210 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7480             : 
    7481             :         /*
    7482             :          * Compensate for leading decimal zeroes in the first numeric digit by
    7483             :          * decrementing the exponent.
    7484             :          */
    7485         210 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7486             :     }
    7487             :     else
    7488             :     {
    7489             :         /*
    7490             :          * If var has no digits, then it must be zero.
    7491             :          *
    7492             :          * Zero doesn't technically have a meaningful exponent in normalised
    7493             :          * notation, but we just display the exponent as zero for consistency
    7494             :          * of output.
    7495             :          */
    7496          18 :         exponent = 0;
    7497             :     }
    7498             : 
    7499             :     /*
    7500             :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7501             :      * decimal digits in the process.
    7502             :      */
    7503         228 :     init_var(&tmp_var);
    7504             : 
    7505         228 :     power_ten_int(exponent, &tmp_var);
    7506         228 :     div_var(var, &tmp_var, &tmp_var, rscale, true, true);
    7507         228 :     sig_out = get_str_from_var(&tmp_var);
    7508             : 
    7509         228 :     free_var(&tmp_var);
    7510             : 
    7511             :     /*
    7512             :      * Allocate space for the result.
    7513             :      *
    7514             :      * In addition to the significand, we need room for the exponent
    7515             :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7516             :      * exponent itself, and of course the null terminator.
    7517             :      */
    7518         228 :     len = strlen(sig_out) + 13;
    7519         228 :     str = palloc(len);
    7520         228 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7521             : 
    7522         228 :     pfree(sig_out);
    7523             : 
    7524         228 :     return str;
    7525             : }
    7526             : 
    7527             : 
    7528             : /*
    7529             :  * numericvar_serialize - serialize NumericVar to binary format
    7530             :  *
    7531             :  * At variable level, no checks are performed on the weight or dscale, allowing
    7532             :  * us to pass around intermediate values with higher precision than supported
    7533             :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7534             :  * which use 16-bit integers for these fields.
    7535             :  */
    7536             : static void
    7537          90 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7538             : {
    7539             :     int         i;
    7540             : 
    7541          90 :     pq_sendint32(buf, var->ndigits);
    7542          90 :     pq_sendint32(buf, var->weight);
    7543          90 :     pq_sendint32(buf, var->sign);
    7544          90 :     pq_sendint32(buf, var->dscale);
    7545      637742 :     for (i = 0; i < var->ndigits; i++)
    7546      637652 :         pq_sendint16(buf, var->digits[i]);
    7547          90 : }
    7548             : 
    7549             : /*
    7550             :  * numericvar_deserialize - deserialize binary format to NumericVar
    7551             :  */
    7552             : static void
    7553          90 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7554             : {
    7555             :     int         len,
    7556             :                 i;
    7557             : 
    7558          90 :     len = pq_getmsgint(buf, sizeof(int32));
    7559             : 
    7560          90 :     alloc_var(var, len);        /* sets var->ndigits */
    7561             : 
    7562          90 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7563          90 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7564          90 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7565      637742 :     for (i = 0; i < len; i++)
    7566      637652 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7567          90 : }
    7568             : 
    7569             : 
    7570             : /*
    7571             :  * duplicate_numeric() - copy a packed-format Numeric
    7572             :  *
    7573             :  * This will handle NaN and Infinity cases.
    7574             :  */
    7575             : static Numeric
    7576       28496 : duplicate_numeric(Numeric num)
    7577             : {
    7578             :     Numeric     res;
    7579             : 
    7580       28496 :     res = (Numeric) palloc(VARSIZE(num));
    7581       28496 :     memcpy(res, num, VARSIZE(num));
    7582       28496 :     return res;
    7583             : }
    7584             : 
    7585             : /*
    7586             :  * make_result_opt_error() -
    7587             :  *
    7588             :  *  Create the packed db numeric format in palloc()'d memory from
    7589             :  *  a variable.  This will handle NaN and Infinity cases.
    7590             :  *
    7591             :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
    7592             :  *  NULL is returned.  This is helpful when caller needs to handle errors.
    7593             :  */
    7594             : static Numeric
    7595     3810052 : make_result_opt_error(const NumericVar *var, bool *have_error)
    7596             : {
    7597             :     Numeric     result;
    7598     3810052 :     NumericDigit *digits = var->digits;
    7599     3810052 :     int         weight = var->weight;
    7600     3810052 :     int         sign = var->sign;
    7601             :     int         n;
    7602             :     Size        len;
    7603             : 
    7604     3810052 :     if (have_error)
    7605      161966 :         *have_error = false;
    7606             : 
    7607     3810052 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7608             :     {
    7609             :         /*
    7610             :          * Verify valid special value.  This could be just an Assert, perhaps,
    7611             :          * but it seems worthwhile to expend a few cycles to ensure that we
    7612             :          * never write any nonzero reserved bits to disk.
    7613             :          */
    7614        3282 :         if (!(sign == NUMERIC_NAN ||
    7615             :               sign == NUMERIC_PINF ||
    7616             :               sign == NUMERIC_NINF))
    7617           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7618             : 
    7619        3282 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7620             : 
    7621        3282 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7622        3282 :         result->choice.n_header = sign;
    7623             :         /* the header word is all we need */
    7624             : 
    7625             :         dump_numeric("make_result()", result);
    7626        3282 :         return result;
    7627             :     }
    7628             : 
    7629     3806770 :     n = var->ndigits;
    7630             : 
    7631             :     /* truncate leading zeroes */
    7632     3806806 :     while (n > 0 && *digits == 0)
    7633             :     {
    7634          36 :         digits++;
    7635          36 :         weight--;
    7636          36 :         n--;
    7637             :     }
    7638             :     /* truncate trailing zeroes */
    7639     3892106 :     while (n > 0 && digits[n - 1] == 0)
    7640       85336 :         n--;
    7641             : 
    7642             :     /* If zero result, force to weight=0 and positive sign */
    7643     3806770 :     if (n == 0)
    7644             :     {
    7645      132196 :         weight = 0;
    7646      132196 :         sign = NUMERIC_POS;
    7647             :     }
    7648             : 
    7649             :     /* Build the result */
    7650     3806770 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7651             :     {
    7652     3804836 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7653     3804836 :         result = (Numeric) palloc(len);
    7654     3804836 :         SET_VARSIZE(result, len);
    7655     3804836 :         result->choice.n_short.n_header =
    7656             :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7657             :              : NUMERIC_SHORT)
    7658     3804836 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7659     3804836 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7660     3804836 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7661             :     }
    7662             :     else
    7663             :     {
    7664        1934 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7665        1934 :         result = (Numeric) palloc(len);
    7666        1934 :         SET_VARSIZE(result, len);
    7667        1934 :         result->choice.n_long.n_sign_dscale =
    7668        1934 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7669        1934 :         result->choice.n_long.n_weight = weight;
    7670             :     }
    7671             : 
    7672             :     Assert(NUMERIC_NDIGITS(result) == n);
    7673     3806770 :     if (n > 0)
    7674     3674574 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7675             : 
    7676             :     /* Check for overflow of int16 fields */
    7677     3806770 :     if (NUMERIC_WEIGHT(result) != weight ||
    7678     3806740 :         NUMERIC_DSCALE(result) != var->dscale)
    7679             :     {
    7680          30 :         if (have_error)
    7681             :         {
    7682          18 :             *have_error = true;
    7683          18 :             return NULL;
    7684             :         }
    7685             :         else
    7686             :         {
    7687          12 :             ereport(ERROR,
    7688             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7689             :                      errmsg("value overflows numeric format")));
    7690             :         }
    7691             :     }
    7692             : 
    7693             :     dump_numeric("make_result()", result);
    7694     3806740 :     return result;
    7695             : }
    7696             : 
    7697             : 
    7698             : /*
    7699             :  * make_result() -
    7700             :  *
    7701             :  *  An interface to make_result_opt_error() without "have_error" argument.
    7702             :  */
    7703             : static Numeric
    7704     2268224 : make_result(const NumericVar *var)
    7705             : {
    7706     2268224 :     return make_result_opt_error(var, NULL);
    7707             : }
    7708             : 
    7709             : 
    7710             : /*
    7711             :  * apply_typmod() -
    7712             :  *
    7713             :  *  Do bounds checking and rounding according to the specified typmod.
    7714             :  *  Note that this is only applied to normal finite values.
    7715             :  *
    7716             :  * Returns true on success, false on failure (if escontext points to an
    7717             :  * ErrorSaveContext; otherwise errors are thrown).
    7718             :  */
    7719             : static bool
    7720      166070 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    7721             : {
    7722             :     int         precision;
    7723             :     int         scale;
    7724             :     int         maxdigits;
    7725             :     int         ddigits;
    7726             :     int         i;
    7727             : 
    7728             :     /* Do nothing if we have an invalid typmod */
    7729      166070 :     if (!is_valid_numeric_typmod(typmod))
    7730      136916 :         return true;
    7731             : 
    7732       29154 :     precision = numeric_typmod_precision(typmod);
    7733       29154 :     scale = numeric_typmod_scale(typmod);
    7734       29154 :     maxdigits = precision - scale;
    7735             : 
    7736             :     /* Round to target scale (and set var->dscale) */
    7737       29154 :     round_var(var, scale);
    7738             : 
    7739             :     /* but don't allow var->dscale to be negative */
    7740       29154 :     if (var->dscale < 0)
    7741         126 :         var->dscale = 0;
    7742             : 
    7743             :     /*
    7744             :      * Check for overflow - note we can't do this before rounding, because
    7745             :      * rounding could raise the weight.  Also note that the var's weight could
    7746             :      * be inflated by leading zeroes, which will be stripped before storage
    7747             :      * but perhaps might not have been yet. In any case, we must recognize a
    7748             :      * true zero, whose weight doesn't mean anything.
    7749             :      */
    7750       29154 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    7751       29154 :     if (ddigits > maxdigits)
    7752             :     {
    7753             :         /* Determine true weight; and check for all-zero result */
    7754        6422 :         for (i = 0; i < var->ndigits; i++)
    7755             :         {
    7756        6406 :             NumericDigit dig = var->digits[i];
    7757             : 
    7758        6406 :             if (dig)
    7759             :             {
    7760             :                 /* Adjust for any high-order decimal zero digits */
    7761             : #if DEC_DIGITS == 4
    7762        6406 :                 if (dig < 10)
    7763         306 :                     ddigits -= 3;
    7764        6100 :                 else if (dig < 100)
    7765         624 :                     ddigits -= 2;
    7766        5476 :                 else if (dig < 1000)
    7767        5458 :                     ddigits -= 1;
    7768             : #elif DEC_DIGITS == 2
    7769             :                 if (dig < 10)
    7770             :                     ddigits -= 1;
    7771             : #elif DEC_DIGITS == 1
    7772             :                 /* no adjustment */
    7773             : #else
    7774             : #error unsupported NBASE
    7775             : #endif
    7776        6406 :                 if (ddigits > maxdigits)
    7777          84 :                     ereturn(escontext, false,
    7778             :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7779             :                              errmsg("numeric field overflow"),
    7780             :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    7781             :                                        precision, scale,
    7782             :                     /* Display 10^0 as 1 */
    7783             :                                        maxdigits ? "10^" : "",
    7784             :                                        maxdigits ? maxdigits : 1
    7785             :                                        )));
    7786        6322 :                 break;
    7787             :             }
    7788           0 :             ddigits -= DEC_DIGITS;
    7789             :         }
    7790             :     }
    7791             : 
    7792       29070 :     return true;
    7793             : }
    7794             : 
    7795             : /*
    7796             :  * apply_typmod_special() -
    7797             :  *
    7798             :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    7799             :  *  For convenience of most callers, the value is presented in packed form.
    7800             :  *
    7801             :  * Returns true on success, false on failure (if escontext points to an
    7802             :  * ErrorSaveContext; otherwise errors are thrown).
    7803             :  */
    7804             : static bool
    7805        1896 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    7806             : {
    7807             :     int         precision;
    7808             :     int         scale;
    7809             : 
    7810             :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    7811             : 
    7812             :     /*
    7813             :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    7814             :      * but it's a longstanding behavior.  Inf is rejected if we have any
    7815             :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    7816             :      * any finite number of digits.
    7817             :      */
    7818        1896 :     if (NUMERIC_IS_NAN(num))
    7819         798 :         return true;
    7820             : 
    7821             :     /* Do nothing if we have a default typmod (-1) */
    7822        1098 :     if (!is_valid_numeric_typmod(typmod))
    7823        1080 :         return true;
    7824             : 
    7825          18 :     precision = numeric_typmod_precision(typmod);
    7826          18 :     scale = numeric_typmod_scale(typmod);
    7827             : 
    7828          18 :     ereturn(escontext, false,
    7829             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7830             :              errmsg("numeric field overflow"),
    7831             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    7832             :                        precision, scale)));
    7833             : }
    7834             : 
    7835             : 
    7836             : /*
    7837             :  * Convert numeric to int8, rounding if needed.
    7838             :  *
    7839             :  * If overflow, return false (no error is raised).  Return true if okay.
    7840             :  */
    7841             : static bool
    7842       10386 : numericvar_to_int64(const NumericVar *var, int64 *result)
    7843             : {
    7844             :     NumericDigit *digits;
    7845             :     int         ndigits;
    7846             :     int         weight;
    7847             :     int         i;
    7848             :     int64       val;
    7849             :     bool        neg;
    7850             :     NumericVar  rounded;
    7851             : 
    7852             :     /* Round to nearest integer */
    7853       10386 :     init_var(&rounded);
    7854       10386 :     set_var_from_var(var, &rounded);
    7855       10386 :     round_var(&rounded, 0);
    7856             : 
    7857             :     /* Check for zero input */
    7858       10386 :     strip_var(&rounded);
    7859       10386 :     ndigits = rounded.ndigits;
    7860       10386 :     if (ndigits == 0)
    7861             :     {
    7862         478 :         *result = 0;
    7863         478 :         free_var(&rounded);
    7864         478 :         return true;
    7865             :     }
    7866             : 
    7867             :     /*
    7868             :      * For input like 10000000000, we must treat stripped digits as real. So
    7869             :      * the loop assumes there are weight+1 digits before the decimal point.
    7870             :      */
    7871        9908 :     weight = rounded.weight;
    7872             :     Assert(weight >= 0 && ndigits <= weight + 1);
    7873             : 
    7874             :     /*
    7875             :      * Construct the result. To avoid issues with converting a value
    7876             :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    7877             :      * bit two's complement integer), accumulate value as a negative number.
    7878             :      */
    7879        9908 :     digits = rounded.digits;
    7880        9908 :     neg = (rounded.sign == NUMERIC_NEG);
    7881        9908 :     val = -digits[0];
    7882       14108 :     for (i = 1; i <= weight; i++)
    7883             :     {
    7884        4248 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    7885             :         {
    7886          30 :             free_var(&rounded);
    7887          30 :             return false;
    7888             :         }
    7889             : 
    7890        4218 :         if (i < ndigits)
    7891             :         {
    7892        3940 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    7893             :             {
    7894          18 :                 free_var(&rounded);
    7895          18 :                 return false;
    7896             :             }
    7897             :         }
    7898             :     }
    7899             : 
    7900        9860 :     free_var(&rounded);
    7901             : 
    7902        9860 :     if (!neg)
    7903             :     {
    7904        9068 :         if (unlikely(val == PG_INT64_MIN))
    7905          24 :             return false;
    7906        9044 :         val = -val;
    7907             :     }
    7908        9836 :     *result = val;
    7909             : 
    7910        9836 :     return true;
    7911             : }
    7912             : 
    7913             : /*
    7914             :  * Convert int8 value to numeric.
    7915             :  */
    7916             : static void
    7917     1900126 : int64_to_numericvar(int64 val, NumericVar *var)
    7918             : {
    7919             :     uint64      uval,
    7920             :                 newuval;
    7921             :     NumericDigit *ptr;
    7922             :     int         ndigits;
    7923             : 
    7924             :     /* int64 can require at most 19 decimal digits; add one for safety */
    7925     1900126 :     alloc_var(var, 20 / DEC_DIGITS);
    7926     1900126 :     if (val < 0)
    7927             :     {
    7928        1814 :         var->sign = NUMERIC_NEG;
    7929        1814 :         uval = pg_abs_s64(val);
    7930             :     }
    7931             :     else
    7932             :     {
    7933     1898312 :         var->sign = NUMERIC_POS;
    7934     1898312 :         uval = val;
    7935             :     }
    7936     1900126 :     var->dscale = 0;
    7937     1900126 :     if (val == 0)
    7938             :     {
    7939       30766 :         var->ndigits = 0;
    7940       30766 :         var->weight = 0;
    7941       30766 :         return;
    7942             :     }
    7943     1869360 :     ptr = var->digits + var->ndigits;
    7944     1869360 :     ndigits = 0;
    7945             :     do
    7946             :     {
    7947     2193114 :         ptr--;
    7948     2193114 :         ndigits++;
    7949     2193114 :         newuval = uval / NBASE;
    7950     2193114 :         *ptr = uval - newuval * NBASE;
    7951     2193114 :         uval = newuval;
    7952     2193114 :     } while (uval);
    7953     1869360 :     var->digits = ptr;
    7954     1869360 :     var->ndigits = ndigits;
    7955     1869360 :     var->weight = ndigits - 1;
    7956             : }
    7957             : 
    7958             : /*
    7959             :  * Convert numeric to uint64, rounding if needed.
    7960             :  *
    7961             :  * If overflow, return false (no error is raised).  Return true if okay.
    7962             :  */
    7963             : static bool
    7964         114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    7965             : {
    7966             :     NumericDigit *digits;
    7967             :     int         ndigits;
    7968             :     int         weight;
    7969             :     int         i;
    7970             :     uint64      val;
    7971             :     NumericVar  rounded;
    7972             : 
    7973             :     /* Round to nearest integer */
    7974         114 :     init_var(&rounded);
    7975         114 :     set_var_from_var(var, &rounded);
    7976         114 :     round_var(&rounded, 0);
    7977             : 
    7978             :     /* Check for zero input */
    7979         114 :     strip_var(&rounded);
    7980         114 :     ndigits = rounded.ndigits;
    7981         114 :     if (ndigits == 0)
    7982             :     {
    7983          18 :         *result = 0;
    7984          18 :         free_var(&rounded);
    7985          18 :         return true;
    7986             :     }
    7987             : 
    7988             :     /* Check for negative input */
    7989          96 :     if (rounded.sign == NUMERIC_NEG)
    7990             :     {
    7991          12 :         free_var(&rounded);
    7992          12 :         return false;
    7993             :     }
    7994             : 
    7995             :     /*
    7996             :      * For input like 10000000000, we must treat stripped digits as real. So
    7997             :      * the loop assumes there are weight+1 digits before the decimal point.
    7998             :      */
    7999          84 :     weight = rounded.weight;
    8000             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8001             : 
    8002             :     /* Construct the result */
    8003          84 :     digits = rounded.digits;
    8004          84 :     val = digits[0];
    8005         246 :     for (i = 1; i <= weight; i++)
    8006             :     {
    8007         174 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    8008             :         {
    8009           0 :             free_var(&rounded);
    8010           0 :             return false;
    8011             :         }
    8012             : 
    8013         174 :         if (i < ndigits)
    8014             :         {
    8015         174 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    8016             :             {
    8017          12 :                 free_var(&rounded);
    8018          12 :                 return false;
    8019             :             }
    8020             :         }
    8021             :     }
    8022             : 
    8023          72 :     free_var(&rounded);
    8024             : 
    8025          72 :     *result = val;
    8026             : 
    8027          72 :     return true;
    8028             : }
    8029             : 
    8030             : /*
    8031             :  * Convert 128 bit integer to numeric.
    8032             :  */
    8033             : static void
    8034        8796 : int128_to_numericvar(INT128 val, NumericVar *var)
    8035             : {
    8036             :     int         sign;
    8037             :     NumericDigit *ptr;
    8038             :     int         ndigits;
    8039             :     int32       dig;
    8040             : 
    8041             :     /* int128 can require at most 39 decimal digits; add one for safety */
    8042        8796 :     alloc_var(var, 40 / DEC_DIGITS);
    8043        8796 :     sign = int128_sign(val);
    8044        8796 :     var->sign = sign < 0 ? NUMERIC_NEG : NUMERIC_POS;
    8045        8796 :     var->dscale = 0;
    8046        8796 :     if (sign == 0)
    8047             :     {
    8048         214 :         var->ndigits = 0;
    8049         214 :         var->weight = 0;
    8050         214 :         return;
    8051             :     }
    8052        8582 :     ptr = var->digits + var->ndigits;
    8053        8582 :     ndigits = 0;
    8054             :     do
    8055             :     {
    8056       45238 :         ptr--;
    8057       45238 :         ndigits++;
    8058       45238 :         int128_div_mod_int32(&val, NBASE, &dig);
    8059       45238 :         *ptr = (NumericDigit) abs(dig);
    8060       45238 :     } while (!int128_is_zero(val));
    8061        8582 :     var->digits = ptr;
    8062        8582 :     var->ndigits = ndigits;
    8063        8582 :     var->weight = ndigits - 1;
    8064             : }
    8065             : 
    8066             : /*
    8067             :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    8068             :  */
    8069             : static double
    8070         466 : numericvar_to_double_no_overflow(const NumericVar *var)
    8071             : {
    8072             :     char       *tmp;
    8073             :     double      val;
    8074             :     char       *endptr;
    8075             : 
    8076         466 :     tmp = get_str_from_var(var);
    8077             : 
    8078             :     /* unlike float8in, we ignore ERANGE from strtod */
    8079         466 :     val = strtod(tmp, &endptr);
    8080         466 :     if (*endptr != '\0')
    8081             :     {
    8082             :         /* shouldn't happen ... */
    8083           0 :         ereport(ERROR,
    8084             :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8085             :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8086             :                         "double precision", tmp)));
    8087             :     }
    8088             : 
    8089         466 :     pfree(tmp);
    8090             : 
    8091         466 :     return val;
    8092             : }
    8093             : 
    8094             : 
    8095             : /*
    8096             :  * cmp_var() -
    8097             :  *
    8098             :  *  Compare two values on variable level.  We assume zeroes have been
    8099             :  *  truncated to no digits.
    8100             :  */
    8101             : static int
    8102      170228 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8103             : {
    8104      340456 :     return cmp_var_common(var1->digits, var1->ndigits,
    8105      170228 :                           var1->weight, var1->sign,
    8106      170228 :                           var2->digits, var2->ndigits,
    8107      170228 :                           var2->weight, var2->sign);
    8108             : }
    8109             : 
    8110             : /*
    8111             :  * cmp_var_common() -
    8112             :  *
    8113             :  *  Main routine of cmp_var(). This function can be used by both
    8114             :  *  NumericVar and Numeric.
    8115             :  */
    8116             : static int
    8117    19507068 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8118             :                int var1weight, int var1sign,
    8119             :                const NumericDigit *var2digits, int var2ndigits,
    8120             :                int var2weight, int var2sign)
    8121             : {
    8122    19507068 :     if (var1ndigits == 0)
    8123             :     {
    8124      531782 :         if (var2ndigits == 0)
    8125      434270 :             return 0;
    8126       97512 :         if (var2sign == NUMERIC_NEG)
    8127        4142 :             return 1;
    8128       93370 :         return -1;
    8129             :     }
    8130    18975286 :     if (var2ndigits == 0)
    8131             :     {
    8132       71956 :         if (var1sign == NUMERIC_POS)
    8133       65232 :             return 1;
    8134        6724 :         return -1;
    8135             :     }
    8136             : 
    8137    18903330 :     if (var1sign == NUMERIC_POS)
    8138             :     {
    8139    18823146 :         if (var2sign == NUMERIC_NEG)
    8140       24060 :             return 1;
    8141    18799086 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8142             :                               var2digits, var2ndigits, var2weight);
    8143             :     }
    8144             : 
    8145       80184 :     if (var2sign == NUMERIC_POS)
    8146       22806 :         return -1;
    8147             : 
    8148       57378 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8149             :                           var1digits, var1ndigits, var1weight);
    8150             : }
    8151             : 
    8152             : 
    8153             : /*
    8154             :  * add_var() -
    8155             :  *
    8156             :  *  Full version of add functionality on variable level (handling signs).
    8157             :  *  result might point to one of the operands too without danger.
    8158             :  */
    8159             : static void
    8160      618100 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8161             : {
    8162             :     /*
    8163             :      * Decide on the signs of the two variables what to do
    8164             :      */
    8165      618100 :     if (var1->sign == NUMERIC_POS)
    8166             :     {
    8167      616534 :         if (var2->sign == NUMERIC_POS)
    8168             :         {
    8169             :             /*
    8170             :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8171             :              */
    8172      416170 :             add_abs(var1, var2, result);
    8173      416170 :             result->sign = NUMERIC_POS;
    8174             :         }
    8175             :         else
    8176             :         {
    8177             :             /*
    8178             :              * var1 is positive, var2 is negative Must compare absolute values
    8179             :              */
    8180      200364 :             switch (cmp_abs(var1, var2))
    8181             :             {
    8182         216 :                 case 0:
    8183             :                     /* ----------
    8184             :                      * ABS(var1) == ABS(var2)
    8185             :                      * result = ZERO
    8186             :                      * ----------
    8187             :                      */
    8188         216 :                     zero_var(result);
    8189         216 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8190         216 :                     break;
    8191             : 
    8192      186508 :                 case 1:
    8193             :                     /* ----------
    8194             :                      * ABS(var1) > ABS(var2)
    8195             :                      * result = +(ABS(var1) - ABS(var2))
    8196             :                      * ----------
    8197             :                      */
    8198      186508 :                     sub_abs(var1, var2, result);
    8199      186508 :                     result->sign = NUMERIC_POS;
    8200      186508 :                     break;
    8201             : 
    8202       13640 :                 case -1:
    8203             :                     /* ----------
    8204             :                      * ABS(var1) < ABS(var2)
    8205             :                      * result = -(ABS(var2) - ABS(var1))
    8206             :                      * ----------
    8207             :                      */
    8208       13640 :                     sub_abs(var2, var1, result);
    8209       13640 :                     result->sign = NUMERIC_NEG;
    8210       13640 :                     break;
    8211             :             }
    8212             :         }
    8213             :     }
    8214             :     else
    8215             :     {
    8216        1566 :         if (var2->sign == NUMERIC_POS)
    8217             :         {
    8218             :             /* ----------
    8219             :              * var1 is negative, var2 is positive
    8220             :              * Must compare absolute values
    8221             :              * ----------
    8222             :              */
    8223         468 :             switch (cmp_abs(var1, var2))
    8224             :             {
    8225          30 :                 case 0:
    8226             :                     /* ----------
    8227             :                      * ABS(var1) == ABS(var2)
    8228             :                      * result = ZERO
    8229             :                      * ----------
    8230             :                      */
    8231          30 :                     zero_var(result);
    8232          30 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8233          30 :                     break;
    8234             : 
    8235         294 :                 case 1:
    8236             :                     /* ----------
    8237             :                      * ABS(var1) > ABS(var2)
    8238             :                      * result = -(ABS(var1) - ABS(var2))
    8239             :                      * ----------
    8240             :                      */
    8241         294 :                     sub_abs(var1, var2, result);
    8242         294 :                     result->sign = NUMERIC_NEG;
    8243         294 :                     break;
    8244             : 
    8245         144 :                 case -1:
    8246             :                     /* ----------
    8247             :                      * ABS(var1) < ABS(var2)
    8248             :                      * result = +(ABS(var2) - ABS(var1))
    8249             :                      * ----------
    8250             :                      */
    8251         144 :                     sub_abs(var2, var1, result);
    8252         144 :                     result->sign = NUMERIC_POS;
    8253         144 :                     break;
    8254             :             }
    8255             :         }
    8256             :         else
    8257             :         {
    8258             :             /* ----------
    8259             :              * Both are negative
    8260             :              * result = -(ABS(var1) + ABS(var2))
    8261             :              * ----------
    8262             :              */
    8263        1098 :             add_abs(var1, var2, result);
    8264        1098 :             result->sign = NUMERIC_NEG;
    8265             :         }
    8266             :     }
    8267      618100 : }
    8268             : 
    8269             : 
    8270             : /*
    8271             :  * sub_var() -
    8272             :  *
    8273             :  *  Full version of sub functionality on variable level (handling signs).
    8274             :  *  result might point to one of the operands too without danger.
    8275             :  */
    8276             : static void
    8277      533012 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8278             : {
    8279             :     /*
    8280             :      * Decide on the signs of the two variables what to do
    8281             :      */
    8282      533012 :     if (var1->sign == NUMERIC_POS)
    8283             :     {
    8284      532102 :         if (var2->sign == NUMERIC_NEG)
    8285             :         {
    8286             :             /* ----------
    8287             :              * var1 is positive, var2 is negative
    8288             :              * result = +(ABS(var1) + ABS(var2))
    8289             :              * ----------
    8290             :              */
    8291       28590 :             add_abs(var1, var2, result);
    8292       28590 :             result->sign = NUMERIC_POS;
    8293             :         }
    8294             :         else
    8295             :         {
    8296             :             /* ----------
    8297             :              * Both are positive
    8298             :              * Must compare absolute values
    8299             :              * ----------
    8300             :              */
    8301      503512 :             switch (cmp_abs(var1, var2))
    8302             :             {
    8303       49108 :                 case 0:
    8304             :                     /* ----------
    8305             :                      * ABS(var1) == ABS(var2)
    8306             :                      * result = ZERO
    8307             :                      * ----------
    8308             :                      */
    8309       49108 :                     zero_var(result);
    8310       49108 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8311       49108 :                     break;
    8312             : 
    8313      443642 :                 case 1:
    8314             :                     /* ----------
    8315             :                      * ABS(var1) > ABS(var2)
    8316             :                      * result = +(ABS(var1) - ABS(var2))
    8317             :                      * ----------
    8318             :                      */
    8319      443642 :                     sub_abs(var1, var2, result);
    8320      443642 :                     result->sign = NUMERIC_POS;
    8321      443642 :                     break;
    8322             : 
    8323       10762 :                 case -1:
    8324             :                     /* ----------
    8325             :                      * ABS(var1) < ABS(var2)
    8326             :                      * result = -(ABS(var2) - ABS(var1))
    8327             :                      * ----------
    8328             :                      */
    8329       10762 :                     sub_abs(var2, var1, result);
    8330       10762 :                     result->sign = NUMERIC_NEG;
    8331       10762 :                     break;
    8332             :             }
    8333             :         }
    8334             :     }
    8335             :     else
    8336             :     {
    8337         910 :         if (var2->sign == NUMERIC_NEG)
    8338             :         {
    8339             :             /* ----------
    8340             :              * Both are negative
    8341             :              * Must compare absolute values
    8342             :              * ----------
    8343             :              */
    8344         454 :             switch (cmp_abs(var1, var2))
    8345             :             {
    8346         166 :                 case 0:
    8347             :                     /* ----------
    8348             :                      * ABS(var1) == ABS(var2)
    8349             :                      * result = ZERO
    8350             :                      * ----------
    8351             :                      */
    8352         166 :                     zero_var(result);
    8353         166 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8354         166 :                     break;
    8355             : 
    8356         240 :                 case 1:
    8357             :                     /* ----------
    8358             :                      * ABS(var1) > ABS(var2)
    8359             :                      * result = -(ABS(var1) - ABS(var2))
    8360             :                      * ----------
    8361             :                      */
    8362         240 :                     sub_abs(var1, var2, result);
    8363         240 :                     result->sign = NUMERIC_NEG;
    8364         240 :                     break;
    8365             : 
    8366          48 :                 case -1:
    8367             :                     /* ----------
    8368             :                      * ABS(var1) < ABS(var2)
    8369             :                      * result = +(ABS(var2) - ABS(var1))
    8370             :                      * ----------
    8371             :                      */
    8372          48 :                     sub_abs(var2, var1, result);
    8373          48 :                     result->sign = NUMERIC_POS;
    8374          48 :                     break;
    8375             :             }
    8376             :         }
    8377             :         else
    8378             :         {
    8379             :             /* ----------
    8380             :              * var1 is negative, var2 is positive
    8381             :              * result = -(ABS(var1) + ABS(var2))
    8382             :              * ----------
    8383             :              */
    8384         456 :             add_abs(var1, var2, result);
    8385         456 :             result->sign = NUMERIC_NEG;
    8386             :         }
    8387             :     }
    8388      533012 : }
    8389             : 
    8390             : 
    8391             : /*
    8392             :  * mul_var() -
    8393             :  *
    8394             :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8395             :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8396             :  */
    8397             : static void
    8398     1189790 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8399             :         int rscale)
    8400             : {
    8401             :     int         res_ndigits;
    8402             :     int         res_ndigitpairs;
    8403             :     int         res_sign;
    8404             :     int         res_weight;
    8405             :     int         pair_offset;
    8406             :     int         maxdigits;
    8407             :     int         maxdigitpairs;
    8408             :     uint64     *dig,
    8409             :                *dig_i1_off;
    8410             :     uint64      maxdig;
    8411             :     uint64      carry;
    8412             :     uint64      newdig;
    8413             :     int         var1ndigits;
    8414             :     int         var2ndigits;
    8415             :     int         var1ndigitpairs;
    8416             :     int         var2ndigitpairs;
    8417             :     NumericDigit *var1digits;
    8418             :     NumericDigit *var2digits;
    8419             :     uint32      var1digitpair;
    8420             :     uint32     *var2digitpairs;
    8421             :     NumericDigit *res_digits;
    8422             :     int         i,
    8423             :                 i1,
    8424             :                 i2,
    8425             :                 i2limit;
    8426             : 
    8427             :     /*
    8428             :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8429             :      * performance because the inner multiplication loop is much simpler than
    8430             :      * the outer loop, so it's better to have a smaller number of iterations
    8431             :      * of the outer loop.  This also reduces the number of times that the
    8432             :      * accumulator array needs to be normalized.
    8433             :      */
    8434     1189790 :     if (var1->ndigits > var2->ndigits)
    8435             :     {
    8436       15210 :         const NumericVar *tmp = var1;
    8437             : 
    8438       15210 :         var1 = var2;
    8439       15210 :         var2 = tmp;
    8440             :     }
    8441             : 
    8442             :     /* copy these values into local vars for speed in inner loop */
    8443     1189790 :     var1ndigits = var1->ndigits;
    8444     1189790 :     var2ndigits = var2->ndigits;
    8445     1189790 :     var1digits = var1->digits;
    8446     1189790 :     var2digits = var2->digits;
    8447             : 
    8448     1189790 :     if (var1ndigits == 0)
    8449             :     {
    8450             :         /* one or both inputs is zero; so is result */
    8451        2894 :         zero_var(result);
    8452        2894 :         result->dscale = rscale;
    8453        2894 :         return;
    8454             :     }
    8455             : 
    8456             :     /*
    8457             :      * If var1 has 1-6 digits and the exact result was requested, delegate to
    8458             :      * mul_var_short() which uses a faster direct multiplication algorithm.
    8459             :      */
    8460     1186896 :     if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
    8461             :     {
    8462     1158420 :         mul_var_short(var1, var2, result);
    8463     1158420 :         return;
    8464             :     }
    8465             : 
    8466             :     /* Determine result sign */
    8467       28476 :     if (var1->sign == var2->sign)
    8468       26994 :         res_sign = NUMERIC_POS;
    8469             :     else
    8470        1482 :         res_sign = NUMERIC_NEG;
    8471             : 
    8472             :     /*
    8473             :      * Determine the number of result digits to compute and the (maximum
    8474             :      * possible) result weight.  If the exact result would have more than
    8475             :      * rscale fractional digits, truncate the computation with
    8476             :      * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
    8477             :      * only contribute to the right of that.  (This will give the exact
    8478             :      * rounded-to-rscale answer unless carries out of the ignored positions
    8479             :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8480             :      *
    8481             :      * Note: an exact computation could not produce more than var1ndigits +
    8482             :      * var2ndigits digits, but we allocate at least one extra output digit in
    8483             :      * case rscale-driven rounding produces a carry out of the highest exact
    8484             :      * digit.
    8485             :      *
    8486             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    8487             :      * actually process the input digits in pairs, producing a base-NBASE^2
    8488             :      * intermediate result.  This significantly improves performance, since
    8489             :      * schoolbook multiplication is O(N^2) in the number of input digits, and
    8490             :      * working in base NBASE^2 effectively halves "N".
    8491             :      *
    8492             :      * Note: in a truncated computation, we must compute at least one extra
    8493             :      * output digit to ensure that all the guard digits are fully computed.
    8494             :      */
    8495             :     /* digit pairs in each input */
    8496       28476 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    8497       28476 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    8498             : 
    8499             :     /* digits in exact result */
    8500       28476 :     res_ndigits = var1ndigits + var2ndigits;
    8501             : 
    8502             :     /* digit pairs in exact result with at least one extra output digit */
    8503       28476 :     res_ndigitpairs = res_ndigits / 2 + 1;
    8504             : 
    8505             :     /* pair offset to align result to end of dig[] */
    8506       28476 :     pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
    8507             : 
    8508             :     /* maximum possible result weight (odd-length inputs shifted up below) */
    8509       28476 :     res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
    8510       28476 :         res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
    8511             : 
    8512             :     /* rscale-based truncation with at least one extra output digit */
    8513       28476 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8514             :         MUL_GUARD_DIGITS;
    8515       28476 :     maxdigitpairs = maxdigits / 2 + 1;
    8516             : 
    8517       28476 :     res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
    8518       28476 :     res_ndigits = 2 * res_ndigitpairs;
    8519             : 
    8520             :     /*
    8521             :      * In the computation below, digit pair i1 of var1 and digit pair i2 of
    8522             :      * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
    8523             :      * input digit pairs with index >= res_ndigitpairs - pair_offset don't
    8524             :      * contribute to the result, and can be ignored.
    8525             :      */
    8526       28476 :     if (res_ndigitpairs <= pair_offset)
    8527             :     {
    8528             :         /* All input digits will be ignored; so result is zero */
    8529          12 :         zero_var(result);
    8530          12 :         result->dscale = rscale;
    8531          12 :         return;
    8532             :     }
    8533       28464 :     var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
    8534       28464 :     var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
    8535             : 
    8536             :     /*
    8537             :      * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
    8538             :      * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
    8539             :      * headroom to avoid normalizing carries immediately.
    8540             :      *
    8541             :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8542             :      * threatens to exceed PG_UINT64_MAX, we take the time to propagate
    8543             :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    8544             :      * during the carry propagation passes either.  The carry values could be
    8545             :      * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
    8546             :      * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
    8547             :      *
    8548             :      * To avoid overflow in maxdig itself, it actually represents the maximum
    8549             :      * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
    8550             :      * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
    8551             :      *
    8552             :      * The conversion of var1 to base NBASE^2 is done on the fly, as each new
    8553             :      * digit is required.  The digits of var2 are converted upfront, and
    8554             :      * stored at the end of dig[].  To avoid loss of precision, the input
    8555             :      * digits are aligned with the start of digit pair array, effectively
    8556             :      * shifting them up (multiplying by NBASE) if the inputs have an odd
    8557             :      * number of NBASE digits.
    8558             :      */
    8559       28464 :     dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
    8560             :                             var2ndigitpairs * sizeof(uint32));
    8561             : 
    8562             :     /* convert var2 to base NBASE^2, shifting up if its length is odd */
    8563       28464 :     var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
    8564             : 
    8565     1547190 :     for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
    8566     1518726 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8567             : 
    8568       28464 :     if (2 * i2 + 1 < var2ndigits)
    8569       20448 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
    8570             :     else
    8571        8016 :         var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
    8572             : 
    8573             :     /*
    8574             :      * Start by multiplying var2 by the least significant contributing digit
    8575             :      * pair from var1, storing the results at the end of dig[], and filling
    8576             :      * the leading digits with zeros.
    8577             :      *
    8578             :      * The loop here is the same as the inner loop below, except that we set
    8579             :      * the results in dig[], rather than adding to them.  This is the
    8580             :      * performance bottleneck for multiplication, so we want to keep it simple
    8581             :      * enough so that it can be auto-vectorized.  Accordingly, process the
    8582             :      * digits left-to-right even though schoolbook multiplication would
    8583             :      * suggest right-to-left.  Since we aren't propagating carries in this
    8584             :      * loop, the order does not matter.
    8585             :      */
    8586       28464 :     i1 = var1ndigitpairs - 1;
    8587       28464 :     if (2 * i1 + 1 < var1ndigits)
    8588       12720 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8589             :     else
    8590       15744 :         var1digitpair = var1digits[2 * i1] * NBASE;
    8591       28464 :     maxdig = var1digitpair;
    8592             : 
    8593       28464 :     i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8594       28464 :     dig_i1_off = &dig[i1 + pair_offset];
    8595             : 
    8596       28464 :     memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
    8597     1376622 :     for (i2 = 0; i2 < i2limit; i2++)
    8598     1348158 :         dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
    8599             : 
    8600             :     /*
    8601             :      * Next, multiply var2 by the remaining digit pairs from var1, adding the
    8602             :      * results to dig[] at the appropriate offsets, and normalizing whenever
    8603             :      * there is a risk of any dig[] entry overflowing.
    8604             :      */
    8605     1501710 :     for (i1 = i1 - 1; i1 >= 0; i1--)
    8606             :     {
    8607     1473246 :         var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
    8608     1473246 :         if (var1digitpair == 0)
    8609     1179516 :             continue;
    8610             : 
    8611             :         /* Time to normalize? */
    8612      293730 :         maxdig += var1digitpair;
    8613      293730 :         if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
    8614             :         {
    8615             :             /* Yes, do it (to base NBASE^2) */
    8616          30 :             carry = 0;
    8617      119964 :             for (i = res_ndigitpairs - 1; i >= 0; i--)
    8618             :             {
    8619      119934 :                 newdig = dig[i] + carry;
    8620      119934 :                 if (newdig >= NBASE_SQR)
    8621             :                 {
    8622      115242 :                     carry = newdig / NBASE_SQR;
    8623      115242 :                     newdig -= carry * NBASE_SQR;
    8624             :                 }
    8625             :                 else
    8626        4692 :                     carry = 0;
    8627      119934 :                 dig[i] = newdig;
    8628             :             }
    8629             :             Assert(carry == 0);
    8630             :             /* Reset maxdig to indicate new worst-case */
    8631          30 :             maxdig = 1 + var1digitpair;
    8632             :         }
    8633             : 
    8634             :         /* Multiply and add */
    8635      293730 :         i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
    8636      293730 :         dig_i1_off = &dig[i1 + pair_offset];
    8637             : 
    8638   124047846 :         for (i2 = 0; i2 < i2limit; i2++)
    8639   123754116 :             dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
    8640             :     }
    8641             : 
    8642             :     /*
    8643             :      * Now we do a final carry propagation pass to normalize back to base
    8644             :      * NBASE^2, and construct the base-NBASE result digits.  Note that this is
    8645             :      * still done at full precision w/guard digits.
    8646             :      */
    8647       28464 :     alloc_var(result, res_ndigits);
    8648       28464 :     res_digits = result->digits;
    8649       28464 :     carry = 0;
    8650     2882922 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    8651             :     {
    8652     2854458 :         newdig = dig[i] + carry;
    8653     2854458 :         if (newdig >= NBASE_SQR)
    8654             :         {
    8655      406914 :             carry = newdig / NBASE_SQR;
    8656      406914 :             newdig -= carry * NBASE_SQR;
    8657             :         }
    8658             :         else
    8659     2447544 :             carry = 0;
    8660     2854458 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    8661     2854458 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    8662             :     }
    8663             :     Assert(carry == 0);
    8664             : 
    8665       28464 :     pfree(dig);
    8666             : 
    8667             :     /*
    8668             :      * Finally, round the result to the requested precision.
    8669             :      */
    8670       28464 :     result->weight = res_weight;
    8671       28464 :     result->sign = res_sign;
    8672             : 
    8673             :     /* Round to target rscale (and set result->dscale) */
    8674       28464 :     round_var(result, rscale);
    8675             : 
    8676             :     /* Strip leading and trailing zeroes */
    8677       28464 :     strip_var(result);
    8678             : }
    8679             : 
    8680             : 
    8681             : /*
    8682             :  * mul_var_short() -
    8683             :  *
    8684             :  *  Special-case multiplication function used when var1 has 1-6 digits, var2
    8685             :  *  has at least as many digits as var1, and the exact product var1 * var2 is
    8686             :  *  requested.
    8687             :  */
    8688             : static void
    8689     1158420 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
    8690             :               NumericVar *result)
    8691             : {
    8692     1158420 :     int         var1ndigits = var1->ndigits;
    8693     1158420 :     int         var2ndigits = var2->ndigits;
    8694     1158420 :     NumericDigit *var1digits = var1->digits;
    8695     1158420 :     NumericDigit *var2digits = var2->digits;
    8696             :     int         res_sign;
    8697             :     int         res_weight;
    8698             :     int         res_ndigits;
    8699             :     NumericDigit *res_buf;
    8700             :     NumericDigit *res_digits;
    8701     1158420 :     uint32      carry = 0;
    8702             :     uint32      term;
    8703             : 
    8704             :     /* Check preconditions */
    8705             :     Assert(var1ndigits >= 1);
    8706             :     Assert(var1ndigits <= 6);
    8707             :     Assert(var2ndigits >= var1ndigits);
    8708             : 
    8709             :     /*
    8710             :      * Determine the result sign, weight, and number of digits to calculate.
    8711             :      * The weight figured here is correct if the product has no leading zero
    8712             :      * digits; otherwise strip_var() will fix things up.  Note that, unlike
    8713             :      * mul_var(), we do not need to allocate an extra output digit, because we
    8714             :      * are not rounding here.
    8715             :      */
    8716     1158420 :     if (var1->sign == var2->sign)
    8717     1157228 :         res_sign = NUMERIC_POS;
    8718             :     else
    8719        1192 :         res_sign = NUMERIC_NEG;
    8720     1158420 :     res_weight = var1->weight + var2->weight + 1;
    8721     1158420 :     res_ndigits = var1ndigits + var2ndigits;
    8722             : 
    8723             :     /* Allocate result digit array */
    8724     1158420 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    8725     1158420 :     res_buf[0] = 0;             /* spare digit for later rounding */
    8726     1158420 :     res_digits = res_buf + 1;
    8727             : 
    8728             :     /*
    8729             :      * Compute the result digits in reverse, in one pass, propagating the
    8730             :      * carry up as we go.  The i'th result digit consists of the sum of the
    8731             :      * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
    8732             :      */
    8733             : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
    8734             : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
    8735             : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
    8736             : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
    8737             : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
    8738             : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
    8739             : 
    8740     1158420 :     switch (var1ndigits)
    8741             :     {
    8742     1152714 :         case 1:
    8743             :             /* ---------
    8744             :              * 1-digit case:
    8745             :              *      var1ndigits = 1
    8746             :              *      var2ndigits >= 1
    8747             :              *      res_ndigits = var2ndigits + 1
    8748             :              * ----------
    8749             :              */
    8750     3605228 :             for (int i = var2ndigits - 1; i >= 0; i--)
    8751             :             {
    8752     2452514 :                 term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
    8753     2452514 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8754     2452514 :                 carry = term / NBASE;
    8755             :             }
    8756     1152714 :             res_digits[0] = (NumericDigit) carry;
    8757     1152714 :             break;
    8758             : 
    8759         756 :         case 2:
    8760             :             /* ---------
    8761             :              * 2-digit case:
    8762             :              *      var1ndigits = 2
    8763             :              *      var2ndigits >= 2
    8764             :              *      res_ndigits = var2ndigits + 2
    8765             :              * ----------
    8766             :              */
    8767             :             /* last result digit and carry */
    8768         756 :             term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
    8769         756 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8770         756 :             carry = term / NBASE;
    8771             : 
    8772             :             /* remaining digits, except for the first two */
    8773        2304 :             for (int i = var2ndigits - 1; i >= 1; i--)
    8774             :             {
    8775        1548 :                 term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
    8776        1548 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8777        1548 :                 carry = term / NBASE;
    8778             :             }
    8779         756 :             break;
    8780             : 
    8781         204 :         case 3:
    8782             :             /* ---------
    8783             :              * 3-digit case:
    8784             :              *      var1ndigits = 3
    8785             :              *      var2ndigits >= 3
    8786             :              *      res_ndigits = var2ndigits + 3
    8787             :              * ----------
    8788             :              */
    8789             :             /* last two result digits */
    8790         204 :             term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
    8791         204 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8792         204 :             carry = term / NBASE;
    8793             : 
    8794         204 :             term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8795         204 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8796         204 :             carry = term / NBASE;
    8797             : 
    8798             :             /* remaining digits, except for the first three */
    8799         546 :             for (int i = var2ndigits - 1; i >= 2; i--)
    8800             :             {
    8801         342 :                 term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
    8802         342 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8803         342 :                 carry = term / NBASE;
    8804             :             }
    8805         204 :             break;
    8806             : 
    8807        4038 :         case 4:
    8808             :             /* ---------
    8809             :              * 4-digit case:
    8810             :              *      var1ndigits = 4
    8811             :              *      var2ndigits >= 4
    8812             :              *      res_ndigits = var2ndigits + 4
    8813             :              * ----------
    8814             :              */
    8815             :             /* last three result digits */
    8816        4038 :             term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
    8817        4038 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8818        4038 :             carry = term / NBASE;
    8819             : 
    8820        4038 :             term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    8821        4038 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8822        4038 :             carry = term / NBASE;
    8823             : 
    8824        4038 :             term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8825        4038 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    8826        4038 :             carry = term / NBASE;
    8827             : 
    8828             :             /* remaining digits, except for the first four */
    8829       11268 :             for (int i = var2ndigits - 1; i >= 3; i--)
    8830             :             {
    8831        7230 :                 term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
    8832        7230 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8833        7230 :                 carry = term / NBASE;
    8834             :             }
    8835        4038 :             break;
    8836             : 
    8837         114 :         case 5:
    8838             :             /* ---------
    8839             :              * 5-digit case:
    8840             :              *      var1ndigits = 5
    8841             :              *      var2ndigits >= 5
    8842             :              *      res_ndigits = var2ndigits + 5
    8843             :              * ----------
    8844             :              */
    8845             :             /* last four result digits */
    8846         114 :             term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
    8847         114 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8848         114 :             carry = term / NBASE;
    8849             : 
    8850         114 :             term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    8851         114 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8852         114 :             carry = term / NBASE;
    8853             : 
    8854         114 :             term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    8855         114 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    8856         114 :             carry = term / NBASE;
    8857             : 
    8858         114 :             term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8859         114 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    8860         114 :             carry = term / NBASE;
    8861             : 
    8862             :             /* remaining digits, except for the first five */
    8863         300 :             for (int i = var2ndigits - 1; i >= 4; i--)
    8864             :             {
    8865         186 :                 term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
    8866         186 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8867         186 :                 carry = term / NBASE;
    8868             :             }
    8869         114 :             break;
    8870             : 
    8871         594 :         case 6:
    8872             :             /* ---------
    8873             :              * 6-digit case:
    8874             :              *      var1ndigits = 6
    8875             :              *      var2ndigits >= 6
    8876             :              *      res_ndigits = var2ndigits + 6
    8877             :              * ----------
    8878             :              */
    8879             :             /* last five result digits */
    8880         594 :             term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
    8881         594 :             res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
    8882         594 :             carry = term / NBASE;
    8883             : 
    8884         594 :             term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
    8885         594 :             res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
    8886         594 :             carry = term / NBASE;
    8887             : 
    8888         594 :             term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
    8889         594 :             res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
    8890         594 :             carry = term / NBASE;
    8891             : 
    8892         594 :             term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
    8893         594 :             res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
    8894         594 :             carry = term / NBASE;
    8895             : 
    8896         594 :             term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
    8897         594 :             res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
    8898         594 :             carry = term / NBASE;
    8899             : 
    8900             :             /* remaining digits, except for the first six */
    8901        1656 :             for (int i = var2ndigits - 1; i >= 5; i--)
    8902             :             {
    8903        1062 :                 term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
    8904        1062 :                 res_digits[i + 1] = (NumericDigit) (term % NBASE);
    8905        1062 :                 carry = term / NBASE;
    8906             :             }
    8907         594 :             break;
    8908             :     }
    8909             : 
    8910             :     /*
    8911             :      * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
    8912             :      * significant result digits.
    8913             :      */
    8914     1158420 :     switch (var1ndigits)
    8915             :     {
    8916         594 :         case 6:
    8917         594 :             term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
    8918         594 :             res_digits[5] = (NumericDigit) (term % NBASE);
    8919         594 :             carry = term / NBASE;
    8920             :             /* FALLTHROUGH */
    8921         708 :         case 5:
    8922         708 :             term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
    8923         708 :             res_digits[4] = (NumericDigit) (term % NBASE);
    8924         708 :             carry = term / NBASE;
    8925             :             /* FALLTHROUGH */
    8926        4746 :         case 4:
    8927        4746 :             term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
    8928        4746 :             res_digits[3] = (NumericDigit) (term % NBASE);
    8929        4746 :             carry = term / NBASE;
    8930             :             /* FALLTHROUGH */
    8931        4950 :         case 3:
    8932        4950 :             term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
    8933        4950 :             res_digits[2] = (NumericDigit) (term % NBASE);
    8934        4950 :             carry = term / NBASE;
    8935             :             /* FALLTHROUGH */
    8936        5706 :         case 2:
    8937        5706 :             term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
    8938        5706 :             res_digits[1] = (NumericDigit) (term % NBASE);
    8939        5706 :             res_digits[0] = (NumericDigit) (term / NBASE);
    8940        5706 :             break;
    8941             :     }
    8942             : 
    8943             :     /* Store the product in result */
    8944     1158420 :     digitbuf_free(result->buf);
    8945     1158420 :     result->ndigits = res_ndigits;
    8946     1158420 :     result->buf = res_buf;
    8947     1158420 :     result->digits = res_digits;
    8948     1158420 :     result->weight = res_weight;
    8949     1158420 :     result->sign = res_sign;
    8950     1158420 :     result->dscale = var1->dscale + var2->dscale;
    8951             : 
    8952             :     /* Strip leading and trailing zeroes */
    8953     1158420 :     strip_var(result);
    8954     1158420 : }
    8955             : 
    8956             : 
    8957             : /*
    8958             :  * div_var() -
    8959             :  *
    8960             :  *  Compute the quotient var1 / var2 to rscale fractional digits.
    8961             :  *
    8962             :  *  If "round" is true, the result is rounded at the rscale'th digit; if
    8963             :  *  false, it is truncated (towards zero) at that digit.
    8964             :  *
    8965             :  *  If "exact" is true, the exact result is computed to the specified rscale;
    8966             :  *  if false, successive quotient digits are approximated up to rscale plus
    8967             :  *  DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
    8968             :  *  the right of that, before rounding or truncating to the specified rscale.
    8969             :  *  This can be significantly faster, and usually gives the same result as the
    8970             :  *  exact computation, but it may occasionally be off by one in the final
    8971             :  *  digit, if contributions from the ignored digits would have propagated
    8972             :  *  through the guard digits.  This is good enough for the transcendental
    8973             :  *  functions, where small errors are acceptable.
    8974             :  */
    8975             : static void
    8976      571188 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8977             :         int rscale, bool round, bool exact)
    8978             : {
    8979      571188 :     int         var1ndigits = var1->ndigits;
    8980      571188 :     int         var2ndigits = var2->ndigits;
    8981             :     int         res_sign;
    8982             :     int         res_weight;
    8983             :     int         res_ndigits;
    8984             :     int         var1ndigitpairs;
    8985             :     int         var2ndigitpairs;
    8986             :     int         res_ndigitpairs;
    8987             :     int         div_ndigitpairs;
    8988             :     int64      *dividend;
    8989             :     int32      *divisor;
    8990             :     double      fdivisor,
    8991             :                 fdivisorinverse,
    8992             :                 fdividend,
    8993             :                 fquotient;
    8994             :     int64       maxdiv;
    8995             :     int         qi;
    8996             :     int32       qdigit;
    8997             :     int64       carry;
    8998             :     int64       newdig;
    8999             :     int64      *remainder;
    9000             :     NumericDigit *res_digits;
    9001             :     int         i;
    9002             : 
    9003             :     /*
    9004             :      * First of all division by zero check; we must not be handed an
    9005             :      * unnormalized divisor.
    9006             :      */
    9007      571188 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    9008          62 :         ereport(ERROR,
    9009             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    9010             :                  errmsg("division by zero")));
    9011             : 
    9012             :     /*
    9013             :      * If the divisor has just one or two digits, delegate to div_var_int(),
    9014             :      * which uses fast short division.
    9015             :      *
    9016             :      * Similarly, on platforms with 128-bit integer support, delegate to
    9017             :      * div_var_int64() for divisors with three or four digits.
    9018             :      */
    9019      571126 :     if (var2ndigits <= 2)
    9020             :     {
    9021             :         int         idivisor;
    9022             :         int         idivisor_weight;
    9023             : 
    9024      565120 :         idivisor = var2->digits[0];
    9025      565120 :         idivisor_weight = var2->weight;
    9026      565120 :         if (var2ndigits == 2)
    9027             :         {
    9028        3902 :             idivisor = idivisor * NBASE + var2->digits[1];
    9029        3902 :             idivisor_weight--;
    9030             :         }
    9031      565120 :         if (var2->sign == NUMERIC_NEG)
    9032         654 :             idivisor = -idivisor;
    9033             : 
    9034      565120 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    9035      565120 :         return;
    9036             :     }
    9037             : #ifdef HAVE_INT128
    9038        6006 :     if (var2ndigits <= 4)
    9039             :     {
    9040             :         int64       idivisor;
    9041             :         int         idivisor_weight;
    9042             : 
    9043         528 :         idivisor = var2->digits[0];
    9044         528 :         idivisor_weight = var2->weight;
    9045        1968 :         for (i = 1; i < var2ndigits; i++)
    9046             :         {
    9047        1440 :             idivisor = idivisor * NBASE + var2->digits[i];
    9048        1440 :             idivisor_weight--;
    9049             :         }
    9050         528 :         if (var2->sign == NUMERIC_NEG)
    9051         120 :             idivisor = -idivisor;
    9052             : 
    9053         528 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    9054         528 :         return;
    9055             :     }
    9056             : #endif
    9057             : 
    9058             :     /*
    9059             :      * Otherwise, perform full long division.
    9060             :      */
    9061             : 
    9062             :     /* Result zero check */
    9063        5478 :     if (var1ndigits == 0)
    9064             :     {
    9065          36 :         zero_var(result);
    9066          36 :         result->dscale = rscale;
    9067          36 :         return;
    9068             :     }
    9069             : 
    9070             :     /*
    9071             :      * The approximate computation can be significantly faster than the exact
    9072             :      * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
    9073             :      * shorter below.  However, that comes with the tradeoff of computing
    9074             :      * DIV_GUARD_DIGITS extra base-NBASE result digits.  Ignoring all other
    9075             :      * overheads, that suggests that, in theory, the approximate computation
    9076             :      * will only be faster than the exact one when var2ndigits is greater than
    9077             :      * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
    9078             :      *
    9079             :      * Thus, we're better off doing an exact computation when var2 is shorter
    9080             :      * than this.  Empirically, it has been found that the exact threshold is
    9081             :      * a little higher, due to other overheads in the outer division loop.
    9082             :      */
    9083        5442 :     if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
    9084        3708 :         exact = true;
    9085             : 
    9086             :     /*
    9087             :      * Determine the result sign, weight and number of digits to calculate.
    9088             :      * The weight figured here is correct if the emitted quotient has no
    9089             :      * leading zero digits; otherwise strip_var() will fix things up.
    9090             :      */
    9091        5442 :     if (var1->sign == var2->sign)
    9092        5310 :         res_sign = NUMERIC_POS;
    9093             :     else
    9094         132 :         res_sign = NUMERIC_NEG;
    9095        5442 :     res_weight = var1->weight - var2->weight + 1;
    9096             :     /* The number of accurate result digits we need to produce: */
    9097        5442 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9098             :     /* ... but always at least 1 */
    9099        5442 :     res_ndigits = Max(res_ndigits, 1);
    9100             :     /* If rounding needed, figure one more digit to ensure correct result */
    9101        5442 :     if (round)
    9102         906 :         res_ndigits++;
    9103             :     /* Add guard digits for roundoff error when producing approx result */
    9104        5442 :     if (!exact)
    9105        1722 :         res_ndigits += DIV_GUARD_DIGITS;
    9106             : 
    9107             :     /*
    9108             :      * The computation itself is done using base-NBASE^2 arithmetic, so we
    9109             :      * actually process the input digits in pairs, producing a base-NBASE^2
    9110             :      * intermediate result.  This significantly improves performance, since
    9111             :      * the computation is O(N^2) in the number of input digits, and working in
    9112             :      * base NBASE^2 effectively halves "N".
    9113             :      */
    9114        5442 :     var1ndigitpairs = (var1ndigits + 1) / 2;
    9115        5442 :     var2ndigitpairs = (var2ndigits + 1) / 2;
    9116        5442 :     res_ndigitpairs = (res_ndigits + 1) / 2;
    9117        5442 :     res_ndigits = 2 * res_ndigitpairs;
    9118             : 
    9119             :     /*
    9120             :      * We do the arithmetic in an array "dividend[]" of signed 64-bit
    9121             :      * integers.  Since PG_INT64_MAX is much larger than NBASE^4, this gives
    9122             :      * us a lot of headroom to avoid normalizing carries immediately.
    9123             :      *
    9124             :      * When performing an exact computation, the working dividend requires
    9125             :      * res_ndigitpairs + var2ndigitpairs digits.  If var1 is larger than that,
    9126             :      * the extra digits do not contribute to the result, and are ignored.
    9127             :      *
    9128             :      * When performing an approximate computation, the working dividend only
    9129             :      * requires res_ndigitpairs digits (which includes the extra guard
    9130             :      * digits).  All input digits beyond that are ignored.
    9131             :      */
    9132        5442 :     if (exact)
    9133             :     {
    9134        3720 :         div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
    9135        3720 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9136             :     }
    9137             :     else
    9138             :     {
    9139        1722 :         div_ndigitpairs = res_ndigitpairs;
    9140        1722 :         var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
    9141        1722 :         var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
    9142             :     }
    9143             : 
    9144             :     /*
    9145             :      * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
    9146             :      * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
    9147             :      *
    9148             :      * For convenience, we allocate one extra dividend digit, which is set to
    9149             :      * zero and not counted in div_ndigitpairs, so that the main loop below
    9150             :      * can safely read and write the (qi+1)'th digit in the approximate case.
    9151             :      */
    9152        5442 :     dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
    9153             :                                 var2ndigitpairs * sizeof(int32));
    9154        5442 :     divisor = (int32 *) (dividend + div_ndigitpairs + 1);
    9155             : 
    9156             :     /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
    9157       49458 :     for (i = 0; i < var1ndigitpairs - 1; i++)
    9158       44016 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9159             : 
    9160        5442 :     if (2 * i + 1 < var1ndigits)
    9161        3282 :         dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
    9162             :     else
    9163        2160 :         dividend[i] = var1->digits[2 * i] * NBASE;
    9164             : 
    9165        5442 :     memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
    9166             : 
    9167             :     /* load var2 into divisor[0 .. var2ndigitpairs-1] */
    9168       39840 :     for (i = 0; i < var2ndigitpairs - 1; i++)
    9169       34398 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9170             : 
    9171        5442 :     if (2 * i + 1 < var2ndigits)
    9172        2922 :         divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
    9173             :     else
    9174        2520 :         divisor[i] = var2->digits[2 * i] * NBASE;
    9175             : 
    9176             :     /*
    9177             :      * We estimate each quotient digit using floating-point arithmetic, taking
    9178             :      * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
    9179             :      * This must be float to avoid overflow.
    9180             :      *
    9181             :      * Since the floating-point dividend and divisor use 4 base-NBASE input
    9182             :      * digits, they include roughly 40-53 bits of information from their
    9183             :      * respective inputs (assuming NBASE is 10000), which fits well in IEEE
    9184             :      * double-precision variables.  The relative error in the floating-point
    9185             :      * quotient digit will then be less than around 2/NBASE^3, so the
    9186             :      * estimated base-NBASE^2 quotient digit will typically be correct, and
    9187             :      * should not be off by more than one from the correct value.
    9188             :      */
    9189        5442 :     fdivisor = (double) divisor[0] * NBASE_SQR;
    9190        5442 :     if (var2ndigitpairs > 1)
    9191        5442 :         fdivisor += (double) divisor[1];
    9192        5442 :     fdivisorinverse = 1.0 / fdivisor;
    9193             : 
    9194             :     /*
    9195             :      * maxdiv tracks the maximum possible absolute value of any dividend[]
    9196             :      * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
    9197             :      * propagate carries.  Furthermore, we need to ensure that overflow
    9198             :      * doesn't occur during the carry propagation passes either.  The carry
    9199             :      * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
    9200             :      * so really we must normalize when digits threaten to exceed PG_INT64_MAX
    9201             :      * - PG_INT64_MAX/NBASE^2 - 1.
    9202             :      *
    9203             :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9204             :      * value divided by NBASE^2-1, i.e., at the top of the loop it is known
    9205             :      * that no dividend[] entry has an absolute value exceeding maxdiv *
    9206             :      * (NBASE^2-1).
    9207             :      *
    9208             :      * Actually, though, that holds good only for dividend[] entries after
    9209             :      * dividend[qi]; the adjustment done at the bottom of the loop may cause
    9210             :      * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
    9211             :      * the next iteration is beyond the limit.  This does not cause problems,
    9212             :      * as explained below.
    9213             :      */
    9214        5442 :     maxdiv = 1;
    9215             : 
    9216             :     /*
    9217             :      * Outer loop computes next quotient digit, which goes in dividend[qi].
    9218             :      */
    9219       49542 :     for (qi = 0; qi < res_ndigitpairs; qi++)
    9220             :     {
    9221             :         /* Approximate the current dividend value */
    9222       44100 :         fdividend = (double) dividend[qi] * NBASE_SQR;
    9223       44100 :         fdividend += (double) dividend[qi + 1];
    9224             : 
    9225             :         /* Compute the (approximate) quotient digit */
    9226       44100 :         fquotient = fdividend * fdivisorinverse;
    9227       44100 :         qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9228           6 :             (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9229             : 
    9230       44100 :         if (qdigit != 0)
    9231             :         {
    9232             :             /* Do we need to normalize now? */
    9233       40506 :             maxdiv += i64abs(qdigit);
    9234       40506 :             if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
    9235             :             {
    9236             :                 /*
    9237             :                  * Yes, do it.  Note that if var2ndigitpairs is much smaller
    9238             :                  * than div_ndigitpairs, we can save a significant amount of
    9239             :                  * effort here by noting that we only need to normalise those
    9240             :                  * dividend[] entries touched where prior iterations
    9241             :                  * subtracted multiples of the divisor.
    9242             :                  */
    9243           6 :                 carry = 0;
    9244        6750 :                 for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
    9245             :                 {
    9246        6744 :                     newdig = dividend[i] + carry;
    9247        6744 :                     if (newdig < 0)
    9248             :                     {
    9249        6744 :                         carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9250        6744 :                         newdig -= carry * NBASE_SQR;
    9251             :                     }
    9252           0 :                     else if (newdig >= NBASE_SQR)
    9253             :                     {
    9254           0 :                         carry = newdig / NBASE_SQR;
    9255           0 :                         newdig -= carry * NBASE_SQR;
    9256             :                     }
    9257             :                     else
    9258           0 :                         carry = 0;
    9259        6744 :                     dividend[i] = newdig;
    9260             :                 }
    9261           6 :                 dividend[qi] += carry;
    9262             : 
    9263             :                 /*
    9264             :                  * All the dividend[] digits except possibly dividend[qi] are
    9265             :                  * now in the range 0..NBASE^2-1.  We do not need to consider
    9266             :                  * dividend[qi] in the maxdiv value anymore, so we can reset
    9267             :                  * maxdiv to 1.
    9268             :                  */
    9269           6 :                 maxdiv = 1;
    9270             : 
    9271             :                 /*
    9272             :                  * Recompute the quotient digit since new info may have
    9273             :                  * propagated into the top two dividend digits.
    9274             :                  */
    9275           6 :                 fdividend = (double) dividend[qi] * NBASE_SQR;
    9276           6 :                 fdividend += (double) dividend[qi + 1];
    9277           6 :                 fquotient = fdividend * fdivisorinverse;
    9278           6 :                 qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
    9279           0 :                     (((int32) fquotient) - 1);  /* truncate towards -infinity */
    9280             : 
    9281           6 :                 maxdiv += i64abs(qdigit);
    9282             :             }
    9283             : 
    9284             :             /*
    9285             :              * Subtract off the appropriate multiple of the divisor.
    9286             :              *
    9287             :              * The digits beyond dividend[qi] cannot overflow, because we know
    9288             :              * they will fall within the maxdiv limit.  As for dividend[qi]
    9289             :              * itself, note that qdigit is approximately trunc(dividend[qi] /
    9290             :              * divisor[0]), which would make the new value simply dividend[qi]
    9291             :              * mod divisor[0].  The lower-order terms in qdigit can change
    9292             :              * this result by not more than about twice PG_INT64_MAX/NBASE^2,
    9293             :              * so overflow is impossible.
    9294             :              *
    9295             :              * This inner loop is the performance bottleneck for division, so
    9296             :              * code it in the same way as the inner loop of mul_var() so that
    9297             :              * it can be auto-vectorized.
    9298             :              */
    9299       40506 :             if (qdigit != 0)
    9300             :             {
    9301       40506 :                 int         istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
    9302       40506 :                 int64      *dividend_qi = &dividend[qi];
    9303             : 
    9304     7861254 :                 for (i = 0; i < istop; i++)
    9305     7820748 :                     dividend_qi[i] -= (int64) qdigit * divisor[i];
    9306             :             }
    9307             :         }
    9308             : 
    9309             :         /*
    9310             :          * The dividend digit we are about to replace might still be nonzero.
    9311             :          * Fold it into the next digit position.
    9312             :          *
    9313             :          * There is no risk of overflow here, although proving that requires
    9314             :          * some care.  Much as with the argument for dividend[qi] not
    9315             :          * overflowing, if we consider the first two terms in the numerator
    9316             :          * and denominator of qdigit, we can see that the final value of
    9317             :          * dividend[qi + 1] will be approximately a remainder mod
    9318             :          * (divisor[0]*NBASE^2 + divisor[1]).  Accounting for the lower-order
    9319             :          * terms is a bit complicated but ends up adding not much more than
    9320             :          * PG_INT64_MAX/NBASE^2 to the possible range.  Thus, dividend[qi + 1]
    9321             :          * cannot overflow here, and in its role as dividend[qi] in the next
    9322             :          * loop iteration, it can't be large enough to cause overflow in the
    9323             :          * carry propagation step (if any), either.
    9324             :          *
    9325             :          * But having said that: dividend[qi] can be more than
    9326             :          * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
    9327             :          * dividend[qi] * NBASE^2 *can* overflow.  When that happens, adding
    9328             :          * it to dividend[qi + 1] will always cause a canceling overflow so
    9329             :          * that the end result is correct.  We could avoid the intermediate
    9330             :          * overflow by doing the multiplication and addition using unsigned
    9331             :          * int64 arithmetic, which is modulo 2^64, but so far there appears no
    9332             :          * need.
    9333             :          */
    9334       44100 :         dividend[qi + 1] += dividend[qi] * NBASE_SQR;
    9335             : 
    9336       44100 :         dividend[qi] = qdigit;
    9337             :     }
    9338             : 
    9339             :     /*
    9340             :      * If an exact result was requested, use the remainder to correct the
    9341             :      * approximate quotient.  The remainder is in dividend[], immediately
    9342             :      * after the quotient digits.  Note, however, that although the remainder
    9343             :      * starts at dividend[qi = res_ndigitpairs], the first digit is the result
    9344             :      * of folding two remainder digits into one above, and the remainder
    9345             :      * currently only occupies var2ndigitpairs - 1 digits (the last digit of
    9346             :      * the working dividend was untouched by the computation above).  Thus we
    9347             :      * expand the remainder down by one base-NBASE^2 digit when we normalize
    9348             :      * it, so that it completely fills the last var2ndigitpairs digits of the
    9349             :      * dividend array.
    9350             :      */
    9351        5442 :     if (exact)
    9352             :     {
    9353             :         /* Normalize the remainder, expanding it down by one digit */
    9354        3720 :         remainder = &dividend[qi];
    9355        3720 :         carry = 0;
    9356       20214 :         for (i = var2ndigitpairs - 2; i >= 0; i--)
    9357             :         {
    9358       16494 :             newdig = remainder[i] + carry;
    9359       16494 :             if (newdig < 0)
    9360             :             {
    9361       12732 :                 carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9362       12732 :                 newdig -= carry * NBASE_SQR;
    9363             :             }
    9364        3762 :             else if (newdig >= NBASE_SQR)
    9365             :             {
    9366        3684 :                 carry = newdig / NBASE_SQR;
    9367        3684 :                 newdig -= carry * NBASE_SQR;
    9368             :             }
    9369             :             else
    9370          78 :                 carry = 0;
    9371       16494 :             remainder[i + 1] = newdig;
    9372             :         }
    9373        3720 :         remainder[0] = carry;
    9374             : 
    9375        3720 :         if (remainder[0] < 0)
    9376             :         {
    9377             :             /*
    9378             :              * The remainder is negative, so the approximate quotient is too
    9379             :              * large.  Correct by reducing the quotient by one and adding the
    9380             :              * divisor to the remainder until the remainder is positive.  We
    9381             :              * expect the quotient to be off by at most one, which has been
    9382             :              * borne out in all testing, but not conclusively proven, so we
    9383             :              * allow for larger corrections, just in case.
    9384             :              */
    9385             :             do
    9386             :             {
    9387             :                 /* Add the divisor to the remainder */
    9388           6 :                 carry = 0;
    9389          78 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9390             :                 {
    9391          72 :                     newdig = remainder[i] + divisor[i] + carry;
    9392          72 :                     if (newdig >= NBASE_SQR)
    9393             :                     {
    9394           0 :                         remainder[i] = newdig - NBASE_SQR;
    9395           0 :                         carry = 1;
    9396             :                     }
    9397             :                     else
    9398             :                     {
    9399          72 :                         remainder[i] = newdig;
    9400          72 :                         carry = 0;
    9401             :                     }
    9402             :                 }
    9403           6 :                 remainder[0] += divisor[0] + carry;
    9404             : 
    9405             :                 /* Subtract 1 from the quotient (propagating carries later) */
    9406           6 :                 dividend[qi - 1]--;
    9407             : 
    9408           6 :             } while (remainder[0] < 0);
    9409             :         }
    9410             :         else
    9411             :         {
    9412             :             /*
    9413             :              * The remainder is nonnegative.  If it's greater than or equal to
    9414             :              * the divisor, then the approximate quotient is too small and
    9415             :              * must be corrected.  As above, we don't expect to have to apply
    9416             :              * more than one correction, but allow for it just in case.
    9417             :              */
    9418             :             while (true)
    9419           6 :             {
    9420        3720 :                 bool        less = false;
    9421             : 
    9422             :                 /* Is remainder < divisor? */
    9423        3738 :                 for (i = 0; i < var2ndigitpairs; i++)
    9424             :                 {
    9425        3732 :                     if (remainder[i] < divisor[i])
    9426             :                     {
    9427        3714 :                         less = true;
    9428        3714 :                         break;
    9429             :                     }
    9430          18 :                     if (remainder[i] > divisor[i])
    9431           0 :                         break;  /* remainder > divisor */
    9432             :                 }
    9433        3720 :                 if (less)
    9434        3714 :                     break;      /* quotient is correct */
    9435             : 
    9436             :                 /* Subtract the divisor from the remainder */
    9437           6 :                 carry = 0;
    9438          18 :                 for (i = var2ndigitpairs - 1; i > 0; i--)
    9439             :                 {
    9440          12 :                     newdig = remainder[i] - divisor[i] + carry;
    9441          12 :                     if (newdig < 0)
    9442             :                     {
    9443           0 :                         remainder[i] = newdig + NBASE_SQR;
    9444           0 :                         carry = -1;
    9445             :                     }
    9446             :                     else
    9447             :                     {
    9448          12 :                         remainder[i] = newdig;
    9449          12 :                         carry = 0;
    9450             :                     }
    9451             :                 }
    9452           6 :                 remainder[0] = remainder[0] - divisor[0] + carry;
    9453             : 
    9454             :                 /* Add 1 to the quotient (propagating carries later) */
    9455           6 :                 dividend[qi - 1]++;
    9456             :             }
    9457             :         }
    9458             :     }
    9459             : 
    9460             :     /*
    9461             :      * Because the quotient digits were estimates that might have been off by
    9462             :      * one (and we didn't bother propagating carries when adjusting the
    9463             :      * quotient above), some quotient digits might be out of range, so do a
    9464             :      * final carry propagation pass to normalize back to base NBASE^2, and
    9465             :      * construct the base-NBASE result digits.  Note that this is still done
    9466             :      * at full precision w/guard digits.
    9467             :      */
    9468        5442 :     alloc_var(result, res_ndigits);
    9469        5442 :     res_digits = result->digits;
    9470        5442 :     carry = 0;
    9471       49542 :     for (i = res_ndigitpairs - 1; i >= 0; i--)
    9472             :     {
    9473       44100 :         newdig = dividend[i] + carry;
    9474       44100 :         if (newdig < 0)
    9475             :         {
    9476           6 :             carry = -((-newdig - 1) / NBASE_SQR) - 1;
    9477           6 :             newdig -= carry * NBASE_SQR;
    9478             :         }
    9479       44094 :         else if (newdig >= NBASE_SQR)
    9480             :         {
    9481           0 :             carry = newdig / NBASE_SQR;
    9482           0 :             newdig -= carry * NBASE_SQR;
    9483             :         }
    9484             :         else
    9485       44094 :             carry = 0;
    9486       44100 :         res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
    9487       44100 :         res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
    9488             :     }
    9489             :     Assert(carry == 0);
    9490             : 
    9491        5442 :     pfree(dividend);
    9492             : 
    9493             :     /*
    9494             :      * Finally, round or truncate the result to the requested precision.
    9495             :      */
    9496        5442 :     result->weight = res_weight;
    9497        5442 :     result->sign = res_sign;
    9498             : 
    9499             :     /* Round or truncate to target rscale (and set result->dscale) */
    9500        5442 :     if (round)
    9501         906 :         round_var(result, rscale);
    9502             :     else
    9503        4536 :         trunc_var(result, rscale);
    9504             : 
    9505             :     /* Strip leading and trailing zeroes */
    9506        5442 :     strip_var(result);
    9507             : }
    9508             : 
    9509             : 
    9510             : /*
    9511             :  * div_var_int() -
    9512             :  *
    9513             :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9514             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9515             :  */
    9516             : static void
    9517      584278 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9518             :             NumericVar *result, int rscale, bool round)
    9519             : {
    9520      584278 :     NumericDigit *var_digits = var->digits;
    9521      584278 :     int         var_ndigits = var->ndigits;
    9522             :     int         res_sign;
    9523             :     int         res_weight;
    9524             :     int         res_ndigits;
    9525             :     NumericDigit *res_buf;
    9526             :     NumericDigit *res_digits;
    9527             :     uint32      divisor;
    9528             :     int         i;
    9529             : 
    9530             :     /* Guard against division by zero */
    9531      584278 :     if (ival == 0)
    9532           0 :         ereport(ERROR,
    9533             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9534             :                 errmsg("division by zero"));
    9535             : 
    9536             :     /* Result zero check */
    9537      584278 :     if (var_ndigits == 0)
    9538             :     {
    9539        2300 :         zero_var(result);
    9540        2300 :         result->dscale = rscale;
    9541        2300 :         return;
    9542             :     }
    9543             : 
    9544             :     /*
    9545             :      * Determine the result sign, weight and number of digits to calculate.
    9546             :      * The weight figured here is correct if the emitted quotient has no
    9547             :      * leading zero digits; otherwise strip_var() will fix things up.
    9548             :      */
    9549      581978 :     if (var->sign == NUMERIC_POS)
    9550      578990 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9551             :     else
    9552        2988 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9553      581978 :     res_weight = var->weight - ival_weight;
    9554             :     /* The number of accurate result digits we need to produce: */
    9555      581978 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9556             :     /* ... but always at least 1 */
    9557      581978 :     res_ndigits = Max(res_ndigits, 1);
    9558             :     /* If rounding needed, figure one more digit to ensure correct result */
    9559      581978 :     if (round)
    9560      166686 :         res_ndigits++;
    9561             : 
    9562      581978 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9563      581978 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9564      581978 :     res_digits = res_buf + 1;
    9565             : 
    9566             :     /*
    9567             :      * Now compute the quotient digits.  This is the short division algorithm
    9568             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9569             :      * allow the divisor to exceed the internal base.
    9570             :      *
    9571             :      * In this algorithm, the carry from one digit to the next is at most
    9572             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9573             :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9574             :      * integer if this exceeds UINT_MAX.
    9575             :      */
    9576      581978 :     divisor = abs(ival);
    9577             : 
    9578      581978 :     if (divisor <= UINT_MAX / NBASE)
    9579             :     {
    9580             :         /* carry cannot overflow 32 bits */
    9581      578676 :         uint32      carry = 0;
    9582             : 
    9583     2844902 :         for (i = 0; i < res_ndigits; i++)
    9584             :         {
    9585     2266226 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9586     2266226 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9587     2266226 :             carry = carry % divisor;
    9588             :         }
    9589             :     }
    9590             :     else
    9591             :     {
    9592             :         /* carry may exceed 32 bits */
    9593        3302 :         uint64      carry = 0;
    9594             : 
    9595       10572 :         for (i = 0; i < res_ndigits; i++)
    9596             :         {
    9597        7270 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9598        7270 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9599        7270 :             carry = carry % divisor;
    9600             :         }
    9601             :     }
    9602             : 
    9603             :     /* Store the quotient in result */
    9604      581978 :     digitbuf_free(result->buf);
    9605      581978 :     result->ndigits = res_ndigits;
    9606      581978 :     result->buf = res_buf;
    9607      581978 :     result->digits = res_digits;
    9608      581978 :     result->weight = res_weight;
    9609      581978 :     result->sign = res_sign;
    9610             : 
    9611             :     /* Round or truncate to target rscale (and set result->dscale) */
    9612      581978 :     if (round)
    9613      166686 :         round_var(result, rscale);
    9614             :     else
    9615      415292 :         trunc_var(result, rscale);
    9616             : 
    9617             :     /* Strip leading/trailing zeroes */
    9618      581978 :     strip_var(result);
    9619             : }
    9620             : 
    9621             : 
    9622             : #ifdef HAVE_INT128
    9623             : /*
    9624             :  * div_var_int64() -
    9625             :  *
    9626             :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
    9627             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9628             :  *
    9629             :  *  This duplicates the logic in div_var_int(), so any changes made there
    9630             :  *  should be made here too.
    9631             :  */
    9632             : static void
    9633         528 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
    9634             :               NumericVar *result, int rscale, bool round)
    9635             : {
    9636         528 :     NumericDigit *var_digits = var->digits;
    9637         528 :     int         var_ndigits = var->ndigits;
    9638             :     int         res_sign;
    9639             :     int         res_weight;
    9640             :     int         res_ndigits;
    9641             :     NumericDigit *res_buf;
    9642             :     NumericDigit *res_digits;
    9643             :     uint64      divisor;
    9644             :     int         i;
    9645             : 
    9646             :     /* Guard against division by zero */
    9647         528 :     if (ival == 0)
    9648           0 :         ereport(ERROR,
    9649             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9650             :                 errmsg("division by zero"));
    9651             : 
    9652             :     /* Result zero check */
    9653         528 :     if (var_ndigits == 0)
    9654             :     {
    9655          96 :         zero_var(result);
    9656          96 :         result->dscale = rscale;
    9657          96 :         return;
    9658             :     }
    9659             : 
    9660             :     /*
    9661             :      * Determine the result sign, weight and number of digits to calculate.
    9662             :      * The weight figured here is correct if the emitted quotient has no
    9663             :      * leading zero digits; otherwise strip_var() will fix things up.
    9664             :      */
    9665         432 :     if (var->sign == NUMERIC_POS)
    9666         258 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9667             :     else
    9668         174 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9669         432 :     res_weight = var->weight - ival_weight;
    9670             :     /* The number of accurate result digits we need to produce: */
    9671         432 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9672             :     /* ... but always at least 1 */
    9673         432 :     res_ndigits = Max(res_ndigits, 1);
    9674             :     /* If rounding needed, figure one more digit to ensure correct result */
    9675         432 :     if (round)
    9676         426 :         res_ndigits++;
    9677             : 
    9678         432 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9679         432 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9680         432 :     res_digits = res_buf + 1;
    9681             : 
    9682             :     /*
    9683             :      * Now compute the quotient digits.  This is the short division algorithm
    9684             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9685             :      * allow the divisor to exceed the internal base.
    9686             :      *
    9687             :      * In this algorithm, the carry from one digit to the next is at most
    9688             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9689             :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
    9690             :      * integer if this exceeds PG_UINT64_MAX.
    9691             :      */
    9692         432 :     divisor = i64abs(ival);
    9693             : 
    9694         432 :     if (divisor <= PG_UINT64_MAX / NBASE)
    9695             :     {
    9696             :         /* carry cannot overflow 64 bits */
    9697         336 :         uint64      carry = 0;
    9698             : 
    9699        3414 :         for (i = 0; i < res_ndigits; i++)
    9700             :         {
    9701        3078 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9702        3078 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9703        3078 :             carry = carry % divisor;
    9704             :         }
    9705             :     }
    9706             :     else
    9707             :     {
    9708             :         /* carry may exceed 64 bits */
    9709          96 :         uint128     carry = 0;
    9710             : 
    9711        1032 :         for (i = 0; i < res_ndigits; i++)
    9712             :         {
    9713         936 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9714         936 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9715         936 :             carry = carry % divisor;
    9716             :         }
    9717             :     }
    9718             : 
    9719             :     /* Store the quotient in result */
    9720         432 :     digitbuf_free(result->buf);
    9721         432 :     result->ndigits = res_ndigits;
    9722         432 :     result->buf = res_buf;
    9723         432 :     result->digits = res_digits;
    9724         432 :     result->weight = res_weight;
    9725         432 :     result->sign = res_sign;
    9726             : 
    9727             :     /* Round or truncate to target rscale (and set result->dscale) */
    9728         432 :     if (round)
    9729         426 :         round_var(result, rscale);
    9730             :     else
    9731           6 :         trunc_var(result, rscale);
    9732             : 
    9733             :     /* Strip leading/trailing zeroes */
    9734         432 :     strip_var(result);
    9735             : }
    9736             : #endif
    9737             : 
    9738             : 
    9739             : /*
    9740             :  * Default scale selection for division
    9741             :  *
    9742             :  * Returns the appropriate result scale for the division result.
    9743             :  */
    9744             : static int
    9745      149620 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
    9746             : {
    9747             :     int         weight1,
    9748             :                 weight2,
    9749             :                 qweight,
    9750             :                 i;
    9751             :     NumericDigit firstdigit1,
    9752             :                 firstdigit2;
    9753             :     int         rscale;
    9754             : 
    9755             :     /*
    9756             :      * The result scale of a division isn't specified in any SQL standard. For
    9757             :      * PostgreSQL we select a result scale that will give at least
    9758             :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
    9759             :      * result no less accurate than float8; but use a scale not less than
    9760             :      * either input's display scale.
    9761             :      */
    9762             : 
    9763             :     /* Get the actual (normalized) weight and first digit of each input */
    9764             : 
    9765      149620 :     weight1 = 0;                /* values to use if var1 is zero */
    9766      149620 :     firstdigit1 = 0;
    9767      149620 :     for (i = 0; i < var1->ndigits; i++)
    9768             :     {
    9769      147920 :         firstdigit1 = var1->digits[i];
    9770      147920 :         if (firstdigit1 != 0)
    9771             :         {
    9772      147920 :             weight1 = var1->weight - i;
    9773      147920 :             break;
    9774             :         }
    9775             :     }
    9776             : 
    9777      149620 :     weight2 = 0;                /* values to use if var2 is zero */
    9778      149620 :     firstdigit2 = 0;
    9779      149620 :     for (i = 0; i < var2->ndigits; i++)
    9780             :     {
    9781      149570 :         firstdigit2 = var2->digits[i];
    9782      149570 :         if (firstdigit2 != 0)
    9783             :         {
    9784      149570 :             weight2 = var2->weight - i;
    9785      149570 :             break;
    9786             :         }
    9787             :     }
    9788             : 
    9789             :     /*
    9790             :      * Estimate weight of quotient.  If the two first digits are equal, we
    9791             :      * can't be sure, but assume that var1 is less than var2.
    9792             :      */
    9793      149620 :     qweight = weight1 - weight2;
    9794      149620 :     if (firstdigit1 <= firstdigit2)
    9795      132784 :         qweight--;
    9796             : 
    9797             :     /* Select result scale */
    9798      149620 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
    9799      149620 :     rscale = Max(rscale, var1->dscale);
    9800      149620 :     rscale = Max(rscale, var2->dscale);
    9801      149620 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    9802      149620 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    9803             : 
    9804      149620 :     return rscale;
    9805             : }
    9806             : 
    9807             : 
    9808             : /*
    9809             :  * mod_var() -
    9810             :  *
    9811             :  *  Calculate the modulo of two numerics at variable level
    9812             :  */
    9813             : static void
    9814      413768 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9815             : {
    9816             :     NumericVar  tmp;
    9817             : 
    9818      413768 :     init_var(&tmp);
    9819             : 
    9820             :     /* ---------
    9821             :      * We do this using the equation
    9822             :      *      mod(x,y) = x - trunc(x/y)*y
    9823             :      * div_var can be persuaded to give us trunc(x/y) directly.
    9824             :      * ----------
    9825             :      */
    9826      413768 :     div_var(var1, var2, &tmp, 0, false, true);
    9827             : 
    9828      413756 :     mul_var(var2, &tmp, &tmp, var2->dscale);
    9829             : 
    9830      413756 :     sub_var(var1, &tmp, result);
    9831             : 
    9832      413756 :     free_var(&tmp);
    9833      413756 : }
    9834             : 
    9835             : 
    9836             : /*
    9837             :  * div_mod_var() -
    9838             :  *
    9839             :  *  Calculate the truncated integer quotient and numeric remainder of two
    9840             :  *  numeric variables.  The remainder is precise to var2's dscale.
    9841             :  */
    9842             : static void
    9843        4518 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
    9844             :             NumericVar *quot, NumericVar *rem)
    9845             : {
    9846             :     NumericVar  q;
    9847             :     NumericVar  r;
    9848             : 
    9849        4518 :     init_var(&q);
    9850        4518 :     init_var(&r);
    9851             : 
    9852             :     /*
    9853             :      * Use div_var() with exact = false to get an initial estimate for the
    9854             :      * integer quotient (truncated towards zero).  This might be slightly
    9855             :      * inaccurate, but we correct it below.
    9856             :      */
    9857        4518 :     div_var(var1, var2, &q, 0, false, false);
    9858             : 
    9859             :     /* Compute initial estimate of remainder using the quotient estimate. */
    9860        4518 :     mul_var(var2, &q, &r, var2->dscale);
    9861        4518 :     sub_var(var1, &r, &r);
    9862             : 
    9863             :     /*
    9864             :      * Adjust the results if necessary --- the remainder should have the same
    9865             :      * sign as var1, and its absolute value should be less than the absolute
    9866             :      * value of var2.
    9867             :      */
    9868        4518 :     while (r.ndigits != 0 && r.sign != var1->sign)
    9869             :     {
    9870             :         /* The absolute value of the quotient is too large */
    9871           0 :         if (var1->sign == var2->sign)
    9872             :         {
    9873           0 :             sub_var(&q, &const_one, &q);
    9874           0 :             add_var(&r, var2, &r);
    9875             :         }
    9876             :         else
    9877             :         {
    9878           0 :             add_var(&q, &const_one, &q);
    9879           0 :             sub_var(&r, var2, &r);
    9880             :         }
    9881             :     }
    9882             : 
    9883        4518 :     while (cmp_abs(&r, var2) >= 0)
    9884             :     {
    9885             :         /* The absolute value of the quotient is too small */
    9886           0 :         if (var1->sign == var2->sign)
    9887             :         {
    9888           0 :             add_var(&q, &const_one, &q);
    9889           0 :             sub_var(&r, var2, &r);
    9890             :         }
    9891             :         else
    9892             :         {
    9893           0 :             sub_var(&q, &const_one, &q);
    9894           0 :             add_var(&r, var2, &r);
    9895             :         }
    9896             :     }
    9897             : 
    9898        4518 :     set_var_from_var(&q, quot);
    9899        4518 :     set_var_from_var(&r, rem);
    9900             : 
    9901        4518 :     free_var(&q);
    9902        4518 :     free_var(&r);
    9903        4518 : }
    9904             : 
    9905             : 
    9906             : /*
    9907             :  * ceil_var() -
    9908             :  *
    9909             :  *  Return the smallest integer greater than or equal to the argument
    9910             :  *  on variable level
    9911             :  */
    9912             : static void
    9913         204 : ceil_var(const NumericVar *var, NumericVar *result)
    9914             : {
    9915             :     NumericVar  tmp;
    9916             : 
    9917         204 :     init_var(&tmp);
    9918         204 :     set_var_from_var(var, &tmp);
    9919             : 
    9920         204 :     trunc_var(&tmp, 0);
    9921             : 
    9922         204 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
    9923          60 :         add_var(&tmp, &const_one, &tmp);
    9924             : 
    9925         204 :     set_var_from_var(&tmp, result);
    9926         204 :     free_var(&tmp);
    9927         204 : }
    9928             : 
    9929             : 
    9930             : /*
    9931             :  * floor_var() -
    9932             :  *
    9933             :  *  Return the largest integer equal to or less than the argument
    9934             :  *  on variable level
    9935             :  */
    9936             : static void
    9937         108 : floor_var(const NumericVar *var, NumericVar *result)
    9938             : {
    9939             :     NumericVar  tmp;
    9940             : 
    9941         108 :     init_var(&tmp);
    9942         108 :     set_var_from_var(var, &tmp);
    9943             : 
    9944         108 :     trunc_var(&tmp, 0);
    9945             : 
    9946         108 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
    9947          30 :         sub_var(&tmp, &const_one, &tmp);
    9948             : 
    9949         108 :     set_var_from_var(&tmp, result);
    9950         108 :     free_var(&tmp);
    9951         108 : }
    9952             : 
    9953             : 
    9954             : /*
    9955             :  * gcd_var() -
    9956             :  *
    9957             :  *  Calculate the greatest common divisor of two numerics at variable level
    9958             :  */
    9959             : static void
    9960         222 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9961             : {
    9962             :     int         res_dscale;
    9963             :     int         cmp;
    9964             :     NumericVar  tmp_arg;
    9965             :     NumericVar  mod;
    9966             : 
    9967         222 :     res_dscale = Max(var1->dscale, var2->dscale);
    9968             : 
    9969             :     /*
    9970             :      * Arrange for var1 to be the number with the greater absolute value.
    9971             :      *
    9972             :      * This would happen automatically in the loop below, but avoids an
    9973             :      * expensive modulo operation.
    9974             :      */
    9975         222 :     cmp = cmp_abs(var1, var2);
    9976         222 :     if (cmp < 0)
    9977             :     {
    9978          84 :         const NumericVar *tmp = var1;
    9979             : 
    9980          84 :         var1 = var2;
    9981          84 :         var2 = tmp;
    9982             :     }
    9983             : 
    9984             :     /*
    9985             :      * Also avoid the taking the modulo if the inputs have the same absolute
    9986             :      * value, or if the smaller input is zero.
    9987             :      */
    9988         222 :     if (cmp == 0 || var2->ndigits == 0)
    9989             :     {
    9990          72 :         set_var_from_var(var1, result);
    9991          72 :         result->sign = NUMERIC_POS;
    9992          72 :         result->dscale = res_dscale;
    9993          72 :         return;
    9994             :     }
    9995             : 
    9996         150 :     init_var(&tmp_arg);
    9997         150 :     init_var(&mod);
    9998             : 
    9999             :     /* Use the Euclidean algorithm to find the GCD */
   10000         150 :     set_var_from_var(var1, &tmp_arg);
   10001         150 :     set_var_from_var(var2, result);
   10002             : 
   10003             :     for (;;)
   10004             :     {
   10005             :         /* this loop can take a while, so allow it to be interrupted */
   10006         588 :         CHECK_FOR_INTERRUPTS();
   10007             : 
   10008         588 :         mod_var(&tmp_arg, result, &mod);
   10009         588 :         if (mod.ndigits == 0)
   10010         150 :             break;
   10011         438 :         set_var_from_var(result, &tmp_arg);
   10012         438 :         set_var_from_var(&mod, result);
   10013             :     }
   10014         150 :     result->sign = NUMERIC_POS;
   10015         150 :     result->dscale = res_dscale;
   10016             : 
   10017         150 :     free_var(&tmp_arg);
   10018         150 :     free_var(&mod);
   10019             : }
   10020             : 
   10021             : 
   10022             : /*
   10023             :  * sqrt_var() -
   10024             :  *
   10025             :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
   10026             :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
   10027             :  *  point.
   10028             :  */
   10029             : static void
   10030        4194 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
   10031             : {
   10032             :     int         stat;
   10033             :     int         res_weight;
   10034             :     int         res_ndigits;
   10035             :     int         src_ndigits;
   10036             :     int         step;
   10037             :     int         ndigits[32];
   10038             :     int         blen;
   10039             :     int64       arg_int64;
   10040             :     int         src_idx;
   10041             :     int64       s_int64;
   10042             :     int64       r_int64;
   10043             :     NumericVar  s_var;
   10044             :     NumericVar  r_var;
   10045             :     NumericVar  a0_var;
   10046             :     NumericVar  a1_var;
   10047             :     NumericVar  q_var;
   10048             :     NumericVar  u_var;
   10049             : 
   10050        4194 :     stat = cmp_var(arg, &const_zero);
   10051        4194 :     if (stat == 0)
   10052             :     {
   10053          18 :         zero_var(result);
   10054          18 :         result->dscale = rscale;
   10055          18 :         return;
   10056             :     }
   10057             : 
   10058             :     /*
   10059             :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
   10060             :      * SQLSTATE error code if the operand is negative.
   10061             :      */
   10062        4176 :     if (stat < 0)
   10063           6 :         ereport(ERROR,
   10064             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10065             :                  errmsg("cannot take square root of a negative number")));
   10066             : 
   10067        4170 :     init_var(&s_var);
   10068        4170 :     init_var(&r_var);
   10069        4170 :     init_var(&a0_var);
   10070        4170 :     init_var(&a1_var);
   10071        4170 :     init_var(&q_var);
   10072        4170 :     init_var(&u_var);
   10073             : 
   10074             :     /*
   10075             :      * The result weight is half the input weight, rounded towards minus
   10076             :      * infinity --- res_weight = floor(arg->weight / 2).
   10077             :      */
   10078        4170 :     if (arg->weight >= 0)
   10079        3858 :         res_weight = arg->weight / 2;
   10080             :     else
   10081         312 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10082             : 
   10083             :     /*
   10084             :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10085             :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10086             :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10087             :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10088             :      */
   10089        4170 :     if (rscale + 1 >= 0)
   10090        4170 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10091             :     else
   10092           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10093        4170 :     res_ndigits = Max(res_ndigits, 1);
   10094             : 
   10095             :     /*
   10096             :      * Number of source NBASE digits logically required to produce a result
   10097             :      * with this precision --- every digit before the decimal point, plus 2
   10098             :      * for each result digit after the decimal point (or minus 2 for each
   10099             :      * result digit we round before the decimal point).
   10100             :      */
   10101        4170 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10102        4170 :     src_ndigits = Max(src_ndigits, 1);
   10103             : 
   10104             :     /* ----------
   10105             :      * From this point on, we treat the input and the result as integers and
   10106             :      * compute the integer square root and remainder using the Karatsuba
   10107             :      * Square Root algorithm, which may be written recursively as follows:
   10108             :      *
   10109             :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10110             :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10111             :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10112             :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10113             :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10114             :      *      Let s = s*b + q
   10115             :      *      Let r = u*b + a0 - q^2
   10116             :      *      If r < 0 Then
   10117             :      *          Let r = r + s
   10118             :      *          Let s = s - 1
   10119             :      *          Let r = r + s
   10120             :      *      Return (s,r)
   10121             :      *
   10122             :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10123             :      * RR-3805, November 1999.  At the time of writing this was available
   10124             :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10125             :      *
   10126             :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10127             :      * "choose a base b such that n requires at least four base-b digits to
   10128             :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10129             :      * than b".  For optimal performance, b should have approximately a
   10130             :      * quarter the number of digits in the input, so that the outer square
   10131             :      * root computes roughly twice as many digits as the inner one.  For
   10132             :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10133             :      *
   10134             :      * We implement the algorithm iteratively rather than recursively, to
   10135             :      * allow the working variables to be reused.  With this approach, each
   10136             :      * digit of the input is read precisely once --- src_idx tracks the number
   10137             :      * of input digits used so far.
   10138             :      *
   10139             :      * The array ndigits[] holds the number of NBASE digits of the input that
   10140             :      * will have been used at the end of each iteration, which roughly doubles
   10141             :      * each time.  Note that the array elements are stored in reverse order,
   10142             :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10143             :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10144             :      * the square root of the 3 most significant NBASE digits.
   10145             :      *
   10146             :      * In each iteration, we choose blen to be the largest integer for which
   10147             :      * the input number has a3 >= b/4, when written in the form above.  In
   10148             :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10149             :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10150             :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10151             :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10152             :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10153             :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10154             :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10155             :      * the first input digit.
   10156             :      *
   10157             :      * Additionally, we can put an upper bound on the number of steps required
   10158             :      * as follows --- suppose that the number of source digits is an n-bit
   10159             :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10160             :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10161             :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10162             :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10163             :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10164             :      * This pattern repeats, and in the worst case the array ndigits[] will
   10165             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10166             :      * will require n steps.  Therefore, since all digit array sizes are
   10167             :      * signed 32-bit integers, the number of steps required is guaranteed to
   10168             :      * be less than 32.
   10169             :      * ----------
   10170             :      */
   10171        4170 :     step = 0;
   10172       19962 :     while ((ndigits[step] = src_ndigits) > 4)
   10173             :     {
   10174             :         /* Choose b so that a3 >= b/4, as described above */
   10175       15792 :         blen = src_ndigits / 4;
   10176       15792 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10177         324 :             blen--;
   10178             : 
   10179             :         /* Number of digits in the next step (inner square root) */
   10180       15792 :         src_ndigits -= 2 * blen;
   10181       15792 :         step++;
   10182             :     }
   10183             : 
   10184             :     /*
   10185             :      * First iteration (innermost square root and remainder):
   10186             :      *
   10187             :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10188             :      * has at most 9 decimal digits, so estimate it using double precision
   10189             :      * arithmetic, which will in fact almost certainly return the correct
   10190             :      * result with no further correction required.
   10191             :      */
   10192        4170 :     arg_int64 = arg->digits[0];
   10193       13314 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10194             :     {
   10195        9144 :         arg_int64 *= NBASE;
   10196        9144 :         if (src_idx < arg->ndigits)
   10197        7686 :             arg_int64 += arg->digits[src_idx];
   10198             :     }
   10199             : 
   10200        4170 :     s_int64 = (int64) sqrt((double) arg_int64);
   10201        4170 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10202             : 
   10203             :     /*
   10204             :      * Use Newton's method to correct the result, if necessary.
   10205             :      *
   10206             :      * This uses integer division with truncation to compute the truncated
   10207             :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10208             :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10209             :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10210             :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10211             :      * checking the remainder.
   10212             :      */
   10213        4170 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10214             :     {
   10215           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10216           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10217             :     }
   10218             : 
   10219             :     /*
   10220             :      * Iterations with src_ndigits <= 8:
   10221             :      *
   10222             :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10223             :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10224             :      * input no longer does) and we can continue to compute using int64
   10225             :      * variables to avoid more expensive numeric computations.
   10226             :      *
   10227             :      * It is fairly easy to see that there is no risk of the intermediate
   10228             :      * values below overflowing 64-bit integers.  In the worst case, the
   10229             :      * previous iteration will have computed a 3-digit square root (of a
   10230             :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10231             :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10232             :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10233             :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10234             :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10235             :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10236             :      * in 64-bit integers.
   10237             :      */
   10238        4170 :     step--;
   10239       10566 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10240             :     {
   10241             :         int         b;
   10242             :         int         a0;
   10243             :         int         a1;
   10244             :         int         i;
   10245             :         int64       numer;
   10246             :         int64       denom;
   10247             :         int64       q;
   10248             :         int64       u;
   10249             : 
   10250        6396 :         blen = (src_ndigits - src_idx) / 2;
   10251             : 
   10252             :         /* Extract a1 and a0, and compute b */
   10253        6396 :         a0 = 0;
   10254        6396 :         a1 = 0;
   10255        6396 :         b = 1;
   10256             : 
   10257       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10258             :         {
   10259        6540 :             b *= NBASE;
   10260        6540 :             a1 *= NBASE;
   10261        6540 :             if (src_idx < arg->ndigits)
   10262        4800 :                 a1 += arg->digits[src_idx];
   10263             :         }
   10264             : 
   10265       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10266             :         {
   10267        6540 :             a0 *= NBASE;
   10268        6540 :             if (src_idx < arg->ndigits)
   10269        4644 :                 a0 += arg->digits[src_idx];
   10270             :         }
   10271             : 
   10272             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10273        6396 :         numer = r_int64 * b + a1;
   10274        6396 :         denom = 2 * s_int64;
   10275        6396 :         q = numer / denom;
   10276        6396 :         u = numer - q * denom;
   10277             : 
   10278             :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10279        6396 :         s_int64 = s_int64 * b + q;
   10280        6396 :         r_int64 = u * b + a0 - q * q;
   10281             : 
   10282        6396 :         if (r_int64 < 0)
   10283             :         {
   10284             :             /* s is too large by 1; set r += s, s--, r += s */
   10285         210 :             r_int64 += s_int64;
   10286         210 :             s_int64--;
   10287         210 :             r_int64 += s_int64;
   10288             :         }
   10289             : 
   10290             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10291        6396 :         step--;
   10292             :     }
   10293             : 
   10294             :     /*
   10295             :      * On platforms with 128-bit integer support, we can further delay the
   10296             :      * need to use numeric variables.
   10297             :      */
   10298             : #ifdef HAVE_INT128
   10299        4170 :     if (step >= 0)
   10300             :     {
   10301             :         int128      s_int128;
   10302             :         int128      r_int128;
   10303             : 
   10304        4170 :         s_int128 = s_int64;
   10305        4170 :         r_int128 = r_int64;
   10306             : 
   10307             :         /*
   10308             :          * Iterations with src_ndigits <= 16:
   10309             :          *
   10310             :          * The result fits in an int128 (even though the input doesn't) so we
   10311             :          * use int128 variables to avoid more expensive numeric computations.
   10312             :          */
   10313        9048 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10314             :         {
   10315             :             int64       b;
   10316             :             int64       a0;
   10317             :             int64       a1;
   10318             :             int64       i;
   10319             :             int128      numer;
   10320             :             int128      denom;
   10321             :             int128      q;
   10322             :             int128      u;
   10323             : 
   10324        4878 :             blen = (src_ndigits - src_idx) / 2;
   10325             : 
   10326             :             /* Extract a1 and a0, and compute b */
   10327        4878 :             a0 = 0;
   10328        4878 :             a1 = 0;
   10329        4878 :             b = 1;
   10330             : 
   10331       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10332             :             {
   10333       11202 :                 b *= NBASE;
   10334       11202 :                 a1 *= NBASE;
   10335       11202 :                 if (src_idx < arg->ndigits)
   10336        6606 :                     a1 += arg->digits[src_idx];
   10337             :             }
   10338             : 
   10339       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10340             :             {
   10341       11202 :                 a0 *= NBASE;
   10342       11202 :                 if (src_idx < arg->ndigits)
   10343        4470 :                     a0 += arg->digits[src_idx];
   10344             :             }
   10345             : 
   10346             :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10347        4878 :             numer = r_int128 * b + a1;
   10348        4878 :             denom = 2 * s_int128;
   10349        4878 :             q = numer / denom;
   10350        4878 :             u = numer - q * denom;
   10351             : 
   10352             :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10353        4878 :             s_int128 = s_int128 * b + q;
   10354        4878 :             r_int128 = u * b + a0 - q * q;
   10355             : 
   10356        4878 :             if (r_int128 < 0)
   10357             :             {
   10358             :                 /* s is too large by 1; set r += s, s--, r += s */
   10359         192 :                 r_int128 += s_int128;
   10360         192 :                 s_int128--;
   10361         192 :                 r_int128 += s_int128;
   10362             :             }
   10363             : 
   10364             :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10365        4878 :             step--;
   10366             :         }
   10367             : 
   10368             :         /*
   10369             :          * All remaining iterations require numeric variables.  Convert the
   10370             :          * integer values to NumericVar and continue.  Note that in the final
   10371             :          * iteration we don't need the remainder, so we can save a few cycles
   10372             :          * there by not fully computing it.
   10373             :          */
   10374        4170 :         int128_to_numericvar(s_int128, &s_var);
   10375        4170 :         if (step >= 0)
   10376        2724 :             int128_to_numericvar(r_int128, &r_var);
   10377             :     }
   10378             :     else
   10379             :     {
   10380           0 :         int64_to_numericvar(s_int64, &s_var);
   10381             :         /* step < 0, so we certainly don't need r */
   10382             :     }
   10383             : #else                           /* !HAVE_INT128 */
   10384             :     int64_to_numericvar(s_int64, &s_var);
   10385             :     if (step >= 0)
   10386             :         int64_to_numericvar(r_int64, &r_var);
   10387             : #endif                          /* HAVE_INT128 */
   10388             : 
   10389             :     /*
   10390             :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10391             :      * use numeric variables.
   10392             :      */
   10393        8688 :     while (step >= 0)
   10394             :     {
   10395             :         int         tmp_len;
   10396             : 
   10397        4518 :         src_ndigits = ndigits[step];
   10398        4518 :         blen = (src_ndigits - src_idx) / 2;
   10399             : 
   10400             :         /* Extract a1 and a0 */
   10401        4518 :         if (src_idx < arg->ndigits)
   10402             :         {
   10403        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10404        1512 :             alloc_var(&a1_var, tmp_len);
   10405        1512 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10406             :                    tmp_len * sizeof(NumericDigit));
   10407        1512 :             a1_var.weight = blen - 1;
   10408        1512 :             a1_var.sign = NUMERIC_POS;
   10409        1512 :             a1_var.dscale = 0;
   10410        1512 :             strip_var(&a1_var);
   10411             :         }
   10412             :         else
   10413             :         {
   10414        3006 :             zero_var(&a1_var);
   10415        3006 :             a1_var.dscale = 0;
   10416             :         }
   10417        4518 :         src_idx += blen;
   10418             : 
   10419        4518 :         if (src_idx < arg->ndigits)
   10420             :         {
   10421        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10422        1512 :             alloc_var(&a0_var, tmp_len);
   10423        1512 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10424             :                    tmp_len * sizeof(NumericDigit));
   10425        1512 :             a0_var.weight = blen - 1;
   10426        1512 :             a0_var.sign = NUMERIC_POS;
   10427        1512 :             a0_var.dscale = 0;
   10428        1512 :             strip_var(&a0_var);
   10429             :         }
   10430             :         else
   10431             :         {
   10432        3006 :             zero_var(&a0_var);
   10433        3006 :             a0_var.dscale = 0;
   10434             :         }
   10435        4518 :         src_idx += blen;
   10436             : 
   10437             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10438        4518 :         set_var_from_var(&r_var, &q_var);
   10439        4518 :         q_var.weight += blen;
   10440        4518 :         add_var(&q_var, &a1_var, &q_var);
   10441        4518 :         add_var(&s_var, &s_var, &u_var);
   10442        4518 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10443             : 
   10444             :         /* Compute s = s*b + q */
   10445        4518 :         s_var.weight += blen;
   10446        4518 :         add_var(&s_var, &q_var, &s_var);
   10447             : 
   10448             :         /*
   10449             :          * Compute r = u*b + a0 - q^2.
   10450             :          *
   10451             :          * In the final iteration, we don't actually need r; we just need to
   10452             :          * know whether it is negative, so that we know whether to adjust s.
   10453             :          * So instead of the final subtraction we can just compare.
   10454             :          */
   10455        4518 :         u_var.weight += blen;
   10456        4518 :         add_var(&u_var, &a0_var, &u_var);
   10457        4518 :         mul_var(&q_var, &q_var, &q_var, 0);
   10458             : 
   10459        4518 :         if (step > 0)
   10460             :         {
   10461             :             /* Need r for later iterations */
   10462        1794 :             sub_var(&u_var, &q_var, &r_var);
   10463        1794 :             if (r_var.sign == NUMERIC_NEG)
   10464             :             {
   10465             :                 /* s is too large by 1; set r += s, s--, r += s */
   10466         120 :                 add_var(&r_var, &s_var, &r_var);
   10467         120 :                 sub_var(&s_var, &const_one, &s_var);
   10468         120 :                 add_var(&r_var, &s_var, &r_var);
   10469             :             }
   10470             :         }
   10471             :         else
   10472             :         {
   10473             :             /* Don't need r anymore, except to test if s is too large by 1 */
   10474        2724 :             if (cmp_var(&u_var, &q_var) < 0)
   10475          36 :                 sub_var(&s_var, &const_one, &s_var);
   10476             :         }
   10477             : 
   10478             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10479        4518 :         step--;
   10480             :     }
   10481             : 
   10482             :     /*
   10483             :      * Construct the final result, rounding it to the requested precision.
   10484             :      */
   10485        4170 :     set_var_from_var(&s_var, result);
   10486        4170 :     result->weight = res_weight;
   10487        4170 :     result->sign = NUMERIC_POS;
   10488             : 
   10489             :     /* Round to target rscale (and set result->dscale) */
   10490        4170 :     round_var(result, rscale);
   10491             : 
   10492             :     /* Strip leading and trailing zeroes */
   10493        4170 :     strip_var(result);
   10494             : 
   10495        4170 :     free_var(&s_var);
   10496        4170 :     free_var(&r_var);
   10497        4170 :     free_var(&a0_var);
   10498        4170 :     free_var(&a1_var);
   10499        4170 :     free_var(&q_var);
   10500        4170 :     free_var(&u_var);
   10501             : }
   10502             : 
   10503             : 
   10504             : /*
   10505             :  * exp_var() -
   10506             :  *
   10507             :  *  Raise e to the power of x, computed to rscale fractional digits
   10508             :  */
   10509             : static void
   10510         180 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10511             : {
   10512             :     NumericVar  x;
   10513             :     NumericVar  elem;
   10514             :     int         ni;
   10515             :     double      val;
   10516             :     int         dweight;
   10517             :     int         ndiv2;
   10518             :     int         sig_digits;
   10519             :     int         local_rscale;
   10520             : 
   10521         180 :     init_var(&x);
   10522         180 :     init_var(&elem);
   10523             : 
   10524         180 :     set_var_from_var(arg, &x);
   10525             : 
   10526             :     /*
   10527             :      * Estimate the dweight of the result using floating point arithmetic, so
   10528             :      * that we can choose an appropriate local rscale for the calculation.
   10529             :      */
   10530         180 :     val = numericvar_to_double_no_overflow(&x);
   10531             : 
   10532             :     /* Guard against overflow/underflow */
   10533             :     /* If you change this limit, see also power_var()'s limit */
   10534         180 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10535             :     {
   10536           6 :         if (val > 0)
   10537           0 :             ereport(ERROR,
   10538             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10539             :                      errmsg("value overflows numeric format")));
   10540           6 :         zero_var(result);
   10541           6 :         result->dscale = rscale;
   10542           6 :         return;
   10543             :     }
   10544             : 
   10545             :     /* decimal weight = log10(e^x) = x * log10(e) */
   10546         174 :     dweight = (int) (val * 0.434294481903252);
   10547             : 
   10548             :     /*
   10549             :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10550             :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10551             :      *
   10552             :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10553             :      * means that ndiv2 <= 20 here.
   10554             :      */
   10555         174 :     if (fabs(val) > 0.01)
   10556             :     {
   10557         144 :         ndiv2 = 1;
   10558         144 :         val /= 2;
   10559             : 
   10560        1818 :         while (fabs(val) > 0.01)
   10561             :         {
   10562        1674 :             ndiv2++;
   10563        1674 :             val /= 2;
   10564             :         }
   10565             : 
   10566         144 :         local_rscale = x.dscale + ndiv2;
   10567         144 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10568             :     }
   10569             :     else
   10570          30 :         ndiv2 = 0;
   10571             : 
   10572             :     /*
   10573             :      * Set the scale for the Taylor series expansion.  The final result has
   10574             :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10575             :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10576             :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10577             :      * extra digits of precision (plus a few more for good measure).
   10578             :      */
   10579         174 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10580         174 :     sig_digits = Max(sig_digits, 0) + 8;
   10581             : 
   10582         174 :     local_rscale = sig_digits - 1;
   10583             : 
   10584             :     /*
   10585             :      * Use the Taylor series
   10586             :      *
   10587             :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10588             :      *
   10589             :      * Given the limited range of x, this should converge reasonably quickly.
   10590             :      * We run the series until the terms fall below the local_rscale limit.
   10591             :      */
   10592         174 :     add_var(&const_one, &x, result);
   10593             : 
   10594         174 :     mul_var(&x, &x, &elem, local_rscale);
   10595         174 :     ni = 2;
   10596         174 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10597             : 
   10598        4992 :     while (elem.ndigits != 0)
   10599             :     {
   10600        4818 :         add_var(result, &elem, result);
   10601             : 
   10602        4818 :         mul_var(&elem, &x, &elem, local_rscale);
   10603        4818 :         ni++;
   10604        4818 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10605             :     }
   10606             : 
   10607             :     /*
   10608             :      * Compensate for the argument range reduction.  Since the weight of the
   10609             :      * result doubles with each multiplication, we can reduce the local rscale
   10610             :      * as we proceed.
   10611             :      */
   10612        1992 :     while (ndiv2-- > 0)
   10613             :     {
   10614        1818 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   10615        1818 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10616        1818 :         mul_var(result, result, result, local_rscale);
   10617             :     }
   10618             : 
   10619             :     /* Round to requested rscale */
   10620         174 :     round_var(result, rscale);
   10621             : 
   10622         174 :     free_var(&x);
   10623         174 :     free_var(&elem);
   10624             : }
   10625             : 
   10626             : 
   10627             : /*
   10628             :  * Estimate the dweight of the most significant decimal digit of the natural
   10629             :  * logarithm of a number.
   10630             :  *
   10631             :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   10632             :  * determine the appropriate rscale when computing natural logarithms.
   10633             :  *
   10634             :  * Note: many callers call this before range-checking the input.  Therefore,
   10635             :  * we must be robust against values that are invalid to apply ln() to.
   10636             :  * We don't wish to throw an error here, so just return zero in such cases.
   10637             :  */
   10638             : static int
   10639         738 : estimate_ln_dweight(const NumericVar *var)
   10640             : {
   10641             :     int         ln_dweight;
   10642             : 
   10643             :     /* Caller should fail on ln(negative), but for the moment return zero */
   10644         738 :     if (var->sign != NUMERIC_POS)
   10645          42 :         return 0;
   10646             : 
   10647        1314 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   10648         618 :         cmp_var(var, &const_one_point_one) <= 0)
   10649          90 :     {
   10650             :         /*
   10651             :          * 0.9 <= var <= 1.1
   10652             :          *
   10653             :          * ln(var) has a negative weight (possibly very large).  To get a
   10654             :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   10655             :          */
   10656             :         NumericVar  x;
   10657             : 
   10658          90 :         init_var(&x);
   10659          90 :         sub_var(var, &const_one, &x);
   10660             : 
   10661          90 :         if (x.ndigits > 0)
   10662             :         {
   10663             :             /* Use weight of most significant decimal digit of x */
   10664          42 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   10665             :         }
   10666             :         else
   10667             :         {
   10668             :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   10669          48 :             ln_dweight = 0;
   10670             :         }
   10671             : 
   10672          90 :         free_var(&x);
   10673             :     }
   10674             :     else
   10675             :     {
   10676             :         /*
   10677             :          * Estimate the logarithm using the first couple of digits from the
   10678             :          * input number.  This will give an accurate result whenever the input
   10679             :          * is not too close to 1.
   10680             :          */
   10681         606 :         if (var->ndigits > 0)
   10682             :         {
   10683             :             int         digits;
   10684             :             int         dweight;
   10685             :             double      ln_var;
   10686             : 
   10687         564 :             digits = var->digits[0];
   10688         564 :             dweight = var->weight * DEC_DIGITS;
   10689             : 
   10690         564 :             if (var->ndigits > 1)
   10691             :             {
   10692         342 :                 digits = digits * NBASE + var->digits[1];
   10693         342 :                 dweight -= DEC_DIGITS;
   10694             :             }
   10695             : 
   10696             :             /*----------
   10697             :              * We have var ~= digits * 10^dweight
   10698             :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   10699             :              *----------
   10700             :              */
   10701         564 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   10702         564 :             ln_dweight = (int) log10(fabs(ln_var));
   10703             :         }
   10704             :         else
   10705             :         {
   10706             :             /* Caller should fail on ln(0), but for the moment return zero */
   10707          42 :             ln_dweight = 0;
   10708             :         }
   10709             :     }
   10710             : 
   10711         696 :     return ln_dweight;
   10712             : }
   10713             : 
   10714             : 
   10715             : /*
   10716             :  * ln_var() -
   10717             :  *
   10718             :  *  Compute the natural log of x
   10719             :  */
   10720             : static void
   10721         834 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   10722             : {
   10723             :     NumericVar  x;
   10724             :     NumericVar  xx;
   10725             :     int         ni;
   10726             :     NumericVar  elem;
   10727             :     NumericVar  fact;
   10728             :     int         nsqrt;
   10729             :     int         local_rscale;
   10730             :     int         cmp;
   10731             : 
   10732         834 :     cmp = cmp_var(arg, &const_zero);
   10733         834 :     if (cmp == 0)
   10734          42 :         ereport(ERROR,
   10735             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10736             :                  errmsg("cannot take logarithm of zero")));
   10737         792 :     else if (cmp < 0)
   10738          36 :         ereport(ERROR,
   10739             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10740             :                  errmsg("cannot take logarithm of a negative number")));
   10741             : 
   10742         756 :     init_var(&x);
   10743         756 :     init_var(&xx);
   10744         756 :     init_var(&elem);
   10745         756 :     init_var(&fact);
   10746             : 
   10747         756 :     set_var_from_var(arg, &x);
   10748         756 :     set_var_from_var(&const_two, &fact);
   10749             : 
   10750             :     /*
   10751             :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   10752             :      *
   10753             :      * The final logarithm will have up to around rscale+6 significant digits.
   10754             :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   10755             :      * rscale as we work so that we keep this many significant digits at each
   10756             :      * step (plus a few more for good measure).
   10757             :      *
   10758             :      * Note that we allow local_rscale < 0 during this input reduction
   10759             :      * process, which implies rounding before the decimal point.  sqrt_var()
   10760             :      * explicitly supports this, and it significantly reduces the work
   10761             :      * required to reduce very large inputs to the required range.  Once the
   10762             :      * input reduction is complete, x.weight will be 0 and its display scale
   10763             :      * will be non-negative again.
   10764             :      */
   10765         756 :     nsqrt = 0;
   10766        1068 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   10767             :     {
   10768         312 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10769         312 :         sqrt_var(&x, &x, local_rscale);
   10770         312 :         mul_var(&fact, &const_two, &fact, 0);
   10771         312 :         nsqrt++;
   10772             :     }
   10773        4128 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   10774             :     {
   10775        3372 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10776        3372 :         sqrt_var(&x, &x, local_rscale);
   10777        3372 :         mul_var(&fact, &const_two, &fact, 0);
   10778        3372 :         nsqrt++;
   10779             :     }
   10780             : 
   10781             :     /*
   10782             :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   10783             :      *
   10784             :      * z + z^3/3 + z^5/5 + ...
   10785             :      *
   10786             :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   10787             :      * due to the above range-reduction of x.
   10788             :      *
   10789             :      * The convergence of this is not as fast as one would like, but is
   10790             :      * tolerable given that z is small.
   10791             :      *
   10792             :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   10793             :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   10794             :      * digits of precision (plus a few more for good measure).
   10795             :      */
   10796         756 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   10797             : 
   10798         756 :     sub_var(&x, &const_one, result);
   10799         756 :     add_var(&x, &const_one, &elem);
   10800         756 :     div_var(result, &elem, result, local_rscale, true, false);
   10801         756 :     set_var_from_var(result, &xx);
   10802         756 :     mul_var(result, result, &x, local_rscale);
   10803             : 
   10804         756 :     ni = 1;
   10805             : 
   10806             :     for (;;)
   10807             :     {
   10808       14022 :         ni += 2;
   10809       14022 :         mul_var(&xx, &x, &xx, local_rscale);
   10810       14022 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   10811             : 
   10812       14022 :         if (elem.ndigits == 0)
   10813         756 :             break;
   10814             : 
   10815       13266 :         add_var(result, &elem, result);
   10816             : 
   10817       13266 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   10818           0 :             break;
   10819             :     }
   10820             : 
   10821             :     /* Compensate for argument range reduction, round to requested rscale */
   10822         756 :     mul_var(result, &fact, result, rscale);
   10823             : 
   10824         756 :     free_var(&x);
   10825         756 :     free_var(&xx);
   10826         756 :     free_var(&elem);
   10827         756 :     free_var(&fact);
   10828         756 : }
   10829             : 
   10830             : 
   10831             : /*
   10832             :  * log_var() -
   10833             :  *
   10834             :  *  Compute the logarithm of num in a given base.
   10835             :  *
   10836             :  *  Note: this routine chooses dscale of the result.
   10837             :  */
   10838             : static void
   10839         216 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   10840             : {
   10841             :     NumericVar  ln_base;
   10842             :     NumericVar  ln_num;
   10843             :     int         ln_base_dweight;
   10844             :     int         ln_num_dweight;
   10845             :     int         result_dweight;
   10846             :     int         rscale;
   10847             :     int         ln_base_rscale;
   10848             :     int         ln_num_rscale;
   10849             : 
   10850         216 :     init_var(&ln_base);
   10851         216 :     init_var(&ln_num);
   10852             : 
   10853             :     /* Estimated dweights of ln(base), ln(num) and the final result */
   10854         216 :     ln_base_dweight = estimate_ln_dweight(base);
   10855         216 :     ln_num_dweight = estimate_ln_dweight(num);
   10856         216 :     result_dweight = ln_num_dweight - ln_base_dweight;
   10857             : 
   10858             :     /*
   10859             :      * Select the scale of the result so that it will have at least
   10860             :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   10861             :      * input's display scale.
   10862             :      */
   10863         216 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   10864         216 :     rscale = Max(rscale, base->dscale);
   10865         216 :     rscale = Max(rscale, num->dscale);
   10866         216 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10867         216 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10868             : 
   10869             :     /*
   10870             :      * Set the scales for ln(base) and ln(num) so that they each have more
   10871             :      * significant digits than the final result.
   10872             :      */
   10873         216 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   10874         216 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10875             : 
   10876         216 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   10877         216 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10878             : 
   10879             :     /* Form natural logarithms */
   10880         216 :     ln_var(base, &ln_base, ln_base_rscale);
   10881         192 :     ln_var(num, &ln_num, ln_num_rscale);
   10882             : 
   10883             :     /* Divide and round to the required scale */
   10884         162 :     div_var(&ln_num, &ln_base, result, rscale, true, false);
   10885             : 
   10886         156 :     free_var(&ln_num);
   10887         156 :     free_var(&ln_base);
   10888         156 : }
   10889             : 
   10890             : 
   10891             : /*
   10892             :  * power_var() -
   10893             :  *
   10894             :  *  Raise base to the power of exp
   10895             :  *
   10896             :  *  Note: this routine chooses dscale of the result.
   10897             :  */
   10898             : static void
   10899        1398 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   10900             : {
   10901             :     int         res_sign;
   10902             :     NumericVar  abs_base;
   10903             :     NumericVar  ln_base;
   10904             :     NumericVar  ln_num;
   10905             :     int         ln_dweight;
   10906             :     int         rscale;
   10907             :     int         sig_digits;
   10908             :     int         local_rscale;
   10909             :     double      val;
   10910             : 
   10911             :     /* If exp can be represented as an integer, use power_var_int */
   10912        1398 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   10913             :     {
   10914             :         /* exact integer, but does it fit in int? */
   10915             :         int64       expval64;
   10916             : 
   10917        1272 :         if (numericvar_to_int64(exp, &expval64))
   10918             :         {
   10919        1266 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   10920             :             {
   10921             :                 /* Okay, use power_var_int */
   10922        1236 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   10923        1224 :                 return;
   10924             :             }
   10925             :         }
   10926             :     }
   10927             : 
   10928             :     /*
   10929             :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   10930             :      * handled by power_var_int().
   10931             :      */
   10932         162 :     if (cmp_var(base, &const_zero) == 0)
   10933             :     {
   10934          18 :         set_var_from_var(&const_zero, result);
   10935          18 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   10936          18 :         return;
   10937             :     }
   10938             : 
   10939         144 :     init_var(&abs_base);
   10940         144 :     init_var(&ln_base);
   10941         144 :     init_var(&ln_num);
   10942             : 
   10943             :     /*
   10944             :      * If base is negative, insist that exp be an integer.  The result is then
   10945             :      * positive if exp is even and negative if exp is odd.
   10946             :      */
   10947         144 :     if (base->sign == NUMERIC_NEG)
   10948             :     {
   10949             :         /*
   10950             :          * Check that exp is an integer.  This error code is defined by the
   10951             :          * SQL standard, and matches other errors in numeric_power().
   10952             :          */
   10953          36 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   10954          18 :             ereport(ERROR,
   10955             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10956             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   10957             : 
   10958             :         /* Test if exp is odd or even */
   10959          18 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   10960          12 :             (exp->digits[exp->ndigits - 1] & 1))
   10961           6 :             res_sign = NUMERIC_NEG;
   10962             :         else
   10963          12 :             res_sign = NUMERIC_POS;
   10964             : 
   10965             :         /* Then work with abs(base) below */
   10966          18 :         set_var_from_var(base, &abs_base);
   10967          18 :         abs_base.sign = NUMERIC_POS;
   10968          18 :         base = &abs_base;
   10969             :     }
   10970             :     else
   10971         108 :         res_sign = NUMERIC_POS;
   10972             : 
   10973             :     /*----------
   10974             :      * Decide on the scale for the ln() calculation.  For this we need an
   10975             :      * estimate of the weight of the result, which we obtain by doing an
   10976             :      * initial low-precision calculation of exp * ln(base).
   10977             :      *
   10978             :      * We want result = e ^ (exp * ln(base))
   10979             :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   10980             :      *
   10981             :      * We also perform a crude overflow test here so that we can exit early if
   10982             :      * the full-precision result is sure to overflow, and to guard against
   10983             :      * integer overflow when determining the scale for the real calculation.
   10984             :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   10985             :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   10986             :      * Since the values here are only approximations, we apply a small fuzz
   10987             :      * factor to this overflow test and let exp_var() determine the exact
   10988             :      * overflow threshold so that it is consistent for all inputs.
   10989             :      *----------
   10990             :      */
   10991         126 :     ln_dweight = estimate_ln_dweight(base);
   10992             : 
   10993             :     /*
   10994             :      * Set the scale for the low-precision calculation, computing ln(base) to
   10995             :      * around 8 significant digits.  Note that ln_dweight may be as small as
   10996             :      * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
   10997             :      * here.
   10998             :      */
   10999         126 :     local_rscale = 8 - ln_dweight;
   11000         126 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11001             : 
   11002         126 :     ln_var(base, &ln_base, local_rscale);
   11003             : 
   11004         126 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11005             : 
   11006         126 :     val = numericvar_to_double_no_overflow(&ln_num);
   11007             : 
   11008             :     /* initial overflow/underflow test with fuzz factor */
   11009         126 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   11010             :     {
   11011           6 :         if (val > 0)
   11012           0 :             ereport(ERROR,
   11013             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11014             :                      errmsg("value overflows numeric format")));
   11015           6 :         zero_var(result);
   11016           6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11017           6 :         return;
   11018             :     }
   11019             : 
   11020         120 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   11021             : 
   11022             :     /* choose the result scale */
   11023         120 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   11024         120 :     rscale = Max(rscale, base->dscale);
   11025         120 :     rscale = Max(rscale, exp->dscale);
   11026         120 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11027         120 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11028             : 
   11029             :     /* significant digits required in the result */
   11030         120 :     sig_digits = rscale + (int) val;
   11031         120 :     sig_digits = Max(sig_digits, 0);
   11032             : 
   11033             :     /* set the scale for the real exp * ln(base) calculation */
   11034         120 :     local_rscale = sig_digits - ln_dweight + 8;
   11035         120 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11036             : 
   11037             :     /* and do the real calculation */
   11038             : 
   11039         120 :     ln_var(base, &ln_base, local_rscale);
   11040             : 
   11041         120 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11042             : 
   11043         120 :     exp_var(&ln_num, result, rscale);
   11044             : 
   11045         120 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   11046           6 :         result->sign = NUMERIC_NEG;
   11047             : 
   11048         120 :     free_var(&ln_num);
   11049         120 :     free_var(&ln_base);
   11050         120 :     free_var(&abs_base);
   11051             : }
   11052             : 
   11053             : /*
   11054             :  * power_var_int() -
   11055             :  *
   11056             :  *  Raise base to the power of exp, where exp is an integer.
   11057             :  *
   11058             :  *  Note: this routine chooses dscale of the result.
   11059             :  */
   11060             : static void
   11061        1236 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   11062             :               NumericVar *result)
   11063             : {
   11064             :     double      f;
   11065             :     int         p;
   11066             :     int         i;
   11067             :     int         rscale;
   11068             :     int         sig_digits;
   11069             :     unsigned int mask;
   11070             :     bool        neg;
   11071             :     NumericVar  base_prod;
   11072             :     int         local_rscale;
   11073             : 
   11074             :     /*
   11075             :      * Choose the result scale.  For this we need an estimate of the decimal
   11076             :      * weight of the result, which we obtain by approximating using double
   11077             :      * precision arithmetic.
   11078             :      *
   11079             :      * We also perform crude overflow/underflow tests here so that we can exit
   11080             :      * early if the result is sure to overflow/underflow, and to guard against
   11081             :      * integer overflow when choosing the result scale.
   11082             :      */
   11083        1236 :     if (base->ndigits != 0)
   11084             :     {
   11085             :         /*----------
   11086             :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11087             :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11088             :          *----------
   11089             :          */
   11090        1206 :         f = base->digits[0];
   11091        1206 :         p = base->weight * DEC_DIGITS;
   11092             : 
   11093        1290 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11094             :         {
   11095          84 :             f = f * NBASE + base->digits[i];
   11096          84 :             p -= DEC_DIGITS;
   11097             :         }
   11098             : 
   11099        1206 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11100             :     }
   11101             :     else
   11102          30 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11103             : 
   11104             :     /* overflow/underflow tests with fuzz factors */
   11105        1236 :     if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
   11106          12 :         ereport(ERROR,
   11107             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11108             :                  errmsg("value overflows numeric format")));
   11109        1224 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11110             :     {
   11111          12 :         zero_var(result);
   11112          12 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11113         216 :         return;
   11114             :     }
   11115             : 
   11116             :     /*
   11117             :      * Choose the result scale in the same way as power_var(), so it has at
   11118             :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11119             :      * either input's display scale.
   11120             :      */
   11121        1212 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11122        1212 :     rscale = Max(rscale, base->dscale);
   11123        1212 :     rscale = Max(rscale, exp_dscale);
   11124        1212 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11125        1212 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11126             : 
   11127             :     /* Handle some common special cases, as well as corner cases */
   11128        1212 :     switch (exp)
   11129             :     {
   11130          72 :         case 0:
   11131             : 
   11132             :             /*
   11133             :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11134             :              * it as 1 because most programming languages do this. SQL:2003
   11135             :              * also requires a return value of 1.
   11136             :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11137             :              */
   11138          72 :             set_var_from_var(&const_one, result);
   11139          72 :             result->dscale = rscale; /* no need to round */
   11140          72 :             return;
   11141          48 :         case 1:
   11142          48 :             set_var_from_var(base, result);
   11143          48 :             round_var(result, rscale);
   11144          48 :             return;
   11145          30 :         case -1:
   11146          30 :             div_var(&const_one, base, result, rscale, true, true);
   11147          30 :             return;
   11148          54 :         case 2:
   11149          54 :             mul_var(base, base, result, rscale);
   11150          54 :             return;
   11151        1008 :         default:
   11152        1008 :             break;
   11153             :     }
   11154             : 
   11155             :     /* Handle the special case where the base is zero */
   11156        1008 :     if (base->ndigits == 0)
   11157             :     {
   11158           0 :         if (exp < 0)
   11159           0 :             ereport(ERROR,
   11160             :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11161             :                      errmsg("division by zero")));
   11162           0 :         zero_var(result);
   11163           0 :         result->dscale = rscale;
   11164           0 :         return;
   11165             :     }
   11166             : 
   11167             :     /*
   11168             :      * The general case repeatedly multiplies base according to the bit
   11169             :      * pattern of exp.
   11170             :      *
   11171             :      * The local rscale used for each multiplication is varied to keep a fixed
   11172             :      * number of significant digits, sufficient to give the required result
   11173             :      * scale.
   11174             :      */
   11175             : 
   11176             :     /*
   11177             :      * Approximate number of significant digits in the result.  Note that the
   11178             :      * underflow test above, together with the choice of rscale, ensures that
   11179             :      * this approximation is necessarily > 0.
   11180             :      */
   11181        1008 :     sig_digits = 1 + rscale + (int) f;
   11182             : 
   11183             :     /*
   11184             :      * The multiplications to produce the result may introduce an error of up
   11185             :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11186             :      * of precision (plus a few more for good measure).
   11187             :      */
   11188        1008 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11189             : 
   11190             :     /*
   11191             :      * Now we can proceed with the multiplications.
   11192             :      */
   11193        1008 :     neg = (exp < 0);
   11194        1008 :     mask = pg_abs_s32(exp);
   11195             : 
   11196        1008 :     init_var(&base_prod);
   11197        1008 :     set_var_from_var(base, &base_prod);
   11198             : 
   11199        1008 :     if (mask & 1)
   11200         498 :         set_var_from_var(base, result);
   11201             :     else
   11202         510 :         set_var_from_var(&const_one, result);
   11203             : 
   11204        5076 :     while ((mask >>= 1) > 0)
   11205             :     {
   11206             :         /*
   11207             :          * Do the multiplications using rscales large enough to hold the
   11208             :          * results to the required number of significant digits, but don't
   11209             :          * waste time by exceeding the scales of the numbers themselves.
   11210             :          */
   11211        4068 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11212        4068 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11213        4068 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11214             : 
   11215        4068 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11216             : 
   11217        4068 :         if (mask & 1)
   11218             :         {
   11219        2658 :             local_rscale = sig_digits -
   11220        2658 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11221        2658 :             local_rscale = Min(local_rscale,
   11222             :                                base_prod.dscale + result->dscale);
   11223        2658 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11224             : 
   11225        2658 :             mul_var(&base_prod, result, result, local_rscale);
   11226             :         }
   11227             : 
   11228             :         /*
   11229             :          * When abs(base) > 1, the number of digits to the left of the decimal
   11230             :          * point in base_prod doubles at each iteration, so if exp is large we
   11231             :          * could easily spend large amounts of time and memory space doing the
   11232             :          * multiplications.  But once the weight exceeds what will fit in
   11233             :          * int16, the final result is guaranteed to overflow (or underflow, if
   11234             :          * exp < 0), so we can give up before wasting too many cycles.
   11235             :          */
   11236        4068 :         if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
   11237        4068 :             result->weight > NUMERIC_WEIGHT_MAX)
   11238             :         {
   11239             :             /* overflow, unless neg, in which case result should be 0 */
   11240           0 :             if (!neg)
   11241           0 :                 ereport(ERROR,
   11242             :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11243             :                          errmsg("value overflows numeric format")));
   11244           0 :             zero_var(result);
   11245           0 :             neg = false;
   11246           0 :             break;
   11247             :         }
   11248             :     }
   11249             : 
   11250        1008 :     free_var(&base_prod);
   11251             : 
   11252             :     /* Compensate for input sign, and round to requested rscale */
   11253        1008 :     if (neg)
   11254         486 :         div_var(&const_one, result, result, rscale, true, false);
   11255             :     else
   11256         522 :         round_var(result, rscale);
   11257             : }
   11258             : 
   11259             : /*
   11260             :  * power_ten_int() -
   11261             :  *
   11262             :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11263             :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11264             :  */
   11265             : static void
   11266         228 : power_ten_int(int exp, NumericVar *result)
   11267             : {
   11268             :     /* Construct the result directly, starting from 10^0 = 1 */
   11269         228 :     set_var_from_var(&const_one, result);
   11270             : 
   11271             :     /* Scale needed to represent the result exactly */
   11272         228 :     result->dscale = exp < 0 ? -exp : 0;
   11273             : 
   11274             :     /* Base-NBASE weight of result and remaining exponent */
   11275         228 :     if (exp >= 0)
   11276         162 :         result->weight = exp / DEC_DIGITS;
   11277             :     else
   11278          66 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11279             : 
   11280         228 :     exp -= result->weight * DEC_DIGITS;
   11281             : 
   11282             :     /* Final adjustment of the result's single NBASE digit */
   11283         594 :     while (exp-- > 0)
   11284         366 :         result->digits[0] *= 10;
   11285         228 : }
   11286             : 
   11287             : /*
   11288             :  * random_var() - return a random value in the range [rmin, rmax].
   11289             :  */
   11290             : static void
   11291       33438 : random_var(pg_prng_state *state, const NumericVar *rmin,
   11292             :            const NumericVar *rmax, NumericVar *result)
   11293             : {
   11294             :     int         rscale;
   11295             :     NumericVar  rlen;
   11296             :     int         res_ndigits;
   11297             :     int         n;
   11298             :     int         pow10;
   11299             :     int         i;
   11300             :     uint64      rlen64;
   11301             :     int         rlen64_ndigits;
   11302             : 
   11303       33438 :     rscale = Max(rmin->dscale, rmax->dscale);
   11304             : 
   11305             :     /* Compute rlen = rmax - rmin and check the range bounds */
   11306       33438 :     init_var(&rlen);
   11307       33438 :     sub_var(rmax, rmin, &rlen);
   11308             : 
   11309       33438 :     if (rlen.sign == NUMERIC_NEG)
   11310           6 :         ereport(ERROR,
   11311             :                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
   11312             :                 errmsg("lower bound must be less than or equal to upper bound"));
   11313             : 
   11314             :     /* Special case for an empty range */
   11315       33432 :     if (rlen.ndigits == 0)
   11316             :     {
   11317          12 :         set_var_from_var(rmin, result);
   11318          12 :         result->dscale = rscale;
   11319          12 :         free_var(&rlen);
   11320          12 :         return;
   11321             :     }
   11322             : 
   11323             :     /*
   11324             :      * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
   11325             :      * and shift it to the required range by adding rmin.
   11326             :      */
   11327             : 
   11328             :     /* Required result digits */
   11329       33420 :     res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   11330             : 
   11331             :     /*
   11332             :      * To get the required rscale, the final result digit must be a multiple
   11333             :      * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
   11334             :      */
   11335       33420 :     n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
   11336       33420 :     pow10 = 1;
   11337       87900 :     for (i = 0; i < n; i++)
   11338       54480 :         pow10 *= 10;
   11339             : 
   11340             :     /*
   11341             :      * To choose a random value uniformly from the range [0, rlen], we choose
   11342             :      * from the slightly larger range [0, rlen2], where rlen2 is formed from
   11343             :      * rlen by copying the first 4 NBASE digits, and setting all remaining
   11344             :      * decimal digits to "9".
   11345             :      *
   11346             :      * Without loss of generality, we can ignore the weight of rlen2 and treat
   11347             :      * it as a pure integer for the purposes of this discussion.  The process
   11348             :      * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
   11349             :      * is a 64-bit integer formed from the first 4 NBASE digits copied from
   11350             :      * rlen.  Since this trivially factors into smaller pieces that fit in
   11351             :      * 64-bit integers, the task of choosing a random value uniformly from the
   11352             :      * rlen2 + 1 possible values in [0, rlen2] is much simpler.
   11353             :      *
   11354             :      * If the random value selected is too large, it is rejected, and we try
   11355             :      * again until we get a result <= rlen, ensuring that the overall result
   11356             :      * is uniform (no particular value is any more likely than any other).
   11357             :      *
   11358             :      * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
   11359             :      * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
   11360             :      * when DEC_DIGITS is 4). Therefore the probability of needing to reject
   11361             :      * the value chosen and retry is less than 1e-13.
   11362             :      */
   11363       33420 :     rlen64 = (uint64) rlen.digits[0];
   11364       33420 :     rlen64_ndigits = 1;
   11365       76212 :     while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
   11366             :     {
   11367       42792 :         rlen64 *= NBASE;
   11368       42792 :         if (rlen64_ndigits < rlen.ndigits)
   11369        6612 :             rlen64 += rlen.digits[rlen64_ndigits];
   11370       42792 :         rlen64_ndigits++;
   11371             :     }
   11372             : 
   11373             :     /* Loop until we get a result <= rlen */
   11374             :     do
   11375             :     {
   11376             :         NumericDigit *res_digits;
   11377             :         uint64      rand;
   11378             :         int         whole_ndigits;
   11379             : 
   11380       33420 :         alloc_var(result, res_ndigits);
   11381       33420 :         result->sign = NUMERIC_POS;
   11382       33420 :         result->weight = rlen.weight;
   11383       33420 :         result->dscale = rscale;
   11384       33420 :         res_digits = result->digits;
   11385             : 
   11386             :         /*
   11387             :          * Set the first rlen64_ndigits using a random value in [0, rlen64].
   11388             :          *
   11389             :          * If this is the whole result, and rscale is not a multiple of
   11390             :          * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
   11391             :          * multiple of pow10.
   11392             :          */
   11393       33420 :         if (rlen64_ndigits == res_ndigits && pow10 != 1)
   11394       21132 :             rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
   11395             :         else
   11396       12288 :             rand = pg_prng_uint64_range(state, 0, rlen64);
   11397             : 
   11398      109632 :         for (i = rlen64_ndigits - 1; i >= 0; i--)
   11399             :         {
   11400       76212 :             res_digits[i] = (NumericDigit) (rand % NBASE);
   11401       76212 :             rand = rand / NBASE;
   11402             :         }
   11403             : 
   11404             :         /*
   11405             :          * Set the remaining digits to random values in range [0, NBASE),
   11406             :          * noting that the last digit needs to be a multiple of pow10.
   11407             :          */
   11408       33420 :         whole_ndigits = res_ndigits;
   11409       33420 :         if (pow10 != 1)
   11410       33210 :             whole_ndigits--;
   11411             : 
   11412             :         /* Set whole digits in groups of 4 for best performance */
   11413       33420 :         i = rlen64_ndigits;
   11414       33480 :         while (i < whole_ndigits - 3)
   11415             :         {
   11416          60 :             rand = pg_prng_uint64_range(state, 0,
   11417             :                                         (uint64) NBASE * NBASE * NBASE * NBASE - 1);
   11418          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11419          60 :             rand = rand / NBASE;
   11420          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11421          60 :             rand = rand / NBASE;
   11422          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11423          60 :             rand = rand / NBASE;
   11424          60 :             res_digits[i++] = (NumericDigit) rand;
   11425             :         }
   11426             : 
   11427             :         /* Remaining whole digits */
   11428       33630 :         while (i < whole_ndigits)
   11429             :         {
   11430         210 :             rand = pg_prng_uint64_range(state, 0, NBASE - 1);
   11431         210 :             res_digits[i++] = (NumericDigit) rand;
   11432             :         }
   11433             : 
   11434             :         /* Final partial digit (multiple of pow10) */
   11435       33420 :         if (i < res_ndigits)
   11436             :         {
   11437       12078 :             rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
   11438       12078 :             res_digits[i] = (NumericDigit) rand;
   11439             :         }
   11440             : 
   11441             :         /* Remove leading/trailing zeroes */
   11442       33420 :         strip_var(result);
   11443             : 
   11444             :         /* If result > rlen, try again */
   11445             : 
   11446       33420 :     } while (cmp_var(result, &rlen) > 0);
   11447             : 
   11448             :     /* Offset the result to the required range */
   11449       33420 :     add_var(result, rmin, result);
   11450             : 
   11451       33420 :     free_var(&rlen);
   11452             : }
   11453             : 
   11454             : 
   11455             : /* ----------------------------------------------------------------------
   11456             :  *
   11457             :  * Following are the lowest level functions that operate unsigned
   11458             :  * on the variable level
   11459             :  *
   11460             :  * ----------------------------------------------------------------------
   11461             :  */
   11462             : 
   11463             : 
   11464             : /* ----------
   11465             :  * cmp_abs() -
   11466             :  *
   11467             :  *  Compare the absolute values of var1 and var2
   11468             :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11469             :  *              0  for ABS(var1) == ABS(var2)
   11470             :  *              1  for ABS(var1) > ABS(var2)
   11471             :  * ----------
   11472             :  */
   11473             : static int
   11474      709538 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11475             : {
   11476     1419076 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11477      709538 :                           var2->digits, var2->ndigits, var2->weight);
   11478             : }
   11479             : 
   11480             : /* ----------
   11481             :  * cmp_abs_common() -
   11482             :  *
   11483             :  *  Main routine of cmp_abs(). This function can be used by both
   11484             :  *  NumericVar and Numeric.
   11485             :  * ----------
   11486             :  */
   11487             : static int
   11488    19566002 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11489             :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11490             : {
   11491    19566002 :     int         i1 = 0;
   11492    19566002 :     int         i2 = 0;
   11493             : 
   11494             :     /* Check any digits before the first common digit */
   11495             : 
   11496    19566002 :     while (var1weight > var2weight && i1 < var1ndigits)
   11497             :     {
   11498       25784 :         if (var1digits[i1++] != 0)
   11499       25784 :             return 1;
   11500           0 :         var1weight--;
   11501             :     }
   11502    19540218 :     while (var2weight > var1weight && i2 < var2ndigits)
   11503             :     {
   11504      150314 :         if (var2digits[i2++] != 0)
   11505      150314 :             return -1;
   11506           0 :         var2weight--;
   11507             :     }
   11508             : 
   11509             :     /* At this point, either w1 == w2 or we've run out of digits */
   11510             : 
   11511    19389904 :     if (var1weight == var2weight)
   11512             :     {
   11513    31526714 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11514             :         {
   11515    20954802 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11516             : 
   11517    20954802 :             if (stat)
   11518             :             {
   11519     8811634 :                 if (stat > 0)
   11520     5292214 :                     return 1;
   11521     3519420 :                 return -1;
   11522             :             }
   11523             :         }
   11524             :     }
   11525             : 
   11526             :     /*
   11527             :      * At this point, we've run out of digits on one side or the other; so any
   11528             :      * remaining nonzero digits imply that side is larger
   11529             :      */
   11530    10578606 :     while (i1 < var1ndigits)
   11531             :     {
   11532        9500 :         if (var1digits[i1++] != 0)
   11533        9164 :             return 1;
   11534             :     }
   11535    10569430 :     while (i2 < var2ndigits)
   11536             :     {
   11537        1210 :         if (var2digits[i2++] != 0)
   11538         886 :             return -1;
   11539             :     }
   11540             : 
   11541    10568220 :     return 0;
   11542             : }
   11543             : 
   11544             : 
   11545             : /*
   11546             :  * add_abs() -
   11547             :  *
   11548             :  *  Add the absolute values of two variables into result.
   11549             :  *  result might point to one of the operands without danger.
   11550             :  */
   11551             : static void
   11552      446314 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11553             : {
   11554             :     NumericDigit *res_buf;
   11555             :     NumericDigit *res_digits;
   11556             :     int         res_ndigits;
   11557             :     int         res_weight;
   11558             :     int         res_rscale,
   11559             :                 rscale1,
   11560             :                 rscale2;
   11561             :     int         res_dscale;
   11562             :     int         i,
   11563             :                 i1,
   11564             :                 i2;
   11565      446314 :     int         carry = 0;
   11566             : 
   11567             :     /* copy these values into local vars for speed in inner loop */
   11568      446314 :     int         var1ndigits = var1->ndigits;
   11569      446314 :     int         var2ndigits = var2->ndigits;
   11570      446314 :     NumericDigit *var1digits = var1->digits;
   11571      446314 :     NumericDigit *var2digits = var2->digits;
   11572             : 
   11573      446314 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11574             : 
   11575      446314 :     res_dscale = Max(var1->dscale, var2->dscale);
   11576             : 
   11577             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11578      446314 :     rscale1 = var1->ndigits - var1->weight - 1;
   11579      446314 :     rscale2 = var2->ndigits - var2->weight - 1;
   11580      446314 :     res_rscale = Max(rscale1, rscale2);
   11581             : 
   11582      446314 :     res_ndigits = res_rscale + res_weight + 1;
   11583      446314 :     if (res_ndigits <= 0)
   11584           0 :         res_ndigits = 1;
   11585             : 
   11586      446314 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11587      446314 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11588      446314 :     res_digits = res_buf + 1;
   11589             : 
   11590      446314 :     i1 = res_rscale + var1->weight + 1;
   11591      446314 :     i2 = res_rscale + var2->weight + 1;
   11592     3638884 :     for (i = res_ndigits - 1; i >= 0; i--)
   11593             :     {
   11594     3192570 :         i1--;
   11595     3192570 :         i2--;
   11596     3192570 :         if (i1 >= 0 && i1 < var1ndigits)
   11597     1416684 :             carry += var1digits[i1];
   11598     3192570 :         if (i2 >= 0 && i2 < var2ndigits)
   11599     1136434 :             carry += var2digits[i2];
   11600             : 
   11601     3192570 :         if (carry >= NBASE)
   11602             :         {
   11603      226076 :             res_digits[i] = carry - NBASE;
   11604      226076 :             carry = 1;
   11605             :         }
   11606             :         else
   11607             :         {
   11608     2966494 :             res_digits[i] = carry;
   11609     2966494 :             carry = 0;
   11610             :         }
   11611             :     }
   11612             : 
   11613             :     Assert(carry == 0);         /* else we failed to allow for carry out */
   11614             : 
   11615      446314 :     digitbuf_free(result->buf);
   11616      446314 :     result->ndigits = res_ndigits;
   11617      446314 :     result->buf = res_buf;
   11618      446314 :     result->digits = res_digits;
   11619      446314 :     result->weight = res_weight;
   11620      446314 :     result->dscale = res_dscale;
   11621             : 
   11622             :     /* Remove leading/trailing zeroes */
   11623      446314 :     strip_var(result);
   11624      446314 : }
   11625             : 
   11626             : 
   11627             : /*
   11628             :  * sub_abs()
   11629             :  *
   11630             :  *  Subtract the absolute value of var2 from the absolute value of var1
   11631             :  *  and store in result. result might point to one of the operands
   11632             :  *  without danger.
   11633             :  *
   11634             :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   11635             :  */
   11636             : static void
   11637      655278 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11638             : {
   11639             :     NumericDigit *res_buf;
   11640             :     NumericDigit *res_digits;
   11641             :     int         res_ndigits;
   11642             :     int         res_weight;
   11643             :     int         res_rscale,
   11644             :                 rscale1,
   11645             :                 rscale2;
   11646             :     int         res_dscale;
   11647             :     int         i,
   11648             :                 i1,
   11649             :                 i2;
   11650      655278 :     int         borrow = 0;
   11651             : 
   11652             :     /* copy these values into local vars for speed in inner loop */
   11653      655278 :     int         var1ndigits = var1->ndigits;
   11654      655278 :     int         var2ndigits = var2->ndigits;
   11655      655278 :     NumericDigit *var1digits = var1->digits;
   11656      655278 :     NumericDigit *var2digits = var2->digits;
   11657             : 
   11658      655278 :     res_weight = var1->weight;
   11659             : 
   11660      655278 :     res_dscale = Max(var1->dscale, var2->dscale);
   11661             : 
   11662             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11663      655278 :     rscale1 = var1->ndigits - var1->weight - 1;
   11664      655278 :     rscale2 = var2->ndigits - var2->weight - 1;
   11665      655278 :     res_rscale = Max(rscale1, rscale2);
   11666             : 
   11667      655278 :     res_ndigits = res_rscale + res_weight + 1;
   11668      655278 :     if (res_ndigits <= 0)
   11669           0 :         res_ndigits = 1;
   11670             : 
   11671      655278 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11672      655278 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11673      655278 :     res_digits = res_buf + 1;
   11674             : 
   11675      655278 :     i1 = res_rscale + var1->weight + 1;
   11676      655278 :     i2 = res_rscale + var2->weight + 1;
   11677     5188520 :     for (i = res_ndigits - 1; i >= 0; i--)
   11678             :     {
   11679     4533242 :         i1--;
   11680     4533242 :         i2--;
   11681     4533242 :         if (i1 >= 0 && i1 < var1ndigits)
   11682     4112122 :             borrow += var1digits[i1];
   11683     4533242 :         if (i2 >= 0 && i2 < var2ndigits)
   11684     4032070 :             borrow -= var2digits[i2];
   11685             : 
   11686     4533242 :         if (borrow < 0)
   11687             :         {
   11688      454100 :             res_digits[i] = borrow + NBASE;
   11689      454100 :             borrow = -1;
   11690             :         }
   11691             :         else
   11692             :         {
   11693     4079142 :             res_digits[i] = borrow;
   11694     4079142 :             borrow = 0;
   11695             :         }
   11696             :     }
   11697             : 
   11698             :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   11699             : 
   11700      655278 :     digitbuf_free(result->buf);
   11701      655278 :     result->ndigits = res_ndigits;
   11702      655278 :     result->buf = res_buf;
   11703      655278 :     result->digits = res_digits;
   11704      655278 :     result->weight = res_weight;
   11705      655278 :     result->dscale = res_dscale;
   11706             : 
   11707             :     /* Remove leading/trailing zeroes */
   11708      655278 :     strip_var(result);
   11709      655278 : }
   11710             : 
   11711             : /*
   11712             :  * round_var
   11713             :  *
   11714             :  * Round the value of a variable to no more than rscale decimal digits
   11715             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11716             :  * rounding before the decimal point.
   11717             :  */
   11718             : static void
   11719      248768 : round_var(NumericVar *var, int rscale)
   11720             : {
   11721      248768 :     NumericDigit *digits = var->digits;
   11722             :     int         di;
   11723             :     int         ndigits;
   11724             :     int         carry;
   11725             : 
   11726      248768 :     var->dscale = rscale;
   11727             : 
   11728             :     /* decimal digits wanted */
   11729      248768 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11730             : 
   11731             :     /*
   11732             :      * If di = 0, the value loses all digits, but could round up to 1 if its
   11733             :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   11734             :      */
   11735      248768 :     if (di < 0)
   11736             :     {
   11737         104 :         var->ndigits = 0;
   11738         104 :         var->weight = 0;
   11739         104 :         var->sign = NUMERIC_POS;
   11740             :     }
   11741             :     else
   11742             :     {
   11743             :         /* NBASE digits wanted */
   11744      248664 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11745             : 
   11746             :         /* 0, or number of decimal digits to keep in last NBASE digit */
   11747      248664 :         di %= DEC_DIGITS;
   11748             : 
   11749      248664 :         if (ndigits < var->ndigits ||
   11750       45872 :             (ndigits == var->ndigits && di > 0))
   11751             :         {
   11752      206244 :             var->ndigits = ndigits;
   11753             : 
   11754             : #if DEC_DIGITS == 1
   11755             :             /* di must be zero */
   11756             :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11757             : #else
   11758      206244 :             if (di == 0)
   11759      164370 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11760             :             else
   11761             :             {
   11762             :                 /* Must round within last NBASE digit */
   11763             :                 int         extra,
   11764             :                             pow10;
   11765             : 
   11766             : #if DEC_DIGITS == 4
   11767       41874 :                 pow10 = round_powers[di];
   11768             : #elif DEC_DIGITS == 2
   11769             :                 pow10 = 10;
   11770             : #else
   11771             : #error unsupported NBASE
   11772             : #endif
   11773       41874 :                 extra = digits[--ndigits] % pow10;
   11774       41874 :                 digits[ndigits] -= extra;
   11775       41874 :                 carry = 0;
   11776       41874 :                 if (extra >= pow10 / 2)
   11777             :                 {
   11778       19448 :                     pow10 += digits[ndigits];
   11779       19448 :                     if (pow10 >= NBASE)
   11780             :                     {
   11781         812 :                         pow10 -= NBASE;
   11782         812 :                         carry = 1;
   11783             :                     }
   11784       19448 :                     digits[ndigits] = pow10;
   11785             :                 }
   11786             :             }
   11787             : #endif
   11788             : 
   11789             :             /* Propagate carry if needed */
   11790      239866 :             while (carry)
   11791             :             {
   11792       33622 :                 carry += digits[--ndigits];
   11793       33622 :                 if (carry >= NBASE)
   11794             :                 {
   11795       24626 :                     digits[ndigits] = carry - NBASE;
   11796       24626 :                     carry = 1;
   11797             :                 }
   11798             :                 else
   11799             :                 {
   11800        8996 :                     digits[ndigits] = carry;
   11801        8996 :                     carry = 0;
   11802             :                 }
   11803             :             }
   11804             : 
   11805      206244 :             if (ndigits < 0)
   11806             :             {
   11807             :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   11808             :                 Assert(var->digits > var->buf);
   11809          96 :                 var->digits--;
   11810          96 :                 var->ndigits++;
   11811          96 :                 var->weight++;
   11812             :             }
   11813             :         }
   11814             :     }
   11815      248768 : }
   11816             : 
   11817             : /*
   11818             :  * trunc_var
   11819             :  *
   11820             :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   11821             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11822             :  * truncation before the decimal point.
   11823             :  */
   11824             : static void
   11825      420880 : trunc_var(NumericVar *var, int rscale)
   11826             : {
   11827             :     int         di;
   11828             :     int         ndigits;
   11829             : 
   11830      420880 :     var->dscale = rscale;
   11831             : 
   11832             :     /* decimal digits wanted */
   11833      420880 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11834             : 
   11835             :     /*
   11836             :      * If di <= 0, the value loses all digits.
   11837             :      */
   11838      420880 :     if (di <= 0)
   11839             :     {
   11840          90 :         var->ndigits = 0;
   11841          90 :         var->weight = 0;
   11842          90 :         var->sign = NUMERIC_POS;
   11843             :     }
   11844             :     else
   11845             :     {
   11846             :         /* NBASE digits wanted */
   11847      420790 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11848             : 
   11849      420790 :         if (ndigits <= var->ndigits)
   11850             :         {
   11851      420520 :             var->ndigits = ndigits;
   11852             : 
   11853             : #if DEC_DIGITS == 1
   11854             :             /* no within-digit stuff to worry about */
   11855             : #else
   11856             :             /* 0, or number of decimal digits to keep in last NBASE digit */
   11857      420520 :             di %= DEC_DIGITS;
   11858             : 
   11859      420520 :             if (di > 0)
   11860             :             {
   11861             :                 /* Must truncate within last NBASE digit */
   11862         106 :                 NumericDigit *digits = var->digits;
   11863             :                 int         extra,
   11864             :                             pow10;
   11865             : 
   11866             : #if DEC_DIGITS == 4
   11867         106 :                 pow10 = round_powers[di];
   11868             : #elif DEC_DIGITS == 2
   11869             :                 pow10 = 10;
   11870             : #else
   11871             : #error unsupported NBASE
   11872             : #endif
   11873         106 :                 extra = digits[--ndigits] % pow10;
   11874         106 :                 digits[ndigits] -= extra;
   11875             :             }
   11876             : #endif
   11877             :         }
   11878             :     }
   11879      420880 : }
   11880             : 
   11881             : /*
   11882             :  * strip_var
   11883             :  *
   11884             :  * Strip any leading and trailing zeroes from a numeric variable
   11885             :  */
   11886             : static void
   11887     3285004 : strip_var(NumericVar *var)
   11888             : {
   11889     3285004 :     NumericDigit *digits = var->digits;
   11890     3285004 :     int         ndigits = var->ndigits;
   11891             : 
   11892             :     /* Strip leading zeroes */
   11893     5631116 :     while (ndigits > 0 && *digits == 0)
   11894             :     {
   11895     2346112 :         digits++;
   11896     2346112 :         var->weight--;
   11897     2346112 :         ndigits--;
   11898             :     }
   11899             : 
   11900             :     /* Strip trailing zeroes */
   11901     3959360 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   11902      674356 :         ndigits--;
   11903             : 
   11904             :     /* If it's zero, normalize the sign and weight */
   11905     3285004 :     if (ndigits == 0)
   11906             :     {
   11907       50580 :         var->sign = NUMERIC_POS;
   11908       50580 :         var->weight = 0;
   11909             :     }
   11910             : 
   11911     3285004 :     var->digits = digits;
   11912     3285004 :     var->ndigits = ndigits;
   11913     3285004 : }
   11914             : 
   11915             : 
   11916             : /* ----------------------------------------------------------------------
   11917             :  *
   11918             :  * Fast sum accumulator functions
   11919             :  *
   11920             :  * ----------------------------------------------------------------------
   11921             :  */
   11922             : 
   11923             : /*
   11924             :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   11925             :  * are not free'd.
   11926             :  */
   11927             : static void
   11928          18 : accum_sum_reset(NumericSumAccum *accum)
   11929             : {
   11930             :     int         i;
   11931             : 
   11932          18 :     accum->dscale = 0;
   11933          66 :     for (i = 0; i < accum->ndigits; i++)
   11934             :     {
   11935          48 :         accum->pos_digits[i] = 0;
   11936          48 :         accum->neg_digits[i] = 0;
   11937             :     }
   11938          18 : }
   11939             : 
   11940             : /*
   11941             :  * Accumulate a new value.
   11942             :  */
   11943             : static void
   11944     2355704 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   11945             : {
   11946             :     int32      *accum_digits;
   11947             :     int         i,
   11948             :                 val_i;
   11949             :     int         val_ndigits;
   11950             :     NumericDigit *val_digits;
   11951             : 
   11952             :     /*
   11953             :      * If we have accumulated too many values since the last carry
   11954             :      * propagation, do it now, to avoid overflowing.  (We could allow more
   11955             :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   11956             :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   11957             :      * seldom, that the performance difference is negligible.)
   11958             :      */
   11959     2355704 :     if (accum->num_uncarried == NBASE - 1)
   11960         168 :         accum_sum_carry(accum);
   11961             : 
   11962             :     /*
   11963             :      * Adjust the weight or scale of the old value, so that it can accommodate
   11964             :      * the new value.
   11965             :      */
   11966     2355704 :     accum_sum_rescale(accum, val);
   11967             : 
   11968             :     /* */
   11969     2355704 :     if (val->sign == NUMERIC_POS)
   11970     1755026 :         accum_digits = accum->pos_digits;
   11971             :     else
   11972      600678 :         accum_digits = accum->neg_digits;
   11973             : 
   11974             :     /* copy these values into local vars for speed in loop */
   11975     2355704 :     val_ndigits = val->ndigits;
   11976     2355704 :     val_digits = val->digits;
   11977             : 
   11978     2355704 :     i = accum->weight - val->weight;
   11979    11889938 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   11980             :     {
   11981     9534234 :         accum_digits[i] += (int32) val_digits[val_i];
   11982     9534234 :         i++;
   11983             :     }
   11984             : 
   11985     2355704 :     accum->num_uncarried++;
   11986     2355704 : }
   11987             : 
   11988             : /*
   11989             :  * Propagate carries.
   11990             :  */
   11991             : static void
   11992      172770 : accum_sum_carry(NumericSumAccum *accum)
   11993             : {
   11994             :     int         i;
   11995             :     int         ndigits;
   11996             :     int32      *dig;
   11997             :     int32       carry;
   11998      172770 :     int32       newdig = 0;
   11999             : 
   12000             :     /*
   12001             :      * If no new values have been added since last carry propagation, nothing
   12002             :      * to do.
   12003             :      */
   12004      172770 :     if (accum->num_uncarried == 0)
   12005          72 :         return;
   12006             : 
   12007             :     /*
   12008             :      * We maintain that the weight of the accumulator is always one larger
   12009             :      * than needed to hold the current value, before carrying, to make sure
   12010             :      * there is enough space for the possible extra digit when carry is
   12011             :      * propagated.  We cannot expand the buffer here, unless we require
   12012             :      * callers of accum_sum_final() to switch to the right memory context.
   12013             :      */
   12014             :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12015             : 
   12016      172698 :     ndigits = accum->ndigits;
   12017             : 
   12018             :     /* Propagate carry in the positive sum */
   12019      172698 :     dig = accum->pos_digits;
   12020      172698 :     carry = 0;
   12021     2605580 :     for (i = ndigits - 1; i >= 0; i--)
   12022             :     {
   12023     2432882 :         newdig = dig[i] + carry;
   12024     2432882 :         if (newdig >= NBASE)
   12025             :         {
   12026      110822 :             carry = newdig / NBASE;
   12027      110822 :             newdig -= carry * NBASE;
   12028             :         }
   12029             :         else
   12030     2322060 :             carry = 0;
   12031     2432882 :         dig[i] = newdig;
   12032             :     }
   12033             :     /* Did we use up the digit reserved for carry propagation? */
   12034      172698 :     if (newdig > 0)
   12035        2638 :         accum->have_carry_space = false;
   12036             : 
   12037             :     /* And the same for the negative sum */
   12038      172698 :     dig = accum->neg_digits;
   12039      172698 :     carry = 0;
   12040     2605580 :     for (i = ndigits - 1; i >= 0; i--)
   12041             :     {
   12042     2432882 :         newdig = dig[i] + carry;
   12043     2432882 :         if (newdig >= NBASE)
   12044             :         {
   12045         198 :             carry = newdig / NBASE;
   12046         198 :             newdig -= carry * NBASE;
   12047             :         }
   12048             :         else
   12049     2432684 :             carry = 0;
   12050     2432882 :         dig[i] = newdig;
   12051             :     }
   12052      172698 :     if (newdig > 0)
   12053          30 :         accum->have_carry_space = false;
   12054             : 
   12055      172698 :     accum->num_uncarried = 0;
   12056             : }
   12057             : 
   12058             : /*
   12059             :  * Re-scale accumulator to accommodate new value.
   12060             :  *
   12061             :  * If the new value has more digits than the current digit buffers in the
   12062             :  * accumulator, enlarge the buffers.
   12063             :  */
   12064             : static void
   12065     2355704 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   12066             : {
   12067     2355704 :     int         old_weight = accum->weight;
   12068     2355704 :     int         old_ndigits = accum->ndigits;
   12069             :     int         accum_ndigits;
   12070             :     int         accum_weight;
   12071             :     int         accum_rscale;
   12072             :     int         val_rscale;
   12073             : 
   12074     2355704 :     accum_weight = old_weight;
   12075     2355704 :     accum_ndigits = old_ndigits;
   12076             : 
   12077             :     /*
   12078             :      * Does the new value have a larger weight? If so, enlarge the buffers,
   12079             :      * and shift the existing value to the new weight, by adding leading
   12080             :      * zeros.
   12081             :      *
   12082             :      * We enforce that the accumulator always has a weight one larger than
   12083             :      * needed for the inputs, so that we have space for an extra digit at the
   12084             :      * final carry-propagation phase, if necessary.
   12085             :      */
   12086     2355704 :     if (val->weight >= accum_weight)
   12087             :     {
   12088      262224 :         accum_weight = val->weight + 1;
   12089      262224 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   12090             :     }
   12091             : 
   12092             :     /*
   12093             :      * Even though the new value is small, we might've used up the space
   12094             :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   12095             :      * so, enlarge to make room for another one.
   12096             :      */
   12097     2093480 :     else if (!accum->have_carry_space)
   12098             :     {
   12099          90 :         accum_weight++;
   12100          90 :         accum_ndigits++;
   12101             :     }
   12102             : 
   12103             :     /* Is the new value wider on the right side? */
   12104     2355704 :     accum_rscale = accum_ndigits - accum_weight - 1;
   12105     2355704 :     val_rscale = val->ndigits - val->weight - 1;
   12106     2355704 :     if (val_rscale > accum_rscale)
   12107      172246 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   12108             : 
   12109     2355704 :     if (accum_ndigits != old_ndigits ||
   12110             :         accum_weight != old_weight)
   12111             :     {
   12112             :         int32      *new_pos_digits;
   12113             :         int32      *new_neg_digits;
   12114             :         int         weightdiff;
   12115             : 
   12116      262586 :         weightdiff = accum_weight - old_weight;
   12117             : 
   12118      262586 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   12119      262586 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   12120             : 
   12121      262586 :         if (accum->pos_digits)
   12122             :         {
   12123       90410 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   12124             :                    old_ndigits * sizeof(int32));
   12125       90410 :             pfree(accum->pos_digits);
   12126             : 
   12127       90410 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   12128             :                    old_ndigits * sizeof(int32));
   12129       90410 :             pfree(accum->neg_digits);
   12130             :         }
   12131             : 
   12132      262586 :         accum->pos_digits = new_pos_digits;
   12133      262586 :         accum->neg_digits = new_neg_digits;
   12134             : 
   12135      262586 :         accum->weight = accum_weight;
   12136      262586 :         accum->ndigits = accum_ndigits;
   12137             : 
   12138             :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12139      262586 :         accum->have_carry_space = true;
   12140             :     }
   12141             : 
   12142     2355704 :     if (val->dscale > accum->dscale)
   12143         300 :         accum->dscale = val->dscale;
   12144     2355704 : }
   12145             : 
   12146             : /*
   12147             :  * Return the current value of the accumulator.  This perform final carry
   12148             :  * propagation, and adds together the positive and negative sums.
   12149             :  *
   12150             :  * Unlike all the other routines, the caller is not required to switch to
   12151             :  * the memory context that holds the accumulator.
   12152             :  */
   12153             : static void
   12154      172602 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   12155             : {
   12156             :     int         i;
   12157             :     NumericVar  pos_var;
   12158             :     NumericVar  neg_var;
   12159             : 
   12160      172602 :     if (accum->ndigits == 0)
   12161             :     {
   12162           0 :         set_var_from_var(&const_zero, result);
   12163           0 :         return;
   12164             :     }
   12165             : 
   12166             :     /* Perform final carry */
   12167      172602 :     accum_sum_carry(accum);
   12168             : 
   12169             :     /* Create NumericVars representing the positive and negative sums */
   12170      172602 :     init_var(&pos_var);
   12171      172602 :     init_var(&neg_var);
   12172             : 
   12173      172602 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   12174      172602 :     pos_var.weight = neg_var.weight = accum->weight;
   12175      172602 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   12176      172602 :     pos_var.sign = NUMERIC_POS;
   12177      172602 :     neg_var.sign = NUMERIC_NEG;
   12178             : 
   12179      172602 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   12180      172602 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   12181             : 
   12182     2605102 :     for (i = 0; i < accum->ndigits; i++)
   12183             :     {
   12184             :         Assert(accum->pos_digits[i] < NBASE);
   12185     2432500 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   12186             : 
   12187             :         Assert(accum->neg_digits[i] < NBASE);
   12188     2432500 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   12189             :     }
   12190             : 
   12191             :     /* And add them together */
   12192      172602 :     add_var(&pos_var, &neg_var, result);
   12193             : 
   12194             :     /* Remove leading/trailing zeroes */
   12195      172602 :     strip_var(result);
   12196             : }
   12197             : 
   12198             : /*
   12199             :  * Copy an accumulator's state.
   12200             :  *
   12201             :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   12202             :  * freeing old values.
   12203             :  */
   12204             : static void
   12205          42 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   12206             : {
   12207          42 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12208          42 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12209             : 
   12210          42 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12211          42 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12212          42 :     dst->num_uncarried = src->num_uncarried;
   12213          42 :     dst->ndigits = src->ndigits;
   12214          42 :     dst->weight = src->weight;
   12215          42 :     dst->dscale = src->dscale;
   12216          42 : }
   12217             : 
   12218             : /*
   12219             :  * Add the current value of 'accum2' into 'accum'.
   12220             :  */
   12221             : static void
   12222          48 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12223             : {
   12224             :     NumericVar  tmp_var;
   12225             : 
   12226          48 :     init_var(&tmp_var);
   12227             : 
   12228          48 :     accum_sum_final(accum2, &tmp_var);
   12229          48 :     accum_sum_add(accum, &tmp_var);
   12230             : 
   12231          48 :     free_var(&tmp_var);
   12232          48 : }

Generated by: LCOV version 1.16