LCOV - code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 3675 3899 94.3 %
Date: 2024-04-19 05:11:10 Functions: 208 209 99.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * numeric.c
       4             :  *    An exact numeric data type for the Postgres database system
       5             :  *
       6             :  * Original coding 1998, Jan Wieck.  Heavily revised 2003, Tom Lane.
       7             :  *
       8             :  * Many of the algorithmic ideas are borrowed from David M. Smith's "FM"
       9             :  * multiple-precision math library, most recently published as Algorithm
      10             :  * 786: Multiple-Precision Complex Arithmetic and Functions, ACM
      11             :  * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998,
      12             :  * pages 359-367.
      13             :  *
      14             :  * Copyright (c) 1998-2024, PostgreSQL Global Development Group
      15             :  *
      16             :  * IDENTIFICATION
      17             :  *    src/backend/utils/adt/numeric.c
      18             :  *
      19             :  *-------------------------------------------------------------------------
      20             :  */
      21             : 
      22             : #include "postgres.h"
      23             : 
      24             : #include <ctype.h>
      25             : #include <float.h>
      26             : #include <limits.h>
      27             : #include <math.h>
      28             : 
      29             : #include "common/hashfn.h"
      30             : #include "common/int.h"
      31             : #include "funcapi.h"
      32             : #include "lib/hyperloglog.h"
      33             : #include "libpq/pqformat.h"
      34             : #include "miscadmin.h"
      35             : #include "nodes/nodeFuncs.h"
      36             : #include "nodes/supportnodes.h"
      37             : #include "utils/array.h"
      38             : #include "utils/builtins.h"
      39             : #include "utils/float.h"
      40             : #include "utils/guc.h"
      41             : #include "utils/numeric.h"
      42             : #include "utils/pg_lsn.h"
      43             : #include "utils/sortsupport.h"
      44             : 
      45             : /* ----------
      46             :  * Uncomment the following to enable compilation of dump_numeric()
      47             :  * and dump_var() and to get a dump of any result produced by make_result().
      48             :  * ----------
      49             : #define NUMERIC_DEBUG
      50             :  */
      51             : 
      52             : 
      53             : /* ----------
      54             :  * Local data types
      55             :  *
      56             :  * Numeric values are represented in a base-NBASE floating point format.
      57             :  * Each "digit" ranges from 0 to NBASE-1.  The type NumericDigit is signed
      58             :  * and wide enough to store a digit.  We assume that NBASE*NBASE can fit in
      59             :  * an int.  Although the purely calculational routines could handle any even
      60             :  * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
      61             :  * in NBASE a power of ten, so that I/O conversions and decimal rounding
      62             :  * are easy.  Also, it's actually more efficient if NBASE is rather less than
      63             :  * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var_fast to
      64             :  * postpone processing carries.
      65             :  *
      66             :  * Values of NBASE other than 10000 are considered of historical interest only
      67             :  * and are no longer supported in any sense; no mechanism exists for the client
      68             :  * to discover the base, so every client supporting binary mode expects the
      69             :  * base-10000 format.  If you plan to change this, also note the numeric
      70             :  * abbreviation code, which assumes NBASE=10000.
      71             :  * ----------
      72             :  */
      73             : 
      74             : #if 0
      75             : #define NBASE       10
      76             : #define HALF_NBASE  5
      77             : #define DEC_DIGITS  1           /* decimal digits per NBASE digit */
      78             : #define MUL_GUARD_DIGITS    4   /* these are measured in NBASE digits */
      79             : #define DIV_GUARD_DIGITS    8
      80             : 
      81             : typedef signed char NumericDigit;
      82             : #endif
      83             : 
      84             : #if 0
      85             : #define NBASE       100
      86             : #define HALF_NBASE  50
      87             : #define DEC_DIGITS  2           /* decimal digits per NBASE digit */
      88             : #define MUL_GUARD_DIGITS    3   /* these are measured in NBASE digits */
      89             : #define DIV_GUARD_DIGITS    6
      90             : 
      91             : typedef signed char NumericDigit;
      92             : #endif
      93             : 
      94             : #if 1
      95             : #define NBASE       10000
      96             : #define HALF_NBASE  5000
      97             : #define DEC_DIGITS  4           /* decimal digits per NBASE digit */
      98             : #define MUL_GUARD_DIGITS    2   /* these are measured in NBASE digits */
      99             : #define DIV_GUARD_DIGITS    4
     100             : 
     101             : typedef int16 NumericDigit;
     102             : #endif
     103             : 
     104             : /*
     105             :  * The Numeric type as stored on disk.
     106             :  *
     107             :  * If the high bits of the first word of a NumericChoice (n_header, or
     108             :  * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
     109             :  * numeric follows the NumericShort format; if they are NUMERIC_POS or
     110             :  * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
     111             :  * the value is a NaN or Infinity.  We currently always store SPECIAL values
     112             :  * using just two bytes (i.e. only n_header), but previous releases used only
     113             :  * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
     114             :  * on disk if a database has been migrated using pg_upgrade.  In either case,
     115             :  * the low-order bits of a special value's header are reserved and currently
     116             :  * should always be set to zero.
     117             :  *
     118             :  * In the NumericShort format, the remaining 14 bits of the header word
     119             :  * (n_short.n_header) are allocated as follows: 1 for sign (positive or
     120             :  * negative), 6 for dynamic scale, and 7 for weight.  In practice, most
     121             :  * commonly-encountered values can be represented this way.
     122             :  *
     123             :  * In the NumericLong format, the remaining 14 bits of the header word
     124             :  * (n_long.n_sign_dscale) represent the display scale; and the weight is
     125             :  * stored separately in n_weight.
     126             :  *
     127             :  * NOTE: by convention, values in the packed form have been stripped of
     128             :  * all leading and trailing zero digits (where a "digit" is of base NBASE).
     129             :  * In particular, if the value is zero, there will be no digits at all!
     130             :  * The weight is arbitrary in that case, but we normally set it to zero.
     131             :  */
     132             : 
     133             : struct NumericShort
     134             : {
     135             :     uint16      n_header;       /* Sign + display scale + weight */
     136             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     137             : };
     138             : 
     139             : struct NumericLong
     140             : {
     141             :     uint16      n_sign_dscale;  /* Sign + display scale */
     142             :     int16       n_weight;       /* Weight of 1st digit  */
     143             :     NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
     144             : };
     145             : 
     146             : union NumericChoice
     147             : {
     148             :     uint16      n_header;       /* Header word */
     149             :     struct NumericLong n_long;  /* Long form (4-byte header) */
     150             :     struct NumericShort n_short;    /* Short form (2-byte header) */
     151             : };
     152             : 
     153             : struct NumericData
     154             : {
     155             :     int32       vl_len_;        /* varlena header (do not touch directly!) */
     156             :     union NumericChoice choice; /* choice of format */
     157             : };
     158             : 
     159             : 
     160             : /*
     161             :  * Interpretation of high bits.
     162             :  */
     163             : 
     164             : #define NUMERIC_SIGN_MASK   0xC000
     165             : #define NUMERIC_POS         0x0000
     166             : #define NUMERIC_NEG         0x4000
     167             : #define NUMERIC_SHORT       0x8000
     168             : #define NUMERIC_SPECIAL     0xC000
     169             : 
     170             : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
     171             : #define NUMERIC_IS_SHORT(n)     (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
     172             : #define NUMERIC_IS_SPECIAL(n)   (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
     173             : 
     174             : #define NUMERIC_HDRSZ   (VARHDRSZ + sizeof(uint16) + sizeof(int16))
     175             : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
     176             : 
     177             : /*
     178             :  * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
     179             :  * header; otherwise, we want the long one.  Instead of testing against each
     180             :  * value, we can just look at the high bit, for a slight efficiency gain.
     181             :  */
     182             : #define NUMERIC_HEADER_IS_SHORT(n)  (((n)->choice.n_header & 0x8000) != 0)
     183             : #define NUMERIC_HEADER_SIZE(n) \
     184             :     (VARHDRSZ + sizeof(uint16) + \
     185             :      (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
     186             : 
     187             : /*
     188             :  * Definitions for special values (NaN, positive infinity, negative infinity).
     189             :  *
     190             :  * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
     191             :  * infinity, 11 for negative infinity.  (This makes the sign bit match where
     192             :  * it is in a short-format value, though we make no use of that at present.)
     193             :  * We could mask off the remaining bits before testing the active bits, but
     194             :  * currently those bits must be zeroes, so masking would just add cycles.
     195             :  */
     196             : #define NUMERIC_EXT_SIGN_MASK   0xF000  /* high bits plus NaN/Inf flag bits */
     197             : #define NUMERIC_NAN             0xC000
     198             : #define NUMERIC_PINF            0xD000
     199             : #define NUMERIC_NINF            0xF000
     200             : #define NUMERIC_INF_SIGN_MASK   0x2000
     201             : 
     202             : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
     203             : #define NUMERIC_IS_NAN(n)       ((n)->choice.n_header == NUMERIC_NAN)
     204             : #define NUMERIC_IS_PINF(n)      ((n)->choice.n_header == NUMERIC_PINF)
     205             : #define NUMERIC_IS_NINF(n)      ((n)->choice.n_header == NUMERIC_NINF)
     206             : #define NUMERIC_IS_INF(n) \
     207             :     (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
     208             : 
     209             : /*
     210             :  * Short format definitions.
     211             :  */
     212             : 
     213             : #define NUMERIC_SHORT_SIGN_MASK         0x2000
     214             : #define NUMERIC_SHORT_DSCALE_MASK       0x1F80
     215             : #define NUMERIC_SHORT_DSCALE_SHIFT      7
     216             : #define NUMERIC_SHORT_DSCALE_MAX        \
     217             :     (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
     218             : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK  0x0040
     219             : #define NUMERIC_SHORT_WEIGHT_MASK       0x003F
     220             : #define NUMERIC_SHORT_WEIGHT_MAX        NUMERIC_SHORT_WEIGHT_MASK
     221             : #define NUMERIC_SHORT_WEIGHT_MIN        (-(NUMERIC_SHORT_WEIGHT_MASK+1))
     222             : 
     223             : /*
     224             :  * Extract sign, display scale, weight.  These macros extract field values
     225             :  * suitable for the NumericVar format from the Numeric (on-disk) format.
     226             :  *
     227             :  * Note that we don't trouble to ensure that dscale and weight read as zero
     228             :  * for an infinity; however, that doesn't matter since we never convert
     229             :  * "special" numerics to NumericVar form.  Only the constants defined below
     230             :  * (const_nan, etc) ever represent a non-finite value as a NumericVar.
     231             :  */
     232             : 
     233             : #define NUMERIC_DSCALE_MASK         0x3FFF
     234             : #define NUMERIC_DSCALE_MAX          NUMERIC_DSCALE_MASK
     235             : 
     236             : #define NUMERIC_SIGN(n) \
     237             :     (NUMERIC_IS_SHORT(n) ? \
     238             :         (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
     239             :          NUMERIC_NEG : NUMERIC_POS) : \
     240             :         (NUMERIC_IS_SPECIAL(n) ? \
     241             :          NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
     242             : #define NUMERIC_DSCALE(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     243             :     ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
     244             :         >> NUMERIC_SHORT_DSCALE_SHIFT \
     245             :     : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
     246             : #define NUMERIC_WEIGHT(n)   (NUMERIC_HEADER_IS_SHORT((n)) ? \
     247             :     (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
     248             :         ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
     249             :      | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
     250             :     : ((n)->choice.n_long.n_weight))
     251             : 
     252             : /* ----------
     253             :  * NumericVar is the format we use for arithmetic.  The digit-array part
     254             :  * is the same as the NumericData storage format, but the header is more
     255             :  * complex.
     256             :  *
     257             :  * The value represented by a NumericVar is determined by the sign, weight,
     258             :  * ndigits, and digits[] array.  If it is a "special" value (NaN or Inf)
     259             :  * then only the sign field matters; ndigits should be zero, and the weight
     260             :  * and dscale fields are ignored.
     261             :  *
     262             :  * Note: the first digit of a NumericVar's value is assumed to be multiplied
     263             :  * by NBASE ** weight.  Another way to say it is that there are weight+1
     264             :  * digits before the decimal point.  It is possible to have weight < 0.
     265             :  *
     266             :  * buf points at the physical start of the palloc'd digit buffer for the
     267             :  * NumericVar.  digits points at the first digit in actual use (the one
     268             :  * with the specified weight).  We normally leave an unused digit or two
     269             :  * (preset to zeroes) between buf and digits, so that there is room to store
     270             :  * a carry out of the top digit without reallocating space.  We just need to
     271             :  * decrement digits (and increment weight) to make room for the carry digit.
     272             :  * (There is no such extra space in a numeric value stored in the database,
     273             :  * only in a NumericVar in memory.)
     274             :  *
     275             :  * If buf is NULL then the digit buffer isn't actually palloc'd and should
     276             :  * not be freed --- see the constants below for an example.
     277             :  *
     278             :  * dscale, or display scale, is the nominal precision expressed as number
     279             :  * of digits after the decimal point (it must always be >= 0 at present).
     280             :  * dscale may be more than the number of physically stored fractional digits,
     281             :  * implying that we have suppressed storage of significant trailing zeroes.
     282             :  * It should never be less than the number of stored digits, since that would
     283             :  * imply hiding digits that are present.  NOTE that dscale is always expressed
     284             :  * in *decimal* digits, and so it may correspond to a fractional number of
     285             :  * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
     286             :  *
     287             :  * rscale, or result scale, is the target precision for a computation.
     288             :  * Like dscale it is expressed as number of *decimal* digits after the decimal
     289             :  * point, and is always >= 0 at present.
     290             :  * Note that rscale is not stored in variables --- it's figured on-the-fly
     291             :  * from the dscales of the inputs.
     292             :  *
     293             :  * While we consistently use "weight" to refer to the base-NBASE weight of
     294             :  * a numeric value, it is convenient in some scale-related calculations to
     295             :  * make use of the base-10 weight (ie, the approximate log10 of the value).
     296             :  * To avoid confusion, such a decimal-units weight is called a "dweight".
     297             :  *
     298             :  * NB: All the variable-level functions are written in a style that makes it
     299             :  * possible to give one and the same variable as argument and destination.
     300             :  * This is feasible because the digit buffer is separate from the variable.
     301             :  * ----------
     302             :  */
     303             : typedef struct NumericVar
     304             : {
     305             :     int         ndigits;        /* # of digits in digits[] - can be 0! */
     306             :     int         weight;         /* weight of first digit */
     307             :     int         sign;           /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
     308             :     int         dscale;         /* display scale */
     309             :     NumericDigit *buf;          /* start of palloc'd space for digits[] */
     310             :     NumericDigit *digits;       /* base-NBASE digits */
     311             : } NumericVar;
     312             : 
     313             : 
     314             : /* ----------
     315             :  * Data for generate_series
     316             :  * ----------
     317             :  */
     318             : typedef struct
     319             : {
     320             :     NumericVar  current;
     321             :     NumericVar  stop;
     322             :     NumericVar  step;
     323             : } generate_series_numeric_fctx;
     324             : 
     325             : 
     326             : /* ----------
     327             :  * Sort support.
     328             :  * ----------
     329             :  */
     330             : typedef struct
     331             : {
     332             :     void       *buf;            /* buffer for short varlenas */
     333             :     int64       input_count;    /* number of non-null values seen */
     334             :     bool        estimating;     /* true if estimating cardinality */
     335             : 
     336             :     hyperLogLogState abbr_card; /* cardinality estimator */
     337             : } NumericSortSupport;
     338             : 
     339             : 
     340             : /* ----------
     341             :  * Fast sum accumulator.
     342             :  *
     343             :  * NumericSumAccum is used to implement SUM(), and other standard aggregates
     344             :  * that track the sum of input values.  It uses 32-bit integers to store the
     345             :  * digits, instead of the normal 16-bit integers (with NBASE=10000).  This
     346             :  * way, we can safely accumulate up to NBASE - 1 values without propagating
     347             :  * carry, before risking overflow of any of the digits.  'num_uncarried'
     348             :  * tracks how many values have been accumulated without propagating carry.
     349             :  *
     350             :  * Positive and negative values are accumulated separately, in 'pos_digits'
     351             :  * and 'neg_digits'.  This is simpler and faster than deciding whether to add
     352             :  * or subtract from the current value, for each new value (see sub_var() for
     353             :  * the logic we avoid by doing this).  Both buffers are of same size, and
     354             :  * have the same weight and scale.  In accum_sum_final(), the positive and
     355             :  * negative sums are added together to produce the final result.
     356             :  *
     357             :  * When a new value has a larger ndigits or weight than the accumulator
     358             :  * currently does, the accumulator is enlarged to accommodate the new value.
     359             :  * We normally have one zero digit reserved for carry propagation, and that
     360             :  * is indicated by the 'have_carry_space' flag.  When accum_sum_carry() uses
     361             :  * up the reserved digit, it clears the 'have_carry_space' flag.  The next
     362             :  * call to accum_sum_add() will enlarge the buffer, to make room for the
     363             :  * extra digit, and set the flag again.
     364             :  *
     365             :  * To initialize a new accumulator, simply reset all fields to zeros.
     366             :  *
     367             :  * The accumulator does not handle NaNs.
     368             :  * ----------
     369             :  */
     370             : typedef struct NumericSumAccum
     371             : {
     372             :     int         ndigits;
     373             :     int         weight;
     374             :     int         dscale;
     375             :     int         num_uncarried;
     376             :     bool        have_carry_space;
     377             :     int32      *pos_digits;
     378             :     int32      *neg_digits;
     379             : } NumericSumAccum;
     380             : 
     381             : 
     382             : /*
     383             :  * We define our own macros for packing and unpacking abbreviated-key
     384             :  * representations for numeric values in order to avoid depending on
     385             :  * USE_FLOAT8_BYVAL.  The type of abbreviation we use is based only on
     386             :  * the size of a datum, not the argument-passing convention for float8.
     387             :  *
     388             :  * The range of abbreviations for finite values is from +PG_INT64/32_MAX
     389             :  * to -PG_INT64/32_MAX.  NaN has the abbreviation PG_INT64/32_MIN, and we
     390             :  * define the sort ordering to make that work out properly (see further
     391             :  * comments below).  PINF and NINF share the abbreviations of the largest
     392             :  * and smallest finite abbreviation classes.
     393             :  */
     394             : #define NUMERIC_ABBREV_BITS (SIZEOF_DATUM * BITS_PER_BYTE)
     395             : #if SIZEOF_DATUM == 8
     396             : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     397             : #define DatumGetNumericAbbrev(X) ((int64) (X))
     398             : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT64_MIN)
     399             : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT64_MAX)
     400             : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT64_MAX)
     401             : #else
     402             : #define NumericAbbrevGetDatum(X) ((Datum) (X))
     403             : #define DatumGetNumericAbbrev(X) ((int32) (X))
     404             : #define NUMERIC_ABBREV_NAN       NumericAbbrevGetDatum(PG_INT32_MIN)
     405             : #define NUMERIC_ABBREV_PINF      NumericAbbrevGetDatum(-PG_INT32_MAX)
     406             : #define NUMERIC_ABBREV_NINF      NumericAbbrevGetDatum(PG_INT32_MAX)
     407             : #endif
     408             : 
     409             : 
     410             : /* ----------
     411             :  * Some preinitialized constants
     412             :  * ----------
     413             :  */
     414             : static const NumericDigit const_zero_data[1] = {0};
     415             : static const NumericVar const_zero =
     416             : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
     417             : 
     418             : static const NumericDigit const_one_data[1] = {1};
     419             : static const NumericVar const_one =
     420             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
     421             : 
     422             : static const NumericVar const_minus_one =
     423             : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
     424             : 
     425             : static const NumericDigit const_two_data[1] = {2};
     426             : static const NumericVar const_two =
     427             : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
     428             : 
     429             : #if DEC_DIGITS == 4
     430             : static const NumericDigit const_zero_point_nine_data[1] = {9000};
     431             : #elif DEC_DIGITS == 2
     432             : static const NumericDigit const_zero_point_nine_data[1] = {90};
     433             : #elif DEC_DIGITS == 1
     434             : static const NumericDigit const_zero_point_nine_data[1] = {9};
     435             : #endif
     436             : static const NumericVar const_zero_point_nine =
     437             : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
     438             : 
     439             : #if DEC_DIGITS == 4
     440             : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
     441             : #elif DEC_DIGITS == 2
     442             : static const NumericDigit const_one_point_one_data[2] = {1, 10};
     443             : #elif DEC_DIGITS == 1
     444             : static const NumericDigit const_one_point_one_data[2] = {1, 1};
     445             : #endif
     446             : static const NumericVar const_one_point_one =
     447             : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
     448             : 
     449             : static const NumericVar const_nan =
     450             : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
     451             : 
     452             : static const NumericVar const_pinf =
     453             : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
     454             : 
     455             : static const NumericVar const_ninf =
     456             : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
     457             : 
     458             : #if DEC_DIGITS == 4
     459             : static const int round_powers[4] = {0, 1000, 100, 10};
     460             : #endif
     461             : 
     462             : 
     463             : /* ----------
     464             :  * Local functions
     465             :  * ----------
     466             :  */
     467             : 
     468             : #ifdef NUMERIC_DEBUG
     469             : static void dump_numeric(const char *str, Numeric num);
     470             : static void dump_var(const char *str, NumericVar *var);
     471             : #else
     472             : #define dump_numeric(s,n)
     473             : #define dump_var(s,v)
     474             : #endif
     475             : 
     476             : #define digitbuf_alloc(ndigits)  \
     477             :     ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
     478             : #define digitbuf_free(buf)  \
     479             :     do { \
     480             :          if ((buf) != NULL) \
     481             :              pfree(buf); \
     482             :     } while (0)
     483             : 
     484             : #define init_var(v)     memset(v, 0, sizeof(NumericVar))
     485             : 
     486             : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
     487             :     (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
     488             : #define NUMERIC_NDIGITS(num) \
     489             :     ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
     490             : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
     491             :     ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
     492             :     (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
     493             :     (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
     494             : 
     495             : static void alloc_var(NumericVar *var, int ndigits);
     496             : static void free_var(NumericVar *var);
     497             : static void zero_var(NumericVar *var);
     498             : 
     499             : static bool set_var_from_str(const char *str, const char *cp,
     500             :                              NumericVar *dest, const char **endptr,
     501             :                              Node *escontext);
     502             : static bool set_var_from_non_decimal_integer_str(const char *str,
     503             :                                                  const char *cp, int sign,
     504             :                                                  int base, NumericVar *dest,
     505             :                                                  const char **endptr,
     506             :                                                  Node *escontext);
     507             : static void set_var_from_num(Numeric num, NumericVar *dest);
     508             : static void init_var_from_num(Numeric num, NumericVar *dest);
     509             : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
     510             : static char *get_str_from_var(const NumericVar *var);
     511             : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
     512             : 
     513             : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
     514             : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
     515             : 
     516             : static Numeric duplicate_numeric(Numeric num);
     517             : static Numeric make_result(const NumericVar *var);
     518             : static Numeric make_result_opt_error(const NumericVar *var, bool *have_error);
     519             : 
     520             : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
     521             : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
     522             : 
     523             : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
     524             : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
     525             : static void int64_to_numericvar(int64 val, NumericVar *var);
     526             : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
     527             : #ifdef HAVE_INT128
     528             : static bool numericvar_to_int128(const NumericVar *var, int128 *result);
     529             : static void int128_to_numericvar(int128 val, NumericVar *var);
     530             : #endif
     531             : static double numericvar_to_double_no_overflow(const NumericVar *var);
     532             : 
     533             : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
     534             : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
     535             : static int  numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
     536             : static int  numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
     537             : 
     538             : static Datum numeric_abbrev_convert_var(const NumericVar *var,
     539             :                                         NumericSortSupport *nss);
     540             : 
     541             : static int  cmp_numerics(Numeric num1, Numeric num2);
     542             : static int  cmp_var(const NumericVar *var1, const NumericVar *var2);
     543             : static int  cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
     544             :                            int var1weight, int var1sign,
     545             :                            const NumericDigit *var2digits, int var2ndigits,
     546             :                            int var2weight, int var2sign);
     547             : static void add_var(const NumericVar *var1, const NumericVar *var2,
     548             :                     NumericVar *result);
     549             : static void sub_var(const NumericVar *var1, const NumericVar *var2,
     550             :                     NumericVar *result);
     551             : static void mul_var(const NumericVar *var1, const NumericVar *var2,
     552             :                     NumericVar *result,
     553             :                     int rscale);
     554             : static void div_var(const NumericVar *var1, const NumericVar *var2,
     555             :                     NumericVar *result,
     556             :                     int rscale, bool round);
     557             : static void div_var_fast(const NumericVar *var1, const NumericVar *var2,
     558             :                          NumericVar *result, int rscale, bool round);
     559             : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
     560             :                         NumericVar *result, int rscale, bool round);
     561             : #ifdef HAVE_INT128
     562             : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
     563             :                           NumericVar *result, int rscale, bool round);
     564             : #endif
     565             : static int  select_div_scale(const NumericVar *var1, const NumericVar *var2);
     566             : static void mod_var(const NumericVar *var1, const NumericVar *var2,
     567             :                     NumericVar *result);
     568             : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
     569             :                         NumericVar *quot, NumericVar *rem);
     570             : static void ceil_var(const NumericVar *var, NumericVar *result);
     571             : static void floor_var(const NumericVar *var, NumericVar *result);
     572             : 
     573             : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
     574             :                     NumericVar *result);
     575             : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
     576             : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
     577             : static int  estimate_ln_dweight(const NumericVar *var);
     578             : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
     579             : static void log_var(const NumericVar *base, const NumericVar *num,
     580             :                     NumericVar *result);
     581             : static void power_var(const NumericVar *base, const NumericVar *exp,
     582             :                       NumericVar *result);
     583             : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
     584             :                           NumericVar *result);
     585             : static void power_ten_int(int exp, NumericVar *result);
     586             : static void random_var(pg_prng_state *state, const NumericVar *rmin,
     587             :                        const NumericVar *rmax, NumericVar *result);
     588             : 
     589             : static int  cmp_abs(const NumericVar *var1, const NumericVar *var2);
     590             : static int  cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
     591             :                            int var1weight,
     592             :                            const NumericDigit *var2digits, int var2ndigits,
     593             :                            int var2weight);
     594             : static void add_abs(const NumericVar *var1, const NumericVar *var2,
     595             :                     NumericVar *result);
     596             : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
     597             :                     NumericVar *result);
     598             : static void round_var(NumericVar *var, int rscale);
     599             : static void trunc_var(NumericVar *var, int rscale);
     600             : static void strip_var(NumericVar *var);
     601             : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
     602             :                            const NumericVar *count_var, bool reversed_bounds,
     603             :                            NumericVar *result_var);
     604             : 
     605             : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
     606             : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
     607             : static void accum_sum_carry(NumericSumAccum *accum);
     608             : static void accum_sum_reset(NumericSumAccum *accum);
     609             : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
     610             : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
     611             : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
     612             : 
     613             : 
     614             : /* ----------------------------------------------------------------------
     615             :  *
     616             :  * Input-, output- and rounding-functions
     617             :  *
     618             :  * ----------------------------------------------------------------------
     619             :  */
     620             : 
     621             : 
     622             : /*
     623             :  * numeric_in() -
     624             :  *
     625             :  *  Input function for numeric data type
     626             :  */
     627             : Datum
     628      106880 : numeric_in(PG_FUNCTION_ARGS)
     629             : {
     630      106880 :     char       *str = PG_GETARG_CSTRING(0);
     631             : #ifdef NOT_USED
     632             :     Oid         typelem = PG_GETARG_OID(1);
     633             : #endif
     634      106880 :     int32       typmod = PG_GETARG_INT32(2);
     635      106880 :     Node       *escontext = fcinfo->context;
     636             :     Numeric     res;
     637             :     const char *cp;
     638             :     const char *numstart;
     639             :     int         sign;
     640             : 
     641             :     /* Skip leading spaces */
     642      106880 :     cp = str;
     643      107264 :     while (*cp)
     644             :     {
     645      107252 :         if (!isspace((unsigned char) *cp))
     646      106868 :             break;
     647         384 :         cp++;
     648             :     }
     649             : 
     650             :     /*
     651             :      * Process the number's sign. This duplicates logic in set_var_from_str(),
     652             :      * but it's worth doing here, since it simplifies the handling of
     653             :      * infinities and non-decimal integers.
     654             :      */
     655      106880 :     numstart = cp;
     656      106880 :     sign = NUMERIC_POS;
     657             : 
     658      106880 :     if (*cp == '+')
     659          48 :         cp++;
     660      106832 :     else if (*cp == '-')
     661             :     {
     662        3674 :         sign = NUMERIC_NEG;
     663        3674 :         cp++;
     664             :     }
     665             : 
     666             :     /*
     667             :      * Check for NaN and infinities.  We recognize the same strings allowed by
     668             :      * float8in().
     669             :      *
     670             :      * Since all other legal inputs have a digit or a decimal point after the
     671             :      * sign, we need only check for NaN/infinity if that's not the case.
     672             :      */
     673      106880 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
     674             :     {
     675             :         /*
     676             :          * The number must be NaN or infinity; anything else can only be a
     677             :          * syntax error. Note that NaN mustn't have a sign.
     678             :          */
     679        1674 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
     680             :         {
     681         586 :             res = make_result(&const_nan);
     682         586 :             cp = numstart + 3;
     683             :         }
     684        1088 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
     685             :         {
     686         396 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     687         396 :             cp += 8;
     688             :         }
     689         692 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
     690             :         {
     691         588 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
     692         588 :             cp += 3;
     693             :         }
     694             :         else
     695         104 :             goto invalid_syntax;
     696             : 
     697             :         /*
     698             :          * Check for trailing junk; there should be nothing left but spaces.
     699             :          *
     700             :          * We intentionally do this check before applying the typmod because
     701             :          * we would like to throw any trailing-junk syntax error before any
     702             :          * semantic error resulting from apply_typmod_special().
     703             :          */
     704        1612 :         while (*cp)
     705             :         {
     706          42 :             if (!isspace((unsigned char) *cp))
     707           0 :                 goto invalid_syntax;
     708          42 :             cp++;
     709             :         }
     710             : 
     711        1570 :         if (!apply_typmod_special(res, typmod, escontext))
     712           0 :             PG_RETURN_NULL();
     713             :     }
     714             :     else
     715             :     {
     716             :         /*
     717             :          * We have a normal numeric value, which may be a non-decimal integer
     718             :          * or a regular decimal number.
     719             :          */
     720             :         NumericVar  value;
     721             :         int         base;
     722             :         bool        have_error;
     723             : 
     724      105206 :         init_var(&value);
     725             : 
     726             :         /*
     727             :          * Determine the number's base by looking for a non-decimal prefix
     728             :          * indicator ("0x", "0o", or "0b").
     729             :          */
     730      105206 :         if (cp[0] == '0')
     731             :         {
     732       27990 :             switch (cp[1])
     733             :             {
     734          72 :                 case 'x':
     735             :                 case 'X':
     736          72 :                     base = 16;
     737          72 :                     break;
     738          42 :                 case 'o':
     739             :                 case 'O':
     740          42 :                     base = 8;
     741          42 :                     break;
     742          42 :                 case 'b':
     743             :                 case 'B':
     744          42 :                     base = 2;
     745          42 :                     break;
     746       27834 :                 default:
     747       27834 :                     base = 10;
     748             :             }
     749             :         }
     750             :         else
     751       77216 :             base = 10;
     752             : 
     753             :         /* Parse the rest of the number and apply the sign */
     754      105206 :         if (base == 10)
     755             :         {
     756      105050 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
     757          42 :                 PG_RETURN_NULL();
     758      105002 :             value.sign = sign;
     759             :         }
     760             :         else
     761             :         {
     762         156 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
     763             :                                                       &value, &cp, escontext))
     764           0 :                 PG_RETURN_NULL();
     765             :         }
     766             : 
     767             :         /*
     768             :          * Should be nothing left but spaces. As above, throw any typmod error
     769             :          * after finishing syntax check.
     770             :          */
     771      105218 :         while (*cp)
     772             :         {
     773         150 :             if (!isspace((unsigned char) *cp))
     774          72 :                 goto invalid_syntax;
     775          78 :             cp++;
     776             :         }
     777             : 
     778      105068 :         if (!apply_typmod(&value, typmod, escontext))
     779          24 :             PG_RETURN_NULL();
     780             : 
     781      105044 :         res = make_result_opt_error(&value, &have_error);
     782             : 
     783      105044 :         if (have_error)
     784          18 :             ereturn(escontext, (Datum) 0,
     785             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     786             :                      errmsg("value overflows numeric format")));
     787             : 
     788      105026 :         free_var(&value);
     789             :     }
     790             : 
     791      106596 :     PG_RETURN_NUMERIC(res);
     792             : 
     793         176 : invalid_syntax:
     794         176 :     ereturn(escontext, (Datum) 0,
     795             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
     796             :              errmsg("invalid input syntax for type %s: \"%s\"",
     797             :                     "numeric", str)));
     798             : }
     799             : 
     800             : 
     801             : /*
     802             :  * numeric_out() -
     803             :  *
     804             :  *  Output function for numeric data type
     805             :  */
     806             : Datum
     807      784222 : numeric_out(PG_FUNCTION_ARGS)
     808             : {
     809      784222 :     Numeric     num = PG_GETARG_NUMERIC(0);
     810             :     NumericVar  x;
     811             :     char       *str;
     812             : 
     813             :     /*
     814             :      * Handle NaN and infinities
     815             :      */
     816      784222 :     if (NUMERIC_IS_SPECIAL(num))
     817             :     {
     818        3504 :         if (NUMERIC_IS_PINF(num))
     819         998 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
     820        2506 :         else if (NUMERIC_IS_NINF(num))
     821         616 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
     822             :         else
     823        1890 :             PG_RETURN_CSTRING(pstrdup("NaN"));
     824             :     }
     825             : 
     826             :     /*
     827             :      * Get the number in the variable format.
     828             :      */
     829      780718 :     init_var_from_num(num, &x);
     830             : 
     831      780718 :     str = get_str_from_var(&x);
     832             : 
     833      780718 :     PG_RETURN_CSTRING(str);
     834             : }
     835             : 
     836             : /*
     837             :  * numeric_is_nan() -
     838             :  *
     839             :  *  Is Numeric value a NaN?
     840             :  */
     841             : bool
     842       13890 : numeric_is_nan(Numeric num)
     843             : {
     844       13890 :     return NUMERIC_IS_NAN(num);
     845             : }
     846             : 
     847             : /*
     848             :  * numeric_is_inf() -
     849             :  *
     850             :  *  Is Numeric value an infinity?
     851             :  */
     852             : bool
     853         312 : numeric_is_inf(Numeric num)
     854             : {
     855         312 :     return NUMERIC_IS_INF(num);
     856             : }
     857             : 
     858             : /*
     859             :  * numeric_is_integral() -
     860             :  *
     861             :  *  Is Numeric value integral?
     862             :  */
     863             : static bool
     864          66 : numeric_is_integral(Numeric num)
     865             : {
     866             :     NumericVar  arg;
     867             : 
     868             :     /* Reject NaN, but infinities are considered integral */
     869          66 :     if (NUMERIC_IS_SPECIAL(num))
     870             :     {
     871          30 :         if (NUMERIC_IS_NAN(num))
     872           0 :             return false;
     873          30 :         return true;
     874             :     }
     875             : 
     876             :     /* Integral if there are no digits to the right of the decimal point */
     877          36 :     init_var_from_num(num, &arg);
     878             : 
     879          36 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
     880             : }
     881             : 
     882             : /*
     883             :  * make_numeric_typmod() -
     884             :  *
     885             :  *  Pack numeric precision and scale values into a typmod.  The upper 16 bits
     886             :  *  are used for the precision (though actually not all these bits are needed,
     887             :  *  since the maximum allowed precision is 1000).  The lower 16 bits are for
     888             :  *  the scale, but since the scale is constrained to the range [-1000, 1000],
     889             :  *  we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
     890             :  *  unset, for possible future use.
     891             :  *
     892             :  *  For purely historical reasons VARHDRSZ is then added to the result, thus
     893             :  *  the unused space in the upper 16 bits is not all as freely available as it
     894             :  *  might seem.  (We can't let the result overflow to a negative int32, as
     895             :  *  other parts of the system would interpret that as not-a-valid-typmod.)
     896             :  */
     897             : static inline int32
     898        1890 : make_numeric_typmod(int precision, int scale)
     899             : {
     900        1890 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
     901             : }
     902             : 
     903             : /*
     904             :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
     905             :  */
     906             : static inline bool
     907      130612 : is_valid_numeric_typmod(int32 typmod)
     908             : {
     909      130612 :     return typmod >= (int32) VARHDRSZ;
     910             : }
     911             : 
     912             : /*
     913             :  * numeric_typmod_precision() -
     914             :  *
     915             :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
     916             :  */
     917             : static inline int
     918       24704 : numeric_typmod_precision(int32 typmod)
     919             : {
     920       24704 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
     921             : }
     922             : 
     923             : /*
     924             :  * numeric_typmod_scale() -
     925             :  *
     926             :  *  Extract the scale from a numeric typmod --- see make_numeric_typmod().
     927             :  *
     928             :  *  Note that the scale may be negative, so we must do sign extension when
     929             :  *  unpacking it.  We do this using the bit hack (x^1024)-1024, which sign
     930             :  *  extends an 11-bit two's complement number x.
     931             :  */
     932             : static inline int
     933       17122 : numeric_typmod_scale(int32 typmod)
     934             : {
     935       17122 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
     936             : }
     937             : 
     938             : /*
     939             :  * numeric_maximum_size() -
     940             :  *
     941             :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
     942             :  */
     943             : int32
     944        7582 : numeric_maximum_size(int32 typmod)
     945             : {
     946             :     int         precision;
     947             :     int         numeric_digits;
     948             : 
     949        7582 :     if (!is_valid_numeric_typmod(typmod))
     950           0 :         return -1;
     951             : 
     952             :     /* precision (ie, max # of digits) is in upper bits of typmod */
     953        7582 :     precision = numeric_typmod_precision(typmod);
     954             : 
     955             :     /*
     956             :      * This formula computes the maximum number of NumericDigits we could need
     957             :      * in order to store the specified number of decimal digits. Because the
     958             :      * weight is stored as a number of NumericDigits rather than a number of
     959             :      * decimal digits, it's possible that the first NumericDigit will contain
     960             :      * only a single decimal digit.  Thus, the first two decimal digits can
     961             :      * require two NumericDigits to store, but it isn't until we reach
     962             :      * DEC_DIGITS + 2 decimal digits that we potentially need a third
     963             :      * NumericDigit.
     964             :      */
     965        7582 :     numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
     966             : 
     967             :     /*
     968             :      * In most cases, the size of a numeric will be smaller than the value
     969             :      * computed below, because the varlena header will typically get toasted
     970             :      * down to a single byte before being stored on disk, and it may also be
     971             :      * possible to use a short numeric header.  But our job here is to compute
     972             :      * the worst case.
     973             :      */
     974        7582 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
     975             : }
     976             : 
     977             : /*
     978             :  * numeric_out_sci() -
     979             :  *
     980             :  *  Output function for numeric data type in scientific notation.
     981             :  */
     982             : char *
     983         234 : numeric_out_sci(Numeric num, int scale)
     984             : {
     985             :     NumericVar  x;
     986             :     char       *str;
     987             : 
     988             :     /*
     989             :      * Handle NaN and infinities
     990             :      */
     991         234 :     if (NUMERIC_IS_SPECIAL(num))
     992             :     {
     993          18 :         if (NUMERIC_IS_PINF(num))
     994           6 :             return pstrdup("Infinity");
     995          12 :         else if (NUMERIC_IS_NINF(num))
     996           6 :             return pstrdup("-Infinity");
     997             :         else
     998           6 :             return pstrdup("NaN");
     999             :     }
    1000             : 
    1001         216 :     init_var_from_num(num, &x);
    1002             : 
    1003         216 :     str = get_str_from_var_sci(&x, scale);
    1004             : 
    1005         216 :     return str;
    1006             : }
    1007             : 
    1008             : /*
    1009             :  * numeric_normalize() -
    1010             :  *
    1011             :  *  Output function for numeric data type, suppressing insignificant trailing
    1012             :  *  zeroes and then any trailing decimal point.  The intent of this is to
    1013             :  *  produce strings that are equal if and only if the input numeric values
    1014             :  *  compare equal.
    1015             :  */
    1016             : char *
    1017       12966 : numeric_normalize(Numeric num)
    1018             : {
    1019             :     NumericVar  x;
    1020             :     char       *str;
    1021             :     int         last;
    1022             : 
    1023             :     /*
    1024             :      * Handle NaN and infinities
    1025             :      */
    1026       12966 :     if (NUMERIC_IS_SPECIAL(num))
    1027             :     {
    1028           0 :         if (NUMERIC_IS_PINF(num))
    1029           0 :             return pstrdup("Infinity");
    1030           0 :         else if (NUMERIC_IS_NINF(num))
    1031           0 :             return pstrdup("-Infinity");
    1032             :         else
    1033           0 :             return pstrdup("NaN");
    1034             :     }
    1035             : 
    1036       12966 :     init_var_from_num(num, &x);
    1037             : 
    1038       12966 :     str = get_str_from_var(&x);
    1039             : 
    1040             :     /* If there's no decimal point, there's certainly nothing to remove. */
    1041       12966 :     if (strchr(str, '.') != NULL)
    1042             :     {
    1043             :         /*
    1044             :          * Back up over trailing fractional zeroes.  Since there is a decimal
    1045             :          * point, this loop will terminate safely.
    1046             :          */
    1047          42 :         last = strlen(str) - 1;
    1048          84 :         while (str[last] == '0')
    1049          42 :             last--;
    1050             : 
    1051             :         /* We want to get rid of the decimal point too, if it's now last. */
    1052          42 :         if (str[last] == '.')
    1053          42 :             last--;
    1054             : 
    1055             :         /* Delete whatever we backed up over. */
    1056          42 :         str[last + 1] = '\0';
    1057             :     }
    1058             : 
    1059       12966 :     return str;
    1060             : }
    1061             : 
    1062             : /*
    1063             :  *      numeric_recv            - converts external binary format to numeric
    1064             :  *
    1065             :  * External format is a sequence of int16's:
    1066             :  * ndigits, weight, sign, dscale, NumericDigits.
    1067             :  */
    1068             : Datum
    1069         102 : numeric_recv(PG_FUNCTION_ARGS)
    1070             : {
    1071         102 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    1072             : 
    1073             : #ifdef NOT_USED
    1074             :     Oid         typelem = PG_GETARG_OID(1);
    1075             : #endif
    1076         102 :     int32       typmod = PG_GETARG_INT32(2);
    1077             :     NumericVar  value;
    1078             :     Numeric     res;
    1079             :     int         len,
    1080             :                 i;
    1081             : 
    1082         102 :     init_var(&value);
    1083             : 
    1084         102 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1085             : 
    1086         102 :     alloc_var(&value, len);
    1087             : 
    1088         102 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
    1089             :     /* we allow any int16 for weight --- OK? */
    1090             : 
    1091         102 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1092         102 :     if (!(value.sign == NUMERIC_POS ||
    1093           0 :           value.sign == NUMERIC_NEG ||
    1094           0 :           value.sign == NUMERIC_NAN ||
    1095           0 :           value.sign == NUMERIC_PINF ||
    1096           0 :           value.sign == NUMERIC_NINF))
    1097           0 :         ereport(ERROR,
    1098             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1099             :                  errmsg("invalid sign in external \"numeric\" value")));
    1100             : 
    1101         102 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
    1102         102 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
    1103           0 :         ereport(ERROR,
    1104             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1105             :                  errmsg("invalid scale in external \"numeric\" value")));
    1106             : 
    1107         274 :     for (i = 0; i < len; i++)
    1108             :     {
    1109         172 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
    1110             : 
    1111         172 :         if (d < 0 || d >= NBASE)
    1112           0 :             ereport(ERROR,
    1113             :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1114             :                      errmsg("invalid digit in external \"numeric\" value")));
    1115         172 :         value.digits[i] = d;
    1116             :     }
    1117             : 
    1118             :     /*
    1119             :      * If the given dscale would hide any digits, truncate those digits away.
    1120             :      * We could alternatively throw an error, but that would take a bunch of
    1121             :      * extra code (about as much as trunc_var involves), and it might cause
    1122             :      * client compatibility issues.  Be careful not to apply trunc_var to
    1123             :      * special values, as it could do the wrong thing; we don't need it
    1124             :      * anyway, since make_result will ignore all but the sign field.
    1125             :      *
    1126             :      * After doing that, be sure to check the typmod restriction.
    1127             :      */
    1128         102 :     if (value.sign == NUMERIC_POS ||
    1129           0 :         value.sign == NUMERIC_NEG)
    1130             :     {
    1131         102 :         trunc_var(&value, value.dscale);
    1132             : 
    1133         102 :         (void) apply_typmod(&value, typmod, NULL);
    1134             : 
    1135         102 :         res = make_result(&value);
    1136             :     }
    1137             :     else
    1138             :     {
    1139             :         /* apply_typmod_special wants us to make the Numeric first */
    1140           0 :         res = make_result(&value);
    1141             : 
    1142           0 :         (void) apply_typmod_special(res, typmod, NULL);
    1143             :     }
    1144             : 
    1145         102 :     free_var(&value);
    1146             : 
    1147         102 :     PG_RETURN_NUMERIC(res);
    1148             : }
    1149             : 
    1150             : /*
    1151             :  *      numeric_send            - converts numeric to binary format
    1152             :  */
    1153             : Datum
    1154          70 : numeric_send(PG_FUNCTION_ARGS)
    1155             : {
    1156          70 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1157             :     NumericVar  x;
    1158             :     StringInfoData buf;
    1159             :     int         i;
    1160             : 
    1161          70 :     init_var_from_num(num, &x);
    1162             : 
    1163          70 :     pq_begintypsend(&buf);
    1164             : 
    1165          70 :     pq_sendint16(&buf, x.ndigits);
    1166          70 :     pq_sendint16(&buf, x.weight);
    1167          70 :     pq_sendint16(&buf, x.sign);
    1168          70 :     pq_sendint16(&buf, x.dscale);
    1169         194 :     for (i = 0; i < x.ndigits; i++)
    1170         124 :         pq_sendint16(&buf, x.digits[i]);
    1171             : 
    1172          70 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
    1173             : }
    1174             : 
    1175             : 
    1176             : /*
    1177             :  * numeric_support()
    1178             :  *
    1179             :  * Planner support function for the numeric() length coercion function.
    1180             :  *
    1181             :  * Flatten calls that solely represent increases in allowable precision.
    1182             :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
    1183             :  * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
    1184             :  * an unconstrained numeric to any constrained numeric is also unoptimizable.
    1185             :  */
    1186             : Datum
    1187         516 : numeric_support(PG_FUNCTION_ARGS)
    1188             : {
    1189         516 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
    1190         516 :     Node       *ret = NULL;
    1191             : 
    1192         516 :     if (IsA(rawreq, SupportRequestSimplify))
    1193             :     {
    1194         228 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
    1195         228 :         FuncExpr   *expr = req->fcall;
    1196             :         Node       *typmod;
    1197             : 
    1198             :         Assert(list_length(expr->args) >= 2);
    1199             : 
    1200         228 :         typmod = (Node *) lsecond(expr->args);
    1201             : 
    1202         228 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
    1203             :         {
    1204         228 :             Node       *source = (Node *) linitial(expr->args);
    1205         228 :             int32       old_typmod = exprTypmod(source);
    1206         228 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
    1207         228 :             int32       old_scale = numeric_typmod_scale(old_typmod);
    1208         228 :             int32       new_scale = numeric_typmod_scale(new_typmod);
    1209         228 :             int32       old_precision = numeric_typmod_precision(old_typmod);
    1210         228 :             int32       new_precision = numeric_typmod_precision(new_typmod);
    1211             : 
    1212             :             /*
    1213             :              * If new_typmod is invalid, the destination is unconstrained;
    1214             :              * that's always OK.  If old_typmod is valid, the source is
    1215             :              * constrained, and we're OK if the scale is unchanged and the
    1216             :              * precision is not decreasing.  See further notes in function
    1217             :              * header comment.
    1218             :              */
    1219         456 :             if (!is_valid_numeric_typmod(new_typmod) ||
    1220         240 :                 (is_valid_numeric_typmod(old_typmod) &&
    1221           6 :                  new_scale == old_scale && new_precision >= old_precision))
    1222           6 :                 ret = relabel_to_typmod(source, new_typmod);
    1223             :         }
    1224             :     }
    1225             : 
    1226         516 :     PG_RETURN_POINTER(ret);
    1227             : }
    1228             : 
    1229             : /*
    1230             :  * numeric() -
    1231             :  *
    1232             :  *  This is a special function called by the Postgres database system
    1233             :  *  before a value is stored in a tuple's attribute. The precision and
    1234             :  *  scale of the attribute have to be applied on the value.
    1235             :  */
    1236             : Datum
    1237       11790 : numeric     (PG_FUNCTION_ARGS)
    1238             : {
    1239       11790 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1240       11790 :     int32       typmod = PG_GETARG_INT32(1);
    1241             :     Numeric     new;
    1242             :     int         precision;
    1243             :     int         scale;
    1244             :     int         ddigits;
    1245             :     int         maxdigits;
    1246             :     int         dscale;
    1247             :     NumericVar  var;
    1248             : 
    1249             :     /*
    1250             :      * Handle NaN and infinities: if apply_typmod_special doesn't complain,
    1251             :      * just return a copy of the input.
    1252             :      */
    1253       11790 :     if (NUMERIC_IS_SPECIAL(num))
    1254             :     {
    1255         210 :         (void) apply_typmod_special(num, typmod, NULL);
    1256         192 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1257             :     }
    1258             : 
    1259             :     /*
    1260             :      * If the value isn't a valid type modifier, simply return a copy of the
    1261             :      * input value
    1262             :      */
    1263       11580 :     if (!is_valid_numeric_typmod(typmod))
    1264           0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1265             : 
    1266             :     /*
    1267             :      * Get the precision and scale out of the typmod value
    1268             :      */
    1269       11580 :     precision = numeric_typmod_precision(typmod);
    1270       11580 :     scale = numeric_typmod_scale(typmod);
    1271       11580 :     maxdigits = precision - scale;
    1272             : 
    1273             :     /* The target display scale is non-negative */
    1274       11580 :     dscale = Max(scale, 0);
    1275             : 
    1276             :     /*
    1277             :      * If the number is certainly in bounds and due to the target scale no
    1278             :      * rounding could be necessary, just make a copy of the input and modify
    1279             :      * its scale fields, unless the larger scale forces us to abandon the
    1280             :      * short representation.  (Note we assume the existing dscale is
    1281             :      * honest...)
    1282             :      */
    1283       11580 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
    1284       11580 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
    1285        7134 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
    1286           0 :             || !NUMERIC_IS_SHORT(num)))
    1287             :     {
    1288        7134 :         new = duplicate_numeric(num);
    1289        7134 :         if (NUMERIC_IS_SHORT(num))
    1290        7134 :             new->choice.n_short.n_header =
    1291        7134 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
    1292        7134 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
    1293             :         else
    1294           0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
    1295           0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
    1296        7134 :         PG_RETURN_NUMERIC(new);
    1297             :     }
    1298             : 
    1299             :     /*
    1300             :      * We really need to fiddle with things - unpack the number into a
    1301             :      * variable and let apply_typmod() do it.
    1302             :      */
    1303        4446 :     init_var(&var);
    1304             : 
    1305        4446 :     set_var_from_num(num, &var);
    1306        4446 :     (void) apply_typmod(&var, typmod, NULL);
    1307        4386 :     new = make_result(&var);
    1308             : 
    1309        4386 :     free_var(&var);
    1310             : 
    1311        4386 :     PG_RETURN_NUMERIC(new);
    1312             : }
    1313             : 
    1314             : Datum
    1315        1932 : numerictypmodin(PG_FUNCTION_ARGS)
    1316             : {
    1317        1932 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
    1318             :     int32      *tl;
    1319             :     int         n;
    1320             :     int32       typmod;
    1321             : 
    1322        1932 :     tl = ArrayGetIntegerTypmods(ta, &n);
    1323             : 
    1324        1932 :     if (n == 2)
    1325             :     {
    1326        1912 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1327          18 :             ereport(ERROR,
    1328             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1329             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1330             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1331        1894 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
    1332          12 :             ereport(ERROR,
    1333             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1334             :                      errmsg("NUMERIC scale %d must be between %d and %d",
    1335             :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
    1336        1882 :         typmod = make_numeric_typmod(tl[0], tl[1]);
    1337             :     }
    1338          20 :     else if (n == 1)
    1339             :     {
    1340           8 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
    1341           0 :             ereport(ERROR,
    1342             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1343             :                      errmsg("NUMERIC precision %d must be between 1 and %d",
    1344             :                             tl[0], NUMERIC_MAX_PRECISION)));
    1345             :         /* scale defaults to zero */
    1346           8 :         typmod = make_numeric_typmod(tl[0], 0);
    1347             :     }
    1348             :     else
    1349             :     {
    1350          12 :         ereport(ERROR,
    1351             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1352             :                  errmsg("invalid NUMERIC type modifier")));
    1353             :         typmod = 0;             /* keep compiler quiet */
    1354             :     }
    1355             : 
    1356        1890 :     PG_RETURN_INT32(typmod);
    1357             : }
    1358             : 
    1359             : Datum
    1360         376 : numerictypmodout(PG_FUNCTION_ARGS)
    1361             : {
    1362         376 :     int32       typmod = PG_GETARG_INT32(0);
    1363         376 :     char       *res = (char *) palloc(64);
    1364             : 
    1365         376 :     if (is_valid_numeric_typmod(typmod))
    1366         376 :         snprintf(res, 64, "(%d,%d)",
    1367             :                  numeric_typmod_precision(typmod),
    1368             :                  numeric_typmod_scale(typmod));
    1369             :     else
    1370           0 :         *res = '\0';
    1371             : 
    1372         376 :     PG_RETURN_CSTRING(res);
    1373             : }
    1374             : 
    1375             : 
    1376             : /* ----------------------------------------------------------------------
    1377             :  *
    1378             :  * Sign manipulation, rounding and the like
    1379             :  *
    1380             :  * ----------------------------------------------------------------------
    1381             :  */
    1382             : 
    1383             : Datum
    1384       19506 : numeric_abs(PG_FUNCTION_ARGS)
    1385             : {
    1386       19506 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1387             :     Numeric     res;
    1388             : 
    1389             :     /*
    1390             :      * Do it the easy way directly on the packed format
    1391             :      */
    1392       19506 :     res = duplicate_numeric(num);
    1393             : 
    1394       19506 :     if (NUMERIC_IS_SHORT(num))
    1395       19440 :         res->choice.n_short.n_header =
    1396       19440 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
    1397          66 :     else if (NUMERIC_IS_SPECIAL(num))
    1398             :     {
    1399             :         /* This changes -Inf to Inf, and doesn't affect NaN */
    1400          18 :         res->choice.n_short.n_header =
    1401          18 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
    1402             :     }
    1403             :     else
    1404          48 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
    1405             : 
    1406       19506 :     PG_RETURN_NUMERIC(res);
    1407             : }
    1408             : 
    1409             : 
    1410             : Datum
    1411         884 : numeric_uminus(PG_FUNCTION_ARGS)
    1412             : {
    1413         884 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1414             :     Numeric     res;
    1415             : 
    1416             :     /*
    1417             :      * Do it the easy way directly on the packed format
    1418             :      */
    1419         884 :     res = duplicate_numeric(num);
    1420             : 
    1421         884 :     if (NUMERIC_IS_SPECIAL(num))
    1422             :     {
    1423             :         /* Flip the sign, if it's Inf or -Inf */
    1424         126 :         if (!NUMERIC_IS_NAN(num))
    1425          84 :             res->choice.n_short.n_header =
    1426          84 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
    1427             :     }
    1428             : 
    1429             :     /*
    1430             :      * The packed format is known to be totally zero digit trimmed always. So
    1431             :      * once we've eliminated specials, we can identify a zero by the fact that
    1432             :      * there are no digits at all. Do nothing to a zero.
    1433             :      */
    1434         758 :     else if (NUMERIC_NDIGITS(num) != 0)
    1435             :     {
    1436             :         /* Else, flip the sign */
    1437         644 :         if (NUMERIC_IS_SHORT(num))
    1438         644 :             res->choice.n_short.n_header =
    1439         644 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
    1440           0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
    1441           0 :             res->choice.n_long.n_sign_dscale =
    1442           0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
    1443             :         else
    1444           0 :             res->choice.n_long.n_sign_dscale =
    1445           0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
    1446             :     }
    1447             : 
    1448         884 :     PG_RETURN_NUMERIC(res);
    1449             : }
    1450             : 
    1451             : 
    1452             : Datum
    1453         498 : numeric_uplus(PG_FUNCTION_ARGS)
    1454             : {
    1455         498 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1456             : 
    1457         498 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
    1458             : }
    1459             : 
    1460             : 
    1461             : /*
    1462             :  * numeric_sign_internal() -
    1463             :  *
    1464             :  * Returns -1 if the argument is less than 0, 0 if the argument is equal
    1465             :  * to 0, and 1 if the argument is greater than zero.  Caller must have
    1466             :  * taken care of the NaN case, but we can handle infinities here.
    1467             :  */
    1468             : static int
    1469        3546 : numeric_sign_internal(Numeric num)
    1470             : {
    1471        3546 :     if (NUMERIC_IS_SPECIAL(num))
    1472             :     {
    1473             :         Assert(!NUMERIC_IS_NAN(num));
    1474             :         /* Must be Inf or -Inf */
    1475         312 :         if (NUMERIC_IS_PINF(num))
    1476         186 :             return 1;
    1477             :         else
    1478         126 :             return -1;
    1479             :     }
    1480             : 
    1481             :     /*
    1482             :      * The packed format is known to be totally zero digit trimmed always. So
    1483             :      * once we've eliminated specials, we can identify a zero by the fact that
    1484             :      * there are no digits at all.
    1485             :      */
    1486        3234 :     else if (NUMERIC_NDIGITS(num) == 0)
    1487         228 :         return 0;
    1488        3006 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
    1489         726 :         return -1;
    1490             :     else
    1491        2280 :         return 1;
    1492             : }
    1493             : 
    1494             : /*
    1495             :  * numeric_sign() -
    1496             :  *
    1497             :  * returns -1 if the argument is less than 0, 0 if the argument is equal
    1498             :  * to 0, and 1 if the argument is greater than zero.
    1499             :  */
    1500             : Datum
    1501          48 : numeric_sign(PG_FUNCTION_ARGS)
    1502             : {
    1503          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1504             : 
    1505             :     /*
    1506             :      * Handle NaN (infinities can be handled normally)
    1507             :      */
    1508          48 :     if (NUMERIC_IS_NAN(num))
    1509           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    1510             : 
    1511          42 :     switch (numeric_sign_internal(num))
    1512             :     {
    1513           6 :         case 0:
    1514           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    1515          18 :         case 1:
    1516          18 :             PG_RETURN_NUMERIC(make_result(&const_one));
    1517          18 :         case -1:
    1518          18 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
    1519             :     }
    1520             : 
    1521             :     Assert(false);
    1522           0 :     return (Datum) 0;
    1523             : }
    1524             : 
    1525             : 
    1526             : /*
    1527             :  * numeric_round() -
    1528             :  *
    1529             :  *  Round a value to have 'scale' digits after the decimal point.
    1530             :  *  We allow negative 'scale', implying rounding before the decimal
    1531             :  *  point --- Oracle interprets rounding that way.
    1532             :  */
    1533             : Datum
    1534        7742 : numeric_round(PG_FUNCTION_ARGS)
    1535             : {
    1536        7742 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1537        7742 :     int32       scale = PG_GETARG_INT32(1);
    1538             :     Numeric     res;
    1539             :     NumericVar  arg;
    1540             : 
    1541             :     /*
    1542             :      * Handle NaN and infinities
    1543             :      */
    1544        7742 :     if (NUMERIC_IS_SPECIAL(num))
    1545          96 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1546             : 
    1547             :     /*
    1548             :      * Limit the scale value to avoid possible overflow in calculations
    1549             :      */
    1550        7646 :     scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
    1551        7646 :     scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
    1552             : 
    1553             :     /*
    1554             :      * Unpack the argument and round it at the proper digit position
    1555             :      */
    1556        7646 :     init_var(&arg);
    1557        7646 :     set_var_from_num(num, &arg);
    1558             : 
    1559        7646 :     round_var(&arg, scale);
    1560             : 
    1561             :     /* We don't allow negative output dscale */
    1562        7646 :     if (scale < 0)
    1563         180 :         arg.dscale = 0;
    1564             : 
    1565             :     /*
    1566             :      * Return the rounded result
    1567             :      */
    1568        7646 :     res = make_result(&arg);
    1569             : 
    1570        7646 :     free_var(&arg);
    1571        7646 :     PG_RETURN_NUMERIC(res);
    1572             : }
    1573             : 
    1574             : 
    1575             : /*
    1576             :  * numeric_trunc() -
    1577             :  *
    1578             :  *  Truncate a value to have 'scale' digits after the decimal point.
    1579             :  *  We allow negative 'scale', implying a truncation before the decimal
    1580             :  *  point --- Oracle interprets truncation that way.
    1581             :  */
    1582             : Datum
    1583         578 : numeric_trunc(PG_FUNCTION_ARGS)
    1584             : {
    1585         578 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1586         578 :     int32       scale = PG_GETARG_INT32(1);
    1587             :     Numeric     res;
    1588             :     NumericVar  arg;
    1589             : 
    1590             :     /*
    1591             :      * Handle NaN and infinities
    1592             :      */
    1593         578 :     if (NUMERIC_IS_SPECIAL(num))
    1594          36 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1595             : 
    1596             :     /*
    1597             :      * Limit the scale value to avoid possible overflow in calculations
    1598             :      */
    1599         542 :     scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
    1600         542 :     scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
    1601             : 
    1602             :     /*
    1603             :      * Unpack the argument and truncate it at the proper digit position
    1604             :      */
    1605         542 :     init_var(&arg);
    1606         542 :     set_var_from_num(num, &arg);
    1607             : 
    1608         542 :     trunc_var(&arg, scale);
    1609             : 
    1610             :     /* We don't allow negative output dscale */
    1611         542 :     if (scale < 0)
    1612           0 :         arg.dscale = 0;
    1613             : 
    1614             :     /*
    1615             :      * Return the truncated result
    1616             :      */
    1617         542 :     res = make_result(&arg);
    1618             : 
    1619         542 :     free_var(&arg);
    1620         542 :     PG_RETURN_NUMERIC(res);
    1621             : }
    1622             : 
    1623             : 
    1624             : /*
    1625             :  * numeric_ceil() -
    1626             :  *
    1627             :  *  Return the smallest integer greater than or equal to the argument
    1628             :  */
    1629             : Datum
    1630         222 : numeric_ceil(PG_FUNCTION_ARGS)
    1631             : {
    1632         222 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1633             :     Numeric     res;
    1634             :     NumericVar  result;
    1635             : 
    1636             :     /*
    1637             :      * Handle NaN and infinities
    1638             :      */
    1639         222 :     if (NUMERIC_IS_SPECIAL(num))
    1640          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1641             : 
    1642         204 :     init_var_from_num(num, &result);
    1643         204 :     ceil_var(&result, &result);
    1644             : 
    1645         204 :     res = make_result(&result);
    1646         204 :     free_var(&result);
    1647             : 
    1648         204 :     PG_RETURN_NUMERIC(res);
    1649             : }
    1650             : 
    1651             : 
    1652             : /*
    1653             :  * numeric_floor() -
    1654             :  *
    1655             :  *  Return the largest integer equal to or less than the argument
    1656             :  */
    1657             : Datum
    1658         126 : numeric_floor(PG_FUNCTION_ARGS)
    1659             : {
    1660         126 :     Numeric     num = PG_GETARG_NUMERIC(0);
    1661             :     Numeric     res;
    1662             :     NumericVar  result;
    1663             : 
    1664             :     /*
    1665             :      * Handle NaN and infinities
    1666             :      */
    1667         126 :     if (NUMERIC_IS_SPECIAL(num))
    1668          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    1669             : 
    1670         108 :     init_var_from_num(num, &result);
    1671         108 :     floor_var(&result, &result);
    1672             : 
    1673         108 :     res = make_result(&result);
    1674         108 :     free_var(&result);
    1675             : 
    1676         108 :     PG_RETURN_NUMERIC(res);
    1677             : }
    1678             : 
    1679             : 
    1680             : /*
    1681             :  * generate_series_numeric() -
    1682             :  *
    1683             :  *  Generate series of numeric.
    1684             :  */
    1685             : Datum
    1686         216 : generate_series_numeric(PG_FUNCTION_ARGS)
    1687             : {
    1688         216 :     return generate_series_step_numeric(fcinfo);
    1689             : }
    1690             : 
    1691             : Datum
    1692         420 : generate_series_step_numeric(PG_FUNCTION_ARGS)
    1693             : {
    1694             :     generate_series_numeric_fctx *fctx;
    1695             :     FuncCallContext *funcctx;
    1696             :     MemoryContext oldcontext;
    1697             : 
    1698         420 :     if (SRF_IS_FIRSTCALL())
    1699             :     {
    1700         138 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
    1701         138 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
    1702         138 :         NumericVar  steploc = const_one;
    1703             : 
    1704             :         /* Reject NaN and infinities in start and stop values */
    1705         138 :         if (NUMERIC_IS_SPECIAL(start_num))
    1706             :         {
    1707          12 :             if (NUMERIC_IS_NAN(start_num))
    1708           6 :                 ereport(ERROR,
    1709             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1710             :                          errmsg("start value cannot be NaN")));
    1711             :             else
    1712           6 :                 ereport(ERROR,
    1713             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1714             :                          errmsg("start value cannot be infinity")));
    1715             :         }
    1716         126 :         if (NUMERIC_IS_SPECIAL(stop_num))
    1717             :         {
    1718          12 :             if (NUMERIC_IS_NAN(stop_num))
    1719           6 :                 ereport(ERROR,
    1720             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1721             :                          errmsg("stop value cannot be NaN")));
    1722             :             else
    1723           6 :                 ereport(ERROR,
    1724             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1725             :                          errmsg("stop value cannot be infinity")));
    1726             :         }
    1727             : 
    1728             :         /* see if we were given an explicit step size */
    1729         114 :         if (PG_NARGS() == 3)
    1730             :         {
    1731          54 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
    1732             : 
    1733          54 :             if (NUMERIC_IS_SPECIAL(step_num))
    1734             :             {
    1735          12 :                 if (NUMERIC_IS_NAN(step_num))
    1736           6 :                     ereport(ERROR,
    1737             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1738             :                              errmsg("step size cannot be NaN")));
    1739             :                 else
    1740           6 :                     ereport(ERROR,
    1741             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1742             :                              errmsg("step size cannot be infinity")));
    1743             :             }
    1744             : 
    1745          42 :             init_var_from_num(step_num, &steploc);
    1746             : 
    1747          42 :             if (cmp_var(&steploc, &const_zero) == 0)
    1748           6 :                 ereport(ERROR,
    1749             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1750             :                          errmsg("step size cannot equal zero")));
    1751             :         }
    1752             : 
    1753             :         /* create a function context for cross-call persistence */
    1754          96 :         funcctx = SRF_FIRSTCALL_INIT();
    1755             : 
    1756             :         /*
    1757             :          * Switch to memory context appropriate for multiple function calls.
    1758             :          */
    1759          96 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1760             : 
    1761             :         /* allocate memory for user context */
    1762             :         fctx = (generate_series_numeric_fctx *)
    1763          96 :             palloc(sizeof(generate_series_numeric_fctx));
    1764             : 
    1765             :         /*
    1766             :          * Use fctx to keep state from call to call. Seed current with the
    1767             :          * original start value. We must copy the start_num and stop_num
    1768             :          * values rather than pointing to them, since we may have detoasted
    1769             :          * them in the per-call context.
    1770             :          */
    1771          96 :         init_var(&fctx->current);
    1772          96 :         init_var(&fctx->stop);
    1773          96 :         init_var(&fctx->step);
    1774             : 
    1775          96 :         set_var_from_num(start_num, &fctx->current);
    1776          96 :         set_var_from_num(stop_num, &fctx->stop);
    1777          96 :         set_var_from_var(&steploc, &fctx->step);
    1778             : 
    1779          96 :         funcctx->user_fctx = fctx;
    1780          96 :         MemoryContextSwitchTo(oldcontext);
    1781             :     }
    1782             : 
    1783             :     /* stuff done on every call of the function */
    1784         378 :     funcctx = SRF_PERCALL_SETUP();
    1785             : 
    1786             :     /*
    1787             :      * Get the saved state and use current state as the result of this
    1788             :      * iteration.
    1789             :      */
    1790         378 :     fctx = funcctx->user_fctx;
    1791             : 
    1792         732 :     if ((fctx->step.sign == NUMERIC_POS &&
    1793         354 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
    1794         138 :         (fctx->step.sign == NUMERIC_NEG &&
    1795          24 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
    1796             :     {
    1797         282 :         Numeric     result = make_result(&fctx->current);
    1798             : 
    1799             :         /* switch to memory context appropriate for iteration calculation */
    1800         282 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
    1801             : 
    1802             :         /* increment current in preparation for next iteration */
    1803         282 :         add_var(&fctx->current, &fctx->step, &fctx->current);
    1804         282 :         MemoryContextSwitchTo(oldcontext);
    1805             : 
    1806             :         /* do when there is more left to send */
    1807         282 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
    1808             :     }
    1809             :     else
    1810             :         /* do when there is no more left */
    1811          96 :         SRF_RETURN_DONE(funcctx);
    1812             : }
    1813             : 
    1814             : 
    1815             : /*
    1816             :  * Implements the numeric version of the width_bucket() function
    1817             :  * defined by SQL2003. See also width_bucket_float8().
    1818             :  *
    1819             :  * 'bound1' and 'bound2' are the lower and upper bounds of the
    1820             :  * histogram's range, respectively. 'count' is the number of buckets
    1821             :  * in the histogram. width_bucket() returns an integer indicating the
    1822             :  * bucket number that 'operand' belongs to in an equiwidth histogram
    1823             :  * with the specified characteristics. An operand smaller than the
    1824             :  * lower bound is assigned to bucket 0. An operand greater than the
    1825             :  * upper bound is assigned to an additional bucket (with number
    1826             :  * count+1). We don't allow "NaN" for any of the numeric arguments.
    1827             :  */
    1828             : Datum
    1829         780 : width_bucket_numeric(PG_FUNCTION_ARGS)
    1830             : {
    1831         780 :     Numeric     operand = PG_GETARG_NUMERIC(0);
    1832         780 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
    1833         780 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
    1834         780 :     int32       count = PG_GETARG_INT32(3);
    1835             :     NumericVar  count_var;
    1836             :     NumericVar  result_var;
    1837             :     int32       result;
    1838             : 
    1839         780 :     if (count <= 0)
    1840          12 :         ereport(ERROR,
    1841             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1842             :                  errmsg("count must be greater than zero")));
    1843             : 
    1844         768 :     if (NUMERIC_IS_SPECIAL(operand) ||
    1845         750 :         NUMERIC_IS_SPECIAL(bound1) ||
    1846         744 :         NUMERIC_IS_SPECIAL(bound2))
    1847             :     {
    1848          36 :         if (NUMERIC_IS_NAN(operand) ||
    1849          30 :             NUMERIC_IS_NAN(bound1) ||
    1850          30 :             NUMERIC_IS_NAN(bound2))
    1851           6 :             ereport(ERROR,
    1852             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1853             :                      errmsg("operand, lower bound, and upper bound cannot be NaN")));
    1854             :         /* We allow "operand" to be infinite; cmp_numerics will cope */
    1855          30 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
    1856          18 :             ereport(ERROR,
    1857             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1858             :                      errmsg("lower and upper bounds must be finite")));
    1859             :     }
    1860             : 
    1861         744 :     init_var(&result_var);
    1862         744 :     init_var(&count_var);
    1863             : 
    1864             :     /* Convert 'count' to a numeric, for ease of use later */
    1865         744 :     int64_to_numericvar((int64) count, &count_var);
    1866             : 
    1867         744 :     switch (cmp_numerics(bound1, bound2))
    1868             :     {
    1869           6 :         case 0:
    1870           6 :             ereport(ERROR,
    1871             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
    1872             :                      errmsg("lower bound cannot equal upper bound")));
    1873             :             break;
    1874             : 
    1875             :             /* bound1 < bound2 */
    1876         546 :         case -1:
    1877         546 :             if (cmp_numerics(operand, bound1) < 0)
    1878         114 :                 set_var_from_var(&const_zero, &result_var);
    1879         432 :             else if (cmp_numerics(operand, bound2) >= 0)
    1880         108 :                 add_var(&count_var, &const_one, &result_var);
    1881             :             else
    1882         324 :                 compute_bucket(operand, bound1, bound2, &count_var, false,
    1883             :                                &result_var);
    1884         546 :             break;
    1885             : 
    1886             :             /* bound1 > bound2 */
    1887         192 :         case 1:
    1888         192 :             if (cmp_numerics(operand, bound1) > 0)
    1889          12 :                 set_var_from_var(&const_zero, &result_var);
    1890         180 :             else if (cmp_numerics(operand, bound2) <= 0)
    1891          24 :                 add_var(&count_var, &const_one, &result_var);
    1892             :             else
    1893         156 :                 compute_bucket(operand, bound1, bound2, &count_var, true,
    1894             :                                &result_var);
    1895         192 :             break;
    1896             :     }
    1897             : 
    1898             :     /* if result exceeds the range of a legal int4, we ereport here */
    1899         738 :     if (!numericvar_to_int32(&result_var, &result))
    1900           0 :         ereport(ERROR,
    1901             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    1902             :                  errmsg("integer out of range")));
    1903             : 
    1904         738 :     free_var(&count_var);
    1905         738 :     free_var(&result_var);
    1906             : 
    1907         738 :     PG_RETURN_INT32(result);
    1908             : }
    1909             : 
    1910             : /*
    1911             :  * 'operand' is inside the bucket range, so determine the correct
    1912             :  * bucket for it to go. The calculations performed by this function
    1913             :  * are derived directly from the SQL2003 spec. Note however that we
    1914             :  * multiply by count before dividing, to avoid unnecessary roundoff error.
    1915             :  */
    1916             : static void
    1917         480 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
    1918             :                const NumericVar *count_var, bool reversed_bounds,
    1919             :                NumericVar *result_var)
    1920             : {
    1921             :     NumericVar  bound1_var;
    1922             :     NumericVar  bound2_var;
    1923             :     NumericVar  operand_var;
    1924             : 
    1925         480 :     init_var_from_num(bound1, &bound1_var);
    1926         480 :     init_var_from_num(bound2, &bound2_var);
    1927         480 :     init_var_from_num(operand, &operand_var);
    1928             : 
    1929         480 :     if (!reversed_bounds)
    1930             :     {
    1931         324 :         sub_var(&operand_var, &bound1_var, &operand_var);
    1932         324 :         sub_var(&bound2_var, &bound1_var, &bound2_var);
    1933             :     }
    1934             :     else
    1935             :     {
    1936         156 :         sub_var(&bound1_var, &operand_var, &operand_var);
    1937         156 :         sub_var(&bound1_var, &bound2_var, &bound2_var);
    1938             :     }
    1939             : 
    1940         480 :     mul_var(&operand_var, count_var, &operand_var,
    1941         480 :             operand_var.dscale + count_var->dscale);
    1942         480 :     div_var(&operand_var, &bound2_var, result_var,
    1943             :             select_div_scale(&operand_var, &bound2_var), true);
    1944             : 
    1945             :     /*
    1946             :      * Roundoff in the division could give us a quotient exactly equal to
    1947             :      * "count", which is too large.  Clamp so that we do not emit a result
    1948             :      * larger than "count".
    1949             :      */
    1950         480 :     if (cmp_var(result_var, count_var) >= 0)
    1951          12 :         set_var_from_var(count_var, result_var);
    1952             :     else
    1953             :     {
    1954         468 :         add_var(result_var, &const_one, result_var);
    1955         468 :         floor_var(result_var, result_var);
    1956             :     }
    1957             : 
    1958         480 :     free_var(&bound1_var);
    1959         480 :     free_var(&bound2_var);
    1960         480 :     free_var(&operand_var);
    1961         480 : }
    1962             : 
    1963             : /* ----------------------------------------------------------------------
    1964             :  *
    1965             :  * Comparison functions
    1966             :  *
    1967             :  * Note: btree indexes need these routines not to leak memory; therefore,
    1968             :  * be careful to free working copies of toasted datums.  Most places don't
    1969             :  * need to be so careful.
    1970             :  *
    1971             :  * Sort support:
    1972             :  *
    1973             :  * We implement the sortsupport strategy routine in order to get the benefit of
    1974             :  * abbreviation. The ordinary numeric comparison can be quite slow as a result
    1975             :  * of palloc/pfree cycles (due to detoasting packed values for alignment);
    1976             :  * while this could be worked on itself, the abbreviation strategy gives more
    1977             :  * speedup in many common cases.
    1978             :  *
    1979             :  * Two different representations are used for the abbreviated form, one in
    1980             :  * int32 and one in int64, whichever fits into a by-value Datum.  In both cases
    1981             :  * the representation is negated relative to the original value, because we use
    1982             :  * the largest negative value for NaN, which sorts higher than other values. We
    1983             :  * convert the absolute value of the numeric to a 31-bit or 63-bit positive
    1984             :  * value, and then negate it if the original number was positive.
    1985             :  *
    1986             :  * We abort the abbreviation process if the abbreviation cardinality is below
    1987             :  * 0.01% of the row count (1 per 10k non-null rows).  The actual break-even
    1988             :  * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
    1989             :  * very small penalty), but we don't want to build up too many abbreviated
    1990             :  * values before first testing for abort, so we take the slightly pessimistic
    1991             :  * number.  We make no attempt to estimate the cardinality of the real values,
    1992             :  * since it plays no part in the cost model here (if the abbreviation is equal,
    1993             :  * the cost of comparing equal and unequal underlying values is comparable).
    1994             :  * We discontinue even checking for abort (saving us the hashing overhead) if
    1995             :  * the estimated cardinality gets to 100k; that would be enough to support many
    1996             :  * billions of rows while doing no worse than breaking even.
    1997             :  *
    1998             :  * ----------------------------------------------------------------------
    1999             :  */
    2000             : 
    2001             : /*
    2002             :  * Sort support strategy routine.
    2003             :  */
    2004             : Datum
    2005         972 : numeric_sortsupport(PG_FUNCTION_ARGS)
    2006             : {
    2007         972 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
    2008             : 
    2009         972 :     ssup->comparator = numeric_fast_cmp;
    2010             : 
    2011         972 :     if (ssup->abbreviate)
    2012             :     {
    2013             :         NumericSortSupport *nss;
    2014         250 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
    2015             : 
    2016         250 :         nss = palloc(sizeof(NumericSortSupport));
    2017             : 
    2018             :         /*
    2019             :          * palloc a buffer for handling unaligned packed values in addition to
    2020             :          * the support struct
    2021             :          */
    2022         250 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
    2023             : 
    2024         250 :         nss->input_count = 0;
    2025         250 :         nss->estimating = true;
    2026         250 :         initHyperLogLog(&nss->abbr_card, 10);
    2027             : 
    2028         250 :         ssup->ssup_extra = nss;
    2029             : 
    2030         250 :         ssup->abbrev_full_comparator = ssup->comparator;
    2031         250 :         ssup->comparator = numeric_cmp_abbrev;
    2032         250 :         ssup->abbrev_converter = numeric_abbrev_convert;
    2033         250 :         ssup->abbrev_abort = numeric_abbrev_abort;
    2034             : 
    2035         250 :         MemoryContextSwitchTo(oldcontext);
    2036             :     }
    2037             : 
    2038         972 :     PG_RETURN_VOID();
    2039             : }
    2040             : 
    2041             : /*
    2042             :  * Abbreviate a numeric datum, handling NaNs and detoasting
    2043             :  * (must not leak memory!)
    2044             :  */
    2045             : static Datum
    2046       19132 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
    2047             : {
    2048       19132 :     NumericSortSupport *nss = ssup->ssup_extra;
    2049       19132 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
    2050             :     Numeric     value;
    2051             :     Datum       result;
    2052             : 
    2053       19132 :     nss->input_count += 1;
    2054             : 
    2055             :     /*
    2056             :      * This is to handle packed datums without needing a palloc/pfree cycle;
    2057             :      * we keep and reuse a buffer large enough to handle any short datum.
    2058             :      */
    2059       19132 :     if (VARATT_IS_SHORT(original_varatt))
    2060             :     {
    2061        1026 :         void       *buf = nss->buf;
    2062        1026 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
    2063             : 
    2064             :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
    2065             : 
    2066        1026 :         SET_VARSIZE(buf, VARHDRSZ + sz);
    2067        1026 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
    2068             : 
    2069        1026 :         value = (Numeric) buf;
    2070             :     }
    2071             :     else
    2072       18106 :         value = (Numeric) original_varatt;
    2073             : 
    2074       19132 :     if (NUMERIC_IS_SPECIAL(value))
    2075             :     {
    2076         150 :         if (NUMERIC_IS_PINF(value))
    2077          48 :             result = NUMERIC_ABBREV_PINF;
    2078         102 :         else if (NUMERIC_IS_NINF(value))
    2079          48 :             result = NUMERIC_ABBREV_NINF;
    2080             :         else
    2081          54 :             result = NUMERIC_ABBREV_NAN;
    2082             :     }
    2083             :     else
    2084             :     {
    2085             :         NumericVar  var;
    2086             : 
    2087       18982 :         init_var_from_num(value, &var);
    2088             : 
    2089       18982 :         result = numeric_abbrev_convert_var(&var, nss);
    2090             :     }
    2091             : 
    2092             :     /* should happen only for external/compressed toasts */
    2093       19132 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
    2094           0 :         pfree(original_varatt);
    2095             : 
    2096       19132 :     return result;
    2097             : }
    2098             : 
    2099             : /*
    2100             :  * Consider whether to abort abbreviation.
    2101             :  *
    2102             :  * We pay no attention to the cardinality of the non-abbreviated data. There is
    2103             :  * no reason to do so: unlike text, we have no fast check for equal values, so
    2104             :  * we pay the full overhead whenever the abbreviations are equal regardless of
    2105             :  * whether the underlying values are also equal.
    2106             :  */
    2107             : static bool
    2108         144 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
    2109             : {
    2110         144 :     NumericSortSupport *nss = ssup->ssup_extra;
    2111             :     double      abbr_card;
    2112             : 
    2113         144 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
    2114         144 :         return false;
    2115             : 
    2116           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
    2117             : 
    2118             :     /*
    2119             :      * If we have >100k distinct values, then even if we were sorting many
    2120             :      * billion rows we'd likely still break even, and the penalty of undoing
    2121             :      * that many rows of abbrevs would probably not be worth it. Stop even
    2122             :      * counting at that point.
    2123             :      */
    2124           0 :     if (abbr_card > 100000.0)
    2125             :     {
    2126             : #ifdef TRACE_SORT
    2127           0 :         if (trace_sort)
    2128           0 :             elog(LOG,
    2129             :                  "numeric_abbrev: estimation ends at cardinality %f"
    2130             :                  " after " INT64_FORMAT " values (%d rows)",
    2131             :                  abbr_card, nss->input_count, memtupcount);
    2132             : #endif
    2133           0 :         nss->estimating = false;
    2134           0 :         return false;
    2135             :     }
    2136             : 
    2137             :     /*
    2138             :      * Target minimum cardinality is 1 per ~10k of non-null inputs.  (The
    2139             :      * break even point is somewhere between one per 100k rows, where
    2140             :      * abbreviation has a very slight penalty, and 1 per 10k where it wins by
    2141             :      * a measurable percentage.)  We use the relatively pessimistic 10k
    2142             :      * threshold, and add a 0.5 row fudge factor, because it allows us to
    2143             :      * abort earlier on genuinely pathological data where we've had exactly
    2144             :      * one abbreviated value in the first 10k (non-null) rows.
    2145             :      */
    2146           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
    2147             :     {
    2148             : #ifdef TRACE_SORT
    2149           0 :         if (trace_sort)
    2150           0 :             elog(LOG,
    2151             :                  "numeric_abbrev: aborting abbreviation at cardinality %f"
    2152             :                  " below threshold %f after " INT64_FORMAT " values (%d rows)",
    2153             :                  abbr_card, nss->input_count / 10000.0 + 0.5,
    2154             :                  nss->input_count, memtupcount);
    2155             : #endif
    2156           0 :         return true;
    2157             :     }
    2158             : 
    2159             : #ifdef TRACE_SORT
    2160           0 :     if (trace_sort)
    2161           0 :         elog(LOG,
    2162             :              "numeric_abbrev: cardinality %f"
    2163             :              " after " INT64_FORMAT " values (%d rows)",
    2164             :              abbr_card, nss->input_count, memtupcount);
    2165             : #endif
    2166             : 
    2167           0 :     return false;
    2168             : }
    2169             : 
    2170             : /*
    2171             :  * Non-fmgr interface to the comparison routine to allow sortsupport to elide
    2172             :  * the fmgr call.  The saving here is small given how slow numeric comparisons
    2173             :  * are, but it is a required part of the sort support API when abbreviations
    2174             :  * are performed.
    2175             :  *
    2176             :  * Two palloc/pfree cycles could be saved here by using persistent buffers for
    2177             :  * aligning short-varlena inputs, but this has not so far been considered to
    2178             :  * be worth the effort.
    2179             :  */
    2180             : static int
    2181     4548032 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
    2182             : {
    2183     4548032 :     Numeric     nx = DatumGetNumeric(x);
    2184     4548032 :     Numeric     ny = DatumGetNumeric(y);
    2185             :     int         result;
    2186             : 
    2187     4548032 :     result = cmp_numerics(nx, ny);
    2188             : 
    2189     4548032 :     if ((Pointer) nx != DatumGetPointer(x))
    2190      172830 :         pfree(nx);
    2191     4548032 :     if ((Pointer) ny != DatumGetPointer(y))
    2192      172824 :         pfree(ny);
    2193             : 
    2194     4548032 :     return result;
    2195             : }
    2196             : 
    2197             : /*
    2198             :  * Compare abbreviations of values. (Abbreviations may be equal where the true
    2199             :  * values differ, but if the abbreviations differ, they must reflect the
    2200             :  * ordering of the true values.)
    2201             :  */
    2202             : static int
    2203      189274 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
    2204             : {
    2205             :     /*
    2206             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
    2207             :      * negated relative to the original value, to handle NaN/infinity cases.
    2208             :      */
    2209      189274 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
    2210       97796 :         return 1;
    2211       91478 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
    2212       91248 :         return -1;
    2213         230 :     return 0;
    2214             : }
    2215             : 
    2216             : /*
    2217             :  * Abbreviate a NumericVar according to the available bit size.
    2218             :  *
    2219             :  * The 31-bit value is constructed as:
    2220             :  *
    2221             :  *  0 + 7bits digit weight + 24 bits digit value
    2222             :  *
    2223             :  * where the digit weight is in single decimal digits, not digit words, and
    2224             :  * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
    2225             :  * significant decimal digits of the value converted to binary. Values whose
    2226             :  * weights would fall outside the representable range are rounded off to zero
    2227             :  * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
    2228             :  * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
    2229             :  * where values are outside the range 10^-44 to 10^83, which is not considered
    2230             :  * to be a serious limitation, or when values are of the same magnitude and
    2231             :  * equal in the first 7 decimal digits, which is considered to be an
    2232             :  * unavoidable limitation given the available bits. (Stealing three more bits
    2233             :  * to compare another digit would narrow the range of representable weights by
    2234             :  * a factor of 8, which starts to look like a real limiting factor.)
    2235             :  *
    2236             :  * (The value 44 for the excess is essentially arbitrary)
    2237             :  *
    2238             :  * The 63-bit value is constructed as:
    2239             :  *
    2240             :  *  0 + 7bits weight + 4 x 14-bit packed digit words
    2241             :  *
    2242             :  * The weight in this case is again stored in excess-44, but this time it is
    2243             :  * the original weight in digit words (i.e. powers of 10000). The first four
    2244             :  * digit words of the value (if present; trailing zeros are assumed as needed)
    2245             :  * are packed into 14 bits each to form the rest of the value. Again,
    2246             :  * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
    2247             :  * representable range in this case is 10^-176 to 10^332, which is considered
    2248             :  * to be good enough for all practical purposes, and comparison of 4 words
    2249             :  * means that at least 13 decimal digits are compared, which is considered to
    2250             :  * be a reasonable compromise between effectiveness and efficiency in computing
    2251             :  * the abbreviation.
    2252             :  *
    2253             :  * (The value 44 for the excess is even more arbitrary here, it was chosen just
    2254             :  * to match the value used in the 31-bit case)
    2255             :  *
    2256             :  * [1] - Excess-k representation means that the value is offset by adding 'k'
    2257             :  * and then treated as unsigned, so the smallest representable value is stored
    2258             :  * with all bits zero. This allows simple comparisons to work on the composite
    2259             :  * value.
    2260             :  */
    2261             : 
    2262             : #if NUMERIC_ABBREV_BITS == 64
    2263             : 
    2264             : static Datum
    2265       18982 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2266             : {
    2267       18982 :     int         ndigits = var->ndigits;
    2268       18982 :     int         weight = var->weight;
    2269             :     int64       result;
    2270             : 
    2271       18982 :     if (ndigits == 0 || weight < -44)
    2272             :     {
    2273          52 :         result = 0;
    2274             :     }
    2275       18930 :     else if (weight > 83)
    2276             :     {
    2277          12 :         result = PG_INT64_MAX;
    2278             :     }
    2279             :     else
    2280             :     {
    2281       18918 :         result = ((int64) (weight + 44) << 56);
    2282             : 
    2283       18918 :         switch (ndigits)
    2284             :         {
    2285           0 :             default:
    2286           0 :                 result |= ((int64) var->digits[3]);
    2287             :                 /* FALLTHROUGH */
    2288        6206 :             case 3:
    2289        6206 :                 result |= ((int64) var->digits[2]) << 14;
    2290             :                 /* FALLTHROUGH */
    2291       18264 :             case 2:
    2292       18264 :                 result |= ((int64) var->digits[1]) << 28;
    2293             :                 /* FALLTHROUGH */
    2294       18918 :             case 1:
    2295       18918 :                 result |= ((int64) var->digits[0]) << 42;
    2296       18918 :                 break;
    2297             :         }
    2298             :     }
    2299             : 
    2300             :     /* the abbrev is negated relative to the original */
    2301       18982 :     if (var->sign == NUMERIC_POS)
    2302       18884 :         result = -result;
    2303             : 
    2304       18982 :     if (nss->estimating)
    2305             :     {
    2306       18982 :         uint32      tmp = ((uint32) result
    2307       18982 :                            ^ (uint32) ((uint64) result >> 32));
    2308             : 
    2309       18982 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2310             :     }
    2311             : 
    2312       18982 :     return NumericAbbrevGetDatum(result);
    2313             : }
    2314             : 
    2315             : #endif                          /* NUMERIC_ABBREV_BITS == 64 */
    2316             : 
    2317             : #if NUMERIC_ABBREV_BITS == 32
    2318             : 
    2319             : static Datum
    2320             : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
    2321             : {
    2322             :     int         ndigits = var->ndigits;
    2323             :     int         weight = var->weight;
    2324             :     int32       result;
    2325             : 
    2326             :     if (ndigits == 0 || weight < -11)
    2327             :     {
    2328             :         result = 0;
    2329             :     }
    2330             :     else if (weight > 20)
    2331             :     {
    2332             :         result = PG_INT32_MAX;
    2333             :     }
    2334             :     else
    2335             :     {
    2336             :         NumericDigit nxt1 = (ndigits > 1) ? var->digits[1] : 0;
    2337             : 
    2338             :         weight = (weight + 11) * 4;
    2339             : 
    2340             :         result = var->digits[0];
    2341             : 
    2342             :         /*
    2343             :          * "result" now has 1 to 4 nonzero decimal digits. We pack in more
    2344             :          * digits to make 7 in total (largest we can fit in 24 bits)
    2345             :          */
    2346             : 
    2347             :         if (result > 999)
    2348             :         {
    2349             :             /* already have 4 digits, add 3 more */
    2350             :             result = (result * 1000) + (nxt1 / 10);
    2351             :             weight += 3;
    2352             :         }
    2353             :         else if (result > 99)
    2354             :         {
    2355             :             /* already have 3 digits, add 4 more */
    2356             :             result = (result * 10000) + nxt1;
    2357             :             weight += 2;
    2358             :         }
    2359             :         else if (result > 9)
    2360             :         {
    2361             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2362             : 
    2363             :             /* already have 2 digits, add 5 more */
    2364             :             result = (result * 100000) + (nxt1 * 10) + (nxt2 / 1000);
    2365             :             weight += 1;
    2366             :         }
    2367             :         else
    2368             :         {
    2369             :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
    2370             : 
    2371             :             /* already have 1 digit, add 6 more */
    2372             :             result = (result * 1000000) + (nxt1 * 100) + (nxt2 / 100);
    2373             :         }
    2374             : 
    2375             :         result = result | (weight << 24);
    2376             :     }
    2377             : 
    2378             :     /* the abbrev is negated relative to the original */
    2379             :     if (var->sign == NUMERIC_POS)
    2380             :         result = -result;
    2381             : 
    2382             :     if (nss->estimating)
    2383             :     {
    2384             :         uint32      tmp = (uint32) result;
    2385             : 
    2386             :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
    2387             :     }
    2388             : 
    2389             :     return NumericAbbrevGetDatum(result);
    2390             : }
    2391             : 
    2392             : #endif                          /* NUMERIC_ABBREV_BITS == 32 */
    2393             : 
    2394             : /*
    2395             :  * Ordinary (non-sortsupport) comparisons follow.
    2396             :  */
    2397             : 
    2398             : Datum
    2399      764220 : numeric_cmp(PG_FUNCTION_ARGS)
    2400             : {
    2401      764220 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2402      764220 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2403             :     int         result;
    2404             : 
    2405      764220 :     result = cmp_numerics(num1, num2);
    2406             : 
    2407      764220 :     PG_FREE_IF_COPY(num1, 0);
    2408      764220 :     PG_FREE_IF_COPY(num2, 1);
    2409             : 
    2410      764220 :     PG_RETURN_INT32(result);
    2411             : }
    2412             : 
    2413             : 
    2414             : Datum
    2415      625756 : numeric_eq(PG_FUNCTION_ARGS)
    2416             : {
    2417      625756 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2418      625756 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2419             :     bool        result;
    2420             : 
    2421      625756 :     result = cmp_numerics(num1, num2) == 0;
    2422             : 
    2423      625756 :     PG_FREE_IF_COPY(num1, 0);
    2424      625756 :     PG_FREE_IF_COPY(num2, 1);
    2425             : 
    2426      625756 :     PG_RETURN_BOOL(result);
    2427             : }
    2428             : 
    2429             : Datum
    2430        5376 : numeric_ne(PG_FUNCTION_ARGS)
    2431             : {
    2432        5376 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2433        5376 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2434             :     bool        result;
    2435             : 
    2436        5376 :     result = cmp_numerics(num1, num2) != 0;
    2437             : 
    2438        5376 :     PG_FREE_IF_COPY(num1, 0);
    2439        5376 :     PG_FREE_IF_COPY(num2, 1);
    2440             : 
    2441        5376 :     PG_RETURN_BOOL(result);
    2442             : }
    2443             : 
    2444             : Datum
    2445       61840 : numeric_gt(PG_FUNCTION_ARGS)
    2446             : {
    2447       61840 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2448       61840 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2449             :     bool        result;
    2450             : 
    2451       61840 :     result = cmp_numerics(num1, num2) > 0;
    2452             : 
    2453       61840 :     PG_FREE_IF_COPY(num1, 0);
    2454       61840 :     PG_FREE_IF_COPY(num2, 1);
    2455             : 
    2456       61840 :     PG_RETURN_BOOL(result);
    2457             : }
    2458             : 
    2459             : Datum
    2460       16764 : numeric_ge(PG_FUNCTION_ARGS)
    2461             : {
    2462       16764 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2463       16764 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2464             :     bool        result;
    2465             : 
    2466       16764 :     result = cmp_numerics(num1, num2) >= 0;
    2467             : 
    2468       16764 :     PG_FREE_IF_COPY(num1, 0);
    2469       16764 :     PG_FREE_IF_COPY(num2, 1);
    2470             : 
    2471       16764 :     PG_RETURN_BOOL(result);
    2472             : }
    2473             : 
    2474             : Datum
    2475       52302 : numeric_lt(PG_FUNCTION_ARGS)
    2476             : {
    2477       52302 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2478       52302 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2479             :     bool        result;
    2480             : 
    2481       52302 :     result = cmp_numerics(num1, num2) < 0;
    2482             : 
    2483       52302 :     PG_FREE_IF_COPY(num1, 0);
    2484       52302 :     PG_FREE_IF_COPY(num2, 1);
    2485             : 
    2486       52302 :     PG_RETURN_BOOL(result);
    2487             : }
    2488             : 
    2489             : Datum
    2490       15272 : numeric_le(PG_FUNCTION_ARGS)
    2491             : {
    2492       15272 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2493       15272 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2494             :     bool        result;
    2495             : 
    2496       15272 :     result = cmp_numerics(num1, num2) <= 0;
    2497             : 
    2498       15272 :     PG_FREE_IF_COPY(num1, 0);
    2499       15272 :     PG_FREE_IF_COPY(num2, 1);
    2500             : 
    2501       15272 :     PG_RETURN_BOOL(result);
    2502             : }
    2503             : 
    2504             : static int
    2505     6111084 : cmp_numerics(Numeric num1, Numeric num2)
    2506             : {
    2507             :     int         result;
    2508             : 
    2509             :     /*
    2510             :      * We consider all NANs to be equal and larger than any non-NAN (including
    2511             :      * Infinity).  This is somewhat arbitrary; the important thing is to have
    2512             :      * a consistent sort order.
    2513             :      */
    2514     6111084 :     if (NUMERIC_IS_SPECIAL(num1))
    2515             :     {
    2516        7824 :         if (NUMERIC_IS_NAN(num1))
    2517             :         {
    2518        7734 :             if (NUMERIC_IS_NAN(num2))
    2519         924 :                 result = 0;     /* NAN = NAN */
    2520             :             else
    2521        6810 :                 result = 1;     /* NAN > non-NAN */
    2522             :         }
    2523          90 :         else if (NUMERIC_IS_PINF(num1))
    2524             :         {
    2525          72 :             if (NUMERIC_IS_NAN(num2))
    2526           0 :                 result = -1;    /* PINF < NAN */
    2527          72 :             else if (NUMERIC_IS_PINF(num2))
    2528           6 :                 result = 0;     /* PINF = PINF */
    2529             :             else
    2530          66 :                 result = 1;     /* PINF > anything else */
    2531             :         }
    2532             :         else                    /* num1 must be NINF */
    2533             :         {
    2534          18 :             if (NUMERIC_IS_NINF(num2))
    2535           6 :                 result = 0;     /* NINF = NINF */
    2536             :             else
    2537          12 :                 result = -1;    /* NINF < anything else */
    2538             :         }
    2539             :     }
    2540     6103260 :     else if (NUMERIC_IS_SPECIAL(num2))
    2541             :     {
    2542       11228 :         if (NUMERIC_IS_NINF(num2))
    2543          12 :             result = 1;         /* normal > NINF */
    2544             :         else
    2545       11216 :             result = -1;        /* normal < NAN or PINF */
    2546             :     }
    2547             :     else
    2548             :     {
    2549    12185196 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
    2550     6092346 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
    2551     6092032 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
    2552     6092850 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
    2553             :     }
    2554             : 
    2555     6111084 :     return result;
    2556             : }
    2557             : 
    2558             : /*
    2559             :  * in_range support function for numeric.
    2560             :  */
    2561             : Datum
    2562        1152 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
    2563             : {
    2564        1152 :     Numeric     val = PG_GETARG_NUMERIC(0);
    2565        1152 :     Numeric     base = PG_GETARG_NUMERIC(1);
    2566        1152 :     Numeric     offset = PG_GETARG_NUMERIC(2);
    2567        1152 :     bool        sub = PG_GETARG_BOOL(3);
    2568        1152 :     bool        less = PG_GETARG_BOOL(4);
    2569             :     bool        result;
    2570             : 
    2571             :     /*
    2572             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
    2573             :      * and NaN is because appropriate semantics for that seem non-obvious.
    2574             :      */
    2575        1152 :     if (NUMERIC_IS_NAN(offset) ||
    2576        1146 :         NUMERIC_IS_NINF(offset) ||
    2577        1146 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
    2578           6 :         ereport(ERROR,
    2579             :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
    2580             :                  errmsg("invalid preceding or following size in window function")));
    2581             : 
    2582             :     /*
    2583             :      * Deal with cases where val and/or base is NaN, following the rule that
    2584             :      * NaN sorts after non-NaN (cf cmp_numerics).  The offset cannot affect
    2585             :      * the conclusion.
    2586             :      */
    2587        1146 :     if (NUMERIC_IS_NAN(val))
    2588             :     {
    2589         186 :         if (NUMERIC_IS_NAN(base))
    2590          60 :             result = true;      /* NAN = NAN */
    2591             :         else
    2592         126 :             result = !less;     /* NAN > non-NAN */
    2593             :     }
    2594         960 :     else if (NUMERIC_IS_NAN(base))
    2595             :     {
    2596         126 :         result = less;          /* non-NAN < NAN */
    2597             :     }
    2598             : 
    2599             :     /*
    2600             :      * Deal with infinite offset (necessarily +Inf, at this point).
    2601             :      */
    2602         834 :     else if (NUMERIC_IS_SPECIAL(offset))
    2603             :     {
    2604             :         Assert(NUMERIC_IS_PINF(offset));
    2605         420 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
    2606             :         {
    2607             :             /*
    2608             :              * base +/- offset would produce NaN, so return true for any val
    2609             :              * (see in_range_float8_float8() for reasoning).
    2610             :              */
    2611         174 :             result = true;
    2612             :         }
    2613         246 :         else if (sub)
    2614             :         {
    2615             :             /* base - offset must be -inf */
    2616         150 :             if (less)
    2617          54 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
    2618             :             else
    2619          96 :                 result = true;  /* any val is >= sum */
    2620             :         }
    2621             :         else
    2622             :         {
    2623             :             /* base + offset must be +inf */
    2624          96 :             if (less)
    2625           0 :                 result = true;  /* any val is <= sum */
    2626             :             else
    2627          96 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
    2628             :         }
    2629             :     }
    2630             : 
    2631             :     /*
    2632             :      * Deal with cases where val and/or base is infinite.  The offset, being
    2633             :      * now known finite, cannot affect the conclusion.
    2634             :      */
    2635         414 :     else if (NUMERIC_IS_SPECIAL(val))
    2636             :     {
    2637          78 :         if (NUMERIC_IS_PINF(val))
    2638             :         {
    2639          36 :             if (NUMERIC_IS_PINF(base))
    2640          24 :                 result = true;  /* PINF = PINF */
    2641             :             else
    2642          12 :                 result = !less; /* PINF > any other non-NAN */
    2643             :         }
    2644             :         else                    /* val must be NINF */
    2645             :         {
    2646          42 :             if (NUMERIC_IS_NINF(base))
    2647          30 :                 result = true;  /* NINF = NINF */
    2648             :             else
    2649          12 :                 result = less;  /* NINF < anything else */
    2650             :         }
    2651             :     }
    2652         336 :     else if (NUMERIC_IS_SPECIAL(base))
    2653             :     {
    2654          24 :         if (NUMERIC_IS_NINF(base))
    2655          12 :             result = !less;     /* normal > NINF */
    2656             :         else
    2657          12 :             result = less;      /* normal < PINF */
    2658             :     }
    2659             :     else
    2660             :     {
    2661             :         /*
    2662             :          * Otherwise go ahead and compute base +/- offset.  While it's
    2663             :          * possible for this to overflow the numeric format, it's unlikely
    2664             :          * enough that we don't take measures to prevent it.
    2665             :          */
    2666             :         NumericVar  valv;
    2667             :         NumericVar  basev;
    2668             :         NumericVar  offsetv;
    2669             :         NumericVar  sum;
    2670             : 
    2671         312 :         init_var_from_num(val, &valv);
    2672         312 :         init_var_from_num(base, &basev);
    2673         312 :         init_var_from_num(offset, &offsetv);
    2674         312 :         init_var(&sum);
    2675             : 
    2676         312 :         if (sub)
    2677         156 :             sub_var(&basev, &offsetv, &sum);
    2678             :         else
    2679         156 :             add_var(&basev, &offsetv, &sum);
    2680             : 
    2681         312 :         if (less)
    2682         156 :             result = (cmp_var(&valv, &sum) <= 0);
    2683             :         else
    2684         156 :             result = (cmp_var(&valv, &sum) >= 0);
    2685             : 
    2686         312 :         free_var(&sum);
    2687             :     }
    2688             : 
    2689        1146 :     PG_FREE_IF_COPY(val, 0);
    2690        1146 :     PG_FREE_IF_COPY(base, 1);
    2691        1146 :     PG_FREE_IF_COPY(offset, 2);
    2692             : 
    2693        1146 :     PG_RETURN_BOOL(result);
    2694             : }
    2695             : 
    2696             : Datum
    2697      607470 : hash_numeric(PG_FUNCTION_ARGS)
    2698             : {
    2699      607470 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2700             :     Datum       digit_hash;
    2701             :     Datum       result;
    2702             :     int         weight;
    2703             :     int         start_offset;
    2704             :     int         end_offset;
    2705             :     int         i;
    2706             :     int         hash_len;
    2707             :     NumericDigit *digits;
    2708             : 
    2709             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2710      607470 :     if (NUMERIC_IS_SPECIAL(key))
    2711           0 :         PG_RETURN_UINT32(0);
    2712             : 
    2713      607470 :     weight = NUMERIC_WEIGHT(key);
    2714      607470 :     start_offset = 0;
    2715      607470 :     end_offset = 0;
    2716             : 
    2717             :     /*
    2718             :      * Omit any leading or trailing zeros from the input to the hash. The
    2719             :      * numeric implementation *should* guarantee that leading and trailing
    2720             :      * zeros are suppressed, but we're paranoid. Note that we measure the
    2721             :      * starting and ending offsets in units of NumericDigits, not bytes.
    2722             :      */
    2723      607470 :     digits = NUMERIC_DIGITS(key);
    2724      607470 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2725             :     {
    2726      605834 :         if (digits[i] != (NumericDigit) 0)
    2727      605834 :             break;
    2728             : 
    2729           0 :         start_offset++;
    2730             : 
    2731             :         /*
    2732             :          * The weight is effectively the # of digits before the decimal point,
    2733             :          * so decrement it for each leading zero we skip.
    2734             :          */
    2735           0 :         weight--;
    2736             :     }
    2737             : 
    2738             :     /*
    2739             :      * If there are no non-zero digits, then the value of the number is zero,
    2740             :      * regardless of any other fields.
    2741             :      */
    2742      607470 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2743        1636 :         PG_RETURN_UINT32(-1);
    2744             : 
    2745      605834 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2746             :     {
    2747      605834 :         if (digits[i] != (NumericDigit) 0)
    2748      605834 :             break;
    2749             : 
    2750           0 :         end_offset++;
    2751             :     }
    2752             : 
    2753             :     /* If we get here, there should be at least one non-zero digit */
    2754             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2755             : 
    2756             :     /*
    2757             :      * Note that we don't hash on the Numeric's scale, since two numerics can
    2758             :      * compare equal but have different scales. We also don't hash on the
    2759             :      * sign, although we could: since a sign difference implies inequality,
    2760             :      * this shouldn't affect correctness.
    2761             :      */
    2762      605834 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2763      605834 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
    2764             :                           hash_len * sizeof(NumericDigit));
    2765             : 
    2766             :     /* Mix in the weight, via XOR */
    2767      605834 :     result = digit_hash ^ weight;
    2768             : 
    2769      605834 :     PG_RETURN_DATUM(result);
    2770             : }
    2771             : 
    2772             : /*
    2773             :  * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
    2774             :  * Otherwise, similar to hash_numeric.
    2775             :  */
    2776             : Datum
    2777          84 : hash_numeric_extended(PG_FUNCTION_ARGS)
    2778             : {
    2779          84 :     Numeric     key = PG_GETARG_NUMERIC(0);
    2780          84 :     uint64      seed = PG_GETARG_INT64(1);
    2781             :     Datum       digit_hash;
    2782             :     Datum       result;
    2783             :     int         weight;
    2784             :     int         start_offset;
    2785             :     int         end_offset;
    2786             :     int         i;
    2787             :     int         hash_len;
    2788             :     NumericDigit *digits;
    2789             : 
    2790             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
    2791          84 :     if (NUMERIC_IS_SPECIAL(key))
    2792           0 :         PG_RETURN_UINT64(seed);
    2793             : 
    2794          84 :     weight = NUMERIC_WEIGHT(key);
    2795          84 :     start_offset = 0;
    2796          84 :     end_offset = 0;
    2797             : 
    2798          84 :     digits = NUMERIC_DIGITS(key);
    2799          84 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
    2800             :     {
    2801          72 :         if (digits[i] != (NumericDigit) 0)
    2802          72 :             break;
    2803             : 
    2804           0 :         start_offset++;
    2805             : 
    2806           0 :         weight--;
    2807             :     }
    2808             : 
    2809          84 :     if (NUMERIC_NDIGITS(key) == start_offset)
    2810          12 :         PG_RETURN_UINT64(seed - 1);
    2811             : 
    2812          72 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
    2813             :     {
    2814          72 :         if (digits[i] != (NumericDigit) 0)
    2815          72 :             break;
    2816             : 
    2817           0 :         end_offset++;
    2818             :     }
    2819             : 
    2820             :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
    2821             : 
    2822          72 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
    2823          72 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
    2824          72 :                                                       + start_offset),
    2825             :                                    hash_len * sizeof(NumericDigit),
    2826             :                                    seed);
    2827             : 
    2828          72 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
    2829             : 
    2830          72 :     PG_RETURN_DATUM(result);
    2831             : }
    2832             : 
    2833             : 
    2834             : /* ----------------------------------------------------------------------
    2835             :  *
    2836             :  * Basic arithmetic functions
    2837             :  *
    2838             :  * ----------------------------------------------------------------------
    2839             :  */
    2840             : 
    2841             : 
    2842             : /*
    2843             :  * numeric_add() -
    2844             :  *
    2845             :  *  Add two numerics
    2846             :  */
    2847             : Datum
    2848      252052 : numeric_add(PG_FUNCTION_ARGS)
    2849             : {
    2850      252052 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2851      252052 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2852             :     Numeric     res;
    2853             : 
    2854      252052 :     res = numeric_add_opt_error(num1, num2, NULL);
    2855             : 
    2856      252052 :     PG_RETURN_NUMERIC(res);
    2857             : }
    2858             : 
    2859             : /*
    2860             :  * numeric_add_opt_error() -
    2861             :  *
    2862             :  *  Internal version of numeric_add().  If "*have_error" flag is provided,
    2863             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2864             :  *  need to handle errors by itself.
    2865             :  */
    2866             : Numeric
    2867      253090 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2868             : {
    2869             :     NumericVar  arg1;
    2870             :     NumericVar  arg2;
    2871             :     NumericVar  result;
    2872             :     Numeric     res;
    2873             : 
    2874             :     /*
    2875             :      * Handle NaN and infinities
    2876             :      */
    2877      253090 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2878             :     {
    2879         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2880          78 :             return make_result(&const_nan);
    2881         120 :         if (NUMERIC_IS_PINF(num1))
    2882             :         {
    2883          36 :             if (NUMERIC_IS_NINF(num2))
    2884           6 :                 return make_result(&const_nan); /* Inf + -Inf */
    2885             :             else
    2886          30 :                 return make_result(&const_pinf);
    2887             :         }
    2888          84 :         if (NUMERIC_IS_NINF(num1))
    2889             :         {
    2890          36 :             if (NUMERIC_IS_PINF(num2))
    2891           6 :                 return make_result(&const_nan); /* -Inf + Inf */
    2892             :             else
    2893          30 :                 return make_result(&const_ninf);
    2894             :         }
    2895             :         /* by here, num1 must be finite, so num2 is not */
    2896          48 :         if (NUMERIC_IS_PINF(num2))
    2897          24 :             return make_result(&const_pinf);
    2898             :         Assert(NUMERIC_IS_NINF(num2));
    2899          24 :         return make_result(&const_ninf);
    2900             :     }
    2901             : 
    2902             :     /*
    2903             :      * Unpack the values, let add_var() compute the result and return it.
    2904             :      */
    2905      252892 :     init_var_from_num(num1, &arg1);
    2906      252892 :     init_var_from_num(num2, &arg2);
    2907             : 
    2908      252892 :     init_var(&result);
    2909      252892 :     add_var(&arg1, &arg2, &result);
    2910             : 
    2911      252892 :     res = make_result_opt_error(&result, have_error);
    2912             : 
    2913      252892 :     free_var(&result);
    2914             : 
    2915      252892 :     return res;
    2916             : }
    2917             : 
    2918             : 
    2919             : /*
    2920             :  * numeric_sub() -
    2921             :  *
    2922             :  *  Subtract one numeric from another
    2923             :  */
    2924             : Datum
    2925       93526 : numeric_sub(PG_FUNCTION_ARGS)
    2926             : {
    2927       93526 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    2928       93526 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    2929             :     Numeric     res;
    2930             : 
    2931       93526 :     res = numeric_sub_opt_error(num1, num2, NULL);
    2932             : 
    2933       93526 :     PG_RETURN_NUMERIC(res);
    2934             : }
    2935             : 
    2936             : 
    2937             : /*
    2938             :  * numeric_sub_opt_error() -
    2939             :  *
    2940             :  *  Internal version of numeric_sub().  If "*have_error" flag is provided,
    2941             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    2942             :  *  need to handle errors by itself.
    2943             :  */
    2944             : Numeric
    2945       93676 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
    2946             : {
    2947             :     NumericVar  arg1;
    2948             :     NumericVar  arg2;
    2949             :     NumericVar  result;
    2950             :     Numeric     res;
    2951             : 
    2952             :     /*
    2953             :      * Handle NaN and infinities
    2954             :      */
    2955       93676 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    2956             :     {
    2957        2216 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    2958        2096 :             return make_result(&const_nan);
    2959         120 :         if (NUMERIC_IS_PINF(num1))
    2960             :         {
    2961          36 :             if (NUMERIC_IS_PINF(num2))
    2962           6 :                 return make_result(&const_nan); /* Inf - Inf */
    2963             :             else
    2964          30 :                 return make_result(&const_pinf);
    2965             :         }
    2966          84 :         if (NUMERIC_IS_NINF(num1))
    2967             :         {
    2968          36 :             if (NUMERIC_IS_NINF(num2))
    2969           6 :                 return make_result(&const_nan); /* -Inf - -Inf */
    2970             :             else
    2971          30 :                 return make_result(&const_ninf);
    2972             :         }
    2973             :         /* by here, num1 must be finite, so num2 is not */
    2974          48 :         if (NUMERIC_IS_PINF(num2))
    2975          24 :             return make_result(&const_ninf);
    2976             :         Assert(NUMERIC_IS_NINF(num2));
    2977          24 :         return make_result(&const_pinf);
    2978             :     }
    2979             : 
    2980             :     /*
    2981             :      * Unpack the values, let sub_var() compute the result and return it.
    2982             :      */
    2983       91460 :     init_var_from_num(num1, &arg1);
    2984       91460 :     init_var_from_num(num2, &arg2);
    2985             : 
    2986       91460 :     init_var(&result);
    2987       91460 :     sub_var(&arg1, &arg2, &result);
    2988             : 
    2989       91460 :     res = make_result_opt_error(&result, have_error);
    2990             : 
    2991       91460 :     free_var(&result);
    2992             : 
    2993       91460 :     return res;
    2994             : }
    2995             : 
    2996             : 
    2997             : /*
    2998             :  * numeric_mul() -
    2999             :  *
    3000             :  *  Calculate the product of two numerics
    3001             :  */
    3002             : Datum
    3003      489678 : numeric_mul(PG_FUNCTION_ARGS)
    3004             : {
    3005      489678 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3006      489678 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3007             :     Numeric     res;
    3008             : 
    3009      489678 :     res = numeric_mul_opt_error(num1, num2, NULL);
    3010             : 
    3011      489678 :     PG_RETURN_NUMERIC(res);
    3012             : }
    3013             : 
    3014             : 
    3015             : /*
    3016             :  * numeric_mul_opt_error() -
    3017             :  *
    3018             :  *  Internal version of numeric_mul().  If "*have_error" flag is provided,
    3019             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3020             :  *  need to handle errors by itself.
    3021             :  */
    3022             : Numeric
    3023      489714 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3024             : {
    3025             :     NumericVar  arg1;
    3026             :     NumericVar  arg2;
    3027             :     NumericVar  result;
    3028             :     Numeric     res;
    3029             : 
    3030             :     /*
    3031             :      * Handle NaN and infinities
    3032             :      */
    3033      489714 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3034             :     {
    3035         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3036          78 :             return make_result(&const_nan);
    3037         120 :         if (NUMERIC_IS_PINF(num1))
    3038             :         {
    3039          36 :             switch (numeric_sign_internal(num2))
    3040             :             {
    3041           6 :                 case 0:
    3042           6 :                     return make_result(&const_nan); /* Inf * 0 */
    3043          18 :                 case 1:
    3044          18 :                     return make_result(&const_pinf);
    3045          12 :                 case -1:
    3046          12 :                     return make_result(&const_ninf);
    3047             :             }
    3048             :             Assert(false);
    3049             :         }
    3050          84 :         if (NUMERIC_IS_NINF(num1))
    3051             :         {
    3052          36 :             switch (numeric_sign_internal(num2))
    3053             :             {
    3054           6 :                 case 0:
    3055           6 :                     return make_result(&const_nan); /* -Inf * 0 */
    3056          18 :                 case 1:
    3057          18 :                     return make_result(&const_ninf);
    3058          12 :                 case -1:
    3059          12 :                     return make_result(&const_pinf);
    3060             :             }
    3061             :             Assert(false);
    3062             :         }
    3063             :         /* by here, num1 must be finite, so num2 is not */
    3064          48 :         if (NUMERIC_IS_PINF(num2))
    3065             :         {
    3066          24 :             switch (numeric_sign_internal(num1))
    3067             :             {
    3068           6 :                 case 0:
    3069           6 :                     return make_result(&const_nan); /* 0 * Inf */
    3070          12 :                 case 1:
    3071          12 :                     return make_result(&const_pinf);
    3072           6 :                 case -1:
    3073           6 :                     return make_result(&const_ninf);
    3074             :             }
    3075             :             Assert(false);
    3076             :         }
    3077             :         Assert(NUMERIC_IS_NINF(num2));
    3078          24 :         switch (numeric_sign_internal(num1))
    3079             :         {
    3080           6 :             case 0:
    3081           6 :                 return make_result(&const_nan); /* 0 * -Inf */
    3082          12 :             case 1:
    3083          12 :                 return make_result(&const_ninf);
    3084           6 :             case -1:
    3085           6 :                 return make_result(&const_pinf);
    3086             :         }
    3087             :         Assert(false);
    3088             :     }
    3089             : 
    3090             :     /*
    3091             :      * Unpack the values, let mul_var() compute the result and return it.
    3092             :      * Unlike add_var() and sub_var(), mul_var() will round its result. In the
    3093             :      * case of numeric_mul(), which is invoked for the * operator on numerics,
    3094             :      * we request exact representation for the product (rscale = sum(dscale of
    3095             :      * arg1, dscale of arg2)).  If the exact result has more digits after the
    3096             :      * decimal point than can be stored in a numeric, we round it.  Rounding
    3097             :      * after computing the exact result ensures that the final result is
    3098             :      * correctly rounded (rounding in mul_var() using a truncated product
    3099             :      * would not guarantee this).
    3100             :      */
    3101      489516 :     init_var_from_num(num1, &arg1);
    3102      489516 :     init_var_from_num(num2, &arg2);
    3103             : 
    3104      489516 :     init_var(&result);
    3105      489516 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
    3106             : 
    3107      489516 :     if (result.dscale > NUMERIC_DSCALE_MAX)
    3108           6 :         round_var(&result, NUMERIC_DSCALE_MAX);
    3109             : 
    3110      489516 :     res = make_result_opt_error(&result, have_error);
    3111             : 
    3112      489516 :     free_var(&result);
    3113             : 
    3114      489516 :     return res;
    3115             : }
    3116             : 
    3117             : 
    3118             : /*
    3119             :  * numeric_div() -
    3120             :  *
    3121             :  *  Divide one numeric into another
    3122             :  */
    3123             : Datum
    3124      151376 : numeric_div(PG_FUNCTION_ARGS)
    3125             : {
    3126      151376 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3127      151376 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3128             :     Numeric     res;
    3129             : 
    3130      151376 :     res = numeric_div_opt_error(num1, num2, NULL);
    3131             : 
    3132      151344 :     PG_RETURN_NUMERIC(res);
    3133             : }
    3134             : 
    3135             : 
    3136             : /*
    3137             :  * numeric_div_opt_error() -
    3138             :  *
    3139             :  *  Internal version of numeric_div().  If "*have_error" flag is provided,
    3140             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3141             :  *  need to handle errors by itself.
    3142             :  */
    3143             : Numeric
    3144      152216 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3145             : {
    3146             :     NumericVar  arg1;
    3147             :     NumericVar  arg2;
    3148             :     NumericVar  result;
    3149             :     Numeric     res;
    3150             :     int         rscale;
    3151             : 
    3152      152216 :     if (have_error)
    3153          48 :         *have_error = false;
    3154             : 
    3155             :     /*
    3156             :      * Handle NaN and infinities
    3157             :      */
    3158      152216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3159             :     {
    3160         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3161          78 :             return make_result(&const_nan);
    3162         120 :         if (NUMERIC_IS_PINF(num1))
    3163             :         {
    3164          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3165          12 :                 return make_result(&const_nan); /* Inf / [-]Inf */
    3166          24 :             switch (numeric_sign_internal(num2))
    3167             :             {
    3168           6 :                 case 0:
    3169           6 :                     if (have_error)
    3170             :                     {
    3171           0 :                         *have_error = true;
    3172           0 :                         return NULL;
    3173             :                     }
    3174           6 :                     ereport(ERROR,
    3175             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3176             :                              errmsg("division by zero")));
    3177             :                     break;
    3178          12 :                 case 1:
    3179          12 :                     return make_result(&const_pinf);
    3180           6 :                 case -1:
    3181           6 :                     return make_result(&const_ninf);
    3182             :             }
    3183          84 :             Assert(false);
    3184             :         }
    3185          84 :         if (NUMERIC_IS_NINF(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_ninf);
    3203           6 :                 case -1:
    3204           6 :                     return make_result(&const_pinf);
    3205             :             }
    3206          48 :             Assert(false);
    3207             :         }
    3208             :         /* by here, num1 must be finite, so num2 is not */
    3209             : 
    3210             :         /*
    3211             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3212             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3213             :          * really do underflow, so let's just return zero.
    3214             :          */
    3215          48 :         return make_result(&const_zero);
    3216             :     }
    3217             : 
    3218             :     /*
    3219             :      * Unpack the arguments
    3220             :      */
    3221      152018 :     init_var_from_num(num1, &arg1);
    3222      152018 :     init_var_from_num(num2, &arg2);
    3223             : 
    3224      152018 :     init_var(&result);
    3225             : 
    3226             :     /*
    3227             :      * Select scale for division result
    3228             :      */
    3229      152018 :     rscale = select_div_scale(&arg1, &arg2);
    3230             : 
    3231             :     /*
    3232             :      * If "have_error" is provided, check for division by zero here
    3233             :      */
    3234      152018 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3235             :     {
    3236          12 :         *have_error = true;
    3237          12 :         return NULL;
    3238             :     }
    3239             : 
    3240             :     /*
    3241             :      * Do the divide and return the result
    3242             :      */
    3243      152006 :     div_var(&arg1, &arg2, &result, rscale, true);
    3244             : 
    3245      151968 :     res = make_result_opt_error(&result, have_error);
    3246             : 
    3247      151968 :     free_var(&result);
    3248             : 
    3249      151968 :     return res;
    3250             : }
    3251             : 
    3252             : 
    3253             : /*
    3254             :  * numeric_div_trunc() -
    3255             :  *
    3256             :  *  Divide one numeric into another, truncating the result to an integer
    3257             :  */
    3258             : Datum
    3259        1200 : numeric_div_trunc(PG_FUNCTION_ARGS)
    3260             : {
    3261        1200 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3262        1200 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3263             :     NumericVar  arg1;
    3264             :     NumericVar  arg2;
    3265             :     NumericVar  result;
    3266             :     Numeric     res;
    3267             : 
    3268             :     /*
    3269             :      * Handle NaN and infinities
    3270             :      */
    3271        1200 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3272             :     {
    3273         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3274          78 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3275         120 :         if (NUMERIC_IS_PINF(num1))
    3276             :         {
    3277          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3278          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
    3279          24 :             switch (numeric_sign_internal(num2))
    3280             :             {
    3281           6 :                 case 0:
    3282           6 :                     ereport(ERROR,
    3283             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3284             :                              errmsg("division by zero")));
    3285             :                     break;
    3286          12 :                 case 1:
    3287          12 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3288           6 :                 case -1:
    3289           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3290             :             }
    3291          84 :             Assert(false);
    3292             :         }
    3293          84 :         if (NUMERIC_IS_NINF(num1))
    3294             :         {
    3295          36 :             if (NUMERIC_IS_SPECIAL(num2))
    3296          12 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
    3297          24 :             switch (numeric_sign_internal(num2))
    3298             :             {
    3299           6 :                 case 0:
    3300           6 :                     ereport(ERROR,
    3301             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
    3302             :                              errmsg("division by zero")));
    3303             :                     break;
    3304          12 :                 case 1:
    3305          12 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
    3306           6 :                 case -1:
    3307           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
    3308             :             }
    3309          48 :             Assert(false);
    3310             :         }
    3311             :         /* by here, num1 must be finite, so num2 is not */
    3312             : 
    3313             :         /*
    3314             :          * POSIX would have us return zero or minus zero if num1 is zero, and
    3315             :          * otherwise throw an underflow error.  But the numeric type doesn't
    3316             :          * really do underflow, so let's just return zero.
    3317             :          */
    3318          48 :         PG_RETURN_NUMERIC(make_result(&const_zero));
    3319             :     }
    3320             : 
    3321             :     /*
    3322             :      * Unpack the arguments
    3323             :      */
    3324        1002 :     init_var_from_num(num1, &arg1);
    3325        1002 :     init_var_from_num(num2, &arg2);
    3326             : 
    3327        1002 :     init_var(&result);
    3328             : 
    3329             :     /*
    3330             :      * Do the divide and return the result
    3331             :      */
    3332        1002 :     div_var(&arg1, &arg2, &result, 0, false);
    3333             : 
    3334         996 :     res = make_result(&result);
    3335             : 
    3336         996 :     free_var(&result);
    3337             : 
    3338         996 :     PG_RETURN_NUMERIC(res);
    3339             : }
    3340             : 
    3341             : 
    3342             : /*
    3343             :  * numeric_mod() -
    3344             :  *
    3345             :  *  Calculate the modulo of two numerics
    3346             :  */
    3347             : Datum
    3348       54224 : numeric_mod(PG_FUNCTION_ARGS)
    3349             : {
    3350       54224 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3351       54224 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3352             :     Numeric     res;
    3353             : 
    3354       54224 :     res = numeric_mod_opt_error(num1, num2, NULL);
    3355             : 
    3356       54206 :     PG_RETURN_NUMERIC(res);
    3357             : }
    3358             : 
    3359             : 
    3360             : /*
    3361             :  * numeric_mod_opt_error() -
    3362             :  *
    3363             :  *  Internal version of numeric_mod().  If "*have_error" flag is provided,
    3364             :  *  on error it's set to true, NULL returned.  This is helpful when caller
    3365             :  *  need to handle errors by itself.
    3366             :  */
    3367             : Numeric
    3368       54236 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
    3369             : {
    3370             :     Numeric     res;
    3371             :     NumericVar  arg1;
    3372             :     NumericVar  arg2;
    3373             :     NumericVar  result;
    3374             : 
    3375       54236 :     if (have_error)
    3376           0 :         *have_error = false;
    3377             : 
    3378             :     /*
    3379             :      * Handle NaN and infinities.  We follow POSIX fmod() on this, except that
    3380             :      * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
    3381             :      * returning NaN.  We choose to throw error only for y-is-zero.
    3382             :      */
    3383       54236 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3384             :     {
    3385         198 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3386          78 :             return make_result(&const_nan);
    3387         120 :         if (NUMERIC_IS_INF(num1))
    3388             :         {
    3389          72 :             if (numeric_sign_internal(num2) == 0)
    3390             :             {
    3391          12 :                 if (have_error)
    3392             :                 {
    3393           0 :                     *have_error = true;
    3394           0 :                     return NULL;
    3395             :                 }
    3396          12 :                 ereport(ERROR,
    3397             :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
    3398             :                          errmsg("division by zero")));
    3399             :             }
    3400             :             /* Inf % any nonzero = NaN */
    3401          60 :             return make_result(&const_nan);
    3402             :         }
    3403             :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
    3404          48 :         return duplicate_numeric(num1);
    3405             :     }
    3406             : 
    3407       54038 :     init_var_from_num(num1, &arg1);
    3408       54038 :     init_var_from_num(num2, &arg2);
    3409             : 
    3410       54038 :     init_var(&result);
    3411             : 
    3412             :     /*
    3413             :      * If "have_error" is provided, check for division by zero here
    3414             :      */
    3415       54038 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
    3416             :     {
    3417           0 :         *have_error = true;
    3418           0 :         return NULL;
    3419             :     }
    3420             : 
    3421       54038 :     mod_var(&arg1, &arg2, &result);
    3422             : 
    3423       54026 :     res = make_result_opt_error(&result, NULL);
    3424             : 
    3425       54026 :     free_var(&result);
    3426             : 
    3427       54026 :     return res;
    3428             : }
    3429             : 
    3430             : 
    3431             : /*
    3432             :  * numeric_inc() -
    3433             :  *
    3434             :  *  Increment a number by one
    3435             :  */
    3436             : Datum
    3437          48 : numeric_inc(PG_FUNCTION_ARGS)
    3438             : {
    3439          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3440             :     NumericVar  arg;
    3441             :     Numeric     res;
    3442             : 
    3443             :     /*
    3444             :      * Handle NaN and infinities
    3445             :      */
    3446          48 :     if (NUMERIC_IS_SPECIAL(num))
    3447          18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3448             : 
    3449             :     /*
    3450             :      * Compute the result and return it
    3451             :      */
    3452          30 :     init_var_from_num(num, &arg);
    3453             : 
    3454          30 :     add_var(&arg, &const_one, &arg);
    3455             : 
    3456          30 :     res = make_result(&arg);
    3457             : 
    3458          30 :     free_var(&arg);
    3459             : 
    3460          30 :     PG_RETURN_NUMERIC(res);
    3461             : }
    3462             : 
    3463             : 
    3464             : /*
    3465             :  * numeric_smaller() -
    3466             :  *
    3467             :  *  Return the smaller of two numbers
    3468             :  */
    3469             : Datum
    3470         798 : numeric_smaller(PG_FUNCTION_ARGS)
    3471             : {
    3472         798 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3473         798 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3474             : 
    3475             :     /*
    3476             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3477             :      * particularly as regards comparisons involving NaN.
    3478             :      */
    3479         798 :     if (cmp_numerics(num1, num2) < 0)
    3480         638 :         PG_RETURN_NUMERIC(num1);
    3481             :     else
    3482         160 :         PG_RETURN_NUMERIC(num2);
    3483             : }
    3484             : 
    3485             : 
    3486             : /*
    3487             :  * numeric_larger() -
    3488             :  *
    3489             :  *  Return the larger of two numbers
    3490             :  */
    3491             : Datum
    3492       18630 : numeric_larger(PG_FUNCTION_ARGS)
    3493             : {
    3494       18630 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3495       18630 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3496             : 
    3497             :     /*
    3498             :      * Use cmp_numerics so that this will agree with the comparison operators,
    3499             :      * particularly as regards comparisons involving NaN.
    3500             :      */
    3501       18630 :     if (cmp_numerics(num1, num2) > 0)
    3502       17724 :         PG_RETURN_NUMERIC(num1);
    3503             :     else
    3504         906 :         PG_RETURN_NUMERIC(num2);
    3505             : }
    3506             : 
    3507             : 
    3508             : /* ----------------------------------------------------------------------
    3509             :  *
    3510             :  * Advanced math functions
    3511             :  *
    3512             :  * ----------------------------------------------------------------------
    3513             :  */
    3514             : 
    3515             : /*
    3516             :  * numeric_gcd() -
    3517             :  *
    3518             :  *  Calculate the greatest common divisor of two numerics
    3519             :  */
    3520             : Datum
    3521         216 : numeric_gcd(PG_FUNCTION_ARGS)
    3522             : {
    3523         216 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3524         216 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3525             :     NumericVar  arg1;
    3526             :     NumericVar  arg2;
    3527             :     NumericVar  result;
    3528             :     Numeric     res;
    3529             : 
    3530             :     /*
    3531             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3532             :      * cases.
    3533             :      */
    3534         216 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3535          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3536             : 
    3537             :     /*
    3538             :      * Unpack the arguments
    3539             :      */
    3540         120 :     init_var_from_num(num1, &arg1);
    3541         120 :     init_var_from_num(num2, &arg2);
    3542             : 
    3543         120 :     init_var(&result);
    3544             : 
    3545             :     /*
    3546             :      * Find the GCD and return the result
    3547             :      */
    3548         120 :     gcd_var(&arg1, &arg2, &result);
    3549             : 
    3550         120 :     res = make_result(&result);
    3551             : 
    3552         120 :     free_var(&result);
    3553             : 
    3554         120 :     PG_RETURN_NUMERIC(res);
    3555             : }
    3556             : 
    3557             : 
    3558             : /*
    3559             :  * numeric_lcm() -
    3560             :  *
    3561             :  *  Calculate the least common multiple of two numerics
    3562             :  */
    3563             : Datum
    3564         246 : numeric_lcm(PG_FUNCTION_ARGS)
    3565             : {
    3566         246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3567         246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3568             :     NumericVar  arg1;
    3569             :     NumericVar  arg2;
    3570             :     NumericVar  result;
    3571             :     Numeric     res;
    3572             : 
    3573             :     /*
    3574             :      * Handle NaN and infinities: we consider the result to be NaN in all such
    3575             :      * cases.
    3576             :      */
    3577         246 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3578          96 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    3579             : 
    3580             :     /*
    3581             :      * Unpack the arguments
    3582             :      */
    3583         150 :     init_var_from_num(num1, &arg1);
    3584         150 :     init_var_from_num(num2, &arg2);
    3585             : 
    3586         150 :     init_var(&result);
    3587             : 
    3588             :     /*
    3589             :      * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
    3590             :      * zero if either input is zero.
    3591             :      *
    3592             :      * Note that the division is guaranteed to be exact, returning an integer
    3593             :      * result, so the LCM is an integral multiple of both x and y.  A display
    3594             :      * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
    3595             :      * but as with other numeric functions, we choose to return a result whose
    3596             :      * display scale is no smaller than either input.
    3597             :      */
    3598         150 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
    3599          48 :         set_var_from_var(&const_zero, &result);
    3600             :     else
    3601             :     {
    3602         102 :         gcd_var(&arg1, &arg2, &result);
    3603         102 :         div_var(&arg1, &result, &result, 0, false);
    3604         102 :         mul_var(&arg2, &result, &result, arg2.dscale);
    3605         102 :         result.sign = NUMERIC_POS;
    3606             :     }
    3607             : 
    3608         150 :     result.dscale = Max(arg1.dscale, arg2.dscale);
    3609             : 
    3610         150 :     res = make_result(&result);
    3611             : 
    3612         144 :     free_var(&result);
    3613             : 
    3614         144 :     PG_RETURN_NUMERIC(res);
    3615             : }
    3616             : 
    3617             : 
    3618             : /*
    3619             :  * numeric_fac()
    3620             :  *
    3621             :  * Compute factorial
    3622             :  */
    3623             : Datum
    3624          42 : numeric_fac(PG_FUNCTION_ARGS)
    3625             : {
    3626          42 :     int64       num = PG_GETARG_INT64(0);
    3627             :     Numeric     res;
    3628             :     NumericVar  fact;
    3629             :     NumericVar  result;
    3630             : 
    3631          42 :     if (num < 0)
    3632           6 :         ereport(ERROR,
    3633             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3634             :                  errmsg("factorial of a negative number is undefined")));
    3635          36 :     if (num <= 1)
    3636             :     {
    3637           6 :         res = make_result(&const_one);
    3638           6 :         PG_RETURN_NUMERIC(res);
    3639             :     }
    3640             :     /* Fail immediately if the result would overflow */
    3641          30 :     if (num > 32177)
    3642           6 :         ereport(ERROR,
    3643             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    3644             :                  errmsg("value overflows numeric format")));
    3645             : 
    3646          24 :     init_var(&fact);
    3647          24 :     init_var(&result);
    3648             : 
    3649          24 :     int64_to_numericvar(num, &result);
    3650             : 
    3651         294 :     for (num = num - 1; num > 1; num--)
    3652             :     {
    3653             :         /* this loop can take awhile, so allow it to be interrupted */
    3654         270 :         CHECK_FOR_INTERRUPTS();
    3655             : 
    3656         270 :         int64_to_numericvar(num, &fact);
    3657             : 
    3658         270 :         mul_var(&result, &fact, &result, 0);
    3659             :     }
    3660             : 
    3661          24 :     res = make_result(&result);
    3662             : 
    3663          24 :     free_var(&fact);
    3664          24 :     free_var(&result);
    3665             : 
    3666          24 :     PG_RETURN_NUMERIC(res);
    3667             : }
    3668             : 
    3669             : 
    3670             : /*
    3671             :  * numeric_sqrt() -
    3672             :  *
    3673             :  *  Compute the square root of a numeric.
    3674             :  */
    3675             : Datum
    3676         150 : numeric_sqrt(PG_FUNCTION_ARGS)
    3677             : {
    3678         150 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3679             :     Numeric     res;
    3680             :     NumericVar  arg;
    3681             :     NumericVar  result;
    3682             :     int         sweight;
    3683             :     int         rscale;
    3684             : 
    3685             :     /*
    3686             :      * Handle NaN and infinities
    3687             :      */
    3688         150 :     if (NUMERIC_IS_SPECIAL(num))
    3689             :     {
    3690             :         /* error should match that in sqrt_var() */
    3691          18 :         if (NUMERIC_IS_NINF(num))
    3692           6 :             ereport(ERROR,
    3693             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3694             :                      errmsg("cannot take square root of a negative number")));
    3695             :         /* For NAN or PINF, just duplicate the input */
    3696          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3697             :     }
    3698             : 
    3699             :     /*
    3700             :      * Unpack the argument and determine the result scale.  We choose a scale
    3701             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3702             :      * case not less than the input's dscale.
    3703             :      */
    3704         132 :     init_var_from_num(num, &arg);
    3705             : 
    3706         132 :     init_var(&result);
    3707             : 
    3708             :     /*
    3709             :      * Assume the input was normalized, so arg.weight is accurate.  The result
    3710             :      * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
    3711             :      * digits before the decimal point.  When DEC_DIGITS is even, we can save
    3712             :      * a few cycles, since the division is exact and there is no need to round
    3713             :      * towards negative infinity.
    3714             :      */
    3715             : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
    3716         132 :     sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3717             : #else
    3718             :     if (arg.weight >= 0)
    3719             :         sweight = arg.weight * DEC_DIGITS / 2 + 1;
    3720             :     else
    3721             :         sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
    3722             : #endif
    3723             : 
    3724         132 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
    3725         132 :     rscale = Max(rscale, arg.dscale);
    3726         132 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3727         132 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3728             : 
    3729             :     /*
    3730             :      * Let sqrt_var() do the calculation and return the result.
    3731             :      */
    3732         132 :     sqrt_var(&arg, &result, rscale);
    3733             : 
    3734         126 :     res = make_result(&result);
    3735             : 
    3736         126 :     free_var(&result);
    3737             : 
    3738         126 :     PG_RETURN_NUMERIC(res);
    3739             : }
    3740             : 
    3741             : 
    3742             : /*
    3743             :  * numeric_exp() -
    3744             :  *
    3745             :  *  Raise e to the power of x
    3746             :  */
    3747             : Datum
    3748          78 : numeric_exp(PG_FUNCTION_ARGS)
    3749             : {
    3750          78 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3751             :     Numeric     res;
    3752             :     NumericVar  arg;
    3753             :     NumericVar  result;
    3754             :     int         rscale;
    3755             :     double      val;
    3756             : 
    3757             :     /*
    3758             :      * Handle NaN and infinities
    3759             :      */
    3760          78 :     if (NUMERIC_IS_SPECIAL(num))
    3761             :     {
    3762             :         /* Per POSIX, exp(-Inf) is zero */
    3763          18 :         if (NUMERIC_IS_NINF(num))
    3764           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3765             :         /* For NAN or PINF, just duplicate the input */
    3766          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3767             :     }
    3768             : 
    3769             :     /*
    3770             :      * Unpack the argument and determine the result scale.  We choose a scale
    3771             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
    3772             :      * case not less than the input's dscale.
    3773             :      */
    3774          60 :     init_var_from_num(num, &arg);
    3775             : 
    3776          60 :     init_var(&result);
    3777             : 
    3778             :     /* convert input to float8, ignoring overflow */
    3779          60 :     val = numericvar_to_double_no_overflow(&arg);
    3780             : 
    3781             :     /*
    3782             :      * log10(result) = num * log10(e), so this is approximately the decimal
    3783             :      * weight of the result:
    3784             :      */
    3785          60 :     val *= 0.434294481903252;
    3786             : 
    3787             :     /* limit to something that won't cause integer overflow */
    3788          60 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
    3789          60 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
    3790             : 
    3791          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
    3792          60 :     rscale = Max(rscale, arg.dscale);
    3793          60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3794          60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3795             : 
    3796             :     /*
    3797             :      * Let exp_var() do the calculation and return the result.
    3798             :      */
    3799          60 :     exp_var(&arg, &result, rscale);
    3800             : 
    3801          60 :     res = make_result(&result);
    3802             : 
    3803          60 :     free_var(&result);
    3804             : 
    3805          60 :     PG_RETURN_NUMERIC(res);
    3806             : }
    3807             : 
    3808             : 
    3809             : /*
    3810             :  * numeric_ln() -
    3811             :  *
    3812             :  *  Compute the natural logarithm of x
    3813             :  */
    3814             : Datum
    3815         198 : numeric_ln(PG_FUNCTION_ARGS)
    3816             : {
    3817         198 :     Numeric     num = PG_GETARG_NUMERIC(0);
    3818             :     Numeric     res;
    3819             :     NumericVar  arg;
    3820             :     NumericVar  result;
    3821             :     int         ln_dweight;
    3822             :     int         rscale;
    3823             : 
    3824             :     /*
    3825             :      * Handle NaN and infinities
    3826             :      */
    3827         198 :     if (NUMERIC_IS_SPECIAL(num))
    3828             :     {
    3829          18 :         if (NUMERIC_IS_NINF(num))
    3830           6 :             ereport(ERROR,
    3831             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3832             :                      errmsg("cannot take logarithm of a negative number")));
    3833             :         /* For NAN or PINF, just duplicate the input */
    3834          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    3835             :     }
    3836             : 
    3837         180 :     init_var_from_num(num, &arg);
    3838         180 :     init_var(&result);
    3839             : 
    3840             :     /* Estimated dweight of logarithm */
    3841         180 :     ln_dweight = estimate_ln_dweight(&arg);
    3842             : 
    3843         180 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
    3844         180 :     rscale = Max(rscale, arg.dscale);
    3845         180 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    3846         180 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    3847             : 
    3848         180 :     ln_var(&arg, &result, rscale);
    3849             : 
    3850         156 :     res = make_result(&result);
    3851             : 
    3852         156 :     free_var(&result);
    3853             : 
    3854         156 :     PG_RETURN_NUMERIC(res);
    3855             : }
    3856             : 
    3857             : 
    3858             : /*
    3859             :  * numeric_log() -
    3860             :  *
    3861             :  *  Compute the logarithm of x in a given base
    3862             :  */
    3863             : Datum
    3864         342 : numeric_log(PG_FUNCTION_ARGS)
    3865             : {
    3866         342 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3867         342 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3868             :     Numeric     res;
    3869             :     NumericVar  arg1;
    3870             :     NumericVar  arg2;
    3871             :     NumericVar  result;
    3872             : 
    3873             :     /*
    3874             :      * Handle NaN and infinities
    3875             :      */
    3876         342 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3877             :     {
    3878             :         int         sign1,
    3879             :                     sign2;
    3880             : 
    3881         126 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
    3882          54 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3883             :         /* fail on negative inputs including -Inf, as log_var would */
    3884          72 :         sign1 = numeric_sign_internal(num1);
    3885          72 :         sign2 = numeric_sign_internal(num2);
    3886          72 :         if (sign1 < 0 || sign2 < 0)
    3887          24 :             ereport(ERROR,
    3888             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3889             :                      errmsg("cannot take logarithm of a negative number")));
    3890             :         /* fail on zero inputs, as log_var would */
    3891          48 :         if (sign1 == 0 || sign2 == 0)
    3892           6 :             ereport(ERROR,
    3893             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
    3894             :                      errmsg("cannot take logarithm of zero")));
    3895          42 :         if (NUMERIC_IS_PINF(num1))
    3896             :         {
    3897             :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
    3898          18 :             if (NUMERIC_IS_PINF(num2))
    3899           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
    3900             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
    3901          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    3902             :         }
    3903             :         Assert(NUMERIC_IS_PINF(num2));
    3904             :         /* log(finite-positive, Inf) is Inf */
    3905          24 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    3906             :     }
    3907             : 
    3908             :     /*
    3909             :      * Initialize things
    3910             :      */
    3911         216 :     init_var_from_num(num1, &arg1);
    3912         216 :     init_var_from_num(num2, &arg2);
    3913         216 :     init_var(&result);
    3914             : 
    3915             :     /*
    3916             :      * Call log_var() to compute and return the result; note it handles scale
    3917             :      * selection itself.
    3918             :      */
    3919         216 :     log_var(&arg1, &arg2, &result);
    3920             : 
    3921         156 :     res = make_result(&result);
    3922             : 
    3923         156 :     free_var(&result);
    3924             : 
    3925         156 :     PG_RETURN_NUMERIC(res);
    3926             : }
    3927             : 
    3928             : 
    3929             : /*
    3930             :  * numeric_power() -
    3931             :  *
    3932             :  *  Raise x to the power of y
    3933             :  */
    3934             : Datum
    3935        1632 : numeric_power(PG_FUNCTION_ARGS)
    3936             : {
    3937        1632 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
    3938        1632 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
    3939             :     Numeric     res;
    3940             :     NumericVar  arg1;
    3941             :     NumericVar  arg2;
    3942             :     NumericVar  result;
    3943             :     int         sign1,
    3944             :                 sign2;
    3945             : 
    3946             :     /*
    3947             :      * Handle NaN and infinities
    3948             :      */
    3949        1632 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
    3950             :     {
    3951             :         /*
    3952             :          * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
    3953             :          * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
    3954             :          * (with no error).
    3955             :          */
    3956         234 :         if (NUMERIC_IS_NAN(num1))
    3957             :         {
    3958          54 :             if (!NUMERIC_IS_SPECIAL(num2))
    3959             :             {
    3960          36 :                 init_var_from_num(num2, &arg2);
    3961          36 :                 if (cmp_var(&arg2, &const_zero) == 0)
    3962          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3963             :             }
    3964          42 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3965             :         }
    3966         180 :         if (NUMERIC_IS_NAN(num2))
    3967             :         {
    3968          42 :             if (!NUMERIC_IS_SPECIAL(num1))
    3969             :             {
    3970          36 :                 init_var_from_num(num1, &arg1);
    3971          36 :                 if (cmp_var(&arg1, &const_one) == 0)
    3972          12 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    3973             :             }
    3974          30 :             PG_RETURN_NUMERIC(make_result(&const_nan));
    3975             :         }
    3976             :         /* At least one input is infinite, but error rules still apply */
    3977         138 :         sign1 = numeric_sign_internal(num1);
    3978         138 :         sign2 = numeric_sign_internal(num2);
    3979         138 :         if (sign1 == 0 && sign2 < 0)
    3980           6 :             ereport(ERROR,
    3981             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3982             :                      errmsg("zero raised to a negative power is undefined")));
    3983         132 :         if (sign1 < 0 && !numeric_is_integral(num2))
    3984           6 :             ereport(ERROR,
    3985             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    3986             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
    3987             : 
    3988             :         /*
    3989             :          * POSIX gives this series of rules for pow(3) with infinite inputs:
    3990             :          *
    3991             :          * For any value of y, if x is +1, 1.0 shall be returned.
    3992             :          */
    3993         126 :         if (!NUMERIC_IS_SPECIAL(num1))
    3994             :         {
    3995          42 :             init_var_from_num(num1, &arg1);
    3996          42 :             if (cmp_var(&arg1, &const_one) == 0)
    3997           6 :                 PG_RETURN_NUMERIC(make_result(&const_one));
    3998             :         }
    3999             : 
    4000             :         /*
    4001             :          * For any value of x, if y is [-]0, 1.0 shall be returned.
    4002             :          */
    4003         120 :         if (sign2 == 0)
    4004          12 :             PG_RETURN_NUMERIC(make_result(&const_one));
    4005             : 
    4006             :         /*
    4007             :          * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
    4008             :          * returned.  For y > 0 and not an odd integer, if x is [-]0, +0 shall
    4009             :          * be returned.  (Since we don't deal in minus zero, we need not
    4010             :          * distinguish these two cases.)
    4011             :          */
    4012         108 :         if (sign1 == 0 && sign2 > 0)
    4013           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4014             : 
    4015             :         /*
    4016             :          * If x is -1, and y is [-]Inf, 1.0 shall be returned.
    4017             :          *
    4018             :          * For |x| < 1, if y is -Inf, +Inf shall be returned.
    4019             :          *
    4020             :          * For |x| > 1, if y is -Inf, +0 shall be returned.
    4021             :          *
    4022             :          * For |x| < 1, if y is +Inf, +0 shall be returned.
    4023             :          *
    4024             :          * For |x| > 1, if y is +Inf, +Inf shall be returned.
    4025             :          */
    4026         102 :         if (NUMERIC_IS_INF(num2))
    4027             :         {
    4028             :             bool        abs_x_gt_one;
    4029             : 
    4030          54 :             if (NUMERIC_IS_SPECIAL(num1))
    4031          24 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
    4032             :             else
    4033             :             {
    4034          30 :                 init_var_from_num(num1, &arg1);
    4035          30 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
    4036           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
    4037          24 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
    4038          24 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
    4039             :             }
    4040          48 :             if (abs_x_gt_one == (sign2 > 0))
    4041          30 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4042             :             else
    4043          18 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4044             :         }
    4045             : 
    4046             :         /*
    4047             :          * For y < 0, if x is +Inf, +0 shall be returned.
    4048             :          *
    4049             :          * For y > 0, if x is +Inf, +Inf shall be returned.
    4050             :          */
    4051          48 :         if (NUMERIC_IS_PINF(num1))
    4052             :         {
    4053          24 :             if (sign2 > 0)
    4054          18 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
    4055             :             else
    4056           6 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
    4057             :         }
    4058             : 
    4059             :         Assert(NUMERIC_IS_NINF(num1));
    4060             : 
    4061             :         /*
    4062             :          * For y an odd integer < 0, if x is -Inf, -0 shall be returned.  For
    4063             :          * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
    4064             :          * (Again, we need not distinguish these two cases.)
    4065             :          */
    4066          24 :         if (sign2 < 0)
    4067          12 :             PG_RETURN_NUMERIC(make_result(&const_zero));
    4068             : 
    4069             :         /*
    4070             :          * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
    4071             :          * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
    4072             :          */
    4073          12 :         init_var_from_num(num2, &arg2);
    4074          12 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
    4075          12 :             (arg2.digits[arg2.ndigits - 1] & 1))
    4076           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4077             :         else
    4078           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4079             :     }
    4080             : 
    4081             :     /*
    4082             :      * The SQL spec requires that we emit a particular SQLSTATE error code for
    4083             :      * certain error conditions.  Specifically, we don't return a
    4084             :      * divide-by-zero error code for 0 ^ -1.  Raising a negative number to a
    4085             :      * non-integer power must produce the same error code, but that case is
    4086             :      * handled in power_var().
    4087             :      */
    4088        1398 :     sign1 = numeric_sign_internal(num1);
    4089        1398 :     sign2 = numeric_sign_internal(num2);
    4090             : 
    4091        1398 :     if (sign1 == 0 && sign2 < 0)
    4092          12 :         ereport(ERROR,
    4093             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
    4094             :                  errmsg("zero raised to a negative power is undefined")));
    4095             : 
    4096             :     /*
    4097             :      * Initialize things
    4098             :      */
    4099        1386 :     init_var(&result);
    4100        1386 :     init_var_from_num(num1, &arg1);
    4101        1386 :     init_var_from_num(num2, &arg2);
    4102             : 
    4103             :     /*
    4104             :      * Call power_var() to compute and return the result; note it handles
    4105             :      * scale selection itself.
    4106             :      */
    4107        1386 :     power_var(&arg1, &arg2, &result);
    4108             : 
    4109        1356 :     res = make_result(&result);
    4110             : 
    4111        1356 :     free_var(&result);
    4112             : 
    4113        1356 :     PG_RETURN_NUMERIC(res);
    4114             : }
    4115             : 
    4116             : /*
    4117             :  * numeric_scale() -
    4118             :  *
    4119             :  *  Returns the scale, i.e. the count of decimal digits in the fractional part
    4120             :  */
    4121             : Datum
    4122         108 : numeric_scale(PG_FUNCTION_ARGS)
    4123             : {
    4124         108 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4125             : 
    4126         108 :     if (NUMERIC_IS_SPECIAL(num))
    4127          18 :         PG_RETURN_NULL();
    4128             : 
    4129          90 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
    4130             : }
    4131             : 
    4132             : /*
    4133             :  * Calculate minimum scale for value.
    4134             :  */
    4135             : static int
    4136         372 : get_min_scale(NumericVar *var)
    4137             : {
    4138             :     int         min_scale;
    4139             :     int         last_digit_pos;
    4140             : 
    4141             :     /*
    4142             :      * Ordinarily, the input value will be "stripped" so that the last
    4143             :      * NumericDigit is nonzero.  But we don't want to get into an infinite
    4144             :      * loop if it isn't, so explicitly find the last nonzero digit.
    4145             :      */
    4146         372 :     last_digit_pos = var->ndigits - 1;
    4147         372 :     while (last_digit_pos >= 0 &&
    4148         342 :            var->digits[last_digit_pos] == 0)
    4149           0 :         last_digit_pos--;
    4150             : 
    4151         372 :     if (last_digit_pos >= 0)
    4152             :     {
    4153             :         /* compute min_scale assuming that last ndigit has no zeroes */
    4154         342 :         min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
    4155             : 
    4156             :         /*
    4157             :          * We could get a negative result if there are no digits after the
    4158             :          * decimal point.  In this case the min_scale must be zero.
    4159             :          */
    4160         342 :         if (min_scale > 0)
    4161             :         {
    4162             :             /*
    4163             :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
    4164             :              * zero.
    4165             :              */
    4166         186 :             NumericDigit last_digit = var->digits[last_digit_pos];
    4167             : 
    4168         498 :             while (last_digit % 10 == 0)
    4169             :             {
    4170         312 :                 min_scale--;
    4171         312 :                 last_digit /= 10;
    4172             :             }
    4173             :         }
    4174             :         else
    4175         156 :             min_scale = 0;
    4176             :     }
    4177             :     else
    4178          30 :         min_scale = 0;          /* result if input is zero */
    4179             : 
    4180         372 :     return min_scale;
    4181             : }
    4182             : 
    4183             : /*
    4184             :  * Returns minimum scale required to represent supplied value without loss.
    4185             :  */
    4186             : Datum
    4187          72 : numeric_min_scale(PG_FUNCTION_ARGS)
    4188             : {
    4189          72 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4190             :     NumericVar  arg;
    4191             :     int         min_scale;
    4192             : 
    4193          72 :     if (NUMERIC_IS_SPECIAL(num))
    4194          12 :         PG_RETURN_NULL();
    4195             : 
    4196          60 :     init_var_from_num(num, &arg);
    4197          60 :     min_scale = get_min_scale(&arg);
    4198          60 :     free_var(&arg);
    4199             : 
    4200          60 :     PG_RETURN_INT32(min_scale);
    4201             : }
    4202             : 
    4203             : /*
    4204             :  * Reduce scale of numeric value to represent supplied value without loss.
    4205             :  */
    4206             : Datum
    4207         324 : numeric_trim_scale(PG_FUNCTION_ARGS)
    4208             : {
    4209         324 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4210             :     Numeric     res;
    4211             :     NumericVar  result;
    4212             : 
    4213         324 :     if (NUMERIC_IS_SPECIAL(num))
    4214          12 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
    4215             : 
    4216         312 :     init_var_from_num(num, &result);
    4217         312 :     result.dscale = get_min_scale(&result);
    4218         312 :     res = make_result(&result);
    4219         312 :     free_var(&result);
    4220             : 
    4221         312 :     PG_RETURN_NUMERIC(res);
    4222             : }
    4223             : 
    4224             : /*
    4225             :  * Return a random numeric value in the range [rmin, rmax].
    4226             :  */
    4227             : Numeric
    4228       33462 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
    4229             : {
    4230             :     NumericVar  rmin_var;
    4231             :     NumericVar  rmax_var;
    4232             :     NumericVar  result;
    4233             :     Numeric     res;
    4234             : 
    4235             :     /* Range bounds must not be NaN/infinity */
    4236       33462 :     if (NUMERIC_IS_SPECIAL(rmin))
    4237             :     {
    4238          12 :         if (NUMERIC_IS_NAN(rmin))
    4239           6 :             ereport(ERROR,
    4240             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4241             :                     errmsg("lower bound cannot be NaN"));
    4242             :         else
    4243           6 :             ereport(ERROR,
    4244             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4245             :                     errmsg("lower bound cannot be infinity"));
    4246             :     }
    4247       33450 :     if (NUMERIC_IS_SPECIAL(rmax))
    4248             :     {
    4249          12 :         if (NUMERIC_IS_NAN(rmax))
    4250           6 :             ereport(ERROR,
    4251             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4252             :                     errmsg("upper bound cannot be NaN"));
    4253             :         else
    4254           6 :             ereport(ERROR,
    4255             :                     errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4256             :                     errmsg("upper bound cannot be infinity"));
    4257             :     }
    4258             : 
    4259             :     /* Return a random value in the range [rmin, rmax] */
    4260       33438 :     init_var_from_num(rmin, &rmin_var);
    4261       33438 :     init_var_from_num(rmax, &rmax_var);
    4262             : 
    4263       33438 :     init_var(&result);
    4264             : 
    4265       33438 :     random_var(state, &rmin_var, &rmax_var, &result);
    4266             : 
    4267       33432 :     res = make_result(&result);
    4268             : 
    4269       33432 :     free_var(&result);
    4270             : 
    4271       33432 :     return res;
    4272             : }
    4273             : 
    4274             : 
    4275             : /* ----------------------------------------------------------------------
    4276             :  *
    4277             :  * Type conversion functions
    4278             :  *
    4279             :  * ----------------------------------------------------------------------
    4280             :  */
    4281             : 
    4282             : Numeric
    4283     1849972 : int64_to_numeric(int64 val)
    4284             : {
    4285             :     Numeric     res;
    4286             :     NumericVar  result;
    4287             : 
    4288     1849972 :     init_var(&result);
    4289             : 
    4290     1849972 :     int64_to_numericvar(val, &result);
    4291             : 
    4292     1849972 :     res = make_result(&result);
    4293             : 
    4294     1849972 :     free_var(&result);
    4295             : 
    4296     1849972 :     return res;
    4297             : }
    4298             : 
    4299             : /*
    4300             :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
    4301             :  * numeric division.
    4302             :  */
    4303             : Numeric
    4304       29200 : int64_div_fast_to_numeric(int64 val1, int log10val2)
    4305             : {
    4306             :     Numeric     res;
    4307             :     NumericVar  result;
    4308             :     int         rscale;
    4309             :     int         w;
    4310             :     int         m;
    4311             : 
    4312       29200 :     init_var(&result);
    4313             : 
    4314             :     /* result scale */
    4315       29200 :     rscale = log10val2 < 0 ? 0 : log10val2;
    4316             : 
    4317             :     /* how much to decrease the weight by */
    4318       29200 :     w = log10val2 / DEC_DIGITS;
    4319             :     /* how much is left to divide by */
    4320       29200 :     m = log10val2 % DEC_DIGITS;
    4321       29200 :     if (m < 0)
    4322             :     {
    4323           0 :         m += DEC_DIGITS;
    4324           0 :         w--;
    4325             :     }
    4326             : 
    4327             :     /*
    4328             :      * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
    4329             :      * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
    4330             :      * one more.
    4331             :      */
    4332       29200 :     if (m > 0)
    4333             :     {
    4334             : #if DEC_DIGITS == 4
    4335             :         static const int pow10[] = {1, 10, 100, 1000};
    4336             : #elif DEC_DIGITS == 2
    4337             :         static const int pow10[] = {1, 10};
    4338             : #elif DEC_DIGITS == 1
    4339             :         static const int pow10[] = {1};
    4340             : #else
    4341             : #error unsupported NBASE
    4342             : #endif
    4343       29200 :         int64       factor = pow10[DEC_DIGITS - m];
    4344             :         int64       new_val1;
    4345             : 
    4346             :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
    4347             : 
    4348       29200 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
    4349             :         {
    4350             : #ifdef HAVE_INT128
    4351             :             /* do the multiplication using 128-bit integers */
    4352             :             int128      tmp;
    4353             : 
    4354          12 :             tmp = (int128) val1 * (int128) factor;
    4355             : 
    4356          12 :             int128_to_numericvar(tmp, &result);
    4357             : #else
    4358             :             /* do the multiplication using numerics */
    4359             :             NumericVar  tmp;
    4360             : 
    4361             :             init_var(&tmp);
    4362             : 
    4363             :             int64_to_numericvar(val1, &result);
    4364             :             int64_to_numericvar(factor, &tmp);
    4365             :             mul_var(&result, &tmp, &result, 0);
    4366             : 
    4367             :             free_var(&tmp);
    4368             : #endif
    4369             :         }
    4370             :         else
    4371       29188 :             int64_to_numericvar(new_val1, &result);
    4372             : 
    4373       29200 :         w++;
    4374             :     }
    4375             :     else
    4376           0 :         int64_to_numericvar(val1, &result);
    4377             : 
    4378       29200 :     result.weight -= w;
    4379       29200 :     result.dscale = rscale;
    4380             : 
    4381       29200 :     res = make_result(&result);
    4382             : 
    4383       29200 :     free_var(&result);
    4384             : 
    4385       29200 :     return res;
    4386             : }
    4387             : 
    4388             : Datum
    4389     1532330 : int4_numeric(PG_FUNCTION_ARGS)
    4390             : {
    4391     1532330 :     int32       val = PG_GETARG_INT32(0);
    4392             : 
    4393     1532330 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4394             : }
    4395             : 
    4396             : int32
    4397        8490 : numeric_int4_opt_error(Numeric num, bool *have_error)
    4398             : {
    4399             :     NumericVar  x;
    4400             :     int32       result;
    4401             : 
    4402        8490 :     if (have_error)
    4403        1500 :         *have_error = false;
    4404             : 
    4405        8490 :     if (NUMERIC_IS_SPECIAL(num))
    4406             :     {
    4407          18 :         if (have_error)
    4408             :         {
    4409           0 :             *have_error = true;
    4410           0 :             return 0;
    4411             :         }
    4412             :         else
    4413             :         {
    4414          18 :             if (NUMERIC_IS_NAN(num))
    4415           6 :                 ereport(ERROR,
    4416             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4417             :                          errmsg("cannot convert NaN to %s", "integer")));
    4418             :             else
    4419          12 :                 ereport(ERROR,
    4420             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4421             :                          errmsg("cannot convert infinity to %s", "integer")));
    4422             :         }
    4423             :     }
    4424             : 
    4425             :     /* Convert to variable format, then convert to int4 */
    4426        8472 :     init_var_from_num(num, &x);
    4427             : 
    4428        8472 :     if (!numericvar_to_int32(&x, &result))
    4429             :     {
    4430          84 :         if (have_error)
    4431             :         {
    4432          72 :             *have_error = true;
    4433          72 :             return 0;
    4434             :         }
    4435             :         else
    4436             :         {
    4437          12 :             ereport(ERROR,
    4438             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4439             :                      errmsg("integer out of range")));
    4440             :         }
    4441             :     }
    4442             : 
    4443        8388 :     return result;
    4444             : }
    4445             : 
    4446             : Datum
    4447        6990 : numeric_int4(PG_FUNCTION_ARGS)
    4448             : {
    4449        6990 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4450             : 
    4451        6990 :     PG_RETURN_INT32(numeric_int4_opt_error(num, NULL));
    4452             : }
    4453             : 
    4454             : /*
    4455             :  * Given a NumericVar, convert it to an int32. If the NumericVar
    4456             :  * exceeds the range of an int32, false is returned, otherwise true is returned.
    4457             :  * The input NumericVar is *not* free'd.
    4458             :  */
    4459             : static bool
    4460        9210 : numericvar_to_int32(const NumericVar *var, int32 *result)
    4461             : {
    4462             :     int64       val;
    4463             : 
    4464        9210 :     if (!numericvar_to_int64(var, &val))
    4465           6 :         return false;
    4466             : 
    4467        9204 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
    4468          78 :         return false;
    4469             : 
    4470             :     /* Down-convert to int4 */
    4471        9126 :     *result = (int32) val;
    4472             : 
    4473        9126 :     return true;
    4474             : }
    4475             : 
    4476             : Datum
    4477       36824 : int8_numeric(PG_FUNCTION_ARGS)
    4478             : {
    4479       36824 :     int64       val = PG_GETARG_INT64(0);
    4480             : 
    4481       36824 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4482             : }
    4483             : 
    4484             : int64
    4485         564 : numeric_int8_opt_error(Numeric num, bool *have_error)
    4486             : {
    4487             :     NumericVar  x;
    4488             :     int64       result;
    4489             : 
    4490         564 :     if (have_error)
    4491          48 :         *have_error = false;
    4492             : 
    4493         564 :     if (NUMERIC_IS_SPECIAL(num))
    4494             :     {
    4495          18 :         if (have_error)
    4496             :         {
    4497           0 :             *have_error = true;
    4498           0 :             return 0;
    4499             :         }
    4500             :         else
    4501             :         {
    4502          18 :             if (NUMERIC_IS_NAN(num))
    4503           6 :                 ereport(ERROR,
    4504             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4505             :                          errmsg("cannot convert NaN to %s", "bigint")));
    4506             :             else
    4507          12 :                 ereport(ERROR,
    4508             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4509             :                          errmsg("cannot convert infinity to %s", "bigint")));
    4510             :         }
    4511             :     }
    4512             : 
    4513             :     /* Convert to variable format, then convert to int8 */
    4514         546 :     init_var_from_num(num, &x);
    4515             : 
    4516         546 :     if (!numericvar_to_int64(&x, &result))
    4517             :     {
    4518          60 :         if (have_error)
    4519             :         {
    4520          12 :             *have_error = true;
    4521          12 :             return 0;
    4522             :         }
    4523             :         else
    4524             :         {
    4525          48 :             ereport(ERROR,
    4526             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4527             :                      errmsg("bigint out of range")));
    4528             :         }
    4529             :     }
    4530             : 
    4531         486 :     return result;
    4532             : }
    4533             : 
    4534             : Datum
    4535         516 : numeric_int8(PG_FUNCTION_ARGS)
    4536             : {
    4537         516 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4538             : 
    4539         516 :     PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
    4540             : }
    4541             : 
    4542             : 
    4543             : Datum
    4544           6 : int2_numeric(PG_FUNCTION_ARGS)
    4545             : {
    4546           6 :     int16       val = PG_GETARG_INT16(0);
    4547             : 
    4548           6 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
    4549             : }
    4550             : 
    4551             : 
    4552             : Datum
    4553          96 : numeric_int2(PG_FUNCTION_ARGS)
    4554             : {
    4555          96 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4556             :     NumericVar  x;
    4557             :     int64       val;
    4558             :     int16       result;
    4559             : 
    4560          96 :     if (NUMERIC_IS_SPECIAL(num))
    4561             :     {
    4562          18 :         if (NUMERIC_IS_NAN(num))
    4563           6 :             ereport(ERROR,
    4564             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4565             :                      errmsg("cannot convert NaN to %s", "smallint")));
    4566             :         else
    4567          12 :             ereport(ERROR,
    4568             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4569             :                      errmsg("cannot convert infinity to %s", "smallint")));
    4570             :     }
    4571             : 
    4572             :     /* Convert to variable format and thence to int8 */
    4573          78 :     init_var_from_num(num, &x);
    4574             : 
    4575          78 :     if (!numericvar_to_int64(&x, &val))
    4576           0 :         ereport(ERROR,
    4577             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4578             :                  errmsg("smallint out of range")));
    4579             : 
    4580          78 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
    4581          12 :         ereport(ERROR,
    4582             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    4583             :                  errmsg("smallint out of range")));
    4584             : 
    4585             :     /* Down-convert to int2 */
    4586          66 :     result = (int16) val;
    4587             : 
    4588          66 :     PG_RETURN_INT16(result);
    4589             : }
    4590             : 
    4591             : 
    4592             : Datum
    4593        1074 : float8_numeric(PG_FUNCTION_ARGS)
    4594             : {
    4595        1074 :     float8      val = PG_GETARG_FLOAT8(0);
    4596             :     Numeric     res;
    4597             :     NumericVar  result;
    4598             :     char        buf[DBL_DIG + 100];
    4599             :     const char *endptr;
    4600             : 
    4601        1074 :     if (isnan(val))
    4602           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4603             : 
    4604        1068 :     if (isinf(val))
    4605             :     {
    4606          12 :         if (val < 0)
    4607           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4608             :         else
    4609           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4610             :     }
    4611             : 
    4612        1056 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
    4613             : 
    4614        1056 :     init_var(&result);
    4615             : 
    4616             :     /* Assume we need not worry about leading/trailing spaces */
    4617        1056 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4618             : 
    4619        1056 :     res = make_result(&result);
    4620             : 
    4621        1056 :     free_var(&result);
    4622             : 
    4623        1056 :     PG_RETURN_NUMERIC(res);
    4624             : }
    4625             : 
    4626             : 
    4627             : Datum
    4628      519142 : numeric_float8(PG_FUNCTION_ARGS)
    4629             : {
    4630      519142 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4631             :     char       *tmp;
    4632             :     Datum       result;
    4633             : 
    4634      519142 :     if (NUMERIC_IS_SPECIAL(num))
    4635             :     {
    4636          78 :         if (NUMERIC_IS_PINF(num))
    4637          24 :             PG_RETURN_FLOAT8(get_float8_infinity());
    4638          54 :         else if (NUMERIC_IS_NINF(num))
    4639          24 :             PG_RETURN_FLOAT8(-get_float8_infinity());
    4640             :         else
    4641          30 :             PG_RETURN_FLOAT8(get_float8_nan());
    4642             :     }
    4643             : 
    4644      519064 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4645             :                                               NumericGetDatum(num)));
    4646             : 
    4647      519064 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
    4648             : 
    4649      519064 :     pfree(tmp);
    4650             : 
    4651      519064 :     PG_RETURN_DATUM(result);
    4652             : }
    4653             : 
    4654             : 
    4655             : /*
    4656             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
    4657             :  *
    4658             :  * (internal helper function, not directly callable from SQL)
    4659             :  */
    4660             : Datum
    4661        3170 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
    4662             : {
    4663        3170 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4664             :     double      val;
    4665             : 
    4666        3170 :     if (NUMERIC_IS_SPECIAL(num))
    4667             :     {
    4668           0 :         if (NUMERIC_IS_PINF(num))
    4669           0 :             val = HUGE_VAL;
    4670           0 :         else if (NUMERIC_IS_NINF(num))
    4671           0 :             val = -HUGE_VAL;
    4672             :         else
    4673           0 :             val = get_float8_nan();
    4674             :     }
    4675             :     else
    4676             :     {
    4677             :         NumericVar  x;
    4678             : 
    4679        3170 :         init_var_from_num(num, &x);
    4680        3170 :         val = numericvar_to_double_no_overflow(&x);
    4681             :     }
    4682             : 
    4683        3170 :     PG_RETURN_FLOAT8(val);
    4684             : }
    4685             : 
    4686             : Datum
    4687       21648 : float4_numeric(PG_FUNCTION_ARGS)
    4688             : {
    4689       21648 :     float4      val = PG_GETARG_FLOAT4(0);
    4690             :     Numeric     res;
    4691             :     NumericVar  result;
    4692             :     char        buf[FLT_DIG + 100];
    4693             :     const char *endptr;
    4694             : 
    4695       21648 :     if (isnan(val))
    4696           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    4697             : 
    4698       21642 :     if (isinf(val))
    4699             :     {
    4700          12 :         if (val < 0)
    4701           6 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
    4702             :         else
    4703           6 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
    4704             :     }
    4705             : 
    4706       21630 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
    4707             : 
    4708       21630 :     init_var(&result);
    4709             : 
    4710             :     /* Assume we need not worry about leading/trailing spaces */
    4711       21630 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
    4712             : 
    4713       21630 :     res = make_result(&result);
    4714             : 
    4715       21630 :     free_var(&result);
    4716             : 
    4717       21630 :     PG_RETURN_NUMERIC(res);
    4718             : }
    4719             : 
    4720             : 
    4721             : Datum
    4722        2192 : numeric_float4(PG_FUNCTION_ARGS)
    4723             : {
    4724        2192 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4725             :     char       *tmp;
    4726             :     Datum       result;
    4727             : 
    4728        2192 :     if (NUMERIC_IS_SPECIAL(num))
    4729             :     {
    4730          78 :         if (NUMERIC_IS_PINF(num))
    4731          24 :             PG_RETURN_FLOAT4(get_float4_infinity());
    4732          54 :         else if (NUMERIC_IS_NINF(num))
    4733          24 :             PG_RETURN_FLOAT4(-get_float4_infinity());
    4734             :         else
    4735          30 :             PG_RETURN_FLOAT4(get_float4_nan());
    4736             :     }
    4737             : 
    4738        2114 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
    4739             :                                               NumericGetDatum(num)));
    4740             : 
    4741        2114 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
    4742             : 
    4743        2114 :     pfree(tmp);
    4744             : 
    4745        2114 :     PG_RETURN_DATUM(result);
    4746             : }
    4747             : 
    4748             : 
    4749             : Datum
    4750         120 : numeric_pg_lsn(PG_FUNCTION_ARGS)
    4751             : {
    4752         120 :     Numeric     num = PG_GETARG_NUMERIC(0);
    4753             :     NumericVar  x;
    4754             :     XLogRecPtr  result;
    4755             : 
    4756         120 :     if (NUMERIC_IS_SPECIAL(num))
    4757             :     {
    4758           6 :         if (NUMERIC_IS_NAN(num))
    4759           6 :             ereport(ERROR,
    4760             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4761             :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
    4762             :         else
    4763           0 :             ereport(ERROR,
    4764             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    4765             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
    4766             :     }
    4767             : 
    4768             :     /* Convert to variable format and thence to pg_lsn */
    4769         114 :     init_var_from_num(num, &x);
    4770             : 
    4771         114 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
    4772          24 :         ereport(ERROR,
    4773             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    4774             :                  errmsg("pg_lsn out of range")));
    4775             : 
    4776          90 :     PG_RETURN_LSN(result);
    4777             : }
    4778             : 
    4779             : 
    4780             : /* ----------------------------------------------------------------------
    4781             :  *
    4782             :  * Aggregate functions
    4783             :  *
    4784             :  * The transition datatype for all these aggregates is declared as INTERNAL.
    4785             :  * Actually, it's a pointer to a NumericAggState allocated in the aggregate
    4786             :  * context.  The digit buffers for the NumericVars will be there too.
    4787             :  *
    4788             :  * On platforms which support 128-bit integers some aggregates instead use a
    4789             :  * 128-bit integer based transition datatype to speed up calculations.
    4790             :  *
    4791             :  * ----------------------------------------------------------------------
    4792             :  */
    4793             : 
    4794             : typedef struct NumericAggState
    4795             : {
    4796             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    4797             :     MemoryContext agg_context;  /* context we're calculating in */
    4798             :     int64       N;              /* count of processed numbers */
    4799             :     NumericSumAccum sumX;       /* sum of processed numbers */
    4800             :     NumericSumAccum sumX2;      /* sum of squares of processed numbers */
    4801             :     int         maxScale;       /* maximum scale seen so far */
    4802             :     int64       maxScaleCount;  /* number of values seen with maximum scale */
    4803             :     /* These counts are *not* included in N!  Use NA_TOTAL_COUNT() as needed */
    4804             :     int64       NaNcount;       /* count of NaN values */
    4805             :     int64       pInfcount;      /* count of +Inf values */
    4806             :     int64       nInfcount;      /* count of -Inf values */
    4807             : } NumericAggState;
    4808             : 
    4809             : #define NA_TOTAL_COUNT(na) \
    4810             :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
    4811             : 
    4812             : /*
    4813             :  * Prepare state data for a numeric aggregate function that needs to compute
    4814             :  * sum, count and optionally sum of squares of the input.
    4815             :  */
    4816             : static NumericAggState *
    4817      171120 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
    4818             : {
    4819             :     NumericAggState *state;
    4820             :     MemoryContext agg_context;
    4821             :     MemoryContext old_context;
    4822             : 
    4823      171120 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    4824           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    4825             : 
    4826      171120 :     old_context = MemoryContextSwitchTo(agg_context);
    4827             : 
    4828      171120 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4829      171120 :     state->calcSumX2 = calcSumX2;
    4830      171120 :     state->agg_context = agg_context;
    4831             : 
    4832      171120 :     MemoryContextSwitchTo(old_context);
    4833             : 
    4834      171120 :     return state;
    4835             : }
    4836             : 
    4837             : /*
    4838             :  * Like makeNumericAggState(), but allocate the state in the current memory
    4839             :  * context.
    4840             :  */
    4841             : static NumericAggState *
    4842          64 : makeNumericAggStateCurrentContext(bool calcSumX2)
    4843             : {
    4844             :     NumericAggState *state;
    4845             : 
    4846          64 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
    4847          64 :     state->calcSumX2 = calcSumX2;
    4848          64 :     state->agg_context = CurrentMemoryContext;
    4849             : 
    4850          64 :     return state;
    4851             : }
    4852             : 
    4853             : /*
    4854             :  * Accumulate a new input value for numeric aggregate functions.
    4855             :  */
    4856             : static void
    4857     2113552 : do_numeric_accum(NumericAggState *state, Numeric newval)
    4858             : {
    4859             :     NumericVar  X;
    4860             :     NumericVar  X2;
    4861             :     MemoryContext old_context;
    4862             : 
    4863             :     /* Count NaN/infinity inputs separately from all else */
    4864     2113552 :     if (NUMERIC_IS_SPECIAL(newval))
    4865             :     {
    4866         162 :         if (NUMERIC_IS_PINF(newval))
    4867          72 :             state->pInfcount++;
    4868          90 :         else if (NUMERIC_IS_NINF(newval))
    4869          36 :             state->nInfcount++;
    4870             :         else
    4871          54 :             state->NaNcount++;
    4872         162 :         return;
    4873             :     }
    4874             : 
    4875             :     /* load processed number in short-lived context */
    4876     2113390 :     init_var_from_num(newval, &X);
    4877             : 
    4878             :     /*
    4879             :      * Track the highest input dscale that we've seen, to support inverse
    4880             :      * transitions (see do_numeric_discard).
    4881             :      */
    4882     2113390 :     if (X.dscale > state->maxScale)
    4883             :     {
    4884         156 :         state->maxScale = X.dscale;
    4885         156 :         state->maxScaleCount = 1;
    4886             :     }
    4887     2113234 :     else if (X.dscale == state->maxScale)
    4888     2113198 :         state->maxScaleCount++;
    4889             : 
    4890             :     /* if we need X^2, calculate that in short-lived context */
    4891     2113390 :     if (state->calcSumX2)
    4892             :     {
    4893      240732 :         init_var(&X2);
    4894      240732 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4895             :     }
    4896             : 
    4897             :     /* The rest of this needs to work in the aggregate context */
    4898     2113390 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4899             : 
    4900     2113390 :     state->N++;
    4901             : 
    4902             :     /* Accumulate sums */
    4903     2113390 :     accum_sum_add(&(state->sumX), &X);
    4904             : 
    4905     2113390 :     if (state->calcSumX2)
    4906      240732 :         accum_sum_add(&(state->sumX2), &X2);
    4907             : 
    4908     2113390 :     MemoryContextSwitchTo(old_context);
    4909             : }
    4910             : 
    4911             : /*
    4912             :  * Attempt to remove an input value from the aggregated state.
    4913             :  *
    4914             :  * If the value cannot be removed then the function will return false; the
    4915             :  * possible reasons for failing are described below.
    4916             :  *
    4917             :  * If we aggregate the values 1.01 and 2 then the result will be 3.01.
    4918             :  * If we are then asked to un-aggregate the 1.01 then we must fail as we
    4919             :  * won't be able to tell what the new aggregated value's dscale should be.
    4920             :  * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
    4921             :  * have been zero if we'd really aggregated only 2.
    4922             :  *
    4923             :  * Note: alternatively, we could count the number of inputs with each possible
    4924             :  * dscale (up to some sane limit).  Not yet clear if it's worth the trouble.
    4925             :  */
    4926             : static bool
    4927         342 : do_numeric_discard(NumericAggState *state, Numeric newval)
    4928             : {
    4929             :     NumericVar  X;
    4930             :     NumericVar  X2;
    4931             :     MemoryContext old_context;
    4932             : 
    4933             :     /* Count NaN/infinity inputs separately from all else */
    4934         342 :     if (NUMERIC_IS_SPECIAL(newval))
    4935             :     {
    4936           6 :         if (NUMERIC_IS_PINF(newval))
    4937           0 :             state->pInfcount--;
    4938           6 :         else if (NUMERIC_IS_NINF(newval))
    4939           0 :             state->nInfcount--;
    4940             :         else
    4941           6 :             state->NaNcount--;
    4942           6 :         return true;
    4943             :     }
    4944             : 
    4945             :     /* load processed number in short-lived context */
    4946         336 :     init_var_from_num(newval, &X);
    4947             : 
    4948             :     /*
    4949             :      * state->sumX's dscale is the maximum dscale of any of the inputs.
    4950             :      * Removing the last input with that dscale would require us to recompute
    4951             :      * the maximum dscale of the *remaining* inputs, which we cannot do unless
    4952             :      * no more non-NaN inputs remain at all.  So we report a failure instead,
    4953             :      * and force the aggregation to be redone from scratch.
    4954             :      */
    4955         336 :     if (X.dscale == state->maxScale)
    4956             :     {
    4957         336 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
    4958             :         {
    4959             :             /*
    4960             :              * Some remaining inputs have same dscale, or dscale hasn't gotten
    4961             :              * above zero anyway
    4962             :              */
    4963         318 :             state->maxScaleCount--;
    4964             :         }
    4965          18 :         else if (state->N == 1)
    4966             :         {
    4967             :             /* No remaining non-NaN inputs at all, so reset maxScale */
    4968          12 :             state->maxScale = 0;
    4969          12 :             state->maxScaleCount = 0;
    4970             :         }
    4971             :         else
    4972             :         {
    4973             :             /* Correct new maxScale is uncertain, must fail */
    4974           6 :             return false;
    4975             :         }
    4976             :     }
    4977             : 
    4978             :     /* if we need X^2, calculate that in short-lived context */
    4979         330 :     if (state->calcSumX2)
    4980             :     {
    4981         288 :         init_var(&X2);
    4982         288 :         mul_var(&X, &X, &X2, X.dscale * 2);
    4983             :     }
    4984             : 
    4985             :     /* The rest of this needs to work in the aggregate context */
    4986         330 :     old_context = MemoryContextSwitchTo(state->agg_context);
    4987             : 
    4988         330 :     if (state->N-- > 1)
    4989             :     {
    4990             :         /* Negate X, to subtract it from the sum */
    4991         312 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
    4992         312 :         accum_sum_add(&(state->sumX), &X);
    4993             : 
    4994         312 :         if (state->calcSumX2)
    4995             :         {
    4996             :             /* Negate X^2. X^2 is always positive */
    4997         288 :             X2.sign = NUMERIC_NEG;
    4998         288 :             accum_sum_add(&(state->sumX2), &X2);
    4999             :         }
    5000             :     }
    5001             :     else
    5002             :     {
    5003             :         /* Zero the sums */
    5004             :         Assert(state->N == 0);
    5005             : 
    5006          18 :         accum_sum_reset(&state->sumX);
    5007          18 :         if (state->calcSumX2)
    5008           0 :             accum_sum_reset(&state->sumX2);
    5009             :     }
    5010             : 
    5011         330 :     MemoryContextSwitchTo(old_context);
    5012             : 
    5013         330 :     return true;
    5014             : }
    5015             : 
    5016             : /*
    5017             :  * Generic transition function for numeric aggregates that require sumX2.
    5018             :  */
    5019             : Datum
    5020         642 : numeric_accum(PG_FUNCTION_ARGS)
    5021             : {
    5022             :     NumericAggState *state;
    5023             : 
    5024         642 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5025             : 
    5026             :     /* Create the state data on the first call */
    5027         642 :     if (state == NULL)
    5028         174 :         state = makeNumericAggState(fcinfo, true);
    5029             : 
    5030         642 :     if (!PG_ARGISNULL(1))
    5031         624 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5032             : 
    5033         642 :     PG_RETURN_POINTER(state);
    5034             : }
    5035             : 
    5036             : /*
    5037             :  * Generic combine function for numeric aggregates which require sumX2
    5038             :  */
    5039             : Datum
    5040          26 : numeric_combine(PG_FUNCTION_ARGS)
    5041             : {
    5042             :     NumericAggState *state1;
    5043             :     NumericAggState *state2;
    5044             :     MemoryContext agg_context;
    5045             :     MemoryContext old_context;
    5046             : 
    5047          26 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5048           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5049             : 
    5050          26 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5051          26 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5052             : 
    5053          26 :     if (state2 == NULL)
    5054           0 :         PG_RETURN_POINTER(state1);
    5055             : 
    5056             :     /* manually copy all fields from state2 to state1 */
    5057          26 :     if (state1 == NULL)
    5058             :     {
    5059          18 :         old_context = MemoryContextSwitchTo(agg_context);
    5060             : 
    5061          18 :         state1 = makeNumericAggStateCurrentContext(true);
    5062          18 :         state1->N = state2->N;
    5063          18 :         state1->NaNcount = state2->NaNcount;
    5064          18 :         state1->pInfcount = state2->pInfcount;
    5065          18 :         state1->nInfcount = state2->nInfcount;
    5066          18 :         state1->maxScale = state2->maxScale;
    5067          18 :         state1->maxScaleCount = state2->maxScaleCount;
    5068             : 
    5069          18 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5070          18 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5071             : 
    5072          18 :         MemoryContextSwitchTo(old_context);
    5073             : 
    5074          18 :         PG_RETURN_POINTER(state1);
    5075             :     }
    5076             : 
    5077           8 :     state1->N += state2->N;
    5078           8 :     state1->NaNcount += state2->NaNcount;
    5079           8 :     state1->pInfcount += state2->pInfcount;
    5080           8 :     state1->nInfcount += state2->nInfcount;
    5081             : 
    5082           8 :     if (state2->N > 0)
    5083             :     {
    5084             :         /*
    5085             :          * These are currently only needed for moving aggregates, but let's do
    5086             :          * the right thing anyway...
    5087             :          */
    5088           8 :         if (state2->maxScale > state1->maxScale)
    5089             :         {
    5090           0 :             state1->maxScale = state2->maxScale;
    5091           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5092             :         }
    5093           8 :         else if (state2->maxScale == state1->maxScale)
    5094           8 :             state1->maxScaleCount += state2->maxScaleCount;
    5095             : 
    5096             :         /* The rest of this needs to work in the aggregate context */
    5097           8 :         old_context = MemoryContextSwitchTo(agg_context);
    5098             : 
    5099             :         /* Accumulate sums */
    5100           8 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5101           8 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5102             : 
    5103           8 :         MemoryContextSwitchTo(old_context);
    5104             :     }
    5105           8 :     PG_RETURN_POINTER(state1);
    5106             : }
    5107             : 
    5108             : /*
    5109             :  * Generic transition function for numeric aggregates that don't require sumX2.
    5110             :  */
    5111             : Datum
    5112     1872808 : numeric_avg_accum(PG_FUNCTION_ARGS)
    5113             : {
    5114             :     NumericAggState *state;
    5115             : 
    5116     1872808 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5117             : 
    5118             :     /* Create the state data on the first call */
    5119     1872808 :     if (state == NULL)
    5120      170896 :         state = makeNumericAggState(fcinfo, false);
    5121             : 
    5122     1872808 :     if (!PG_ARGISNULL(1))
    5123     1872748 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
    5124             : 
    5125     1872808 :     PG_RETURN_POINTER(state);
    5126             : }
    5127             : 
    5128             : /*
    5129             :  * Combine function for numeric aggregates which don't require sumX2
    5130             :  */
    5131             : Datum
    5132          14 : numeric_avg_combine(PG_FUNCTION_ARGS)
    5133             : {
    5134             :     NumericAggState *state1;
    5135             :     NumericAggState *state2;
    5136             :     MemoryContext agg_context;
    5137             :     MemoryContext old_context;
    5138             : 
    5139          14 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5140           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5141             : 
    5142          14 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5143          14 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
    5144             : 
    5145          14 :     if (state2 == NULL)
    5146           0 :         PG_RETURN_POINTER(state1);
    5147             : 
    5148             :     /* manually copy all fields from state2 to state1 */
    5149          14 :     if (state1 == NULL)
    5150             :     {
    5151           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5152             : 
    5153           6 :         state1 = makeNumericAggStateCurrentContext(false);
    5154           6 :         state1->N = state2->N;
    5155           6 :         state1->NaNcount = state2->NaNcount;
    5156           6 :         state1->pInfcount = state2->pInfcount;
    5157           6 :         state1->nInfcount = state2->nInfcount;
    5158           6 :         state1->maxScale = state2->maxScale;
    5159           6 :         state1->maxScaleCount = state2->maxScaleCount;
    5160             : 
    5161           6 :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5162             : 
    5163           6 :         MemoryContextSwitchTo(old_context);
    5164             : 
    5165           6 :         PG_RETURN_POINTER(state1);
    5166             :     }
    5167             : 
    5168           8 :     state1->N += state2->N;
    5169           8 :     state1->NaNcount += state2->NaNcount;
    5170           8 :     state1->pInfcount += state2->pInfcount;
    5171           8 :     state1->nInfcount += state2->nInfcount;
    5172             : 
    5173           8 :     if (state2->N > 0)
    5174             :     {
    5175             :         /*
    5176             :          * These are currently only needed for moving aggregates, but let's do
    5177             :          * the right thing anyway...
    5178             :          */
    5179           8 :         if (state2->maxScale > state1->maxScale)
    5180             :         {
    5181           0 :             state1->maxScale = state2->maxScale;
    5182           0 :             state1->maxScaleCount = state2->maxScaleCount;
    5183             :         }
    5184           8 :         else if (state2->maxScale == state1->maxScale)
    5185           8 :             state1->maxScaleCount += state2->maxScaleCount;
    5186             : 
    5187             :         /* The rest of this needs to work in the aggregate context */
    5188           8 :         old_context = MemoryContextSwitchTo(agg_context);
    5189             : 
    5190             :         /* Accumulate sums */
    5191           8 :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5192             : 
    5193           8 :         MemoryContextSwitchTo(old_context);
    5194             :     }
    5195           8 :     PG_RETURN_POINTER(state1);
    5196             : }
    5197             : 
    5198             : /*
    5199             :  * numeric_avg_serialize
    5200             :  *      Serialize NumericAggState for numeric aggregates that don't require
    5201             :  *      sumX2.
    5202             :  */
    5203             : Datum
    5204          14 : numeric_avg_serialize(PG_FUNCTION_ARGS)
    5205             : {
    5206             :     NumericAggState *state;
    5207             :     StringInfoData buf;
    5208             :     bytea      *result;
    5209             :     NumericVar  tmp_var;
    5210             : 
    5211             :     /* Ensure we disallow calling when not in aggregate context */
    5212          14 :     if (!AggCheckCallContext(fcinfo, NULL))
    5213           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5214             : 
    5215          14 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5216             : 
    5217          14 :     init_var(&tmp_var);
    5218             : 
    5219          14 :     pq_begintypsend(&buf);
    5220             : 
    5221             :     /* N */
    5222          14 :     pq_sendint64(&buf, state->N);
    5223             : 
    5224             :     /* sumX */
    5225          14 :     accum_sum_final(&state->sumX, &tmp_var);
    5226          14 :     numericvar_serialize(&buf, &tmp_var);
    5227             : 
    5228             :     /* maxScale */
    5229          14 :     pq_sendint32(&buf, state->maxScale);
    5230             : 
    5231             :     /* maxScaleCount */
    5232          14 :     pq_sendint64(&buf, state->maxScaleCount);
    5233             : 
    5234             :     /* NaNcount */
    5235          14 :     pq_sendint64(&buf, state->NaNcount);
    5236             : 
    5237             :     /* pInfcount */
    5238          14 :     pq_sendint64(&buf, state->pInfcount);
    5239             : 
    5240             :     /* nInfcount */
    5241          14 :     pq_sendint64(&buf, state->nInfcount);
    5242             : 
    5243          14 :     result = pq_endtypsend(&buf);
    5244             : 
    5245          14 :     free_var(&tmp_var);
    5246             : 
    5247          14 :     PG_RETURN_BYTEA_P(result);
    5248             : }
    5249             : 
    5250             : /*
    5251             :  * numeric_avg_deserialize
    5252             :  *      Deserialize bytea into NumericAggState for numeric aggregates that
    5253             :  *      don't require sumX2.
    5254             :  */
    5255             : Datum
    5256          14 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
    5257             : {
    5258             :     bytea      *sstate;
    5259             :     NumericAggState *result;
    5260             :     StringInfoData buf;
    5261             :     NumericVar  tmp_var;
    5262             : 
    5263          14 :     if (!AggCheckCallContext(fcinfo, NULL))
    5264           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5265             : 
    5266          14 :     sstate = PG_GETARG_BYTEA_PP(0);
    5267             : 
    5268          14 :     init_var(&tmp_var);
    5269             : 
    5270             :     /*
    5271             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5272             :      * recv-function infrastructure.
    5273             :      */
    5274          14 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5275          14 :                            VARSIZE_ANY_EXHDR(sstate));
    5276             : 
    5277          14 :     result = makeNumericAggStateCurrentContext(false);
    5278             : 
    5279             :     /* N */
    5280          14 :     result->N = pq_getmsgint64(&buf);
    5281             : 
    5282             :     /* sumX */
    5283          14 :     numericvar_deserialize(&buf, &tmp_var);
    5284          14 :     accum_sum_add(&(result->sumX), &tmp_var);
    5285             : 
    5286             :     /* maxScale */
    5287          14 :     result->maxScale = pq_getmsgint(&buf, 4);
    5288             : 
    5289             :     /* maxScaleCount */
    5290          14 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5291             : 
    5292             :     /* NaNcount */
    5293          14 :     result->NaNcount = pq_getmsgint64(&buf);
    5294             : 
    5295             :     /* pInfcount */
    5296          14 :     result->pInfcount = pq_getmsgint64(&buf);
    5297             : 
    5298             :     /* nInfcount */
    5299          14 :     result->nInfcount = pq_getmsgint64(&buf);
    5300             : 
    5301          14 :     pq_getmsgend(&buf);
    5302             : 
    5303          14 :     free_var(&tmp_var);
    5304             : 
    5305          14 :     PG_RETURN_POINTER(result);
    5306             : }
    5307             : 
    5308             : /*
    5309             :  * numeric_serialize
    5310             :  *      Serialization function for NumericAggState for numeric aggregates that
    5311             :  *      require sumX2.
    5312             :  */
    5313             : Datum
    5314          26 : numeric_serialize(PG_FUNCTION_ARGS)
    5315             : {
    5316             :     NumericAggState *state;
    5317             :     StringInfoData buf;
    5318             :     bytea      *result;
    5319             :     NumericVar  tmp_var;
    5320             : 
    5321             :     /* Ensure we disallow calling when not in aggregate context */
    5322          26 :     if (!AggCheckCallContext(fcinfo, NULL))
    5323           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5324             : 
    5325          26 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
    5326             : 
    5327          26 :     init_var(&tmp_var);
    5328             : 
    5329          26 :     pq_begintypsend(&buf);
    5330             : 
    5331             :     /* N */
    5332          26 :     pq_sendint64(&buf, state->N);
    5333             : 
    5334             :     /* sumX */
    5335          26 :     accum_sum_final(&state->sumX, &tmp_var);
    5336          26 :     numericvar_serialize(&buf, &tmp_var);
    5337             : 
    5338             :     /* sumX2 */
    5339          26 :     accum_sum_final(&state->sumX2, &tmp_var);
    5340          26 :     numericvar_serialize(&buf, &tmp_var);
    5341             : 
    5342             :     /* maxScale */
    5343          26 :     pq_sendint32(&buf, state->maxScale);
    5344             : 
    5345             :     /* maxScaleCount */
    5346          26 :     pq_sendint64(&buf, state->maxScaleCount);
    5347             : 
    5348             :     /* NaNcount */
    5349          26 :     pq_sendint64(&buf, state->NaNcount);
    5350             : 
    5351             :     /* pInfcount */
    5352          26 :     pq_sendint64(&buf, state->pInfcount);
    5353             : 
    5354             :     /* nInfcount */
    5355          26 :     pq_sendint64(&buf, state->nInfcount);
    5356             : 
    5357          26 :     result = pq_endtypsend(&buf);
    5358             : 
    5359          26 :     free_var(&tmp_var);
    5360             : 
    5361          26 :     PG_RETURN_BYTEA_P(result);
    5362             : }
    5363             : 
    5364             : /*
    5365             :  * numeric_deserialize
    5366             :  *      Deserialization function for NumericAggState for numeric aggregates that
    5367             :  *      require sumX2.
    5368             :  */
    5369             : Datum
    5370          26 : numeric_deserialize(PG_FUNCTION_ARGS)
    5371             : {
    5372             :     bytea      *sstate;
    5373             :     NumericAggState *result;
    5374             :     StringInfoData buf;
    5375             :     NumericVar  tmp_var;
    5376             : 
    5377          26 :     if (!AggCheckCallContext(fcinfo, NULL))
    5378           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5379             : 
    5380          26 :     sstate = PG_GETARG_BYTEA_PP(0);
    5381             : 
    5382          26 :     init_var(&tmp_var);
    5383             : 
    5384             :     /*
    5385             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5386             :      * recv-function infrastructure.
    5387             :      */
    5388          26 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5389          26 :                            VARSIZE_ANY_EXHDR(sstate));
    5390             : 
    5391          26 :     result = makeNumericAggStateCurrentContext(false);
    5392             : 
    5393             :     /* N */
    5394          26 :     result->N = pq_getmsgint64(&buf);
    5395             : 
    5396             :     /* sumX */
    5397          26 :     numericvar_deserialize(&buf, &tmp_var);
    5398          26 :     accum_sum_add(&(result->sumX), &tmp_var);
    5399             : 
    5400             :     /* sumX2 */
    5401          26 :     numericvar_deserialize(&buf, &tmp_var);
    5402          26 :     accum_sum_add(&(result->sumX2), &tmp_var);
    5403             : 
    5404             :     /* maxScale */
    5405          26 :     result->maxScale = pq_getmsgint(&buf, 4);
    5406             : 
    5407             :     /* maxScaleCount */
    5408          26 :     result->maxScaleCount = pq_getmsgint64(&buf);
    5409             : 
    5410             :     /* NaNcount */
    5411          26 :     result->NaNcount = pq_getmsgint64(&buf);
    5412             : 
    5413             :     /* pInfcount */
    5414          26 :     result->pInfcount = pq_getmsgint64(&buf);
    5415             : 
    5416             :     /* nInfcount */
    5417          26 :     result->nInfcount = pq_getmsgint64(&buf);
    5418             : 
    5419          26 :     pq_getmsgend(&buf);
    5420             : 
    5421          26 :     free_var(&tmp_var);
    5422             : 
    5423          26 :     PG_RETURN_POINTER(result);
    5424             : }
    5425             : 
    5426             : /*
    5427             :  * Generic inverse transition function for numeric aggregates
    5428             :  * (with or without requirement for X^2).
    5429             :  */
    5430             : Datum
    5431         228 : numeric_accum_inv(PG_FUNCTION_ARGS)
    5432             : {
    5433             :     NumericAggState *state;
    5434             : 
    5435         228 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5436             : 
    5437             :     /* Should not get here with no state */
    5438         228 :     if (state == NULL)
    5439           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
    5440             : 
    5441         228 :     if (!PG_ARGISNULL(1))
    5442             :     {
    5443             :         /* If we fail to perform the inverse transition, return NULL */
    5444         198 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
    5445           6 :             PG_RETURN_NULL();
    5446             :     }
    5447             : 
    5448         222 :     PG_RETURN_POINTER(state);
    5449             : }
    5450             : 
    5451             : 
    5452             : /*
    5453             :  * Integer data types in general use Numeric accumulators to share code
    5454             :  * and avoid risk of overflow.
    5455             :  *
    5456             :  * However for performance reasons optimized special-purpose accumulator
    5457             :  * routines are used when possible.
    5458             :  *
    5459             :  * On platforms with 128-bit integer support, the 128-bit routines will be
    5460             :  * used when sum(X) or sum(X*X) fit into 128-bit.
    5461             :  *
    5462             :  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
    5463             :  * accumulators will be used for SUM and AVG of these data types.
    5464             :  */
    5465             : 
    5466             : #ifdef HAVE_INT128
    5467             : typedef struct Int128AggState
    5468             : {
    5469             :     bool        calcSumX2;      /* if true, calculate sumX2 */
    5470             :     int64       N;              /* count of processed numbers */
    5471             :     int128      sumX;           /* sum of processed numbers */
    5472             :     int128      sumX2;          /* sum of squares of processed numbers */
    5473             : } Int128AggState;
    5474             : 
    5475             : /*
    5476             :  * Prepare state data for a 128-bit aggregate function that needs to compute
    5477             :  * sum, count and optionally sum of squares of the input.
    5478             :  */
    5479             : static Int128AggState *
    5480         666 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
    5481             : {
    5482             :     Int128AggState *state;
    5483             :     MemoryContext agg_context;
    5484             :     MemoryContext old_context;
    5485             : 
    5486         666 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5487           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5488             : 
    5489         666 :     old_context = MemoryContextSwitchTo(agg_context);
    5490             : 
    5491         666 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5492         666 :     state->calcSumX2 = calcSumX2;
    5493             : 
    5494         666 :     MemoryContextSwitchTo(old_context);
    5495             : 
    5496         666 :     return state;
    5497             : }
    5498             : 
    5499             : /*
    5500             :  * Like makeInt128AggState(), but allocate the state in the current memory
    5501             :  * context.
    5502             :  */
    5503             : static Int128AggState *
    5504          22 : makeInt128AggStateCurrentContext(bool calcSumX2)
    5505             : {
    5506             :     Int128AggState *state;
    5507             : 
    5508          22 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
    5509          22 :     state->calcSumX2 = calcSumX2;
    5510             : 
    5511          22 :     return state;
    5512             : }
    5513             : 
    5514             : /*
    5515             :  * Accumulate a new input value for 128-bit aggregate functions.
    5516             :  */
    5517             : static void
    5518      553542 : do_int128_accum(Int128AggState *state, int128 newval)
    5519             : {
    5520      553542 :     if (state->calcSumX2)
    5521      242360 :         state->sumX2 += newval * newval;
    5522             : 
    5523      553542 :     state->sumX += newval;
    5524      553542 :     state->N++;
    5525      553542 : }
    5526             : 
    5527             : /*
    5528             :  * Remove an input value from the aggregated state.
    5529             :  */
    5530             : static void
    5531         312 : do_int128_discard(Int128AggState *state, int128 newval)
    5532             : {
    5533         312 :     if (state->calcSumX2)
    5534         288 :         state->sumX2 -= newval * newval;
    5535             : 
    5536         312 :     state->sumX -= newval;
    5537         312 :     state->N--;
    5538         312 : }
    5539             : 
    5540             : typedef Int128AggState PolyNumAggState;
    5541             : #define makePolyNumAggState makeInt128AggState
    5542             : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
    5543             : #else
    5544             : typedef NumericAggState PolyNumAggState;
    5545             : #define makePolyNumAggState makeNumericAggState
    5546             : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
    5547             : #endif
    5548             : 
    5549             : Datum
    5550         198 : int2_accum(PG_FUNCTION_ARGS)
    5551             : {
    5552             :     PolyNumAggState *state;
    5553             : 
    5554         198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5555             : 
    5556             :     /* Create the state data on the first call */
    5557         198 :     if (state == NULL)
    5558          36 :         state = makePolyNumAggState(fcinfo, true);
    5559             : 
    5560         198 :     if (!PG_ARGISNULL(1))
    5561             :     {
    5562             : #ifdef HAVE_INT128
    5563         180 :         do_int128_accum(state, (int128) PG_GETARG_INT16(1));
    5564             : #else
    5565             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
    5566             : #endif
    5567             :     }
    5568             : 
    5569         198 :     PG_RETURN_POINTER(state);
    5570             : }
    5571             : 
    5572             : Datum
    5573      242198 : int4_accum(PG_FUNCTION_ARGS)
    5574             : {
    5575             :     PolyNumAggState *state;
    5576             : 
    5577      242198 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5578             : 
    5579             :     /* Create the state data on the first call */
    5580      242198 :     if (state == NULL)
    5581          64 :         state = makePolyNumAggState(fcinfo, true);
    5582             : 
    5583      242198 :     if (!PG_ARGISNULL(1))
    5584             :     {
    5585             : #ifdef HAVE_INT128
    5586      242180 :         do_int128_accum(state, (int128) PG_GETARG_INT32(1));
    5587             : #else
    5588             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
    5589             : #endif
    5590             :     }
    5591             : 
    5592      242198 :     PG_RETURN_POINTER(state);
    5593             : }
    5594             : 
    5595             : Datum
    5596      240198 : int8_accum(PG_FUNCTION_ARGS)
    5597             : {
    5598             :     NumericAggState *state;
    5599             : 
    5600      240198 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    5601             : 
    5602             :     /* Create the state data on the first call */
    5603      240198 :     if (state == NULL)
    5604          50 :         state = makeNumericAggState(fcinfo, true);
    5605             : 
    5606      240198 :     if (!PG_ARGISNULL(1))
    5607      240180 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5608             : 
    5609      240198 :     PG_RETURN_POINTER(state);
    5610             : }
    5611             : 
    5612             : /*
    5613             :  * Combine function for numeric aggregates which require sumX2
    5614             :  */
    5615             : Datum
    5616           8 : numeric_poly_combine(PG_FUNCTION_ARGS)
    5617             : {
    5618             :     PolyNumAggState *state1;
    5619             :     PolyNumAggState *state2;
    5620             :     MemoryContext agg_context;
    5621             :     MemoryContext old_context;
    5622             : 
    5623           8 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5624           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5625             : 
    5626           8 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5627           8 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5628             : 
    5629           8 :     if (state2 == NULL)
    5630           0 :         PG_RETURN_POINTER(state1);
    5631             : 
    5632             :     /* manually copy all fields from state2 to state1 */
    5633           8 :     if (state1 == NULL)
    5634             :     {
    5635           6 :         old_context = MemoryContextSwitchTo(agg_context);
    5636             : 
    5637           6 :         state1 = makePolyNumAggState(fcinfo, true);
    5638           6 :         state1->N = state2->N;
    5639             : 
    5640             : #ifdef HAVE_INT128
    5641           6 :         state1->sumX = state2->sumX;
    5642           6 :         state1->sumX2 = state2->sumX2;
    5643             : #else
    5644             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5645             :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
    5646             : #endif
    5647             : 
    5648           6 :         MemoryContextSwitchTo(old_context);
    5649             : 
    5650           6 :         PG_RETURN_POINTER(state1);
    5651             :     }
    5652             : 
    5653           2 :     if (state2->N > 0)
    5654             :     {
    5655           2 :         state1->N += state2->N;
    5656             : 
    5657             : #ifdef HAVE_INT128
    5658           2 :         state1->sumX += state2->sumX;
    5659           2 :         state1->sumX2 += state2->sumX2;
    5660             : #else
    5661             :         /* The rest of this needs to work in the aggregate context */
    5662             :         old_context = MemoryContextSwitchTo(agg_context);
    5663             : 
    5664             :         /* Accumulate sums */
    5665             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5666             :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
    5667             : 
    5668             :         MemoryContextSwitchTo(old_context);
    5669             : #endif
    5670             : 
    5671             :     }
    5672           2 :     PG_RETURN_POINTER(state1);
    5673             : }
    5674             : 
    5675             : /*
    5676             :  * numeric_poly_serialize
    5677             :  *      Serialize PolyNumAggState into bytea for aggregate functions which
    5678             :  *      require sumX2.
    5679             :  */
    5680             : Datum
    5681           8 : numeric_poly_serialize(PG_FUNCTION_ARGS)
    5682             : {
    5683             :     PolyNumAggState *state;
    5684             :     StringInfoData buf;
    5685             :     bytea      *result;
    5686             :     NumericVar  tmp_var;
    5687             : 
    5688             :     /* Ensure we disallow calling when not in aggregate context */
    5689           8 :     if (!AggCheckCallContext(fcinfo, NULL))
    5690           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5691             : 
    5692           8 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5693             : 
    5694             :     /*
    5695             :      * If the platform supports int128 then sumX and sumX2 will be a 128 bit
    5696             :      * integer type. Here we'll convert that into a numeric type so that the
    5697             :      * combine state is in the same format for both int128 enabled machines
    5698             :      * and machines which don't support that type. The logic here is that one
    5699             :      * day we might like to send these over to another server for further
    5700             :      * processing and we want a standard format to work with.
    5701             :      */
    5702             : 
    5703           8 :     init_var(&tmp_var);
    5704             : 
    5705           8 :     pq_begintypsend(&buf);
    5706             : 
    5707             :     /* N */
    5708           8 :     pq_sendint64(&buf, state->N);
    5709             : 
    5710             :     /* sumX */
    5711             : #ifdef HAVE_INT128
    5712           8 :     int128_to_numericvar(state->sumX, &tmp_var);
    5713             : #else
    5714             :     accum_sum_final(&state->sumX, &tmp_var);
    5715             : #endif
    5716           8 :     numericvar_serialize(&buf, &tmp_var);
    5717             : 
    5718             :     /* sumX2 */
    5719             : #ifdef HAVE_INT128
    5720           8 :     int128_to_numericvar(state->sumX2, &tmp_var);
    5721             : #else
    5722             :     accum_sum_final(&state->sumX2, &tmp_var);
    5723             : #endif
    5724           8 :     numericvar_serialize(&buf, &tmp_var);
    5725             : 
    5726           8 :     result = pq_endtypsend(&buf);
    5727             : 
    5728           8 :     free_var(&tmp_var);
    5729             : 
    5730           8 :     PG_RETURN_BYTEA_P(result);
    5731             : }
    5732             : 
    5733             : /*
    5734             :  * numeric_poly_deserialize
    5735             :  *      Deserialize PolyNumAggState from bytea for aggregate functions which
    5736             :  *      require sumX2.
    5737             :  */
    5738             : Datum
    5739           8 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
    5740             : {
    5741             :     bytea      *sstate;
    5742             :     PolyNumAggState *result;
    5743             :     StringInfoData buf;
    5744             :     NumericVar  tmp_var;
    5745             : 
    5746           8 :     if (!AggCheckCallContext(fcinfo, NULL))
    5747           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5748             : 
    5749           8 :     sstate = PG_GETARG_BYTEA_PP(0);
    5750             : 
    5751           8 :     init_var(&tmp_var);
    5752             : 
    5753             :     /*
    5754             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5755             :      * recv-function infrastructure.
    5756             :      */
    5757           8 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5758           8 :                            VARSIZE_ANY_EXHDR(sstate));
    5759             : 
    5760           8 :     result = makePolyNumAggStateCurrentContext(false);
    5761             : 
    5762             :     /* N */
    5763           8 :     result->N = pq_getmsgint64(&buf);
    5764             : 
    5765             :     /* sumX */
    5766           8 :     numericvar_deserialize(&buf, &tmp_var);
    5767             : #ifdef HAVE_INT128
    5768           8 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5769             : #else
    5770             :     accum_sum_add(&result->sumX, &tmp_var);
    5771             : #endif
    5772             : 
    5773             :     /* sumX2 */
    5774           8 :     numericvar_deserialize(&buf, &tmp_var);
    5775             : #ifdef HAVE_INT128
    5776           8 :     numericvar_to_int128(&tmp_var, &result->sumX2);
    5777             : #else
    5778             :     accum_sum_add(&result->sumX2, &tmp_var);
    5779             : #endif
    5780             : 
    5781           8 :     pq_getmsgend(&buf);
    5782             : 
    5783           8 :     free_var(&tmp_var);
    5784             : 
    5785           8 :     PG_RETURN_POINTER(result);
    5786             : }
    5787             : 
    5788             : /*
    5789             :  * Transition function for int8 input when we don't need sumX2.
    5790             :  */
    5791             : Datum
    5792      312298 : int8_avg_accum(PG_FUNCTION_ARGS)
    5793             : {
    5794             :     PolyNumAggState *state;
    5795             : 
    5796      312298 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5797             : 
    5798             :     /* Create the state data on the first call */
    5799      312298 :     if (state == NULL)
    5800         548 :         state = makePolyNumAggState(fcinfo, false);
    5801             : 
    5802      312298 :     if (!PG_ARGISNULL(1))
    5803             :     {
    5804             : #ifdef HAVE_INT128
    5805      311182 :         do_int128_accum(state, (int128) PG_GETARG_INT64(1));
    5806             : #else
    5807             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
    5808             : #endif
    5809             :     }
    5810             : 
    5811      312298 :     PG_RETURN_POINTER(state);
    5812             : }
    5813             : 
    5814             : /*
    5815             :  * Combine function for PolyNumAggState for aggregates which don't require
    5816             :  * sumX2
    5817             :  */
    5818             : Datum
    5819          14 : int8_avg_combine(PG_FUNCTION_ARGS)
    5820             : {
    5821             :     PolyNumAggState *state1;
    5822             :     PolyNumAggState *state2;
    5823             :     MemoryContext agg_context;
    5824             :     MemoryContext old_context;
    5825             : 
    5826          14 :     if (!AggCheckCallContext(fcinfo, &agg_context))
    5827           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5828             : 
    5829          14 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5830          14 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
    5831             : 
    5832          14 :     if (state2 == NULL)
    5833           0 :         PG_RETURN_POINTER(state1);
    5834             : 
    5835             :     /* manually copy all fields from state2 to state1 */
    5836          14 :     if (state1 == NULL)
    5837             :     {
    5838          12 :         old_context = MemoryContextSwitchTo(agg_context);
    5839             : 
    5840          12 :         state1 = makePolyNumAggState(fcinfo, false);
    5841          12 :         state1->N = state2->N;
    5842             : 
    5843             : #ifdef HAVE_INT128
    5844          12 :         state1->sumX = state2->sumX;
    5845             : #else
    5846             :         accum_sum_copy(&state1->sumX, &state2->sumX);
    5847             : #endif
    5848          12 :         MemoryContextSwitchTo(old_context);
    5849             : 
    5850          12 :         PG_RETURN_POINTER(state1);
    5851             :     }
    5852             : 
    5853           2 :     if (state2->N > 0)
    5854             :     {
    5855           2 :         state1->N += state2->N;
    5856             : 
    5857             : #ifdef HAVE_INT128
    5858           2 :         state1->sumX += state2->sumX;
    5859             : #else
    5860             :         /* The rest of this needs to work in the aggregate context */
    5861             :         old_context = MemoryContextSwitchTo(agg_context);
    5862             : 
    5863             :         /* Accumulate sums */
    5864             :         accum_sum_combine(&state1->sumX, &state2->sumX);
    5865             : 
    5866             :         MemoryContextSwitchTo(old_context);
    5867             : #endif
    5868             : 
    5869             :     }
    5870           2 :     PG_RETURN_POINTER(state1);
    5871             : }
    5872             : 
    5873             : /*
    5874             :  * int8_avg_serialize
    5875             :  *      Serialize PolyNumAggState into bytea using the standard
    5876             :  *      recv-function infrastructure.
    5877             :  */
    5878             : Datum
    5879          14 : int8_avg_serialize(PG_FUNCTION_ARGS)
    5880             : {
    5881             :     PolyNumAggState *state;
    5882             :     StringInfoData buf;
    5883             :     bytea      *result;
    5884             :     NumericVar  tmp_var;
    5885             : 
    5886             :     /* Ensure we disallow calling when not in aggregate context */
    5887          14 :     if (!AggCheckCallContext(fcinfo, NULL))
    5888           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5889             : 
    5890          14 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
    5891             : 
    5892             :     /*
    5893             :      * If the platform supports int128 then sumX will be a 128 integer type.
    5894             :      * Here we'll convert that into a numeric type so that the combine state
    5895             :      * is in the same format for both int128 enabled machines and machines
    5896             :      * which don't support that type. The logic here is that one day we might
    5897             :      * like to send these over to another server for further processing and we
    5898             :      * want a standard format to work with.
    5899             :      */
    5900             : 
    5901          14 :     init_var(&tmp_var);
    5902             : 
    5903          14 :     pq_begintypsend(&buf);
    5904             : 
    5905             :     /* N */
    5906          14 :     pq_sendint64(&buf, state->N);
    5907             : 
    5908             :     /* sumX */
    5909             : #ifdef HAVE_INT128
    5910          14 :     int128_to_numericvar(state->sumX, &tmp_var);
    5911             : #else
    5912             :     accum_sum_final(&state->sumX, &tmp_var);
    5913             : #endif
    5914          14 :     numericvar_serialize(&buf, &tmp_var);
    5915             : 
    5916          14 :     result = pq_endtypsend(&buf);
    5917             : 
    5918          14 :     free_var(&tmp_var);
    5919             : 
    5920          14 :     PG_RETURN_BYTEA_P(result);
    5921             : }
    5922             : 
    5923             : /*
    5924             :  * int8_avg_deserialize
    5925             :  *      Deserialize bytea back into PolyNumAggState.
    5926             :  */
    5927             : Datum
    5928          14 : int8_avg_deserialize(PG_FUNCTION_ARGS)
    5929             : {
    5930             :     bytea      *sstate;
    5931             :     PolyNumAggState *result;
    5932             :     StringInfoData buf;
    5933             :     NumericVar  tmp_var;
    5934             : 
    5935          14 :     if (!AggCheckCallContext(fcinfo, NULL))
    5936           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    5937             : 
    5938          14 :     sstate = PG_GETARG_BYTEA_PP(0);
    5939             : 
    5940          14 :     init_var(&tmp_var);
    5941             : 
    5942             :     /*
    5943             :      * Initialize a StringInfo so that we can "receive" it using the standard
    5944             :      * recv-function infrastructure.
    5945             :      */
    5946          14 :     initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
    5947          14 :                            VARSIZE_ANY_EXHDR(sstate));
    5948             : 
    5949          14 :     result = makePolyNumAggStateCurrentContext(false);
    5950             : 
    5951             :     /* N */
    5952          14 :     result->N = pq_getmsgint64(&buf);
    5953             : 
    5954             :     /* sumX */
    5955          14 :     numericvar_deserialize(&buf, &tmp_var);
    5956             : #ifdef HAVE_INT128
    5957          14 :     numericvar_to_int128(&tmp_var, &result->sumX);
    5958             : #else
    5959             :     accum_sum_add(&result->sumX, &tmp_var);
    5960             : #endif
    5961             : 
    5962          14 :     pq_getmsgend(&buf);
    5963             : 
    5964          14 :     free_var(&tmp_var);
    5965             : 
    5966          14 :     PG_RETURN_POINTER(result);
    5967             : }
    5968             : 
    5969             : /*
    5970             :  * Inverse transition functions to go with the above.
    5971             :  */
    5972             : 
    5973             : Datum
    5974         162 : int2_accum_inv(PG_FUNCTION_ARGS)
    5975             : {
    5976             :     PolyNumAggState *state;
    5977             : 
    5978         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    5979             : 
    5980             :     /* Should not get here with no state */
    5981         162 :     if (state == NULL)
    5982           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
    5983             : 
    5984         162 :     if (!PG_ARGISNULL(1))
    5985             :     {
    5986             : #ifdef HAVE_INT128
    5987         144 :         do_int128_discard(state, (int128) PG_GETARG_INT16(1));
    5988             : #else
    5989             :         /* Should never fail, all inputs have dscale 0 */
    5990             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
    5991             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    5992             : #endif
    5993             :     }
    5994             : 
    5995         162 :     PG_RETURN_POINTER(state);
    5996             : }
    5997             : 
    5998             : Datum
    5999         162 : int4_accum_inv(PG_FUNCTION_ARGS)
    6000             : {
    6001             :     PolyNumAggState *state;
    6002             : 
    6003         162 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6004             : 
    6005             :     /* Should not get here with no state */
    6006         162 :     if (state == NULL)
    6007           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
    6008             : 
    6009         162 :     if (!PG_ARGISNULL(1))
    6010             :     {
    6011             : #ifdef HAVE_INT128
    6012         144 :         do_int128_discard(state, (int128) PG_GETARG_INT32(1));
    6013             : #else
    6014             :         /* Should never fail, all inputs have dscale 0 */
    6015             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
    6016             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6017             : #endif
    6018             :     }
    6019             : 
    6020         162 :     PG_RETURN_POINTER(state);
    6021             : }
    6022             : 
    6023             : Datum
    6024         162 : int8_accum_inv(PG_FUNCTION_ARGS)
    6025             : {
    6026             :     NumericAggState *state;
    6027             : 
    6028         162 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6029             : 
    6030             :     /* Should not get here with no state */
    6031         162 :     if (state == NULL)
    6032           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
    6033             : 
    6034         162 :     if (!PG_ARGISNULL(1))
    6035             :     {
    6036             :         /* Should never fail, all inputs have dscale 0 */
    6037         144 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6038           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6039             :     }
    6040             : 
    6041         162 :     PG_RETURN_POINTER(state);
    6042             : }
    6043             : 
    6044             : Datum
    6045          36 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
    6046             : {
    6047             :     PolyNumAggState *state;
    6048             : 
    6049          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6050             : 
    6051             :     /* Should not get here with no state */
    6052          36 :     if (state == NULL)
    6053           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
    6054             : 
    6055          36 :     if (!PG_ARGISNULL(1))
    6056             :     {
    6057             : #ifdef HAVE_INT128
    6058          24 :         do_int128_discard(state, (int128) PG_GETARG_INT64(1));
    6059             : #else
    6060             :         /* Should never fail, all inputs have dscale 0 */
    6061             :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
    6062             :             elog(ERROR, "do_numeric_discard failed unexpectedly");
    6063             : #endif
    6064             :     }
    6065             : 
    6066          36 :     PG_RETURN_POINTER(state);
    6067             : }
    6068             : 
    6069             : Datum
    6070         780 : numeric_poly_sum(PG_FUNCTION_ARGS)
    6071             : {
    6072             : #ifdef HAVE_INT128
    6073             :     PolyNumAggState *state;
    6074             :     Numeric     res;
    6075             :     NumericVar  result;
    6076             : 
    6077         780 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6078             : 
    6079             :     /* If there were no non-null inputs, return NULL */
    6080         780 :     if (state == NULL || state->N == 0)
    6081          24 :         PG_RETURN_NULL();
    6082             : 
    6083         756 :     init_var(&result);
    6084             : 
    6085         756 :     int128_to_numericvar(state->sumX, &result);
    6086             : 
    6087         756 :     res = make_result(&result);
    6088             : 
    6089         756 :     free_var(&result);
    6090             : 
    6091         756 :     PG_RETURN_NUMERIC(res);
    6092             : #else
    6093             :     return numeric_sum(fcinfo);
    6094             : #endif
    6095             : }
    6096             : 
    6097             : Datum
    6098          36 : numeric_poly_avg(PG_FUNCTION_ARGS)
    6099             : {
    6100             : #ifdef HAVE_INT128
    6101             :     PolyNumAggState *state;
    6102             :     NumericVar  result;
    6103             :     Datum       countd,
    6104             :                 sumd;
    6105             : 
    6106          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6107             : 
    6108             :     /* If there were no non-null inputs, return NULL */
    6109          36 :     if (state == NULL || state->N == 0)
    6110          18 :         PG_RETURN_NULL();
    6111             : 
    6112          18 :     init_var(&result);
    6113             : 
    6114          18 :     int128_to_numericvar(state->sumX, &result);
    6115             : 
    6116          18 :     countd = NumericGetDatum(int64_to_numeric(state->N));
    6117          18 :     sumd = NumericGetDatum(make_result(&result));
    6118             : 
    6119          18 :     free_var(&result);
    6120             : 
    6121          18 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6122             : #else
    6123             :     return numeric_avg(fcinfo);
    6124             : #endif
    6125             : }
    6126             : 
    6127             : Datum
    6128          78 : numeric_avg(PG_FUNCTION_ARGS)
    6129             : {
    6130             :     NumericAggState *state;
    6131             :     Datum       N_datum;
    6132             :     Datum       sumX_datum;
    6133             :     NumericVar  sumX_var;
    6134             : 
    6135          78 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6136             : 
    6137             :     /* If there were no non-null inputs, return NULL */
    6138          78 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6139          18 :         PG_RETURN_NULL();
    6140             : 
    6141          60 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6142           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6143             : 
    6144             :     /* adding plus and minus infinities gives NaN */
    6145          54 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6146           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6147          48 :     if (state->pInfcount > 0)
    6148          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6149          30 :     if (state->nInfcount > 0)
    6150           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6151             : 
    6152          24 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
    6153             : 
    6154          24 :     init_var(&sumX_var);
    6155          24 :     accum_sum_final(&state->sumX, &sumX_var);
    6156          24 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
    6157          24 :     free_var(&sumX_var);
    6158             : 
    6159          24 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
    6160             : }
    6161             : 
    6162             : Datum
    6163      170906 : numeric_sum(PG_FUNCTION_ARGS)
    6164             : {
    6165             :     NumericAggState *state;
    6166             :     NumericVar  sumX_var;
    6167             :     Numeric     result;
    6168             : 
    6169      170906 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6170             : 
    6171             :     /* If there were no non-null inputs, return NULL */
    6172      170906 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
    6173          18 :         PG_RETURN_NULL();
    6174             : 
    6175      170888 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
    6176          18 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6177             : 
    6178             :     /* adding plus and minus infinities gives NaN */
    6179      170870 :     if (state->pInfcount > 0 && state->nInfcount > 0)
    6180           6 :         PG_RETURN_NUMERIC(make_result(&const_nan));
    6181      170864 :     if (state->pInfcount > 0)
    6182          18 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
    6183      170846 :     if (state->nInfcount > 0)
    6184           6 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
    6185             : 
    6186      170840 :     init_var(&sumX_var);
    6187      170840 :     accum_sum_final(&state->sumX, &sumX_var);
    6188      170840 :     result = make_result(&sumX_var);
    6189      170840 :     free_var(&sumX_var);
    6190             : 
    6191      170840 :     PG_RETURN_NUMERIC(result);
    6192             : }
    6193             : 
    6194             : /*
    6195             :  * Workhorse routine for the standard deviance and variance
    6196             :  * aggregates. 'state' is aggregate's transition state.
    6197             :  * 'variance' specifies whether we should calculate the
    6198             :  * variance or the standard deviation. 'sample' indicates whether the
    6199             :  * caller is interested in the sample or the population
    6200             :  * variance/stddev.
    6201             :  *
    6202             :  * If appropriate variance statistic is undefined for the input,
    6203             :  * *is_null is set to true and NULL is returned.
    6204             :  */
    6205             : static Numeric
    6206         986 : numeric_stddev_internal(NumericAggState *state,
    6207             :                         bool variance, bool sample,
    6208             :                         bool *is_null)
    6209             : {
    6210             :     Numeric     res;
    6211             :     NumericVar  vN,
    6212             :                 vsumX,
    6213             :                 vsumX2,
    6214             :                 vNminus1;
    6215             :     int64       totCount;
    6216             :     int         rscale;
    6217             : 
    6218             :     /*
    6219             :      * Sample stddev and variance are undefined when N <= 1; population stddev
    6220             :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
    6221             :      * and infinities count as normal inputs for this purpose).
    6222             :      */
    6223         986 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
    6224             :     {
    6225           0 :         *is_null = true;
    6226           0 :         return NULL;
    6227             :     }
    6228             : 
    6229         986 :     if (sample && totCount <= 1)
    6230             :     {
    6231         132 :         *is_null = true;
    6232         132 :         return NULL;
    6233             :     }
    6234             : 
    6235         854 :     *is_null = false;
    6236             : 
    6237             :     /*
    6238             :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
    6239             :      * float8 functions, any infinity input produces NaN output.
    6240             :      */
    6241         854 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
    6242          54 :         return make_result(&const_nan);
    6243             : 
    6244             :     /* OK, normal calculation applies */
    6245         800 :     init_var(&vN);
    6246         800 :     init_var(&vsumX);
    6247         800 :     init_var(&vsumX2);
    6248             : 
    6249         800 :     int64_to_numericvar(state->N, &vN);
    6250         800 :     accum_sum_final(&(state->sumX), &vsumX);
    6251         800 :     accum_sum_final(&(state->sumX2), &vsumX2);
    6252             : 
    6253         800 :     init_var(&vNminus1);
    6254         800 :     sub_var(&vN, &const_one, &vNminus1);
    6255             : 
    6256             :     /* compute rscale for mul_var calls */
    6257         800 :     rscale = vsumX.dscale * 2;
    6258             : 
    6259         800 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
    6260         800 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
    6261         800 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
    6262             : 
    6263         800 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
    6264             :     {
    6265             :         /* Watch out for roundoff error producing a negative numerator */
    6266          80 :         res = make_result(&const_zero);
    6267             :     }
    6268             :     else
    6269             :     {
    6270         720 :         if (sample)
    6271         492 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
    6272             :         else
    6273         228 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
    6274         720 :         rscale = select_div_scale(&vsumX2, &vNminus1);
    6275         720 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true);  /* variance */
    6276         720 :         if (!variance)
    6277         378 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
    6278             : 
    6279         720 :         res = make_result(&vsumX);
    6280             :     }
    6281             : 
    6282         800 :     free_var(&vNminus1);
    6283         800 :     free_var(&vsumX);
    6284         800 :     free_var(&vsumX2);
    6285             : 
    6286         800 :     return res;
    6287             : }
    6288             : 
    6289             : Datum
    6290         180 : numeric_var_samp(PG_FUNCTION_ARGS)
    6291             : {
    6292             :     NumericAggState *state;
    6293             :     Numeric     res;
    6294             :     bool        is_null;
    6295             : 
    6296         180 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6297             : 
    6298         180 :     res = numeric_stddev_internal(state, true, true, &is_null);
    6299             : 
    6300         180 :     if (is_null)
    6301          42 :         PG_RETURN_NULL();
    6302             :     else
    6303         138 :         PG_RETURN_NUMERIC(res);
    6304             : }
    6305             : 
    6306             : Datum
    6307         174 : numeric_stddev_samp(PG_FUNCTION_ARGS)
    6308             : {
    6309             :     NumericAggState *state;
    6310             :     Numeric     res;
    6311             :     bool        is_null;
    6312             : 
    6313         174 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6314             : 
    6315         174 :     res = numeric_stddev_internal(state, false, true, &is_null);
    6316             : 
    6317         174 :     if (is_null)
    6318          42 :         PG_RETURN_NULL();
    6319             :     else
    6320         132 :         PG_RETURN_NUMERIC(res);
    6321             : }
    6322             : 
    6323             : Datum
    6324         114 : numeric_var_pop(PG_FUNCTION_ARGS)
    6325             : {
    6326             :     NumericAggState *state;
    6327             :     Numeric     res;
    6328             :     bool        is_null;
    6329             : 
    6330         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6331             : 
    6332         114 :     res = numeric_stddev_internal(state, true, false, &is_null);
    6333             : 
    6334         114 :     if (is_null)
    6335           0 :         PG_RETURN_NULL();
    6336             :     else
    6337         114 :         PG_RETURN_NUMERIC(res);
    6338             : }
    6339             : 
    6340             : Datum
    6341          96 : numeric_stddev_pop(PG_FUNCTION_ARGS)
    6342             : {
    6343             :     NumericAggState *state;
    6344             :     Numeric     res;
    6345             :     bool        is_null;
    6346             : 
    6347          96 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
    6348             : 
    6349          96 :     res = numeric_stddev_internal(state, false, false, &is_null);
    6350             : 
    6351          96 :     if (is_null)
    6352           0 :         PG_RETURN_NULL();
    6353             :     else
    6354          96 :         PG_RETURN_NUMERIC(res);
    6355             : }
    6356             : 
    6357             : #ifdef HAVE_INT128
    6358             : static Numeric
    6359         422 : numeric_poly_stddev_internal(Int128AggState *state,
    6360             :                              bool variance, bool sample,
    6361             :                              bool *is_null)
    6362             : {
    6363             :     NumericAggState numstate;
    6364             :     Numeric     res;
    6365             : 
    6366             :     /* Initialize an empty agg state */
    6367         422 :     memset(&numstate, 0, sizeof(NumericAggState));
    6368             : 
    6369         422 :     if (state)
    6370             :     {
    6371             :         NumericVar  tmp_var;
    6372             : 
    6373         422 :         numstate.N = state->N;
    6374             : 
    6375         422 :         init_var(&tmp_var);
    6376             : 
    6377         422 :         int128_to_numericvar(state->sumX, &tmp_var);
    6378         422 :         accum_sum_add(&numstate.sumX, &tmp_var);
    6379             : 
    6380         422 :         int128_to_numericvar(state->sumX2, &tmp_var);
    6381         422 :         accum_sum_add(&numstate.sumX2, &tmp_var);
    6382             : 
    6383         422 :         free_var(&tmp_var);
    6384             :     }
    6385             : 
    6386         422 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
    6387             : 
    6388         422 :     if (numstate.sumX.ndigits > 0)
    6389             :     {
    6390         422 :         pfree(numstate.sumX.pos_digits);
    6391         422 :         pfree(numstate.sumX.neg_digits);
    6392             :     }
    6393         422 :     if (numstate.sumX2.ndigits > 0)
    6394             :     {
    6395         422 :         pfree(numstate.sumX2.pos_digits);
    6396         422 :         pfree(numstate.sumX2.neg_digits);
    6397             :     }
    6398             : 
    6399         422 :     return res;
    6400             : }
    6401             : #endif
    6402             : 
    6403             : Datum
    6404         126 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
    6405             : {
    6406             : #ifdef HAVE_INT128
    6407             :     PolyNumAggState *state;
    6408             :     Numeric     res;
    6409             :     bool        is_null;
    6410             : 
    6411         126 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6412             : 
    6413         126 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
    6414             : 
    6415         126 :     if (is_null)
    6416          24 :         PG_RETURN_NULL();
    6417             :     else
    6418         102 :         PG_RETURN_NUMERIC(res);
    6419             : #else
    6420             :     return numeric_var_samp(fcinfo);
    6421             : #endif
    6422             : }
    6423             : 
    6424             : Datum
    6425         164 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
    6426             : {
    6427             : #ifdef HAVE_INT128
    6428             :     PolyNumAggState *state;
    6429             :     Numeric     res;
    6430             :     bool        is_null;
    6431             : 
    6432         164 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6433             : 
    6434         164 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
    6435             : 
    6436         164 :     if (is_null)
    6437          24 :         PG_RETURN_NULL();
    6438             :     else
    6439         140 :         PG_RETURN_NUMERIC(res);
    6440             : #else
    6441             :     return numeric_stddev_samp(fcinfo);
    6442             : #endif
    6443             : }
    6444             : 
    6445             : Datum
    6446          60 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
    6447             : {
    6448             : #ifdef HAVE_INT128
    6449             :     PolyNumAggState *state;
    6450             :     Numeric     res;
    6451             :     bool        is_null;
    6452             : 
    6453          60 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6454             : 
    6455          60 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
    6456             : 
    6457          60 :     if (is_null)
    6458           0 :         PG_RETURN_NULL();
    6459             :     else
    6460          60 :         PG_RETURN_NUMERIC(res);
    6461             : #else
    6462             :     return numeric_var_pop(fcinfo);
    6463             : #endif
    6464             : }
    6465             : 
    6466             : Datum
    6467          72 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
    6468             : {
    6469             : #ifdef HAVE_INT128
    6470             :     PolyNumAggState *state;
    6471             :     Numeric     res;
    6472             :     bool        is_null;
    6473             : 
    6474          72 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
    6475             : 
    6476          72 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
    6477             : 
    6478          72 :     if (is_null)
    6479           0 :         PG_RETURN_NULL();
    6480             :     else
    6481          72 :         PG_RETURN_NUMERIC(res);
    6482             : #else
    6483             :     return numeric_stddev_pop(fcinfo);
    6484             : #endif
    6485             : }
    6486             : 
    6487             : /*
    6488             :  * SUM transition functions for integer datatypes.
    6489             :  *
    6490             :  * To avoid overflow, we use accumulators wider than the input datatype.
    6491             :  * A Numeric accumulator is needed for int8 input; for int4 and int2
    6492             :  * inputs, we use int8 accumulators which should be sufficient for practical
    6493             :  * purposes.  (The latter two therefore don't really belong in this file,
    6494             :  * but we keep them here anyway.)
    6495             :  *
    6496             :  * Because SQL defines the SUM() of no values to be NULL, not zero,
    6497             :  * the initial condition of the transition data value needs to be NULL. This
    6498             :  * means we can't rely on ExecAgg to automatically insert the first non-null
    6499             :  * data value into the transition data: it doesn't know how to do the type
    6500             :  * conversion.  The upshot is that these routines have to be marked non-strict
    6501             :  * and handle substitution of the first non-null input themselves.
    6502             :  *
    6503             :  * Note: these functions are used only in plain aggregation mode.
    6504             :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
    6505             :  */
    6506             : 
    6507             : Datum
    6508          24 : int2_sum(PG_FUNCTION_ARGS)
    6509             : {
    6510             :     int64       newval;
    6511             : 
    6512          24 :     if (PG_ARGISNULL(0))
    6513             :     {
    6514             :         /* No non-null input seen so far... */
    6515           6 :         if (PG_ARGISNULL(1))
    6516           0 :             PG_RETURN_NULL();   /* still no non-null */
    6517             :         /* This is the first non-null input. */
    6518           6 :         newval = (int64) PG_GETARG_INT16(1);
    6519           6 :         PG_RETURN_INT64(newval);
    6520             :     }
    6521             : 
    6522             :     /*
    6523             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6524             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6525             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6526             :      * then of course this is useless as well as incorrect, so just ifdef it
    6527             :      * out.)
    6528             :      */
    6529             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6530             :     if (AggCheckCallContext(fcinfo, NULL))
    6531             :     {
    6532             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6533             : 
    6534             :         /* Leave the running sum unchanged in the new input is null */
    6535             :         if (!PG_ARGISNULL(1))
    6536             :             *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
    6537             : 
    6538             :         PG_RETURN_POINTER(oldsum);
    6539             :     }
    6540             :     else
    6541             : #endif
    6542             :     {
    6543          18 :         int64       oldsum = PG_GETARG_INT64(0);
    6544             : 
    6545             :         /* Leave sum unchanged if new input is null. */
    6546          18 :         if (PG_ARGISNULL(1))
    6547           0 :             PG_RETURN_INT64(oldsum);
    6548             : 
    6549             :         /* OK to do the addition. */
    6550          18 :         newval = oldsum + (int64) PG_GETARG_INT16(1);
    6551             : 
    6552          18 :         PG_RETURN_INT64(newval);
    6553             :     }
    6554             : }
    6555             : 
    6556             : Datum
    6557     3458060 : int4_sum(PG_FUNCTION_ARGS)
    6558             : {
    6559             :     int64       newval;
    6560             : 
    6561     3458060 :     if (PG_ARGISNULL(0))
    6562             :     {
    6563             :         /* No non-null input seen so far... */
    6564       86398 :         if (PG_ARGISNULL(1))
    6565         986 :             PG_RETURN_NULL();   /* still no non-null */
    6566             :         /* This is the first non-null input. */
    6567       85412 :         newval = (int64) PG_GETARG_INT32(1);
    6568       85412 :         PG_RETURN_INT64(newval);
    6569             :     }
    6570             : 
    6571             :     /*
    6572             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6573             :      * parameter in-place to avoid palloc overhead. If not, we need to return
    6574             :      * the new value of the transition variable. (If int8 is pass-by-value,
    6575             :      * then of course this is useless as well as incorrect, so just ifdef it
    6576             :      * out.)
    6577             :      */
    6578             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
    6579             :     if (AggCheckCallContext(fcinfo, NULL))
    6580             :     {
    6581             :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
    6582             : 
    6583             :         /* Leave the running sum unchanged in the new input is null */
    6584             :         if (!PG_ARGISNULL(1))
    6585             :             *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
    6586             : 
    6587             :         PG_RETURN_POINTER(oldsum);
    6588             :     }
    6589             :     else
    6590             : #endif
    6591             :     {
    6592     3371662 :         int64       oldsum = PG_GETARG_INT64(0);
    6593             : 
    6594             :         /* Leave sum unchanged if new input is null. */
    6595     3371662 :         if (PG_ARGISNULL(1))
    6596         874 :             PG_RETURN_INT64(oldsum);
    6597             : 
    6598             :         /* OK to do the addition. */
    6599     3370788 :         newval = oldsum + (int64) PG_GETARG_INT32(1);
    6600             : 
    6601     3370788 :         PG_RETURN_INT64(newval);
    6602             :     }
    6603             : }
    6604             : 
    6605             : /*
    6606             :  * Note: this function is obsolete, it's no longer used for SUM(int8).
    6607             :  */
    6608             : Datum
    6609           0 : int8_sum(PG_FUNCTION_ARGS)
    6610             : {
    6611             :     Numeric     oldsum;
    6612             : 
    6613           0 :     if (PG_ARGISNULL(0))
    6614             :     {
    6615             :         /* No non-null input seen so far... */
    6616           0 :         if (PG_ARGISNULL(1))
    6617           0 :             PG_RETURN_NULL();   /* still no non-null */
    6618             :         /* This is the first non-null input. */
    6619           0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
    6620             :     }
    6621             : 
    6622             :     /*
    6623             :      * Note that we cannot special-case the aggregate case here, as we do for
    6624             :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
    6625             :      * our first parameter in-place.
    6626             :      */
    6627             : 
    6628           0 :     oldsum = PG_GETARG_NUMERIC(0);
    6629             : 
    6630             :     /* Leave sum unchanged if new input is null. */
    6631           0 :     if (PG_ARGISNULL(1))
    6632           0 :         PG_RETURN_NUMERIC(oldsum);
    6633             : 
    6634             :     /* OK to do the addition. */
    6635           0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
    6636             :                                         NumericGetDatum(oldsum),
    6637             :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
    6638             : }
    6639             : 
    6640             : 
    6641             : /*
    6642             :  * Routines for avg(int2) and avg(int4).  The transition datatype
    6643             :  * is a two-element int8 array, holding count and sum.
    6644             :  *
    6645             :  * These functions are also used for sum(int2) and sum(int4) when
    6646             :  * operating in moving-aggregate mode, since for correct inverse transitions
    6647             :  * we need to count the inputs.
    6648             :  */
    6649             : 
    6650             : typedef struct Int8TransTypeData
    6651             : {
    6652             :     int64       count;
    6653             :     int64       sum;
    6654             : } Int8TransTypeData;
    6655             : 
    6656             : Datum
    6657          42 : int2_avg_accum(PG_FUNCTION_ARGS)
    6658             : {
    6659             :     ArrayType  *transarray;
    6660          42 :     int16       newval = PG_GETARG_INT16(1);
    6661             :     Int8TransTypeData *transdata;
    6662             : 
    6663             :     /*
    6664             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6665             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6666             :      * a copy of it before scribbling on it.
    6667             :      */
    6668          42 :     if (AggCheckCallContext(fcinfo, NULL))
    6669          42 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6670             :     else
    6671           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6672             : 
    6673          42 :     if (ARR_HASNULL(transarray) ||
    6674          42 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6675           0 :         elog(ERROR, "expected 2-element int8 array");
    6676             : 
    6677          42 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6678          42 :     transdata->count++;
    6679          42 :     transdata->sum += newval;
    6680             : 
    6681          42 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6682             : }
    6683             : 
    6684             : Datum
    6685     2590302 : int4_avg_accum(PG_FUNCTION_ARGS)
    6686             : {
    6687             :     ArrayType  *transarray;
    6688     2590302 :     int32       newval = PG_GETARG_INT32(1);
    6689             :     Int8TransTypeData *transdata;
    6690             : 
    6691             :     /*
    6692             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6693             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6694             :      * a copy of it before scribbling on it.
    6695             :      */
    6696     2590302 :     if (AggCheckCallContext(fcinfo, NULL))
    6697     2590302 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6698             :     else
    6699           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6700             : 
    6701     2590302 :     if (ARR_HASNULL(transarray) ||
    6702     2590302 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6703           0 :         elog(ERROR, "expected 2-element int8 array");
    6704             : 
    6705     2590302 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6706     2590302 :     transdata->count++;
    6707     2590302 :     transdata->sum += newval;
    6708             : 
    6709     2590302 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6710             : }
    6711             : 
    6712             : Datum
    6713        3422 : int4_avg_combine(PG_FUNCTION_ARGS)
    6714             : {
    6715             :     ArrayType  *transarray1;
    6716             :     ArrayType  *transarray2;
    6717             :     Int8TransTypeData *state1;
    6718             :     Int8TransTypeData *state2;
    6719             : 
    6720        3422 :     if (!AggCheckCallContext(fcinfo, NULL))
    6721           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
    6722             : 
    6723        3422 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
    6724        3422 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
    6725             : 
    6726        3422 :     if (ARR_HASNULL(transarray1) ||
    6727        3422 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6728           0 :         elog(ERROR, "expected 2-element int8 array");
    6729             : 
    6730        3422 :     if (ARR_HASNULL(transarray2) ||
    6731        3422 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6732           0 :         elog(ERROR, "expected 2-element int8 array");
    6733             : 
    6734        3422 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
    6735        3422 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
    6736             : 
    6737        3422 :     state1->count += state2->count;
    6738        3422 :     state1->sum += state2->sum;
    6739             : 
    6740        3422 :     PG_RETURN_ARRAYTYPE_P(transarray1);
    6741             : }
    6742             : 
    6743             : Datum
    6744          12 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
    6745             : {
    6746             :     ArrayType  *transarray;
    6747          12 :     int16       newval = PG_GETARG_INT16(1);
    6748             :     Int8TransTypeData *transdata;
    6749             : 
    6750             :     /*
    6751             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6752             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6753             :      * a copy of it before scribbling on it.
    6754             :      */
    6755          12 :     if (AggCheckCallContext(fcinfo, NULL))
    6756          12 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6757             :     else
    6758           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6759             : 
    6760          12 :     if (ARR_HASNULL(transarray) ||
    6761          12 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6762           0 :         elog(ERROR, "expected 2-element int8 array");
    6763             : 
    6764          12 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6765          12 :     transdata->count--;
    6766          12 :     transdata->sum -= newval;
    6767             : 
    6768          12 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6769             : }
    6770             : 
    6771             : Datum
    6772        1452 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
    6773             : {
    6774             :     ArrayType  *transarray;
    6775        1452 :     int32       newval = PG_GETARG_INT32(1);
    6776             :     Int8TransTypeData *transdata;
    6777             : 
    6778             :     /*
    6779             :      * If we're invoked as an aggregate, we can cheat and modify our first
    6780             :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
    6781             :      * a copy of it before scribbling on it.
    6782             :      */
    6783        1452 :     if (AggCheckCallContext(fcinfo, NULL))
    6784        1452 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
    6785             :     else
    6786           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
    6787             : 
    6788        1452 :     if (ARR_HASNULL(transarray) ||
    6789        1452 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6790           0 :         elog(ERROR, "expected 2-element int8 array");
    6791             : 
    6792        1452 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6793        1452 :     transdata->count--;
    6794        1452 :     transdata->sum -= newval;
    6795             : 
    6796        1452 :     PG_RETURN_ARRAYTYPE_P(transarray);
    6797             : }
    6798             : 
    6799             : Datum
    6800       10750 : int8_avg(PG_FUNCTION_ARGS)
    6801             : {
    6802       10750 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6803             :     Int8TransTypeData *transdata;
    6804             :     Datum       countd,
    6805             :                 sumd;
    6806             : 
    6807       10750 :     if (ARR_HASNULL(transarray) ||
    6808       10750 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6809           0 :         elog(ERROR, "expected 2-element int8 array");
    6810       10750 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6811             : 
    6812             :     /* SQL defines AVG of no values to be NULL */
    6813       10750 :     if (transdata->count == 0)
    6814         118 :         PG_RETURN_NULL();
    6815             : 
    6816       10632 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
    6817       10632 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
    6818             : 
    6819       10632 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
    6820             : }
    6821             : 
    6822             : /*
    6823             :  * SUM(int2) and SUM(int4) both return int8, so we can use this
    6824             :  * final function for both.
    6825             :  */
    6826             : Datum
    6827        3834 : int2int4_sum(PG_FUNCTION_ARGS)
    6828             : {
    6829        3834 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
    6830             :     Int8TransTypeData *transdata;
    6831             : 
    6832        3834 :     if (ARR_HASNULL(transarray) ||
    6833        3834 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
    6834           0 :         elog(ERROR, "expected 2-element int8 array");
    6835        3834 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
    6836             : 
    6837             :     /* SQL defines SUM of no values to be NULL */
    6838        3834 :     if (transdata->count == 0)
    6839         480 :         PG_RETURN_NULL();
    6840             : 
    6841        3354 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
    6842             : }
    6843             : 
    6844             : 
    6845             : /* ----------------------------------------------------------------------
    6846             :  *
    6847             :  * Debug support
    6848             :  *
    6849             :  * ----------------------------------------------------------------------
    6850             :  */
    6851             : 
    6852             : #ifdef NUMERIC_DEBUG
    6853             : 
    6854             : /*
    6855             :  * dump_numeric() - Dump a value in the db storage format for debugging
    6856             :  */
    6857             : static void
    6858             : dump_numeric(const char *str, Numeric num)
    6859             : {
    6860             :     NumericDigit *digits = NUMERIC_DIGITS(num);
    6861             :     int         ndigits;
    6862             :     int         i;
    6863             : 
    6864             :     ndigits = NUMERIC_NDIGITS(num);
    6865             : 
    6866             :     printf("%s: NUMERIC w=%d d=%d ", str,
    6867             :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
    6868             :     switch (NUMERIC_SIGN(num))
    6869             :     {
    6870             :         case NUMERIC_POS:
    6871             :             printf("POS");
    6872             :             break;
    6873             :         case NUMERIC_NEG:
    6874             :             printf("NEG");
    6875             :             break;
    6876             :         case NUMERIC_NAN:
    6877             :             printf("NaN");
    6878             :             break;
    6879             :         case NUMERIC_PINF:
    6880             :             printf("Infinity");
    6881             :             break;
    6882             :         case NUMERIC_NINF:
    6883             :             printf("-Infinity");
    6884             :             break;
    6885             :         default:
    6886             :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
    6887             :             break;
    6888             :     }
    6889             : 
    6890             :     for (i = 0; i < ndigits; i++)
    6891             :         printf(" %0*d", DEC_DIGITS, digits[i]);
    6892             :     printf("\n");
    6893             : }
    6894             : 
    6895             : 
    6896             : /*
    6897             :  * dump_var() - Dump a value in the variable format for debugging
    6898             :  */
    6899             : static void
    6900             : dump_var(const char *str, NumericVar *var)
    6901             : {
    6902             :     int         i;
    6903             : 
    6904             :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
    6905             :     switch (var->sign)
    6906             :     {
    6907             :         case NUMERIC_POS:
    6908             :             printf("POS");
    6909             :             break;
    6910             :         case NUMERIC_NEG:
    6911             :             printf("NEG");
    6912             :             break;
    6913             :         case NUMERIC_NAN:
    6914             :             printf("NaN");
    6915             :             break;
    6916             :         case NUMERIC_PINF:
    6917             :             printf("Infinity");
    6918             :             break;
    6919             :         case NUMERIC_NINF:
    6920             :             printf("-Infinity");
    6921             :             break;
    6922             :         default:
    6923             :             printf("SIGN=0x%x", var->sign);
    6924             :             break;
    6925             :     }
    6926             : 
    6927             :     for (i = 0; i < var->ndigits; i++)
    6928             :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
    6929             : 
    6930             :     printf("\n");
    6931             : }
    6932             : #endif                          /* NUMERIC_DEBUG */
    6933             : 
    6934             : 
    6935             : /* ----------------------------------------------------------------------
    6936             :  *
    6937             :  * Local functions follow
    6938             :  *
    6939             :  * In general, these do not support "special" (NaN or infinity) inputs;
    6940             :  * callers should handle those possibilities first.
    6941             :  * (There are one or two exceptions, noted in their header comments.)
    6942             :  *
    6943             :  * ----------------------------------------------------------------------
    6944             :  */
    6945             : 
    6946             : 
    6947             : /*
    6948             :  * alloc_var() -
    6949             :  *
    6950             :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
    6951             :  */
    6952             : static void
    6953     2904546 : alloc_var(NumericVar *var, int ndigits)
    6954             : {
    6955     2904546 :     digitbuf_free(var->buf);
    6956     2904546 :     var->buf = digitbuf_alloc(ndigits + 1);
    6957     2904546 :     var->buf[0] = 0;         /* spare digit for rounding */
    6958     2904546 :     var->digits = var->buf + 1;
    6959     2904546 :     var->ndigits = ndigits;
    6960     2904546 : }
    6961             : 
    6962             : 
    6963             : /*
    6964             :  * free_var() -
    6965             :  *
    6966             :  *  Return the digit buffer of a variable to the free pool
    6967             :  */
    6968             : static void
    6969     3414476 : free_var(NumericVar *var)
    6970             : {
    6971     3414476 :     digitbuf_free(var->buf);
    6972     3414476 :     var->buf = NULL;
    6973     3414476 :     var->digits = NULL;
    6974     3414476 :     var->sign = NUMERIC_NAN;
    6975     3414476 : }
    6976             : 
    6977             : 
    6978             : /*
    6979             :  * zero_var() -
    6980             :  *
    6981             :  *  Set a variable to ZERO.
    6982             :  *  Note: its dscale is not touched.
    6983             :  */
    6984             : static void
    6985       41418 : zero_var(NumericVar *var)
    6986             : {
    6987       41418 :     digitbuf_free(var->buf);
    6988       41418 :     var->buf = NULL;
    6989       41418 :     var->digits = NULL;
    6990       41418 :     var->ndigits = 0;
    6991       41418 :     var->weight = 0;         /* by convention; doesn't really matter */
    6992       41418 :     var->sign = NUMERIC_POS; /* anything but NAN... */
    6993       41418 : }
    6994             : 
    6995             : 
    6996             : /*
    6997             :  * set_var_from_str()
    6998             :  *
    6999             :  *  Parse a string and put the number into a variable
    7000             :  *
    7001             :  * This function does not handle leading or trailing spaces.  It returns
    7002             :  * the end+1 position parsed into *endptr, so that caller can check for
    7003             :  * trailing spaces/garbage if deemed necessary.
    7004             :  *
    7005             :  * cp is the place to actually start parsing; str is what to use in error
    7006             :  * reports.  (Typically cp would be the same except advanced over spaces.)
    7007             :  *
    7008             :  * Returns true on success, false on failure (if escontext points to an
    7009             :  * ErrorSaveContext; otherwise errors are thrown).
    7010             :  */
    7011             : static bool
    7012      127736 : set_var_from_str(const char *str, const char *cp,
    7013             :                  NumericVar *dest, const char **endptr,
    7014             :                  Node *escontext)
    7015             : {
    7016      127736 :     bool        have_dp = false;
    7017             :     int         i;
    7018             :     unsigned char *decdigits;
    7019      127736 :     int         sign = NUMERIC_POS;
    7020      127736 :     int         dweight = -1;
    7021             :     int         ddigits;
    7022      127736 :     int         dscale = 0;
    7023             :     int         weight;
    7024             :     int         ndigits;
    7025             :     int         offset;
    7026             :     NumericDigit *digits;
    7027             : 
    7028             :     /*
    7029             :      * We first parse the string to extract decimal digits and determine the
    7030             :      * correct decimal weight.  Then convert to NBASE representation.
    7031             :      */
    7032      127736 :     switch (*cp)
    7033             :     {
    7034           0 :         case '+':
    7035           0 :             sign = NUMERIC_POS;
    7036           0 :             cp++;
    7037           0 :             break;
    7038             : 
    7039         300 :         case '-':
    7040         300 :             sign = NUMERIC_NEG;
    7041         300 :             cp++;
    7042         300 :             break;
    7043             :     }
    7044             : 
    7045      127736 :     if (*cp == '.')
    7046             :     {
    7047         382 :         have_dp = true;
    7048         382 :         cp++;
    7049             :     }
    7050             : 
    7051      127736 :     if (!isdigit((unsigned char) *cp))
    7052           0 :         goto invalid_syntax;
    7053             : 
    7054      127736 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
    7055             : 
    7056             :     /* leading padding for digit alignment later */
    7057      127736 :     memset(decdigits, 0, DEC_DIGITS);
    7058      127736 :     i = DEC_DIGITS;
    7059             : 
    7060      524274 :     while (*cp)
    7061             :     {
    7062      397684 :         if (isdigit((unsigned char) *cp))
    7063             :         {
    7064      380154 :             decdigits[i++] = *cp++ - '0';
    7065      380154 :             if (!have_dp)
    7066      308584 :                 dweight++;
    7067             :             else
    7068       71570 :                 dscale++;
    7069             :         }
    7070       17530 :         else if (*cp == '.')
    7071             :         {
    7072       16222 :             if (have_dp)
    7073           0 :                 goto invalid_syntax;
    7074       16222 :             have_dp = true;
    7075       16222 :             cp++;
    7076             :             /* decimal point must not be followed by underscore */
    7077       16222 :             if (*cp == '_')
    7078           6 :                 goto invalid_syntax;
    7079             :         }
    7080        1308 :         else if (*cp == '_')
    7081             :         {
    7082             :             /* underscore must be followed by more digits */
    7083         186 :             cp++;
    7084         186 :             if (!isdigit((unsigned char) *cp))
    7085          18 :                 goto invalid_syntax;
    7086             :         }
    7087             :         else
    7088        1122 :             break;
    7089             :     }
    7090             : 
    7091      127712 :     ddigits = i - DEC_DIGITS;
    7092             :     /* trailing padding for digit alignment later */
    7093      127712 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
    7094             : 
    7095             :     /* Handle exponent, if any */
    7096      127712 :     if (*cp == 'e' || *cp == 'E')
    7097             :     {
    7098        1074 :         int64       exponent = 0;
    7099        1074 :         bool        neg = false;
    7100             : 
    7101             :         /*
    7102             :          * At this point, dweight and dscale can't be more than about
    7103             :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
    7104             :          * constraining the exponent similarly should be enough to prevent
    7105             :          * integer overflow in this function.  If the value is too large to
    7106             :          * fit in storage format, make_result() will complain about it later;
    7107             :          * for consistency use the same ereport errcode/text as make_result().
    7108             :          */
    7109             : 
    7110             :         /* exponent sign */
    7111        1074 :         cp++;
    7112        1074 :         if (*cp == '+')
    7113         154 :             cp++;
    7114         920 :         else if (*cp == '-')
    7115             :         {
    7116         392 :             neg = true;
    7117         392 :             cp++;
    7118             :         }
    7119             : 
    7120             :         /* exponent digits */
    7121        1074 :         if (!isdigit((unsigned char) *cp))
    7122           6 :             goto invalid_syntax;
    7123             : 
    7124        3324 :         while (*cp)
    7125             :         {
    7126        2274 :             if (isdigit((unsigned char) *cp))
    7127             :             {
    7128        2232 :                 exponent = exponent * 10 + (*cp++ - '0');
    7129        2232 :                 if (exponent > PG_INT32_MAX / 2)
    7130           6 :                     goto out_of_range;
    7131             :             }
    7132          42 :             else if (*cp == '_')
    7133             :             {
    7134             :                 /* underscore must be followed by more digits */
    7135          42 :                 cp++;
    7136          42 :                 if (!isdigit((unsigned char) *cp))
    7137          12 :                     goto invalid_syntax;
    7138             :             }
    7139             :             else
    7140           0 :                 break;
    7141             :         }
    7142             : 
    7143        1050 :         if (neg)
    7144         392 :             exponent = -exponent;
    7145             : 
    7146        1050 :         dweight += (int) exponent;
    7147        1050 :         dscale -= (int) exponent;
    7148        1050 :         if (dscale < 0)
    7149         454 :             dscale = 0;
    7150             :     }
    7151             : 
    7152             :     /*
    7153             :      * Okay, convert pure-decimal representation to base NBASE.  First we need
    7154             :      * to determine the converted weight and ndigits.  offset is the number of
    7155             :      * decimal zeroes to insert before the first given digit to have a
    7156             :      * correctly aligned first NBASE digit.
    7157             :      */
    7158      127688 :     if (dweight >= 0)
    7159      127016 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
    7160             :     else
    7161         672 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
    7162      127688 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
    7163      127688 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
    7164             : 
    7165      127688 :     alloc_var(dest, ndigits);
    7166      127688 :     dest->sign = sign;
    7167      127688 :     dest->weight = weight;
    7168      127688 :     dest->dscale = dscale;
    7169             : 
    7170      127688 :     i = DEC_DIGITS - offset;
    7171      127688 :     digits = dest->digits;
    7172             : 
    7173      301266 :     while (ndigits-- > 0)
    7174             :     {
    7175             : #if DEC_DIGITS == 4
    7176      173578 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
    7177      173578 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
    7178             : #elif DEC_DIGITS == 2
    7179             :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
    7180             : #elif DEC_DIGITS == 1
    7181             :         *digits++ = decdigits[i];
    7182             : #else
    7183             : #error unsupported NBASE
    7184             : #endif
    7185      173578 :         i += DEC_DIGITS;
    7186             :     }
    7187             : 
    7188      127688 :     pfree(decdigits);
    7189             : 
    7190             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
    7191      127688 :     strip_var(dest);
    7192             : 
    7193             :     /* Return end+1 position for caller */
    7194      127688 :     *endptr = cp;
    7195             : 
    7196      127688 :     return true;
    7197             : 
    7198           6 : out_of_range:
    7199           6 :     ereturn(escontext, false,
    7200             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7201             :              errmsg("value overflows numeric format")));
    7202             : 
    7203          42 : invalid_syntax:
    7204          42 :     ereturn(escontext, false,
    7205             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7206             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7207             :                     "numeric", str)));
    7208             : }
    7209             : 
    7210             : 
    7211             : /*
    7212             :  * Return the numeric value of a single hex digit.
    7213             :  */
    7214             : static inline int
    7215         708 : xdigit_value(char dig)
    7216             : {
    7217         894 :     return dig >= '0' && dig <= '9' ? dig - '0' :
    7218         294 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
    7219         108 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
    7220             : }
    7221             : 
    7222             : /*
    7223             :  * set_var_from_non_decimal_integer_str()
    7224             :  *
    7225             :  *  Parse a string containing a non-decimal integer
    7226             :  *
    7227             :  * This function does not handle leading or trailing spaces.  It returns
    7228             :  * the end+1 position parsed into *endptr, so that caller can check for
    7229             :  * trailing spaces/garbage if deemed necessary.
    7230             :  *
    7231             :  * cp is the place to actually start parsing; str is what to use in error
    7232             :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
    7233             :  * assumed to have already been parsed, so cp should point to the number's
    7234             :  * first digit in the base specified.
    7235             :  *
    7236             :  * base is expected to be 2, 8 or 16.
    7237             :  *
    7238             :  * Returns true on success, false on failure (if escontext points to an
    7239             :  * ErrorSaveContext; otherwise errors are thrown).
    7240             :  */
    7241             : static bool
    7242         156 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
    7243             :                                      int base, NumericVar *dest,
    7244             :                                      const char **endptr, Node *escontext)
    7245             : {
    7246         156 :     const char *firstdigit = cp;
    7247             :     int64       tmp;
    7248             :     int64       mul;
    7249             :     NumericVar  tmp_var;
    7250             : 
    7251         156 :     init_var(&tmp_var);
    7252             : 
    7253         156 :     zero_var(dest);
    7254             : 
    7255             :     /*
    7256             :      * Process input digits in groups that fit in int64.  Here "tmp" is the
    7257             :      * value of the digits in the group, and "mul" is base^n, where n is the
    7258             :      * number of digits in the group.  Thus tmp < mul, and we must start a new
    7259             :      * group when mul * base threatens to overflow PG_INT64_MAX.
    7260             :      */
    7261         156 :     tmp = 0;
    7262         156 :     mul = 1;
    7263             : 
    7264         156 :     if (base == 16)
    7265             :     {
    7266         828 :         while (*cp)
    7267             :         {
    7268         798 :             if (isxdigit((unsigned char) *cp))
    7269             :             {
    7270         708 :                 if (mul > PG_INT64_MAX / 16)
    7271             :                 {
    7272             :                     /* Add the contribution from this group of digits */
    7273          30 :                     int64_to_numericvar(mul, &tmp_var);
    7274          30 :                     mul_var(dest, &tmp_var, dest, 0);
    7275          30 :                     int64_to_numericvar(tmp, &tmp_var);
    7276          30 :                     add_var(dest, &tmp_var, dest);
    7277             : 
    7278             :                     /* Result will overflow if weight overflows int16 */
    7279          30 :                     if (dest->weight > SHRT_MAX)
    7280           0 :                         goto out_of_range;
    7281             : 
    7282             :                     /* Begin a new group */
    7283          30 :                     tmp = 0;
    7284          30 :                     mul = 1;
    7285             :                 }
    7286             : 
    7287         708 :                 tmp = tmp * 16 + xdigit_value(*cp++);
    7288         708 :                 mul = mul * 16;
    7289             :             }
    7290          90 :             else if (*cp == '_')
    7291             :             {
    7292             :                 /* Underscore must be followed by more digits */
    7293          66 :                 cp++;
    7294          66 :                 if (!isxdigit((unsigned char) *cp))
    7295          18 :                     goto invalid_syntax;
    7296             :             }
    7297             :             else
    7298          24 :                 break;
    7299             :         }
    7300             :     }
    7301          84 :     else if (base == 8)
    7302             :     {
    7303         636 :         while (*cp)
    7304             :         {
    7305         606 :             if (*cp >= '0' && *cp <= '7')
    7306             :             {
    7307         558 :                 if (mul > PG_INT64_MAX / 8)
    7308             :                 {
    7309             :                     /* Add the contribution from this group of digits */
    7310          18 :                     int64_to_numericvar(mul, &tmp_var);
    7311          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7312          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7313          18 :                     add_var(dest, &tmp_var, dest);
    7314             : 
    7315             :                     /* Result will overflow if weight overflows int16 */
    7316          18 :                     if (dest->weight > SHRT_MAX)
    7317           0 :                         goto out_of_range;
    7318             : 
    7319             :                     /* Begin a new group */
    7320          18 :                     tmp = 0;
    7321          18 :                     mul = 1;
    7322             :                 }
    7323             : 
    7324         558 :                 tmp = tmp * 8 + (*cp++ - '0');
    7325         558 :                 mul = mul * 8;
    7326             :             }
    7327          48 :             else if (*cp == '_')
    7328             :             {
    7329             :                 /* Underscore must be followed by more digits */
    7330          36 :                 cp++;
    7331          36 :                 if (*cp < '0' || *cp > '7')
    7332           0 :                     goto invalid_syntax;
    7333             :             }
    7334             :             else
    7335          12 :                 break;
    7336             :         }
    7337             :     }
    7338          42 :     else if (base == 2)
    7339             :     {
    7340        1560 :         while (*cp)
    7341             :         {
    7342        1530 :             if (*cp >= '0' && *cp <= '1')
    7343             :             {
    7344        1416 :                 if (mul > PG_INT64_MAX / 2)
    7345             :                 {
    7346             :                     /* Add the contribution from this group of digits */
    7347          18 :                     int64_to_numericvar(mul, &tmp_var);
    7348          18 :                     mul_var(dest, &tmp_var, dest, 0);
    7349          18 :                     int64_to_numericvar(tmp, &tmp_var);
    7350          18 :                     add_var(dest, &tmp_var, dest);
    7351             : 
    7352             :                     /* Result will overflow if weight overflows int16 */
    7353          18 :                     if (dest->weight > SHRT_MAX)
    7354           0 :                         goto out_of_range;
    7355             : 
    7356             :                     /* Begin a new group */
    7357          18 :                     tmp = 0;
    7358          18 :                     mul = 1;
    7359             :                 }
    7360             : 
    7361        1416 :                 tmp = tmp * 2 + (*cp++ - '0');
    7362        1416 :                 mul = mul * 2;
    7363             :             }
    7364         114 :             else if (*cp == '_')
    7365             :             {
    7366             :                 /* Underscore must be followed by more digits */
    7367         102 :                 cp++;
    7368         102 :                 if (*cp < '0' || *cp > '1')
    7369           0 :                     goto invalid_syntax;
    7370             :             }
    7371             :             else
    7372          12 :                 break;
    7373             :         }
    7374             :     }
    7375             :     else
    7376             :         /* Should never happen; treat as invalid input */
    7377           0 :         goto invalid_syntax;
    7378             : 
    7379             :     /* Check that we got at least one digit */
    7380         138 :     if (unlikely(cp == firstdigit))
    7381           0 :         goto invalid_syntax;
    7382             : 
    7383             :     /* Add the contribution from the final group of digits */
    7384         138 :     int64_to_numericvar(mul, &tmp_var);
    7385         138 :     mul_var(dest, &tmp_var, dest, 0);
    7386         138 :     int64_to_numericvar(tmp, &tmp_var);
    7387         138 :     add_var(dest, &tmp_var, dest);
    7388             : 
    7389         138 :     if (dest->weight > SHRT_MAX)
    7390           0 :         goto out_of_range;
    7391             : 
    7392         138 :     dest->sign = sign;
    7393             : 
    7394         138 :     free_var(&tmp_var);
    7395             : 
    7396             :     /* Return end+1 position for caller */
    7397         138 :     *endptr = cp;
    7398             : 
    7399         138 :     return true;
    7400             : 
    7401           0 : out_of_range:
    7402           0 :     ereturn(escontext, false,
    7403             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7404             :              errmsg("value overflows numeric format")));
    7405             : 
    7406          18 : invalid_syntax:
    7407          18 :     ereturn(escontext, false,
    7408             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    7409             :              errmsg("invalid input syntax for type %s: \"%s\"",
    7410             :                     "numeric", str)));
    7411             : }
    7412             : 
    7413             : 
    7414             : /*
    7415             :  * set_var_from_num() -
    7416             :  *
    7417             :  *  Convert the packed db format into a variable
    7418             :  */
    7419             : static void
    7420       12826 : set_var_from_num(Numeric num, NumericVar *dest)
    7421             : {
    7422             :     int         ndigits;
    7423             : 
    7424       12826 :     ndigits = NUMERIC_NDIGITS(num);
    7425             : 
    7426       12826 :     alloc_var(dest, ndigits);
    7427             : 
    7428       12826 :     dest->weight = NUMERIC_WEIGHT(num);
    7429       12826 :     dest->sign = NUMERIC_SIGN(num);
    7430       12826 :     dest->dscale = NUMERIC_DSCALE(num);
    7431             : 
    7432       12826 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
    7433       12826 : }
    7434             : 
    7435             : 
    7436             : /*
    7437             :  * init_var_from_num() -
    7438             :  *
    7439             :  *  Initialize a variable from packed db format. The digits array is not
    7440             :  *  copied, which saves some cycles when the resulting var is not modified.
    7441             :  *  Also, there's no need to call free_var(), as long as you don't assign any
    7442             :  *  other value to it (with set_var_* functions, or by using the var as the
    7443             :  *  destination of a function like add_var())
    7444             :  *
    7445             :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
    7446             :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
    7447             :  *  propagate to the original Numeric! It's OK to use it as the destination
    7448             :  *  argument of one of the calculational functions, though.
    7449             :  */
    7450             : static void
    7451     5095226 : init_var_from_num(Numeric num, NumericVar *dest)
    7452             : {
    7453     5095226 :     dest->ndigits = NUMERIC_NDIGITS(num);
    7454     5095226 :     dest->weight = NUMERIC_WEIGHT(num);
    7455     5095226 :     dest->sign = NUMERIC_SIGN(num);
    7456     5095226 :     dest->dscale = NUMERIC_DSCALE(num);
    7457     5095226 :     dest->digits = NUMERIC_DIGITS(num);
    7458     5095226 :     dest->buf = NULL;            /* digits array is not palloc'd */
    7459     5095226 : }
    7460             : 
    7461             : 
    7462             : /*
    7463             :  * set_var_from_var() -
    7464             :  *
    7465             :  *  Copy one variable into another
    7466             :  */
    7467             : static void
    7468       36888 : set_var_from_var(const NumericVar *value, NumericVar *dest)
    7469             : {
    7470             :     NumericDigit *newbuf;
    7471             : 
    7472       36888 :     newbuf = digitbuf_alloc(value->ndigits + 1);
    7473       36888 :     newbuf[0] = 0;              /* spare digit for rounding */
    7474       36888 :     if (value->ndigits > 0)       /* else value->digits might be null */
    7475       35954 :         memcpy(newbuf + 1, value->digits,
    7476       35954 :                value->ndigits * sizeof(NumericDigit));
    7477             : 
    7478       36888 :     digitbuf_free(dest->buf);
    7479             : 
    7480       36888 :     memmove(dest, value, sizeof(NumericVar));
    7481       36888 :     dest->buf = newbuf;
    7482       36888 :     dest->digits = newbuf + 1;
    7483       36888 : }
    7484             : 
    7485             : 
    7486             : /*
    7487             :  * get_str_from_var() -
    7488             :  *
    7489             :  *  Convert a var to text representation (guts of numeric_out).
    7490             :  *  The var is displayed to the number of digits indicated by its dscale.
    7491             :  *  Returns a palloc'd string.
    7492             :  */
    7493             : static char *
    7494      797436 : get_str_from_var(const NumericVar *var)
    7495             : {
    7496             :     int         dscale;
    7497             :     char       *str;
    7498             :     char       *cp;
    7499             :     char       *endcp;
    7500             :     int         i;
    7501             :     int         d;
    7502             :     NumericDigit dig;
    7503             : 
    7504             : #if DEC_DIGITS > 1
    7505             :     NumericDigit d1;
    7506             : #endif
    7507             : 
    7508      797436 :     dscale = var->dscale;
    7509             : 
    7510             :     /*
    7511             :      * Allocate space for the result.
    7512             :      *
    7513             :      * i is set to the # of decimal digits before decimal point. dscale is the
    7514             :      * # of decimal digits we will print after decimal point. We may generate
    7515             :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
    7516             :      * need room for sign, decimal point, null terminator.
    7517             :      */
    7518      797436 :     i = (var->weight + 1) * DEC_DIGITS;
    7519      797436 :     if (i <= 0)
    7520      139118 :         i = 1;
    7521             : 
    7522      797436 :     str = palloc(i + dscale + DEC_DIGITS + 2);
    7523      797436 :     cp = str;
    7524             : 
    7525             :     /*
    7526             :      * Output a dash for negative values
    7527             :      */
    7528      797436 :     if (var->sign == NUMERIC_NEG)
    7529        4946 :         *cp++ = '-';
    7530             : 
    7531             :     /*
    7532             :      * Output all digits before the decimal point
    7533             :      */
    7534      797436 :     if (var->weight < 0)
    7535             :     {
    7536      139118 :         d = var->weight + 1;
    7537      139118 :         *cp++ = '0';
    7538             :     }
    7539             :     else
    7540             :     {
    7541     1421528 :         for (d = 0; d <= var->weight; d++)
    7542             :         {
    7543      763210 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
    7544             :             /* In the first digit, suppress extra leading decimal zeroes */
    7545             : #if DEC_DIGITS == 4
    7546             :             {
    7547      763210 :                 bool        putit = (d > 0);
    7548             : 
    7549      763210 :                 d1 = dig / 1000;
    7550      763210 :                 dig -= d1 * 1000;
    7551      763210 :                 putit |= (d1 > 0);
    7552      763210 :                 if (putit)
    7553      111380 :                     *cp++ = d1 + '0';
    7554      763210 :                 d1 = dig / 100;
    7555      763210 :                 dig -= d1 * 100;
    7556      763210 :                 putit |= (d1 > 0);
    7557      763210 :                 if (putit)
    7558      516128 :                     *cp++ = d1 + '0';
    7559      763210 :                 d1 = dig / 10;
    7560      763210 :                 dig -= d1 * 10;
    7561      763210 :                 putit |= (d1 > 0);
    7562      763210 :                 if (putit)
    7563      642996 :                     *cp++ = d1 + '0';
    7564      763210 :                 *cp++ = dig + '0';
    7565             :             }
    7566             : #elif DEC_DIGITS == 2
    7567             :             d1 = dig / 10;
    7568             :             dig -= d1 * 10;
    7569             :             if (d1 > 0 || d > 0)
    7570             :                 *cp++ = d1 + '0';
    7571             :             *cp++ = dig + '0';
    7572             : #elif DEC_DIGITS == 1
    7573             :             *cp++ = dig + '0';
    7574             : #else
    7575             : #error unsupported NBASE
    7576             : #endif
    7577             :         }
    7578             :     }
    7579             : 
    7580             :     /*
    7581             :      * If requested, output a decimal point and all the digits that follow it.
    7582             :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
    7583             :      * needed.
    7584             :      */
    7585      797436 :     if (dscale > 0)
    7586             :     {
    7587      643570 :         *cp++ = '.';
    7588      643570 :         endcp = cp + dscale;
    7589     1897886 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
    7590             :         {
    7591     1254316 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
    7592             : #if DEC_DIGITS == 4
    7593     1254316 :             d1 = dig / 1000;
    7594     1254316 :             dig -= d1 * 1000;
    7595     1254316 :             *cp++ = d1 + '0';
    7596     1254316 :             d1 = dig / 100;
    7597     1254316 :             dig -= d1 * 100;
    7598     1254316 :             *cp++ = d1 + '0';
    7599     1254316 :             d1 = dig / 10;
    7600     1254316 :             dig -= d1 * 10;
    7601     1254316 :             *cp++ = d1 + '0';
    7602     1254316 :             *cp++ = dig + '0';
    7603             : #elif DEC_DIGITS == 2
    7604             :             d1 = dig / 10;
    7605             :             dig -= d1 * 10;
    7606             :             *cp++ = d1 + '0';
    7607             :             *cp++ = dig + '0';
    7608             : #elif DEC_DIGITS == 1
    7609             :             *cp++ = dig + '0';
    7610             : #else
    7611             : #error unsupported NBASE
    7612             : #endif
    7613             :         }
    7614      643570 :         cp = endcp;
    7615             :     }
    7616             : 
    7617             :     /*
    7618             :      * terminate the string and return it
    7619             :      */
    7620      797436 :     *cp = '\0';
    7621      797436 :     return str;
    7622             : }
    7623             : 
    7624             : /*
    7625             :  * get_str_from_var_sci() -
    7626             :  *
    7627             :  *  Convert a var to a normalised scientific notation text representation.
    7628             :  *  This function does the heavy lifting for numeric_out_sci().
    7629             :  *
    7630             :  *  This notation has the general form a * 10^b, where a is known as the
    7631             :  *  "significand" and b is known as the "exponent".
    7632             :  *
    7633             :  *  Because we can't do superscript in ASCII (and because we want to copy
    7634             :  *  printf's behaviour) we display the exponent using E notation, with a
    7635             :  *  minimum of two exponent digits.
    7636             :  *
    7637             :  *  For example, the value 1234 could be output as 1.2e+03.
    7638             :  *
    7639             :  *  We assume that the exponent can fit into an int32.
    7640             :  *
    7641             :  *  rscale is the number of decimal digits desired after the decimal point in
    7642             :  *  the output, negative values will be treated as meaning zero.
    7643             :  *
    7644             :  *  Returns a palloc'd string.
    7645             :  */
    7646             : static char *
    7647         216 : get_str_from_var_sci(const NumericVar *var, int rscale)
    7648             : {
    7649             :     int32       exponent;
    7650             :     NumericVar  tmp_var;
    7651             :     size_t      len;
    7652             :     char       *str;
    7653             :     char       *sig_out;
    7654             : 
    7655         216 :     if (rscale < 0)
    7656           0 :         rscale = 0;
    7657             : 
    7658             :     /*
    7659             :      * Determine the exponent of this number in normalised form.
    7660             :      *
    7661             :      * This is the exponent required to represent the number with only one
    7662             :      * significant digit before the decimal place.
    7663             :      */
    7664         216 :     if (var->ndigits > 0)
    7665             :     {
    7666         198 :         exponent = (var->weight + 1) * DEC_DIGITS;
    7667             : 
    7668             :         /*
    7669             :          * Compensate for leading decimal zeroes in the first numeric digit by
    7670             :          * decrementing the exponent.
    7671             :          */
    7672         198 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
    7673             :     }
    7674             :     else
    7675             :     {
    7676             :         /*
    7677             :          * If var has no digits, then it must be zero.
    7678             :          *
    7679             :          * Zero doesn't technically have a meaningful exponent in normalised
    7680             :          * notation, but we just display the exponent as zero for consistency
    7681             :          * of output.
    7682             :          */
    7683          18 :         exponent = 0;
    7684             :     }
    7685             : 
    7686             :     /*
    7687             :      * Divide var by 10^exponent to get the significand, rounding to rscale
    7688             :      * decimal digits in the process.
    7689             :      */
    7690         216 :     init_var(&tmp_var);
    7691             : 
    7692         216 :     power_ten_int(exponent, &tmp_var);
    7693         216 :     div_var(var, &tmp_var, &tmp_var, rscale, true);
    7694         216 :     sig_out = get_str_from_var(&tmp_var);
    7695             : 
    7696         216 :     free_var(&tmp_var);
    7697             : 
    7698             :     /*
    7699             :      * Allocate space for the result.
    7700             :      *
    7701             :      * In addition to the significand, we need room for the exponent
    7702             :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
    7703             :      * exponent itself, and of course the null terminator.
    7704             :      */
    7705         216 :     len = strlen(sig_out) + 13;
    7706         216 :     str = palloc(len);
    7707         216 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
    7708             : 
    7709         216 :     pfree(sig_out);
    7710             : 
    7711         216 :     return str;
    7712             : }
    7713             : 
    7714             : 
    7715             : /*
    7716             :  * numericvar_serialize - serialize NumericVar to binary format
    7717             :  *
    7718             :  * At variable level, no checks are performed on the weight or dscale, allowing
    7719             :  * us to pass around intermediate values with higher precision than supported
    7720             :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
    7721             :  * which use 16-bit integers for these fields.
    7722             :  */
    7723             : static void
    7724          96 : numericvar_serialize(StringInfo buf, const NumericVar *var)
    7725             : {
    7726             :     int         i;
    7727             : 
    7728          96 :     pq_sendint32(buf, var->ndigits);
    7729          96 :     pq_sendint32(buf, var->weight);
    7730          96 :     pq_sendint32(buf, var->sign);
    7731          96 :     pq_sendint32(buf, var->dscale);
    7732      637784 :     for (i = 0; i < var->ndigits; i++)
    7733      637688 :         pq_sendint16(buf, var->digits[i]);
    7734          96 : }
    7735             : 
    7736             : /*
    7737             :  * numericvar_deserialize - deserialize binary format to NumericVar
    7738             :  */
    7739             : static void
    7740          96 : numericvar_deserialize(StringInfo buf, NumericVar *var)
    7741             : {
    7742             :     int         len,
    7743             :                 i;
    7744             : 
    7745          96 :     len = pq_getmsgint(buf, sizeof(int32));
    7746             : 
    7747          96 :     alloc_var(var, len);        /* sets var->ndigits */
    7748             : 
    7749          96 :     var->weight = pq_getmsgint(buf, sizeof(int32));
    7750          96 :     var->sign = pq_getmsgint(buf, sizeof(int32));
    7751          96 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
    7752      637784 :     for (i = 0; i < len; i++)
    7753      637688 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
    7754          96 : }
    7755             : 
    7756             : 
    7757             : /*
    7758             :  * duplicate_numeric() - copy a packed-format Numeric
    7759             :  *
    7760             :  * This will handle NaN and Infinity cases.
    7761             :  */
    7762             : static Numeric
    7763       28496 : duplicate_numeric(Numeric num)
    7764             : {
    7765             :     Numeric     res;
    7766             : 
    7767       28496 :     res = (Numeric) palloc(VARSIZE(num));
    7768       28496 :     memcpy(res, num, VARSIZE(num));
    7769       28496 :     return res;
    7770             : }
    7771             : 
    7772             : /*
    7773             :  * make_result_opt_error() -
    7774             :  *
    7775             :  *  Create the packed db numeric format in palloc()'d memory from
    7776             :  *  a variable.  This will handle NaN and Infinity cases.
    7777             :  *
    7778             :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
    7779             :  *  NULL is returned.  This is helpful when caller needs to handle errors.
    7780             :  */
    7781             : static Numeric
    7782     3274826 : make_result_opt_error(const NumericVar *var, bool *have_error)
    7783             : {
    7784             :     Numeric     result;
    7785     3274826 :     NumericDigit *digits = var->digits;
    7786     3274826 :     int         weight = var->weight;
    7787     3274826 :     int         sign = var->sign;
    7788             :     int         n;
    7789             :     Size        len;
    7790             : 
    7791     3274826 :     if (have_error)
    7792      105452 :         *have_error = false;
    7793             : 
    7794     3274826 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
    7795             :     {
    7796             :         /*
    7797             :          * Verify valid special value.  This could be just an Assert, perhaps,
    7798             :          * but it seems worthwhile to expend a few cycles to ensure that we
    7799             :          * never write any nonzero reserved bits to disk.
    7800             :          */
    7801        5184 :         if (!(sign == NUMERIC_NAN ||
    7802             :               sign == NUMERIC_PINF ||
    7803             :               sign == NUMERIC_NINF))
    7804           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
    7805             : 
    7806        5184 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
    7807             : 
    7808        5184 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
    7809        5184 :         result->choice.n_header = sign;
    7810             :         /* the header word is all we need */
    7811             : 
    7812             :         dump_numeric("make_result()", result);
    7813        5184 :         return result;
    7814             :     }
    7815             : 
    7816     3269642 :     n = var->ndigits;
    7817             : 
    7818             :     /* truncate leading zeroes */
    7819     3269666 :     while (n > 0 && *digits == 0)
    7820             :     {
    7821          24 :         digits++;
    7822          24 :         weight--;
    7823          24 :         n--;
    7824             :     }
    7825             :     /* truncate trailing zeroes */
    7826     3354804 :     while (n > 0 && digits[n - 1] == 0)
    7827       85162 :         n--;
    7828             : 
    7829             :     /* If zero result, force to weight=0 and positive sign */
    7830     3269642 :     if (n == 0)
    7831             :     {
    7832       96914 :         weight = 0;
    7833       96914 :         sign = NUMERIC_POS;
    7834             :     }
    7835             : 
    7836             :     /* Build the result */
    7837     3269642 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
    7838             :     {
    7839     3267872 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
    7840     3267872 :         result = (Numeric) palloc(len);
    7841     3267872 :         SET_VARSIZE(result, len);
    7842     3267872 :         result->choice.n_short.n_header =
    7843             :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
    7844             :              : NUMERIC_SHORT)
    7845     3267872 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
    7846     3267872 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
    7847     3267872 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
    7848             :     }
    7849             :     else
    7850             :     {
    7851        1770 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
    7852        1770 :         result = (Numeric) palloc(len);
    7853        1770 :         SET_VARSIZE(result, len);
    7854        1770 :         result->choice.n_long.n_sign_dscale =
    7855        1770 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
    7856        1770 :         result->choice.n_long.n_weight = weight;
    7857             :     }
    7858             : 
    7859             :     Assert(NUMERIC_NDIGITS(result) == n);
    7860     3269642 :     if (n > 0)
    7861     3172728 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
    7862             : 
    7863             :     /* Check for overflow of int16 fields */
    7864     3269642 :     if (NUMERIC_WEIGHT(result) != weight ||
    7865     3269618 :         NUMERIC_DSCALE(result) != var->dscale)
    7866             :     {
    7867          24 :         if (have_error)
    7868             :         {
    7869          18 :             *have_error = true;
    7870          18 :             return NULL;
    7871             :         }
    7872             :         else
    7873             :         {
    7874           6 :             ereport(ERROR,
    7875             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7876             :                      errmsg("value overflows numeric format")));
    7877             :         }
    7878             :     }
    7879             : 
    7880             :     dump_numeric("make_result()", result);
    7881     3269618 :     return result;
    7882             : }
    7883             : 
    7884             : 
    7885             : /*
    7886             :  * make_result() -
    7887             :  *
    7888             :  *  An interface to make_result_opt_error() without "have_error" argument.
    7889             :  */
    7890             : static Numeric
    7891     2129920 : make_result(const NumericVar *var)
    7892             : {
    7893     2129920 :     return make_result_opt_error(var, NULL);
    7894             : }
    7895             : 
    7896             : 
    7897             : /*
    7898             :  * apply_typmod() -
    7899             :  *
    7900             :  *  Do bounds checking and rounding according to the specified typmod.
    7901             :  *  Note that this is only applied to normal finite values.
    7902             :  *
    7903             :  * Returns true on success, false on failure (if escontext points to an
    7904             :  * ErrorSaveContext; otherwise errors are thrown).
    7905             :  */
    7906             : static bool
    7907      109616 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
    7908             : {
    7909             :     int         precision;
    7910             :     int         scale;
    7911             :     int         maxdigits;
    7912             :     int         ddigits;
    7913             :     int         i;
    7914             : 
    7915             :     /* Do nothing if we have an invalid typmod */
    7916      109616 :     if (!is_valid_numeric_typmod(typmod))
    7917      104924 :         return true;
    7918             : 
    7919        4692 :     precision = numeric_typmod_precision(typmod);
    7920        4692 :     scale = numeric_typmod_scale(typmod);
    7921        4692 :     maxdigits = precision - scale;
    7922             : 
    7923             :     /* Round to target scale (and set var->dscale) */
    7924        4692 :     round_var(var, scale);
    7925             : 
    7926             :     /* but don't allow var->dscale to be negative */
    7927        4692 :     if (var->dscale < 0)
    7928         126 :         var->dscale = 0;
    7929             : 
    7930             :     /*
    7931             :      * Check for overflow - note we can't do this before rounding, because
    7932             :      * rounding could raise the weight.  Also note that the var's weight could
    7933             :      * be inflated by leading zeroes, which will be stripped before storage
    7934             :      * but perhaps might not have been yet. In any case, we must recognize a
    7935             :      * true zero, whose weight doesn't mean anything.
    7936             :      */
    7937        4692 :     ddigits = (var->weight + 1) * DEC_DIGITS;
    7938        4692 :     if (ddigits > maxdigits)
    7939             :     {
    7940             :         /* Determine true weight; and check for all-zero result */
    7941         404 :         for (i = 0; i < var->ndigits; i++)
    7942             :         {
    7943         388 :             NumericDigit dig = var->digits[i];
    7944             : 
    7945         388 :             if (dig)
    7946             :             {
    7947             :                 /* Adjust for any high-order decimal zero digits */
    7948             : #if DEC_DIGITS == 4
    7949         388 :                 if (dig < 10)
    7950         252 :                     ddigits -= 3;
    7951         136 :                 else if (dig < 100)
    7952          66 :                     ddigits -= 2;
    7953          70 :                 else if (dig < 1000)
    7954          52 :                     ddigits -= 1;
    7955             : #elif DEC_DIGITS == 2
    7956             :                 if (dig < 10)
    7957             :                     ddigits -= 1;
    7958             : #elif DEC_DIGITS == 1
    7959             :                 /* no adjustment */
    7960             : #else
    7961             : #error unsupported NBASE
    7962             : #endif
    7963         388 :                 if (ddigits > maxdigits)
    7964          84 :                     ereturn(escontext, false,
    7965             :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    7966             :                              errmsg("numeric field overflow"),
    7967             :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
    7968             :                                        precision, scale,
    7969             :                     /* Display 10^0 as 1 */
    7970             :                                        maxdigits ? "10^" : "",
    7971             :                                        maxdigits ? maxdigits : 1
    7972             :                                        )));
    7973         304 :                 break;
    7974             :             }
    7975           0 :             ddigits -= DEC_DIGITS;
    7976             :         }
    7977             :     }
    7978             : 
    7979        4608 :     return true;
    7980             : }
    7981             : 
    7982             : /*
    7983             :  * apply_typmod_special() -
    7984             :  *
    7985             :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
    7986             :  *  For convenience of most callers, the value is presented in packed form.
    7987             :  *
    7988             :  * Returns true on success, false on failure (if escontext points to an
    7989             :  * ErrorSaveContext; otherwise errors are thrown).
    7990             :  */
    7991             : static bool
    7992        1780 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
    7993             : {
    7994             :     int         precision;
    7995             :     int         scale;
    7996             : 
    7997             :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
    7998             : 
    7999             :     /*
    8000             :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
    8001             :      * but it's a longstanding behavior.  Inf is rejected if we have any
    8002             :      * typmod restriction, since an infinity shouldn't be claimed to fit in
    8003             :      * any finite number of digits.
    8004             :      */
    8005        1780 :     if (NUMERIC_IS_NAN(num))
    8006         778 :         return true;
    8007             : 
    8008             :     /* Do nothing if we have a default typmod (-1) */
    8009        1002 :     if (!is_valid_numeric_typmod(typmod))
    8010         984 :         return true;
    8011             : 
    8012          18 :     precision = numeric_typmod_precision(typmod);
    8013          18 :     scale = numeric_typmod_scale(typmod);
    8014             : 
    8015          18 :     ereturn(escontext, false,
    8016             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
    8017             :              errmsg("numeric field overflow"),
    8018             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
    8019             :                        precision, scale)));
    8020             : }
    8021             : 
    8022             : 
    8023             : /*
    8024             :  * Convert numeric to int8, rounding if needed.
    8025             :  *
    8026             :  * If overflow, return false (no error is raised).  Return true if okay.
    8027             :  */
    8028             : static bool
    8029       11094 : numericvar_to_int64(const NumericVar *var, int64 *result)
    8030             : {
    8031             :     NumericDigit *digits;
    8032             :     int         ndigits;
    8033             :     int         weight;
    8034             :     int         i;
    8035             :     int64       val;
    8036             :     bool        neg;
    8037             :     NumericVar  rounded;
    8038             : 
    8039             :     /* Round to nearest integer */
    8040       11094 :     init_var(&rounded);
    8041       11094 :     set_var_from_var(var, &rounded);
    8042       11094 :     round_var(&rounded, 0);
    8043             : 
    8044             :     /* Check for zero input */
    8045       11094 :     strip_var(&rounded);
    8046       11094 :     ndigits = rounded.ndigits;
    8047       11094 :     if (ndigits == 0)
    8048             :     {
    8049         466 :         *result = 0;
    8050         466 :         free_var(&rounded);
    8051         466 :         return true;
    8052             :     }
    8053             : 
    8054             :     /*
    8055             :      * For input like 10000000000, we must treat stripped digits as real. So
    8056             :      * the loop assumes there are weight+1 digits before the decimal point.
    8057             :      */
    8058       10628 :     weight = rounded.weight;
    8059             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8060             : 
    8061             :     /*
    8062             :      * Construct the result. To avoid issues with converting a value
    8063             :      * corresponding to INT64_MIN (which can't be represented as a positive 64
    8064             :      * bit two's complement integer), accumulate value as a negative number.
    8065             :      */
    8066       10628 :     digits = rounded.digits;
    8067       10628 :     neg = (rounded.sign == NUMERIC_NEG);
    8068       10628 :     val = -digits[0];
    8069       15614 :     for (i = 1; i <= weight; i++)
    8070             :     {
    8071        5034 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
    8072             :         {
    8073          30 :             free_var(&rounded);
    8074          30 :             return false;
    8075             :         }
    8076             : 
    8077        5004 :         if (i < ndigits)
    8078             :         {
    8079        4744 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
    8080             :             {
    8081          18 :                 free_var(&rounded);
    8082          18 :                 return false;
    8083             :             }
    8084             :         }
    8085             :     }
    8086             : 
    8087       10580 :     free_var(&rounded);
    8088             : 
    8089       10580 :     if (!neg)
    8090             :     {
    8091        9812 :         if (unlikely(val == PG_INT64_MIN))
    8092          24 :             return false;
    8093        9788 :         val = -val;
    8094             :     }
    8095       10556 :     *result = val;
    8096             : 
    8097       10556 :     return true;
    8098             : }
    8099             : 
    8100             : /*
    8101             :  * Convert int8 value to numeric.
    8102             :  */
    8103             : static void
    8104     1881406 : int64_to_numericvar(int64 val, NumericVar *var)
    8105             : {
    8106             :     uint64      uval,
    8107             :                 newuval;
    8108             :     NumericDigit *ptr;
    8109             :     int         ndigits;
    8110             : 
    8111             :     /* int64 can require at most 19 decimal digits; add one for safety */
    8112     1881406 :     alloc_var(var, 20 / DEC_DIGITS);
    8113     1881406 :     if (val < 0)
    8114             :     {
    8115        1616 :         var->sign = NUMERIC_NEG;
    8116        1616 :         uval = -val;
    8117             :     }
    8118             :     else
    8119             :     {
    8120     1879790 :         var->sign = NUMERIC_POS;
    8121     1879790 :         uval = val;
    8122             :     }
    8123     1881406 :     var->dscale = 0;
    8124     1881406 :     if (val == 0)
    8125             :     {
    8126       35046 :         var->ndigits = 0;
    8127       35046 :         var->weight = 0;
    8128       35046 :         return;
    8129             :     }
    8130     1846360 :     ptr = var->digits + var->ndigits;
    8131     1846360 :     ndigits = 0;
    8132             :     do
    8133             :     {
    8134     2171478 :         ptr--;
    8135     2171478 :         ndigits++;
    8136     2171478 :         newuval = uval / NBASE;
    8137     2171478 :         *ptr = uval - newuval * NBASE;
    8138     2171478 :         uval = newuval;
    8139     2171478 :     } while (uval);
    8140     1846360 :     var->digits = ptr;
    8141     1846360 :     var->ndigits = ndigits;
    8142     1846360 :     var->weight = ndigits - 1;
    8143             : }
    8144             : 
    8145             : /*
    8146             :  * Convert numeric to uint64, rounding if needed.
    8147             :  *
    8148             :  * If overflow, return false (no error is raised).  Return true if okay.
    8149             :  */
    8150             : static bool
    8151         114 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
    8152             : {
    8153             :     NumericDigit *digits;
    8154             :     int         ndigits;
    8155             :     int         weight;
    8156             :     int         i;
    8157             :     uint64      val;
    8158             :     NumericVar  rounded;
    8159             : 
    8160             :     /* Round to nearest integer */
    8161         114 :     init_var(&rounded);
    8162         114 :     set_var_from_var(var, &rounded);
    8163         114 :     round_var(&rounded, 0);
    8164             : 
    8165             :     /* Check for zero input */
    8166         114 :     strip_var(&rounded);
    8167         114 :     ndigits = rounded.ndigits;
    8168         114 :     if (ndigits == 0)
    8169             :     {
    8170          18 :         *result = 0;
    8171          18 :         free_var(&rounded);
    8172          18 :         return true;
    8173             :     }
    8174             : 
    8175             :     /* Check for negative input */
    8176          96 :     if (rounded.sign == NUMERIC_NEG)
    8177             :     {
    8178          12 :         free_var(&rounded);
    8179          12 :         return false;
    8180             :     }
    8181             : 
    8182             :     /*
    8183             :      * For input like 10000000000, we must treat stripped digits as real. So
    8184             :      * the loop assumes there are weight+1 digits before the decimal point.
    8185             :      */
    8186          84 :     weight = rounded.weight;
    8187             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8188             : 
    8189             :     /* Construct the result */
    8190          84 :     digits = rounded.digits;
    8191          84 :     val = digits[0];
    8192         246 :     for (i = 1; i <= weight; i++)
    8193             :     {
    8194         174 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
    8195             :         {
    8196           0 :             free_var(&rounded);
    8197           0 :             return false;
    8198             :         }
    8199             : 
    8200         174 :         if (i < ndigits)
    8201             :         {
    8202         174 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
    8203             :             {
    8204          12 :                 free_var(&rounded);
    8205          12 :                 return false;
    8206             :             }
    8207             :         }
    8208             :     }
    8209             : 
    8210          72 :     free_var(&rounded);
    8211             : 
    8212          72 :     *result = val;
    8213             : 
    8214          72 :     return true;
    8215             : }
    8216             : 
    8217             : #ifdef HAVE_INT128
    8218             : /*
    8219             :  * Convert numeric to int128, rounding if needed.
    8220             :  *
    8221             :  * If overflow, return false (no error is raised).  Return true if okay.
    8222             :  */
    8223             : static bool
    8224          30 : numericvar_to_int128(const NumericVar *var, int128 *result)
    8225             : {
    8226             :     NumericDigit *digits;
    8227             :     int         ndigits;
    8228             :     int         weight;
    8229             :     int         i;
    8230             :     int128      val,
    8231             :                 oldval;
    8232             :     bool        neg;
    8233             :     NumericVar  rounded;
    8234             : 
    8235             :     /* Round to nearest integer */
    8236          30 :     init_var(&rounded);
    8237          30 :     set_var_from_var(var, &rounded);
    8238          30 :     round_var(&rounded, 0);
    8239             : 
    8240             :     /* Check for zero input */
    8241          30 :     strip_var(&rounded);
    8242          30 :     ndigits = rounded.ndigits;
    8243          30 :     if (ndigits == 0)
    8244             :     {
    8245           0 :         *result = 0;
    8246           0 :         free_var(&rounded);
    8247           0 :         return true;
    8248             :     }
    8249             : 
    8250             :     /*
    8251             :      * For input like 10000000000, we must treat stripped digits as real. So
    8252             :      * the loop assumes there are weight+1 digits before the decimal point.
    8253             :      */
    8254          30 :     weight = rounded.weight;
    8255             :     Assert(weight >= 0 && ndigits <= weight + 1);
    8256             : 
    8257             :     /* Construct the result */
    8258          30 :     digits = rounded.digits;
    8259          30 :     neg = (rounded.sign == NUMERIC_NEG);
    8260          30 :     val = digits[0];
    8261          86 :     for (i = 1; i <= weight; i++)
    8262             :     {
    8263          56 :         oldval = val;
    8264          56 :         val *= NBASE;
    8265          56 :         if (i < ndigits)
    8266          44 :             val += digits[i];
    8267             : 
    8268             :         /*
    8269             :          * The overflow check is a bit tricky because we want to accept
    8270             :          * INT128_MIN, which will overflow the positive accumulator.  We can
    8271             :          * detect this case easily though because INT128_MIN is the only
    8272             :          * nonzero value for which -val == val (on a two's complement machine,
    8273             :          * anyway).
    8274             :          */
    8275          56 :         if ((val / NBASE) != oldval)    /* possible overflow? */
    8276             :         {
    8277           0 :             if (!neg || (-val) != val || val == 0 || oldval < 0)
    8278             :             {
    8279           0 :                 free_var(&rounded);
    8280           0 :                 return false;
    8281             :             }
    8282             :         }
    8283             :     }
    8284             : 
    8285          30 :     free_var(&rounded);
    8286             : 
    8287          30 :     *result = neg ? -val : val;
    8288          30 :     return true;
    8289             : }
    8290             : 
    8291             : /*
    8292             :  * Convert 128 bit integer to numeric.
    8293             :  */
    8294             : static void
    8295        8554 : int128_to_numericvar(int128 val, NumericVar *var)
    8296             : {
    8297             :     uint128     uval,
    8298             :                 newuval;
    8299             :     NumericDigit *ptr;
    8300             :     int         ndigits;
    8301             : 
    8302             :     /* int128 can require at most 39 decimal digits; add one for safety */
    8303        8554 :     alloc_var(var, 40 / DEC_DIGITS);
    8304        8554 :     if (val < 0)
    8305             :     {
    8306           0 :         var->sign = NUMERIC_NEG;
    8307           0 :         uval = -val;
    8308             :     }
    8309             :     else
    8310             :     {
    8311        8554 :         var->sign = NUMERIC_POS;
    8312        8554 :         uval = val;
    8313             :     }
    8314        8554 :     var->dscale = 0;
    8315        8554 :     if (val == 0)
    8316             :     {
    8317         130 :         var->ndigits = 0;
    8318         130 :         var->weight = 0;
    8319         130 :         return;
    8320             :     }
    8321        8424 :     ptr = var->digits + var->ndigits;
    8322        8424 :     ndigits = 0;
    8323             :     do
    8324             :     {
    8325       44896 :         ptr--;
    8326       44896 :         ndigits++;
    8327       44896 :         newuval = uval / NBASE;
    8328       44896 :         *ptr = uval - newuval * NBASE;
    8329       44896 :         uval = newuval;
    8330       44896 :     } while (uval);
    8331        8424 :     var->digits = ptr;
    8332        8424 :     var->ndigits = ndigits;
    8333        8424 :     var->weight = ndigits - 1;
    8334             : }
    8335             : #endif
    8336             : 
    8337             : /*
    8338             :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
    8339             :  */
    8340             : static double
    8341        3536 : numericvar_to_double_no_overflow(const NumericVar *var)
    8342             : {
    8343             :     char       *tmp;
    8344             :     double      val;
    8345             :     char       *endptr;
    8346             : 
    8347        3536 :     tmp = get_str_from_var(var);
    8348             : 
    8349             :     /* unlike float8in, we ignore ERANGE from strtod */
    8350        3536 :     val = strtod(tmp, &endptr);
    8351        3536 :     if (*endptr != '\0')
    8352             :     {
    8353             :         /* shouldn't happen ... */
    8354           0 :         ereport(ERROR,
    8355             :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
    8356             :                  errmsg("invalid input syntax for type %s: \"%s\"",
    8357             :                         "double precision", tmp)));
    8358             :     }
    8359             : 
    8360        3536 :     pfree(tmp);
    8361             : 
    8362        3536 :     return val;
    8363             : }
    8364             : 
    8365             : 
    8366             : /*
    8367             :  * cmp_var() -
    8368             :  *
    8369             :  *  Compare two values on variable level.  We assume zeroes have been
    8370             :  *  truncated to no digits.
    8371             :  */
    8372             : static int
    8373       50186 : cmp_var(const NumericVar *var1, const NumericVar *var2)
    8374             : {
    8375      100372 :     return cmp_var_common(var1->digits, var1->ndigits,
    8376             :                           var1->weight, var1->sign,
    8377       50186 :                           var2->digits, var2->ndigits,
    8378             :                           var2->weight, var2->sign);
    8379             : }
    8380             : 
    8381             : /*
    8382             :  * cmp_var_common() -
    8383             :  *
    8384             :  *  Main routine of cmp_var(). This function can be used by both
    8385             :  *  NumericVar and Numeric.
    8386             :  */
    8387             : static int
    8388     6142218 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
    8389             :                int var1weight, int var1sign,
    8390             :                const NumericDigit *var2digits, int var2ndigits,
    8391             :                int var2weight, int var2sign)
    8392             : {
    8393     6142218 :     if (var1ndigits == 0)
    8394             :     {
    8395      184226 :         if (var2ndigits == 0)
    8396      156228 :             return 0;
    8397       27998 :         if (var2sign == NUMERIC_NEG)
    8398        4160 :             return 1;
    8399       23838 :         return -1;
    8400             :     }
    8401     5957992 :     if (var2ndigits == 0)
    8402             :     {
    8403       31776 :         if (var1sign == NUMERIC_POS)
    8404       25062 :             return 1;
    8405        6714 :         return -1;
    8406             :     }
    8407             : 
    8408     5926216 :     if (var1sign == NUMERIC_POS)
    8409             :     {
    8410     5839186 :         if (var2sign == NUMERIC_NEG)
    8411       26832 :             return 1;
    8412     5812354 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
    8413             :                               var2digits, var2ndigits, var2weight);
    8414             :     }
    8415             : 
    8416       87030 :     if (var2sign == NUMERIC_POS)
    8417       28666 :         return -1;
    8418             : 
    8419       58364 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
    8420             :                           var1digits, var1ndigits, var1weight);
    8421             : }
    8422             : 
    8423             : 
    8424             : /*
    8425             :  * add_var() -
    8426             :  *
    8427             :  *  Full version of add functionality on variable level (handling signs).
    8428             :  *  result might point to one of the operands too without danger.
    8429             :  */
    8430             : static void
    8431      497524 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8432             : {
    8433             :     /*
    8434             :      * Decide on the signs of the two variables what to do
    8435             :      */
    8436      497524 :     if (var1->sign == NUMERIC_POS)
    8437             :     {
    8438      495958 :         if (var2->sign == NUMERIC_POS)
    8439             :         {
    8440             :             /*
    8441             :              * Both are positive result = +(ABS(var1) + ABS(var2))
    8442             :              */
    8443      295792 :             add_abs(var1, var2, result);
    8444      295792 :             result->sign = NUMERIC_POS;
    8445             :         }
    8446             :         else
    8447             :         {
    8448             :             /*
    8449             :              * var1 is positive, var2 is negative Must compare absolute values
    8450             :              */
    8451      200166 :             switch (cmp_abs(var1, var2))
    8452             :             {
    8453         186 :                 case 0:
    8454             :                     /* ----------
    8455             :                      * ABS(var1) == ABS(var2)
    8456             :                      * result = ZERO
    8457             :                      * ----------
    8458             :                      */
    8459         186 :                     zero_var(result);
    8460         186 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8461         186 :                     break;
    8462             : 
    8463      186188 :                 case 1:
    8464             :                     /* ----------
    8465             :                      * ABS(var1) > ABS(var2)
    8466             :                      * result = +(ABS(var1) - ABS(var2))
    8467             :                      * ----------
    8468             :                      */
    8469      186188 :                     sub_abs(var1, var2, result);
    8470      186188 :                     result->sign = NUMERIC_POS;
    8471      186188 :                     break;
    8472             : 
    8473       13792 :                 case -1:
    8474             :                     /* ----------
    8475             :                      * ABS(var1) < ABS(var2)
    8476             :                      * result = -(ABS(var2) - ABS(var1))
    8477             :                      * ----------
    8478             :                      */
    8479       13792 :                     sub_abs(var2, var1, result);
    8480       13792 :                     result->sign = NUMERIC_NEG;
    8481       13792 :                     break;
    8482             :             }
    8483      495958 :         }
    8484             :     }
    8485             :     else
    8486             :     {
    8487        1566 :         if (var2->sign == NUMERIC_POS)
    8488             :         {
    8489             :             /* ----------
    8490             :              * var1 is negative, var2 is positive
    8491             :              * Must compare absolute values
    8492             :              * ----------
    8493             :              */
    8494         468 :             switch (cmp_abs(var1, var2))
    8495             :             {
    8496          30 :                 case 0:
    8497             :                     /* ----------
    8498             :                      * ABS(var1) == ABS(var2)
    8499             :                      * result = ZERO
    8500             :                      * ----------
    8501             :                      */
    8502          30 :                     zero_var(result);
    8503          30 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8504          30 :                     break;
    8505             : 
    8506         294 :                 case 1:
    8507             :                     /* ----------
    8508             :                      * ABS(var1) > ABS(var2)
    8509             :                      * result = -(ABS(var1) - ABS(var2))
    8510             :                      * ----------
    8511             :                      */
    8512         294 :                     sub_abs(var1, var2, result);
    8513         294 :                     result->sign = NUMERIC_NEG;
    8514         294 :                     break;
    8515             : 
    8516         144 :                 case -1:
    8517             :                     /* ----------
    8518             :                      * ABS(var1) < ABS(var2)
    8519             :                      * result = +(ABS(var2) - ABS(var1))
    8520             :                      * ----------
    8521             :                      */
    8522         144 :                     sub_abs(var2, var1, result);
    8523         144 :                     result->sign = NUMERIC_POS;
    8524         144 :                     break;
    8525             :             }
    8526         468 :         }
    8527             :         else
    8528             :         {
    8529             :             /* ----------
    8530             :              * Both are negative
    8531             :              * result = -(ABS(var1) + ABS(var2))
    8532             :              * ----------
    8533             :              */
    8534        1098 :             add_abs(var1, var2, result);
    8535        1098 :             result->sign = NUMERIC_NEG;
    8536             :         }
    8537             :     }
    8538      497524 : }
    8539             : 
    8540             : 
    8541             : /*
    8542             :  * sub_var() -
    8543             :  *
    8544             :  *  Full version of sub functionality on variable level (handling signs).
    8545             :  *  result might point to one of the operands too without danger.
    8546             :  */
    8547             : static void
    8548      189572 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    8549             : {
    8550             :     /*
    8551             :      * Decide on the signs of the two variables what to do
    8552             :      */
    8553      189572 :     if (var1->sign == NUMERIC_POS)
    8554             :     {
    8555      186664 :         if (var2->sign == NUMERIC_NEG)
    8556             :         {
    8557             :             /* ----------
    8558             :              * var1 is positive, var2 is negative
    8559             :              * result = +(ABS(var1) + ABS(var2))
    8560             :              * ----------
    8561             :              */
    8562       33384 :             add_abs(var1, var2, result);
    8563       33384 :             result->sign = NUMERIC_POS;
    8564             :         }
    8565             :         else
    8566             :         {
    8567             :             /* ----------
    8568             :              * Both are positive
    8569             :              * Must compare absolute values
    8570             :              * ----------
    8571             :              */
    8572      153280 :             switch (cmp_abs(var1, var2))
    8573             :             {
    8574       30670 :                 case 0:
    8575             :                     /* ----------
    8576             :                      * ABS(var1) == ABS(var2)
    8577             :                      * result = ZERO
    8578             :                      * ----------
    8579             :                      */
    8580       30670 :                     zero_var(result);
    8581       30670 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8582       30670 :                     break;
    8583             : 
    8584      115802 :                 case 1:
    8585             :                     /* ----------
    8586             :                      * ABS(var1) > ABS(var2)
    8587             :                      * result = +(ABS(var1) - ABS(var2))
    8588             :                      * ----------
    8589             :                      */
    8590      115802 :                     sub_abs(var1, var2, result);
    8591      115802 :                     result->sign = NUMERIC_POS;
    8592      115802 :                     break;
    8593             : 
    8594        6808 :                 case -1:
    8595             :                     /* ----------
    8596             :                      * ABS(var1) < ABS(var2)
    8597             :                      * result = -(ABS(var2) - ABS(var1))
    8598             :                      * ----------
    8599             :                      */
    8600        6808 :                     sub_abs(var2, var1, result);
    8601        6808 :                     result->sign = NUMERIC_NEG;
    8602        6808 :                     break;
    8603             :             }
    8604      186664 :         }
    8605             :     }
    8606             :     else
    8607             :     {
    8608        2908 :         if (var2->sign == NUMERIC_NEG)
    8609             :         {
    8610             :             /* ----------
    8611             :              * Both are negative
    8612             :              * Must compare absolute values
    8613             :              * ----------
    8614             :              */
    8615        2458 :             switch (cmp_abs(var1, var2))
    8616             :             {
    8617         166 :                 case 0:
    8618             :                     /* ----------
    8619             :                      * ABS(var1) == ABS(var2)
    8620             :                      * result = ZERO
    8621             :                      * ----------
    8622             :                      */
    8623         166 :                     zero_var(result);
    8624         166 :                     result->dscale = Max(var1->dscale, var2->dscale);
    8625         166 :                     break;
    8626             : 
    8627         240 :                 case 1:
    8628             :                     /* ----------
    8629             :                      * ABS(var1) > ABS(var2)
    8630             :                      * result = -(ABS(var1) - ABS(var2))
    8631             :                      * ----------
    8632             :                      */
    8633         240 :                     sub_abs(var1, var2, result);
    8634         240 :                     result->sign = NUMERIC_NEG;
    8635         240 :                     break;
    8636             : 
    8637        2052 :                 case -1:
    8638             :                     /* ----------
    8639             :                      * ABS(var1) < ABS(var2)
    8640             :                      * result = +(ABS(var2) - ABS(var1))
    8641             :                      * ----------
    8642             :                      */
    8643        2052 :                     sub_abs(var2, var1, result);
    8644        2052 :                     result->sign = NUMERIC_POS;
    8645        2052 :                     break;
    8646             :             }
    8647        2458 :         }
    8648             :         else
    8649             :         {
    8650             :             /* ----------
    8651             :              * var1 is negative, var2 is positive
    8652             :              * result = -(ABS(var1) + ABS(var2))
    8653             :              * ----------
    8654             :              */
    8655         450 :             add_abs(var1, var2, result);
    8656         450 :             result->sign = NUMERIC_NEG;
    8657             :         }
    8658             :     }
    8659      189572 : }
    8660             : 
    8661             : 
    8662             : /*
    8663             :  * mul_var() -
    8664             :  *
    8665             :  *  Multiplication on variable level. Product of var1 * var2 is stored
    8666             :  *  in result.  Result is rounded to no more than rscale fractional digits.
    8667             :  */
    8668             : static void
    8669      830598 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8670             :         int rscale)
    8671             : {
    8672             :     int         res_ndigits;
    8673             :     int         res_sign;
    8674             :     int         res_weight;
    8675             :     int         maxdigits;
    8676             :     int        *dig;
    8677             :     int         carry;
    8678             :     int         maxdig;
    8679             :     int         newdig;
    8680             :     int         var1ndigits;
    8681             :     int         var2ndigits;
    8682             :     NumericDigit *var1digits;
    8683             :     NumericDigit *var2digits;
    8684             :     NumericDigit *res_digits;
    8685             :     int         i,
    8686             :                 i1,
    8687             :                 i2;
    8688             : 
    8689             :     /*
    8690             :      * Arrange for var1 to be the shorter of the two numbers.  This improves
    8691             :      * performance because the inner multiplication loop is much simpler than
    8692             :      * the outer loop, so it's better to have a smaller number of iterations
    8693             :      * of the outer loop.  This also reduces the number of times that the
    8694             :      * accumulator array needs to be normalized.
    8695             :      */
    8696      830598 :     if (var1->ndigits > var2->ndigits)
    8697             :     {
    8698       14868 :         const NumericVar *tmp = var1;
    8699             : 
    8700       14868 :         var1 = var2;
    8701       14868 :         var2 = tmp;
    8702             :     }
    8703             : 
    8704             :     /* copy these values into local vars for speed in inner loop */
    8705      830598 :     var1ndigits = var1->ndigits;
    8706      830598 :     var2ndigits = var2->ndigits;
    8707      830598 :     var1digits = var1->digits;
    8708      830598 :     var2digits = var2->digits;
    8709             : 
    8710      830598 :     if (var1ndigits == 0 || var2ndigits == 0)
    8711             :     {
    8712             :         /* one or both inputs is zero; so is result */
    8713        1712 :         zero_var(result);
    8714        1712 :         result->dscale = rscale;
    8715        1712 :         return;
    8716             :     }
    8717             : 
    8718             :     /* Determine result sign and (maximum possible) weight */
    8719      828886 :     if (var1->sign == var2->sign)
    8720      826356 :         res_sign = NUMERIC_POS;
    8721             :     else
    8722        2530 :         res_sign = NUMERIC_NEG;
    8723      828886 :     res_weight = var1->weight + var2->weight + 2;
    8724             : 
    8725             :     /*
    8726             :      * Determine the number of result digits to compute.  If the exact result
    8727             :      * would have more than rscale fractional digits, truncate the computation
    8728             :      * with MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that
    8729             :      * would only contribute to the right of that.  (This will give the exact
    8730             :      * rounded-to-rscale answer unless carries out of the ignored positions
    8731             :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
    8732             :      *
    8733             :      * Note: an exact computation could not produce more than var1ndigits +
    8734             :      * var2ndigits digits, but we allocate one extra output digit in case
    8735             :      * rscale-driven rounding produces a carry out of the highest exact digit.
    8736             :      */
    8737      828886 :     res_ndigits = var1ndigits + var2ndigits + 1;
    8738      828886 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
    8739             :         MUL_GUARD_DIGITS;
    8740      828886 :     res_ndigits = Min(res_ndigits, maxdigits);
    8741             : 
    8742      828886 :     if (res_ndigits < 3)
    8743             :     {
    8744             :         /* All input digits will be ignored; so result is zero */
    8745          12 :         zero_var(result);
    8746          12 :         result->dscale = rscale;
    8747          12 :         return;
    8748             :     }
    8749             : 
    8750             :     /*
    8751             :      * We do the arithmetic in an array "dig[]" of signed int's.  Since
    8752             :      * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
    8753             :      * to avoid normalizing carries immediately.
    8754             :      *
    8755             :      * maxdig tracks the maximum possible value of any dig[] entry; when this
    8756             :      * threatens to exceed INT_MAX, we take the time to propagate carries.
    8757             :      * Furthermore, we need to ensure that overflow doesn't occur during the
    8758             :      * carry propagation passes either.  The carry values could be as much as
    8759             :      * INT_MAX/NBASE, so really we must normalize when digits threaten to
    8760             :      * exceed INT_MAX - INT_MAX/NBASE.
    8761             :      *
    8762             :      * To avoid overflow in maxdig itself, it actually represents the max
    8763             :      * possible value divided by NBASE-1, ie, at the top of the loop it is
    8764             :      * known that no dig[] entry exceeds maxdig * (NBASE-1).
    8765             :      */
    8766      828874 :     dig = (int *) palloc0(res_ndigits * sizeof(int));
    8767      828874 :     maxdig = 0;
    8768             : 
    8769             :     /*
    8770             :      * The least significant digits of var1 should be ignored if they don't
    8771             :      * contribute directly to the first res_ndigits digits of the result that
    8772             :      * we are computing.
    8773             :      *
    8774             :      * Digit i1 of var1 and digit i2 of var2 are multiplied and added to digit
    8775             :      * i1+i2+2 of the accumulator array, so we need only consider digits of
    8776             :      * var1 for which i1 <= res_ndigits - 3.
    8777             :      */
    8778     4633616 :     for (i1 = Min(var1ndigits - 1, res_ndigits - 3); i1 >= 0; i1--)
    8779             :     {
    8780     3804742 :         NumericDigit var1digit = var1digits[i1];
    8781             : 
    8782     3804742 :         if (var1digit == 0)
    8783     2359440 :             continue;
    8784             : 
    8785             :         /* Time to normalize? */
    8786     1445302 :         maxdig += var1digit;
    8787     1445302 :         if (maxdig > (INT_MAX - INT_MAX / NBASE) / (NBASE - 1))
    8788             :         {
    8789             :             /* Yes, do it */
    8790        9144 :             carry = 0;
    8791    45810696 :             for (i = res_ndigits - 1; i >= 0; i--)
    8792             :             {
    8793    45801552 :                 newdig = dig[i] + carry;
    8794    45801552 :                 if (newdig >= NBASE)
    8795             :                 {
    8796    23065602 :                     carry = newdig / NBASE;
    8797    23065602 :                     newdig -= carry * NBASE;
    8798             :                 }
    8799             :                 else
    8800    22735950 :                     carry = 0;
    8801    45801552 :                 dig[i] = newdig;
    8802             :             }
    8803             :             Assert(carry == 0);
    8804             :             /* Reset maxdig to indicate new worst-case */
    8805        9144 :             maxdig = 1 + var1digit;
    8806             :         }
    8807             : 
    8808             :         /*
    8809             :          * Add the appropriate multiple of var2 into the accumulator.
    8810             :          *
    8811             :          * As above, digits of var2 can be ignored if they don't contribute,
    8812             :          * so we only include digits for which i1+i2+2 < res_ndigits.
    8813             :          *
    8814             :          * This inner loop is the performance bottleneck for multiplication,
    8815             :          * so we want to keep it simple enough so that it can be
    8816             :          * auto-vectorized.  Accordingly, process the digits left-to-right
    8817             :          * even though schoolbook multiplication would suggest right-to-left.
    8818             :          * Since we aren't propagating carries in this loop, the order does
    8819             :          * not matter.
    8820             :          */
    8821             :         {
    8822     1445302 :             int         i2limit = Min(var2ndigits, res_ndigits - i1 - 2);
    8823     1445302 :             int        *dig_i1_2 = &dig[i1 + 2];
    8824             : 
    8825   499118302 :             for (i2 = 0; i2 < i2limit; i2++)
    8826   497673000 :                 dig_i1_2[i2] += var1digit * var2digits[i2];
    8827             :         }
    8828             :     }
    8829             : 
    8830             :     /*
    8831             :      * Now we do a final carry propagation pass to normalize the result, which
    8832             :      * we combine with storing the result digits into the output. Note that
    8833             :      * this is still done at full precision w/guard digits.
    8834             :      */
    8835      828874 :     alloc_var(result, res_ndigits);
    8836      828874 :     res_digits = result->digits;
    8837      828874 :     carry = 0;
    8838    10241802 :     for (i = res_ndigits - 1; i >= 0; i--)
    8839             :     {
    8840     9412928 :         newdig = dig[i] + carry;
    8841     9412928 :         if (newdig >= NBASE)
    8842             :         {
    8843     1983224 :             carry = newdig / NBASE;
    8844     1983224 :             newdig -= carry * NBASE;
    8845             :         }
    8846             :         else
    8847     7429704 :             carry = 0;
    8848     9412928 :         res_digits[i] = newdig;
    8849             :     }
    8850             :     Assert(carry == 0);
    8851             : 
    8852      828874 :     pfree(dig);
    8853             : 
    8854             :     /*
    8855             :      * Finally, round the result to the requested precision.
    8856             :      */
    8857      828874 :     result->weight = res_weight;
    8858      828874 :     result->sign = res_sign;
    8859             : 
    8860             :     /* Round to target rscale (and set result->dscale) */
    8861      828874 :     round_var(result, rscale);
    8862             : 
    8863             :     /* Strip leading and trailing zeroes */
    8864      828874 :     strip_var(result);
    8865             : }
    8866             : 
    8867             : 
    8868             : /*
    8869             :  * div_var() -
    8870             :  *
    8871             :  *  Division on variable level. Quotient of var1 / var2 is stored in result.
    8872             :  *  The quotient is figured to exactly rscale fractional digits.
    8873             :  *  If round is true, it is rounded at the rscale'th digit; if false, it
    8874             :  *  is truncated (towards zero) at that digit.
    8875             :  */
    8876             : static void
    8877      209182 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
    8878             :         int rscale, bool round)
    8879             : {
    8880             :     int         div_ndigits;
    8881             :     int         res_ndigits;
    8882             :     int         res_sign;
    8883             :     int         res_weight;
    8884             :     int         carry;
    8885             :     int         borrow;
    8886             :     int         divisor1;
    8887             :     int         divisor2;
    8888             :     NumericDigit *dividend;
    8889             :     NumericDigit *divisor;
    8890             :     NumericDigit *res_digits;
    8891             :     int         i;
    8892             :     int         j;
    8893             : 
    8894             :     /* copy these values into local vars for speed in inner loop */
    8895      209182 :     int         var1ndigits = var1->ndigits;
    8896      209182 :     int         var2ndigits = var2->ndigits;
    8897             : 
    8898             :     /*
    8899             :      * First of all division by zero check; we must not be handed an
    8900             :      * unnormalized divisor.
    8901             :      */
    8902      209182 :     if (var2ndigits == 0 || var2->digits[0] == 0)
    8903          56 :         ereport(ERROR,
    8904             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    8905             :                  errmsg("division by zero")));
    8906             : 
    8907             :     /*
    8908             :      * If the divisor has just one or two digits, delegate to div_var_int(),
    8909             :      * which uses fast short division.
    8910             :      *
    8911             :      * Similarly, on platforms with 128-bit integer support, delegate to
    8912             :      * div_var_int64() for divisors with three or four digits.
    8913             :      */
    8914      209126 :     if (var2ndigits <= 2)
    8915             :     {
    8916             :         int         idivisor;
    8917             :         int         idivisor_weight;
    8918             : 
    8919      205382 :         idivisor = var2->digits[0];
    8920      205382 :         idivisor_weight = var2->weight;
    8921      205382 :         if (var2ndigits == 2)
    8922             :         {
    8923        4748 :             idivisor = idivisor * NBASE + var2->digits[1];
    8924        4748 :             idivisor_weight--;
    8925             :         }
    8926      205382 :         if (var2->sign == NUMERIC_NEG)
    8927         486 :             idivisor = -idivisor;
    8928             : 
    8929      205382 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    8930      205382 :         return;
    8931             :     }
    8932             : #ifdef HAVE_INT128
    8933        3744 :     if (var2ndigits <= 4)
    8934             :     {
    8935             :         int64       idivisor;
    8936             :         int         idivisor_weight;
    8937             : 
    8938         492 :         idivisor = var2->digits[0];
    8939         492 :         idivisor_weight = var2->weight;
    8940        1848 :         for (i = 1; i < var2ndigits; i++)
    8941             :         {
    8942        1356 :             idivisor = idivisor * NBASE + var2->digits[i];
    8943        1356 :             idivisor_weight--;
    8944             :         }
    8945         492 :         if (var2->sign == NUMERIC_NEG)
    8946         120 :             idivisor = -idivisor;
    8947             : 
    8948         492 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    8949         492 :         return;
    8950             :     }
    8951             : #endif
    8952             : 
    8953             :     /*
    8954             :      * Otherwise, perform full long division.
    8955             :      */
    8956             : 
    8957             :     /* Result zero check */
    8958        3252 :     if (var1ndigits == 0)
    8959             :     {
    8960          24 :         zero_var(result);
    8961          24 :         result->dscale = rscale;
    8962          24 :         return;
    8963             :     }
    8964             : 
    8965             :     /*
    8966             :      * Determine the result sign, weight and number of digits to calculate.
    8967             :      * The weight figured here is correct if the emitted quotient has no
    8968             :      * leading zero digits; otherwise strip_var() will fix things up.
    8969             :      */
    8970        3228 :     if (var1->sign == var2->sign)
    8971        3168 :         res_sign = NUMERIC_POS;
    8972             :     else
    8973          60 :         res_sign = NUMERIC_NEG;
    8974        3228 :     res_weight = var1->weight - var2->weight;
    8975             :     /* The number of accurate result digits we need to produce: */
    8976        3228 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    8977             :     /* ... but always at least 1 */
    8978        3228 :     res_ndigits = Max(res_ndigits, 1);
    8979             :     /* If rounding needed, figure one more digit to ensure correct result */
    8980        3228 :     if (round)
    8981        3228 :         res_ndigits++;
    8982             : 
    8983             :     /*
    8984             :      * The working dividend normally requires res_ndigits + var2ndigits
    8985             :      * digits, but make it at least var1ndigits so we can load all of var1
    8986             :      * into it.  (There will be an additional digit dividend[0] in the
    8987             :      * dividend space, but for consistency with Knuth's notation we don't
    8988             :      * count that in div_ndigits.)
    8989             :      */
    8990        3228 :     div_ndigits = res_ndigits + var2ndigits;
    8991        3228 :     div_ndigits = Max(div_ndigits, var1ndigits);
    8992             : 
    8993             :     /*
    8994             :      * We need a workspace with room for the working dividend (div_ndigits+1
    8995             :      * digits) plus room for the possibly-normalized divisor (var2ndigits
    8996             :      * digits).  It is convenient also to have a zero at divisor[0] with the
    8997             :      * actual divisor data in divisor[1 .. var2ndigits].  Transferring the
    8998             :      * digits into the workspace also allows us to realloc the result (which
    8999             :      * might be the same as either input var) before we begin the main loop.
    9000             :      * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
    9001             :      * any additional dividend positions beyond var1ndigits, start out 0.
    9002             :      */
    9003             :     dividend = (NumericDigit *)
    9004        3228 :         palloc0((div_ndigits + var2ndigits + 2) * sizeof(NumericDigit));
    9005        3228 :     divisor = dividend + (div_ndigits + 1);
    9006        3228 :     memcpy(dividend + 1, var1->digits, var1ndigits * sizeof(NumericDigit));
    9007        3228 :     memcpy(divisor + 1, var2->digits, var2ndigits * sizeof(NumericDigit));
    9008             : 
    9009             :     /*
    9010             :      * Now we can realloc the result to hold the generated quotient digits.
    9011             :      */
    9012        3228 :     alloc_var(result, res_ndigits);
    9013        3228 :     res_digits = result->digits;
    9014             : 
    9015             :     /*
    9016             :      * The full multiple-place algorithm is taken from Knuth volume 2,
    9017             :      * Algorithm 4.3.1D.
    9018             :      *
    9019             :      * We need the first divisor digit to be >= NBASE/2.  If it isn't, make it
    9020             :      * so by scaling up both the divisor and dividend by the factor "d".  (The
    9021             :      * reason for allocating dividend[0] above is to leave room for possible
    9022             :      * carry here.)
    9023             :      */
    9024        3228 :     if (divisor[1] < HALF_NBASE)
    9025             :     {
    9026        3228 :         int         d = NBASE / (divisor[1] + 1);
    9027             : 
    9028        3228 :         carry = 0;
    9029       27512 :         for (i = var2ndigits; i > 0; i--)
    9030             :         {
    9031       24284 :             carry += divisor[i] * d;
    9032       24284 :             divisor[i] = carry % NBASE;
    9033       24284 :             carry = carry / NBASE;
    9034             :         }
    9035             :         Assert(carry == 0);
    9036        3228 :         carry = 0;
    9037             :         /* at this point only var1ndigits of dividend can be nonzero */
    9038       27576 :         for (i = var1ndigits; i >= 0; i--)
    9039             :         {
    9040       24348 :             carry += dividend[i] * d;
    9041       24348 :             dividend[i] = carry % NBASE;
    9042       24348 :             carry = carry / NBASE;
    9043             :         }
    9044             :         Assert(carry == 0);
    9045             :         Assert(divisor[1] >= HALF_NBASE);
    9046             :     }
    9047             :     /* First 2 divisor digits are used repeatedly in main loop */
    9048        3228 :     divisor1 = divisor[1];
    9049        3228 :     divisor2 = divisor[2];
    9050             : 
    9051             :     /*
    9052             :      * Begin the main loop.  Each iteration of this loop produces the j'th
    9053             :      * quotient digit by dividing dividend[j .. j + var2ndigits] by the
    9054             :      * divisor; this is essentially the same as the common manual procedure
    9055             :      * for long division.
    9056             :      */
    9057       24398 :     for (j = 0; j < res_ndigits; j++)
    9058             :     {
    9059             :         /* Estimate quotient digit from the first two dividend digits */
    9060       21170 :         int         next2digits = dividend[j] * NBASE + dividend[j + 1];
    9061             :         int         qhat;
    9062             : 
    9063             :         /*
    9064             :          * If next2digits are 0, then quotient digit must be 0 and there's no
    9065             :          * need to adjust the working dividend.  It's worth testing here to
    9066             :          * fall out ASAP when processing trailing zeroes in a dividend.
    9067             :          */
    9068       21170 :         if (next2digits == 0)
    9069             :         {
    9070          72 :             res_digits[j] = 0;
    9071          72 :             continue;
    9072             :         }
    9073             : 
    9074       21098 :         if (dividend[j] == divisor1)
    9075         120 :             qhat = NBASE - 1;
    9076             :         else
    9077       20978 :             qhat = next2digits / divisor1;
    9078             : 
    9079             :         /*
    9080             :          * Adjust quotient digit if it's too large.  Knuth proves that after
    9081             :          * this step, the quotient digit will be either correct or just one
    9082             :          * too large.  (Note: it's OK to use dividend[j+2] here because we
    9083             :          * know the divisor length is at least 2.)
    9084             :          */
    9085       21098 :         while (divisor2 * qhat >
    9086       24708 :                (next2digits - qhat * divisor1) * NBASE + dividend[j + 2])
    9087        3610 :             qhat--;
    9088             : 
    9089             :         /* As above, need do nothing more when quotient digit is 0 */
    9090       21098 :         if (qhat > 0)
    9091             :         {
    9092       19496 :             NumericDigit *dividend_j = &dividend[j];
    9093             : 
    9094             :             /*
    9095             :              * Multiply the divisor by qhat, and subtract that from the
    9096             :              * working dividend.  The multiplication and subtraction are
    9097             :              * folded together here, noting that qhat <= NBASE (since it might
    9098             :              * be one too large), and so the intermediate result "tmp_result"
    9099             :              * is in the range [-NBASE^2, NBASE - 1], and "borrow" is in the
    9100             :              * range [0, NBASE].
    9101             :              */
    9102       19496 :             borrow = 0;
    9103      190528 :             for (i = var2ndigits; i >= 0; i--)
    9104             :             {
    9105             :                 int         tmp_result;
    9106             : 
    9107      171032 :                 tmp_result = dividend_j[i] - borrow - divisor[i] * qhat;
    9108      171032 :                 borrow = (NBASE - 1 - tmp_result) / NBASE;
    9109      171032 :                 dividend_j[i] = tmp_result + borrow * NBASE;
    9110             :             }
    9111             : 
    9112             :             /*
    9113             :              * If we got a borrow out of the top dividend digit, then indeed
    9114             :              * qhat was one too large.  Fix it, and add back the divisor to
    9115             :              * correct the working dividend.  (Knuth proves that this will
    9116             :              * occur only about 3/NBASE of the time; hence, it's a good idea
    9117             :              * to test this code with small NBASE to be sure this section gets
    9118             :              * exercised.)
    9119             :              */
    9120       19496 :             if (borrow)
    9121             :             {
    9122          28 :                 qhat--;
    9123          28 :                 carry = 0;
    9124        2326 :                 for (i = var2ndigits; i >= 0; i--)
    9125             :                 {
    9126        2298 :                     carry += dividend_j[i] + divisor[i];
    9127        2298 :                     if (carry >= NBASE)
    9128             :                     {
    9129        2100 :                         dividend_j[i] = carry - NBASE;
    9130        2100 :                         carry = 1;
    9131             :                     }
    9132             :                     else
    9133             :                     {
    9134         198 :                         dividend_j[i] = carry;
    9135         198 :                         carry = 0;
    9136             :                     }
    9137             :                 }
    9138             :                 /* A carry should occur here to cancel the borrow above */
    9139             :                 Assert(carry == 1);
    9140             :             }
    9141             :         }
    9142             : 
    9143             :         /* And we're done with this quotient digit */
    9144       21098 :         res_digits[j] = qhat;
    9145             :     }
    9146             : 
    9147        3228 :     pfree(dividend);
    9148             : 
    9149             :     /*
    9150             :      * Finally, round or truncate the result to the requested precision.
    9151             :      */
    9152        3228 :     result->weight = res_weight;
    9153        3228 :     result->sign = res_sign;
    9154             : 
    9155             :     /* Round or truncate to target rscale (and set result->dscale) */
    9156        3228 :     if (round)
    9157        3228 :         round_var(result, rscale);
    9158             :     else
    9159           0 :         trunc_var(result, rscale);
    9160             : 
    9161             :     /* Strip leading and trailing zeroes */
    9162        3228 :     strip_var(result);
    9163             : }
    9164             : 
    9165             : 
    9166             : /*
    9167             :  * div_var_fast() -
    9168             :  *
    9169             :  *  This has the same API as div_var, but is implemented using the division
    9170             :  *  algorithm from the "FM" library, rather than Knuth's schoolbook-division
    9171             :  *  approach.  This is significantly faster but can produce inaccurate
    9172             :  *  results, because it sometimes has to propagate rounding to the left,
    9173             :  *  and so we can never be entirely sure that we know the requested digits
    9174             :  *  exactly.  We compute DIV_GUARD_DIGITS extra digits, but there is
    9175             :  *  no certainty that that's enough.  We use this only in the transcendental
    9176             :  *  function calculation routines, where everything is approximate anyway.
    9177             :  *
    9178             :  *  Although we provide a "round" argument for consistency with div_var,
    9179             :  *  it is unwise to use this function with round=false.  In truncation mode
    9180             :  *  it is possible to get a result with no significant digits, for example
    9181             :  *  with rscale=0 we might compute 0.99999... and truncate that to 0 when
    9182             :  *  the correct answer is 1.
    9183             :  */
    9184             : static void
    9185        5916 : div_var_fast(const NumericVar *var1, const NumericVar *var2,
    9186             :              NumericVar *result, int rscale, bool round)
    9187             : {
    9188             :     int         div_ndigits;
    9189             :     int         load_ndigits;
    9190             :     int         res_sign;
    9191             :     int         res_weight;
    9192             :     int        *div;
    9193             :     int         qdigit;
    9194             :     int         carry;
    9195             :     int         maxdiv;
    9196             :     int         newdig;
    9197             :     NumericDigit *res_digits;
    9198             :     double      fdividend,
    9199             :                 fdivisor,
    9200             :                 fdivisorinverse,
    9201             :                 fquotient;
    9202             :     int         qi;
    9203             :     int         i;
    9204             : 
    9205             :     /* copy these values into local vars for speed in inner loop */
    9206        5916 :     int         var1ndigits = var1->ndigits;
    9207        5916 :     int         var2ndigits = var2->ndigits;
    9208        5916 :     NumericDigit *var1digits = var1->digits;
    9209        5916 :     NumericDigit *var2digits = var2->digits;
    9210             : 
    9211             :     /*
    9212             :      * First of all division by zero check; we must not be handed an
    9213             :      * unnormalized divisor.
    9214             :      */
    9215        5916 :     if (var2ndigits == 0 || var2digits[0] == 0)
    9216           6 :         ereport(ERROR,
    9217             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
    9218             :                  errmsg("division by zero")));
    9219             : 
    9220             :     /*
    9221             :      * If the divisor has just one or two digits, delegate to div_var_int(),
    9222             :      * which uses fast short division.
    9223             :      *
    9224             :      * Similarly, on platforms with 128-bit integer support, delegate to
    9225             :      * div_var_int64() for divisors with three or four digits.
    9226             :      */
    9227        5910 :     if (var2ndigits <= 2)
    9228             :     {
    9229             :         int         idivisor;
    9230             :         int         idivisor_weight;
    9231             : 
    9232         528 :         idivisor = var2->digits[0];
    9233         528 :         idivisor_weight = var2->weight;
    9234         528 :         if (var2ndigits == 2)
    9235             :         {
    9236           0 :             idivisor = idivisor * NBASE + var2->digits[1];
    9237           0 :             idivisor_weight--;
    9238             :         }
    9239         528 :         if (var2->sign == NUMERIC_NEG)
    9240           0 :             idivisor = -idivisor;
    9241             : 
    9242         528 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
    9243         528 :         return;
    9244             :     }
    9245             : #ifdef HAVE_INT128
    9246        5382 :     if (var2ndigits <= 4)
    9247             :     {
    9248             :         int64       idivisor;
    9249             :         int         idivisor_weight;
    9250             : 
    9251          42 :         idivisor = var2->digits[0];
    9252          42 :         idivisor_weight = var2->weight;
    9253         150 :         for (i = 1; i < var2ndigits; i++)
    9254             :         {
    9255         108 :             idivisor = idivisor * NBASE + var2->digits[i];
    9256         108 :             idivisor_weight--;
    9257             :         }
    9258          42 :         if (var2->sign == NUMERIC_NEG)
    9259           0 :             idivisor = -idivisor;
    9260             : 
    9261          42 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
    9262          42 :         return;
    9263             :     }
    9264             : #endif
    9265             : 
    9266             :     /*
    9267             :      * Otherwise, perform full long division.
    9268             :      */
    9269             : 
    9270             :     /* Result zero check */
    9271        5340 :     if (var1ndigits == 0)
    9272             :     {
    9273          12 :         zero_var(result);
    9274          12 :         result->dscale = rscale;
    9275          12 :         return;
    9276             :     }
    9277             : 
    9278             :     /*
    9279             :      * Determine the result sign, weight and number of digits to calculate
    9280             :      */
    9281        5328 :     if (var1->sign == var2->sign)
    9282        5256 :         res_sign = NUMERIC_POS;
    9283             :     else
    9284          72 :         res_sign = NUMERIC_NEG;
    9285        5328 :     res_weight = var1->weight - var2->weight + 1;
    9286             :     /* The number of accurate result digits we need to produce: */
    9287        5328 :     div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9288             :     /* Add guard digits for roundoff error */
    9289        5328 :     div_ndigits += DIV_GUARD_DIGITS;
    9290        5328 :     if (div_ndigits < DIV_GUARD_DIGITS)
    9291           0 :         div_ndigits = DIV_GUARD_DIGITS;
    9292             : 
    9293             :     /*
    9294             :      * We do the arithmetic in an array "div[]" of signed int's.  Since
    9295             :      * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
    9296             :      * to avoid normalizing carries immediately.
    9297             :      *
    9298             :      * We start with div[] containing one zero digit followed by the
    9299             :      * dividend's digits (plus appended zeroes to reach the desired precision
    9300             :      * including guard digits).  Each step of the main loop computes an
    9301             :      * (approximate) quotient digit and stores it into div[], removing one
    9302             :      * position of dividend space.  A final pass of carry propagation takes
    9303             :      * care of any mistaken quotient digits.
    9304             :      *
    9305             :      * Note that div[] doesn't necessarily contain all of the digits from the
    9306             :      * dividend --- the desired precision plus guard digits might be less than
    9307             :      * the dividend's precision.  This happens, for example, in the square
    9308             :      * root algorithm, where we typically divide a 2N-digit number by an
    9309             :      * N-digit number, and only require a result with N digits of precision.
    9310             :      */
    9311        5328 :     div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
    9312        5328 :     load_ndigits = Min(div_ndigits, var1ndigits);
    9313       72708 :     for (i = 0; i < load_ndigits; i++)
    9314       67380 :         div[i + 1] = var1digits[i];
    9315             : 
    9316             :     /*
    9317             :      * We estimate each quotient digit using floating-point arithmetic, taking
    9318             :      * the first four digits of the (current) dividend and divisor.  This must
    9319             :      * be float to avoid overflow.  The quotient digits will generally be off
    9320             :      * by no more than one from the exact answer.
    9321             :      */
    9322        5328 :     fdivisor = (double) var2digits[0];
    9323       21312 :     for (i = 1; i < 4; i++)
    9324             :     {
    9325       15984 :         fdivisor *= NBASE;
    9326       15984 :         if (i < var2ndigits)
    9327       15984 :             fdivisor += (double) var2digits[i];
    9328             :     }
    9329        5328 :     fdivisorinverse = 1.0 / fdivisor;
    9330             : 
    9331             :     /*
    9332             :      * maxdiv tracks the maximum possible absolute value of any div[] entry;
    9333             :      * when this threatens to exceed INT_MAX, we take the time to propagate
    9334             :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
    9335             :      * during the carry propagation passes either.  The carry values may have
    9336             :      * an absolute value as high as INT_MAX/NBASE + 1, so really we must
    9337             :      * normalize when digits threaten to exceed INT_MAX - INT_MAX/NBASE - 1.
    9338             :      *
    9339             :      * To avoid overflow in maxdiv itself, it represents the max absolute
    9340             :      * value divided by NBASE-1, ie, at the top of the loop it is known that
    9341             :      * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
    9342             :      *
    9343             :      * Actually, though, that holds good only for div[] entries after div[qi];
    9344             :      * the adjustment done at the bottom of the loop may cause div[qi + 1] to
    9345             :      * exceed the maxdiv limit, so that div[qi] in the next iteration is
    9346             :      * beyond the limit.  This does not cause problems, as explained below.
    9347             :      */
    9348        5328 :     maxdiv = 1;
    9349             : 
    9350             :     /*
    9351             :      * Outer loop computes next quotient digit, which will go into div[qi]
    9352             :      */
    9353       90288 :     for (qi = 0; qi < div_ndigits; qi++)
    9354             :     {
    9355             :         /* Approximate the current dividend value */
    9356       84960 :         fdividend = (double) div[qi];
    9357      339840 :         for (i = 1; i < 4; i++)
    9358             :         {
    9359      254880 :             fdividend *= NBASE;
    9360      254880 :             if (qi + i <= div_ndigits)
    9361      238896 :                 fdividend += (double) div[qi + i];
    9362             :         }
    9363             :         /* Compute the (approximate) quotient digit */
    9364       84960 :         fquotient = fdividend * fdivisorinverse;
    9365       84960 :         qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
    9366           6 :             (((int) fquotient) - 1);    /* truncate towards -infinity */
    9367             : 
    9368       84960 :         if (qdigit != 0)
    9369             :         {
    9370             :             /* Do we need to normalize now? */
    9371       75966 :             maxdiv += abs(qdigit);
    9372       75966 :             if (maxdiv > (INT_MAX - INT_MAX / NBASE - 1) / (NBASE - 1))
    9373             :             {
    9374             :                 /*
    9375             :                  * Yes, do it.  Note that if var2ndigits is much smaller than
    9376             :                  * div_ndigits, we can save a significant amount of effort
    9377             :                  * here by noting that we only need to normalise those div[]
    9378             :                  * entries touched where prior iterations subtracted multiples
    9379             :                  * of the divisor.
    9380             :                  */
    9381          96 :                 carry = 0;
    9382        1896 :                 for (i = Min(qi + var2ndigits - 2, div_ndigits); i > qi; i--)
    9383             :                 {
    9384        1800 :                     newdig = div[i] + carry;
    9385        1800 :                     if (newdig < 0)
    9386             :                     {
    9387        1800 :                         carry = -((-newdig - 1) / NBASE) - 1;
    9388        1800 :                         newdig -= carry * NBASE;
    9389             :                     }
    9390           0 :                     else if (newdig >= NBASE)
    9391             :                     {
    9392           0 :                         carry = newdig / NBASE;
    9393           0 :                         newdig -= carry * NBASE;
    9394             :                     }
    9395             :                     else
    9396           0 :                         carry = 0;
    9397        1800 :                     div[i] = newdig;
    9398             :                 }
    9399          96 :                 newdig = div[qi] + carry;
    9400          96 :                 div[qi] = newdig;
    9401             : 
    9402             :                 /*
    9403             :                  * All the div[] digits except possibly div[qi] are now in the
    9404             :                  * range 0..NBASE-1.  We do not need to consider div[qi] in
    9405             :                  * the maxdiv value anymore, so we can reset maxdiv to 1.
    9406             :                  */
    9407          96 :                 maxdiv = 1;
    9408             : 
    9409             :                 /*
    9410             :                  * Recompute the quotient digit since new info may have
    9411             :                  * propagated into the top four dividend digits
    9412             :                  */
    9413          96 :                 fdividend = (double) div[qi];
    9414         384 :                 for (i = 1; i < 4; i++)
    9415             :                 {
    9416         288 :                     fdividend *= NBASE;
    9417         288 :                     if (qi + i <= div_ndigits)
    9418         288 :                         fdividend += (double) div[qi + i];
    9419             :                 }
    9420             :                 /* Compute the (approximate) quotient digit */
    9421          96 :                 fquotient = fdividend * fdivisorinverse;
    9422          96 :                 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
    9423           0 :                     (((int) fquotient) - 1);    /* truncate towards -infinity */
    9424          96 :                 maxdiv += abs(qdigit);
    9425             :             }
    9426             : 
    9427             :             /*
    9428             :              * Subtract off the appropriate multiple of the divisor.
    9429             :              *
    9430             :              * The digits beyond div[qi] cannot overflow, because we know they
    9431             :              * will fall within the maxdiv limit.  As for div[qi] itself, note
    9432             :              * that qdigit is approximately trunc(div[qi] / vardigits[0]),
    9433             :              * which would make the new value simply div[qi] mod vardigits[0].
    9434             :              * The lower-order terms in qdigit can change this result by not
    9435             :              * more than about twice INT_MAX/NBASE, so overflow is impossible.
    9436             :              *
    9437             :              * This inner loop is the performance bottleneck for division, so
    9438             :              * code it in the same way as the inner loop of mul_var() so that
    9439             :              * it can be auto-vectorized.  We cast qdigit to NumericDigit
    9440             :              * before multiplying to allow the compiler to generate more
    9441             :              * efficient code (using 16-bit multiplication), which is safe
    9442             :              * since we know that the quotient digit is off by at most one, so
    9443             :              * there is no overflow risk.
    9444             :              */
    9445       75966 :             if (qdigit != 0)
    9446             :             {
    9447       75966 :                 int         istop = Min(var2ndigits, div_ndigits - qi + 1);
    9448       75966 :                 int        *div_qi = &div[qi];
    9449             : 
    9450      930036 :                 for (i = 0; i < istop; i++)
    9451      854070 :                     div_qi[i] -= ((NumericDigit) qdigit) * var2digits[i];
    9452             :             }
    9453             :         }
    9454             : 
    9455             :         /*
    9456             :          * The dividend digit we are about to replace might still be nonzero.
    9457             :          * Fold it into the next digit position.
    9458             :          *
    9459             :          * There is no risk of overflow here, although proving that requires
    9460             :          * some care.  Much as with the argument for div[qi] not overflowing,
    9461             :          * if we consider the first two terms in the numerator and denominator
    9462             :          * of qdigit, we can see that the final value of div[qi + 1] will be
    9463             :          * approximately a remainder mod (vardigits[0]*NBASE + vardigits[1]).
    9464             :          * Accounting for the lower-order terms is a bit complicated but ends
    9465             :          * up adding not much more than INT_MAX/NBASE to the possible range.
    9466             :          * Thus, div[qi + 1] cannot overflow here, and in its role as div[qi]
    9467             :          * in the next loop iteration, it can't be large enough to cause
    9468             :          * overflow in the carry propagation step (if any), either.
    9469             :          *
    9470             :          * But having said that: div[qi] can be more than INT_MAX/NBASE, as
    9471             :          * noted above, which means that the product div[qi] * NBASE *can*
    9472             :          * overflow.  When that happens, adding it to div[qi + 1] will always
    9473             :          * cause a canceling overflow so that the end result is correct.  We
    9474             :          * could avoid the intermediate overflow by doing the multiplication
    9475             :          * and addition in int64 arithmetic, but so far there appears no need.
    9476             :          */
    9477       84960 :         div[qi + 1] += div[qi] * NBASE;
    9478             : 
    9479       84960 :         div[qi] = qdigit;
    9480             :     }
    9481             : 
    9482             :     /*
    9483             :      * Approximate and store the last quotient digit (div[div_ndigits])
    9484             :      */
    9485        5328 :     fdividend = (double) div[qi];
    9486       21312 :     for (i = 1; i < 4; i++)
    9487       15984 :         fdividend *= NBASE;
    9488        5328 :     fquotient = fdividend * fdivisorinverse;
    9489        5328 :     qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
    9490           0 :         (((int) fquotient) - 1);    /* truncate towards -infinity */
    9491        5328 :     div[qi] = qdigit;
    9492             : 
    9493             :     /*
    9494             :      * Because the quotient digits might be off by one, some of them might be
    9495             :      * -1 or NBASE at this point.  The represented value is correct in a
    9496             :      * mathematical sense, but it doesn't look right.  We do a final carry
    9497             :      * propagation pass to normalize the digits, which we combine with storing
    9498             :      * the result digits into the output.  Note that this is still done at
    9499             :      * full precision w/guard digits.
    9500             :      */
    9501        5328 :     alloc_var(result, div_ndigits + 1);
    9502        5328 :     res_digits = result->digits;
    9503        5328 :     carry = 0;
    9504       95616 :     for (i = div_ndigits; i >= 0; i--)
    9505             :     {
    9506       90288 :         newdig = div[i] + carry;
    9507       90288 :         if (newdig < 0)
    9508             :         {
    9509          12 :             carry = -((-newdig - 1) / NBASE) - 1;
    9510          12 :             newdig -= carry * NBASE;
    9511             :         }
    9512       90276 :         else if (newdig >= NBASE)
    9513             :         {
    9514         348 :             carry = newdig / NBASE;
    9515         348 :             newdig -= carry * NBASE;
    9516             :         }
    9517             :         else
    9518       89928 :             carry = 0;
    9519       90288 :         res_digits[i] = newdig;
    9520             :     }
    9521             :     Assert(carry == 0);
    9522             : 
    9523        5328 :     pfree(div);
    9524             : 
    9525             :     /*
    9526             :      * Finally, round the result to the requested precision.
    9527             :      */
    9528        5328 :     result->weight = res_weight;
    9529        5328 :     result->sign = res_sign;
    9530             : 
    9531             :     /* Round to target rscale (and set result->dscale) */
    9532        5328 :     if (round)
    9533         810 :         round_var(result, rscale);
    9534             :     else
    9535        4518 :         trunc_var(result, rscale);
    9536             : 
    9537             :     /* Strip leading and trailing zeroes */
    9538        5328 :     strip_var(result);
    9539             : }
    9540             : 
    9541             : 
    9542             : /*
    9543             :  * div_var_int() -
    9544             :  *
    9545             :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
    9546             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9547             :  */
    9548             : static void
    9549      225068 : div_var_int(const NumericVar *var, int ival, int ival_weight,
    9550             :             NumericVar *result, int rscale, bool round)
    9551             : {
    9552      225068 :     NumericDigit *var_digits = var->digits;
    9553      225068 :     int         var_ndigits = var->ndigits;
    9554             :     int         res_sign;
    9555             :     int         res_weight;
    9556             :     int         res_ndigits;
    9557             :     NumericDigit *res_buf;
    9558             :     NumericDigit *res_digits;
    9559             :     uint32      divisor;
    9560             :     int         i;
    9561             : 
    9562             :     /* Guard against division by zero */
    9563      225068 :     if (ival == 0)
    9564           0 :         ereport(ERROR,
    9565             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9566             :                 errmsg("division by zero"));
    9567             : 
    9568             :     /* Result zero check */
    9569      225068 :     if (var_ndigits == 0)
    9570             :     {
    9571        2300 :         zero_var(result);
    9572        2300 :         result->dscale = rscale;
    9573        2300 :         return;
    9574             :     }
    9575             : 
    9576             :     /*
    9577             :      * Determine the result sign, weight and number of digits to calculate.
    9578             :      * The weight figured here is correct if the emitted quotient has no
    9579             :      * leading zero digits; otherwise strip_var() will fix things up.
    9580             :      */
    9581      222768 :     if (var->sign == NUMERIC_POS)
    9582      219942 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9583             :     else
    9584        2826 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9585      222768 :     res_weight = var->weight - ival_weight;
    9586             :     /* The number of accurate result digits we need to produce: */
    9587      222768 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9588             :     /* ... but always at least 1 */
    9589      222768 :     res_ndigits = Max(res_ndigits, 1);
    9590             :     /* If rounding needed, figure one more digit to ensure correct result */
    9591      222768 :     if (round)
    9592      167092 :         res_ndigits++;
    9593             : 
    9594      222768 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9595      222768 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9596      222768 :     res_digits = res_buf + 1;
    9597             : 
    9598             :     /*
    9599             :      * Now compute the quotient digits.  This is the short division algorithm
    9600             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9601             :      * allow the divisor to exceed the internal base.
    9602             :      *
    9603             :      * In this algorithm, the carry from one digit to the next is at most
    9604             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9605             :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
    9606             :      * integer if this exceeds UINT_MAX.
    9607             :      */
    9608      222768 :     divisor = abs(ival);
    9609             : 
    9610      222768 :     if (divisor <= UINT_MAX / NBASE)
    9611             :     {
    9612             :         /* carry cannot overflow 32 bits */
    9613      218608 :         uint32      carry = 0;
    9614             : 
    9615     2126852 :         for (i = 0; i < res_ndigits; i++)
    9616             :         {
    9617     1908244 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9618     1908244 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9619     1908244 :             carry = carry % divisor;
    9620             :         }
    9621             :     }
    9622             :     else
    9623             :     {
    9624             :         /* carry may exceed 32 bits */
    9625        4160 :         uint64      carry = 0;
    9626             : 
    9627       13146 :         for (i = 0; i < res_ndigits; i++)
    9628             :         {
    9629        8986 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9630        8986 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9631        8986 :             carry = carry % divisor;
    9632             :         }
    9633             :     }
    9634             : 
    9635             :     /* Store the quotient in result */
    9636      222768 :     digitbuf_free(result->buf);
    9637      222768 :     result->ndigits = res_ndigits;
    9638      222768 :     result->buf = res_buf;
    9639      222768 :     result->digits = res_digits;
    9640      222768 :     result->weight = res_weight;
    9641      222768 :     result->sign = res_sign;
    9642             : 
    9643             :     /* Round or truncate to target rscale (and set result->dscale) */
    9644      222768 :     if (round)
    9645      167092 :         round_var(result, rscale);
    9646             :     else
    9647       55676 :         trunc_var(result, rscale);
    9648             : 
    9649             :     /* Strip leading/trailing zeroes */
    9650      222768 :     strip_var(result);
    9651             : }
    9652             : 
    9653             : 
    9654             : #ifdef HAVE_INT128
    9655             : /*
    9656             :  * div_var_int64() -
    9657             :  *
    9658             :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
    9659             :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
    9660             :  *
    9661             :  *  This duplicates the logic in div_var_int(), so any changes made there
    9662             :  *  should be made here too.
    9663             :  */
    9664             : static void
    9665         534 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
    9666             :               NumericVar *result, int rscale, bool round)
    9667             : {
    9668         534 :     NumericDigit *var_digits = var->digits;
    9669         534 :     int         var_ndigits = var->ndigits;
    9670             :     int         res_sign;
    9671             :     int         res_weight;
    9672             :     int         res_ndigits;
    9673             :     NumericDigit *res_buf;
    9674             :     NumericDigit *res_digits;
    9675             :     uint64      divisor;
    9676             :     int         i;
    9677             : 
    9678             :     /* Guard against division by zero */
    9679         534 :     if (ival == 0)
    9680           0 :         ereport(ERROR,
    9681             :                 errcode(ERRCODE_DIVISION_BY_ZERO),
    9682             :                 errmsg("division by zero"));
    9683             : 
    9684             :     /* Result zero check */
    9685         534 :     if (var_ndigits == 0)
    9686             :     {
    9687          96 :         zero_var(result);
    9688          96 :         result->dscale = rscale;
    9689          96 :         return;
    9690             :     }
    9691             : 
    9692             :     /*
    9693             :      * Determine the result sign, weight and number of digits to calculate.
    9694             :      * The weight figured here is correct if the emitted quotient has no
    9695             :      * leading zero digits; otherwise strip_var() will fix things up.
    9696             :      */
    9697         438 :     if (var->sign == NUMERIC_POS)
    9698         264 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
    9699             :     else
    9700         174 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
    9701         438 :     res_weight = var->weight - ival_weight;
    9702             :     /* The number of accurate result digits we need to produce: */
    9703         438 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
    9704             :     /* ... but always at least 1 */
    9705         438 :     res_ndigits = Max(res_ndigits, 1);
    9706             :     /* If rounding needed, figure one more digit to ensure correct result */
    9707         438 :     if (round)
    9708         438 :         res_ndigits++;
    9709             : 
    9710         438 :     res_buf = digitbuf_alloc(res_ndigits + 1);
    9711         438 :     res_buf[0] = 0;             /* spare digit for later rounding */
    9712         438 :     res_digits = res_buf + 1;
    9713             : 
    9714             :     /*
    9715             :      * Now compute the quotient digits.  This is the short division algorithm
    9716             :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
    9717             :      * allow the divisor to exceed the internal base.
    9718             :      *
    9719             :      * In this algorithm, the carry from one digit to the next is at most
    9720             :      * divisor - 1.  Therefore, while processing the next digit, carry may
    9721             :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
    9722             :      * integer if this exceeds PG_UINT64_MAX.
    9723             :      */
    9724         438 :     divisor = i64abs(ival);
    9725             : 
    9726         438 :     if (divisor <= PG_UINT64_MAX / NBASE)
    9727             :     {
    9728             :         /* carry cannot overflow 64 bits */
    9729         342 :         uint64      carry = 0;
    9730             : 
    9731        3506 :         for (i = 0; i < res_ndigits; i++)
    9732             :         {
    9733        3164 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9734        3164 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9735        3164 :             carry = carry % divisor;
    9736             :         }
    9737             :     }
    9738             :     else
    9739             :     {
    9740             :         /* carry may exceed 64 bits */
    9741          96 :         uint128     carry = 0;
    9742             : 
    9743        1032 :         for (i = 0; i < res_ndigits; i++)
    9744             :         {
    9745         936 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
    9746         936 :             res_digits[i] = (NumericDigit) (carry / divisor);
    9747         936 :             carry = carry % divisor;
    9748             :         }
    9749             :     }
    9750             : 
    9751             :     /* Store the quotient in result */
    9752         438 :     digitbuf_free(result->buf);
    9753         438 :     result->ndigits = res_ndigits;
    9754         438 :     result->buf = res_buf;
    9755         438 :     result->digits = res_digits;
    9756         438 :     result->weight = res_weight;
    9757         438 :     result->sign = res_sign;
    9758             : 
    9759             :     /* Round or truncate to target rscale (and set result->dscale) */
    9760         438 :     if (round)
    9761         438 :         round_var(result, rscale);
    9762             :     else
    9763           0 :         trunc_var(result, rscale);
    9764             : 
    9765             :     /* Strip leading/trailing zeroes */
    9766         438 :     strip_var(result);
    9767             : }
    9768             : #endif
    9769             : 
    9770             : 
    9771             : /*
    9772             :  * Default scale selection for division
    9773             :  *
    9774             :  * Returns the appropriate result scale for the division result.
    9775             :  */
    9776             : static int
    9777      153218 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
    9778             : {
    9779             :     int         weight1,
    9780             :                 weight2,
    9781             :                 qweight,
    9782             :                 i;
    9783             :     NumericDigit firstdigit1,
    9784             :                 firstdigit2;
    9785             :     int         rscale;
    9786             : 
    9787             :     /*
    9788             :      * The result scale of a division isn't specified in any SQL standard. For
    9789             :      * PostgreSQL we select a result scale that will give at least
    9790             :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
    9791             :      * result no less accurate than float8; but use a scale not less than
    9792             :      * either input's display scale.
    9793             :      */
    9794             : 
    9795             :     /* Get the actual (normalized) weight and first digit of each input */
    9796             : 
    9797      153218 :     weight1 = 0;                /* values to use if var1 is zero */
    9798      153218 :     firstdigit1 = 0;
    9799      153218 :     for (i = 0; i < var1->ndigits; i++)
    9800             :     {
    9801      151488 :         firstdigit1 = var1->digits[i];
    9802      151488 :         if (firstdigit1 != 0)
    9803             :         {
    9804      151488 :             weight1 = var1->weight - i;
    9805      151488 :             break;
    9806             :         }
    9807             :     }
    9808             : 
    9809      153218 :     weight2 = 0;                /* values to use if var2 is zero */
    9810      153218 :     firstdigit2 = 0;
    9811      153218 :     for (i = 0; i < var2->ndigits; i++)
    9812             :     {
    9813      153168 :         firstdigit2 = var2->digits[i];
    9814      153168 :         if (firstdigit2 != 0)
    9815             :         {
    9816      153168 :             weight2 = var2->weight - i;
    9817      153168 :             break;
    9818             :         }
    9819             :     }
    9820             : 
    9821             :     /*
    9822             :      * Estimate weight of quotient.  If the two first digits are equal, we
    9823             :      * can't be sure, but assume that var1 is less than var2.
    9824             :      */
    9825      153218 :     qweight = weight1 - weight2;
    9826      153218 :     if (firstdigit1 <= firstdigit2)
    9827      134446 :         qweight--;
    9828             : 
    9829             :     /* Select result scale */
    9830      153218 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
    9831      153218 :     rscale = Max(rscale, var1->dscale);
    9832      153218 :     rscale = Max(rscale, var2->dscale);
    9833      153218 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
    9834      153218 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
    9835             : 
    9836      153218 :     return rscale;
    9837             : }
    9838             : 
    9839             : 
    9840             : /*
    9841             :  * mod_var() -
    9842             :  *
    9843             :  *  Calculate the modulo of two numerics at variable level
    9844             :  */
    9845             : static void
    9846       54626 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9847             : {
    9848             :     NumericVar  tmp;
    9849             : 
    9850       54626 :     init_var(&tmp);
    9851             : 
    9852             :     /* ---------
    9853             :      * We do this using the equation
    9854             :      *      mod(x,y) = x - trunc(x/y)*y
    9855             :      * div_var can be persuaded to give us trunc(x/y) directly.
    9856             :      * ----------
    9857             :      */
    9858       54626 :     div_var(var1, var2, &tmp, 0, false);
    9859             : 
    9860       54614 :     mul_var(var2, &tmp, &tmp, var2->dscale);
    9861             : 
    9862       54614 :     sub_var(var1, &tmp, result);
    9863             : 
    9864       54614 :     free_var(&tmp);
    9865       54614 : }
    9866             : 
    9867             : 
    9868             : /*
    9869             :  * div_mod_var() -
    9870             :  *
    9871             :  *  Calculate the truncated integer quotient and numeric remainder of two
    9872             :  *  numeric variables.  The remainder is precise to var2's dscale.
    9873             :  */
    9874             : static void
    9875        4518 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
    9876             :             NumericVar *quot, NumericVar *rem)
    9877             : {
    9878             :     NumericVar  q;
    9879             :     NumericVar  r;
    9880             : 
    9881        4518 :     init_var(&q);
    9882        4518 :     init_var(&r);
    9883             : 
    9884             :     /*
    9885             :      * Use div_var_fast() to get an initial estimate for the integer quotient.
    9886             :      * This might be inaccurate (per the warning in div_var_fast's comments),
    9887             :      * but we can correct it below.
    9888             :      */
    9889        4518 :     div_var_fast(var1, var2, &q, 0, false);
    9890             : 
    9891             :     /* Compute initial estimate of remainder using the quotient estimate. */
    9892        4518 :     mul_var(var2, &q, &r, var2->dscale);
    9893        4518 :     sub_var(var1, &r, &r);
    9894             : 
    9895             :     /*
    9896             :      * Adjust the results if necessary --- the remainder should have the same
    9897             :      * sign as var1, and its absolute value should be less than the absolute
    9898             :      * value of var2.
    9899             :      */
    9900        4518 :     while (r.ndigits != 0 && r.sign != var1->sign)
    9901             :     {
    9902             :         /* The absolute value of the quotient is too large */
    9903           0 :         if (var1->sign == var2->sign)
    9904             :         {
    9905           0 :             sub_var(&q, &const_one, &q);
    9906           0 :             add_var(&r, var2, &r);
    9907             :         }
    9908             :         else
    9909             :         {
    9910           0 :             add_var(&q, &const_one, &q);
    9911           0 :             sub_var(&r, var2, &r);
    9912             :         }
    9913             :     }
    9914             : 
    9915        4518 :     while (cmp_abs(&r, var2) >= 0)
    9916             :     {
    9917             :         /* The absolute value of the quotient is too small */
    9918           0 :         if (var1->sign == var2->sign)
    9919             :         {
    9920           0 :             add_var(&q, &const_one, &q);
    9921           0 :             sub_var(&r, var2, &r);
    9922             :         }
    9923             :         else
    9924             :         {
    9925           0 :             sub_var(&q, &const_one, &q);
    9926           0 :             add_var(&r, var2, &r);
    9927             :         }
    9928             :     }
    9929             : 
    9930        4518 :     set_var_from_var(&q, quot);
    9931        4518 :     set_var_from_var(&r, rem);
    9932             : 
    9933        4518 :     free_var(&q);
    9934        4518 :     free_var(&r);
    9935        4518 : }
    9936             : 
    9937             : 
    9938             : /*
    9939             :  * ceil_var() -
    9940             :  *
    9941             :  *  Return the smallest integer greater than or equal to the argument
    9942             :  *  on variable level
    9943             :  */
    9944             : static void
    9945         204 : ceil_var(const NumericVar *var, NumericVar *result)
    9946             : {
    9947             :     NumericVar  tmp;
    9948             : 
    9949         204 :     init_var(&tmp);
    9950         204 :     set_var_from_var(var, &tmp);
    9951             : 
    9952         204 :     trunc_var(&tmp, 0);
    9953             : 
    9954         204 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
    9955          60 :         add_var(&tmp, &const_one, &tmp);
    9956             : 
    9957         204 :     set_var_from_var(&tmp, result);
    9958         204 :     free_var(&tmp);
    9959         204 : }
    9960             : 
    9961             : 
    9962             : /*
    9963             :  * floor_var() -
    9964             :  *
    9965             :  *  Return the largest integer equal to or less than the argument
    9966             :  *  on variable level
    9967             :  */
    9968             : static void
    9969         576 : floor_var(const NumericVar *var, NumericVar *result)
    9970             : {
    9971             :     NumericVar  tmp;
    9972             : 
    9973         576 :     init_var(&tmp);
    9974         576 :     set_var_from_var(var, &tmp);
    9975             : 
    9976         576 :     trunc_var(&tmp, 0);
    9977             : 
    9978         576 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
    9979          30 :         sub_var(&tmp, &const_one, &tmp);
    9980             : 
    9981         576 :     set_var_from_var(&tmp, result);
    9982         576 :     free_var(&tmp);
    9983         576 : }
    9984             : 
    9985             : 
    9986             : /*
    9987             :  * gcd_var() -
    9988             :  *
    9989             :  *  Calculate the greatest common divisor of two numerics at variable level
    9990             :  */
    9991             : static void
    9992         222 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
    9993             : {
    9994             :     int         res_dscale;
    9995             :     int         cmp;
    9996             :     NumericVar  tmp_arg;
    9997             :     NumericVar  mod;
    9998             : 
    9999         222 :     res_dscale = Max(var1->dscale, var2->dscale);
   10000             : 
   10001             :     /*
   10002             :      * Arrange for var1 to be the number with the greater absolute value.
   10003             :      *
   10004             :      * This would happen automatically in the loop below, but avoids an
   10005             :      * expensive modulo operation.
   10006             :      */
   10007         222 :     cmp = cmp_abs(var1, var2);
   10008         222 :     if (cmp < 0)
   10009             :     {
   10010          84 :         const NumericVar *tmp = var1;
   10011             : 
   10012          84 :         var1 = var2;
   10013          84 :         var2 = tmp;
   10014             :     }
   10015             : 
   10016             :     /*
   10017             :      * Also avoid the taking the modulo if the inputs have the same absolute
   10018             :      * value, or if the smaller input is zero.
   10019             :      */
   10020         222 :     if (cmp == 0 || var2->ndigits == 0)
   10021             :     {
   10022          72 :         set_var_from_var(var1, result);
   10023          72 :         result->sign = NUMERIC_POS;
   10024          72 :         result->dscale = res_dscale;
   10025          72 :         return;
   10026             :     }
   10027             : 
   10028         150 :     init_var(&tmp_arg);
   10029         150 :     init_var(&mod);
   10030             : 
   10031             :     /* Use the Euclidean algorithm to find the GCD */
   10032         150 :     set_var_from_var(var1, &tmp_arg);
   10033         150 :     set_var_from_var(var2, result);
   10034             : 
   10035             :     for (;;)
   10036             :     {
   10037             :         /* this loop can take a while, so allow it to be interrupted */
   10038         588 :         CHECK_FOR_INTERRUPTS();
   10039             : 
   10040         588 :         mod_var(&tmp_arg, result, &mod);
   10041         588 :         if (mod.ndigits == 0)
   10042         150 :             break;
   10043         438 :         set_var_from_var(result, &tmp_arg);
   10044         438 :         set_var_from_var(&mod, result);
   10045             :     }
   10046         150 :     result->sign = NUMERIC_POS;
   10047         150 :     result->dscale = res_dscale;
   10048             : 
   10049         150 :     free_var(&tmp_arg);
   10050         150 :     free_var(&mod);
   10051             : }
   10052             : 
   10053             : 
   10054             : /*
   10055             :  * sqrt_var() -
   10056             :  *
   10057             :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
   10058             :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
   10059             :  *  point.
   10060             :  */
   10061             : static void
   10062        4194 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
   10063             : {
   10064             :     int         stat;
   10065             :     int         res_weight;
   10066             :     int         res_ndigits;
   10067             :     int         src_ndigits;
   10068             :     int         step;
   10069             :     int         ndigits[32];
   10070             :     int         blen;
   10071             :     int64       arg_int64;
   10072             :     int         src_idx;
   10073             :     int64       s_int64;
   10074             :     int64       r_int64;
   10075             :     NumericVar  s_var;
   10076             :     NumericVar  r_var;
   10077             :     NumericVar  a0_var;
   10078             :     NumericVar  a1_var;
   10079             :     NumericVar  q_var;
   10080             :     NumericVar  u_var;
   10081             : 
   10082        4194 :     stat = cmp_var(arg, &const_zero);
   10083        4194 :     if (stat == 0)
   10084             :     {
   10085          18 :         zero_var(result);
   10086          18 :         result->dscale = rscale;
   10087          18 :         return;
   10088             :     }
   10089             : 
   10090             :     /*
   10091             :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
   10092             :      * SQLSTATE error code if the operand is negative.
   10093             :      */
   10094        4176 :     if (stat < 0)
   10095           6 :         ereport(ERROR,
   10096             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10097             :                  errmsg("cannot take square root of a negative number")));
   10098             : 
   10099        4170 :     init_var(&s_var);
   10100        4170 :     init_var(&r_var);
   10101        4170 :     init_var(&a0_var);
   10102        4170 :     init_var(&a1_var);
   10103        4170 :     init_var(&q_var);
   10104        4170 :     init_var(&u_var);
   10105             : 
   10106             :     /*
   10107             :      * The result weight is half the input weight, rounded towards minus
   10108             :      * infinity --- res_weight = floor(arg->weight / 2).
   10109             :      */
   10110        4170 :     if (arg->weight >= 0)
   10111        3858 :         res_weight = arg->weight / 2;
   10112             :     else
   10113         312 :         res_weight = -((-arg->weight - 1) / 2 + 1);
   10114             : 
   10115             :     /*
   10116             :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
   10117             :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
   10118             :      * negative here, but must always compute at least 1 NBASE digit.  Thus
   10119             :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
   10120             :      */
   10121        4170 :     if (rscale + 1 >= 0)
   10122        4170 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
   10123             :     else
   10124           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
   10125        4170 :     res_ndigits = Max(res_ndigits, 1);
   10126             : 
   10127             :     /*
   10128             :      * Number of source NBASE digits logically required to produce a result
   10129             :      * with this precision --- every digit before the decimal point, plus 2
   10130             :      * for each result digit after the decimal point (or minus 2 for each
   10131             :      * result digit we round before the decimal point).
   10132             :      */
   10133        4170 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
   10134        4170 :     src_ndigits = Max(src_ndigits, 1);
   10135             : 
   10136             :     /* ----------
   10137             :      * From this point on, we treat the input and the result as integers and
   10138             :      * compute the integer square root and remainder using the Karatsuba
   10139             :      * Square Root algorithm, which may be written recursively as follows:
   10140             :      *
   10141             :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
   10142             :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
   10143             :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
   10144             :      *      Let (s,r) = SqrtRem(a3*b + a2)
   10145             :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
   10146             :      *      Let s = s*b + q
   10147             :      *      Let r = u*b + a0 - q^2
   10148             :      *      If r < 0 Then
   10149             :      *          Let r = r + s
   10150             :      *          Let s = s - 1
   10151             :      *          Let r = r + s
   10152             :      *      Return (s,r)
   10153             :      *
   10154             :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
   10155             :      * RR-3805, November 1999.  At the time of writing this was available
   10156             :      * on the net at <https://hal.inria.fr/inria-00072854>.
   10157             :      *
   10158             :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
   10159             :      * "choose a base b such that n requires at least four base-b digits to
   10160             :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
   10161             :      * than b".  For optimal performance, b should have approximately a
   10162             :      * quarter the number of digits in the input, so that the outer square
   10163             :      * root computes roughly twice as many digits as the inner one.  For
   10164             :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
   10165             :      *
   10166             :      * We implement the algorithm iteratively rather than recursively, to
   10167             :      * allow the working variables to be reused.  With this approach, each
   10168             :      * digit of the input is read precisely once --- src_idx tracks the number
   10169             :      * of input digits used so far.
   10170             :      *
   10171             :      * The array ndigits[] holds the number of NBASE digits of the input that
   10172             :      * will have been used at the end of each iteration, which roughly doubles
   10173             :      * each time.  Note that the array elements are stored in reverse order,
   10174             :      * so if the final iteration requires src_ndigits = 37 input digits, the
   10175             :      * array will contain [37,19,11,7,5,3], and we would start by computing
   10176             :      * the square root of the 3 most significant NBASE digits.
   10177             :      *
   10178             :      * In each iteration, we choose blen to be the largest integer for which
   10179             :      * the input number has a3 >= b/4, when written in the form above.  In
   10180             :      * general, this means blen = src_ndigits / 4 (truncated), but if
   10181             :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
   10182             :      * being less than b/4 (if the first input digit is less than NBASE/4), in
   10183             :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
   10184             :      * in the inner square root is then src_ndigits - 2*blen.  So, for
   10185             :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
   10186             :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
   10187             :      * the first input digit.
   10188             :      *
   10189             :      * Additionally, we can put an upper bound on the number of steps required
   10190             :      * as follows --- suppose that the number of source digits is an n-bit
   10191             :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
   10192             :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
   10193             :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
   10194             :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
   10195             :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
   10196             :      * This pattern repeats, and in the worst case the array ndigits[] will
   10197             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
   10198             :      * will require n steps.  Therefore, since all digit array sizes are
   10199             :      * signed 32-bit integers, the number of steps required is guaranteed to
   10200             :      * be less than 32.
   10201             :      * ----------
   10202             :      */
   10203        4170 :     step = 0;
   10204       19962 :     while ((ndigits[step] = src_ndigits) > 4)
   10205             :     {
   10206             :         /* Choose b so that a3 >= b/4, as described above */
   10207       15792 :         blen = src_ndigits / 4;
   10208       15792 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
   10209         324 :             blen--;
   10210             : 
   10211             :         /* Number of digits in the next step (inner square root) */
   10212       15792 :         src_ndigits -= 2 * blen;
   10213       15792 :         step++;
   10214             :     }
   10215             : 
   10216             :     /*
   10217             :      * First iteration (innermost square root and remainder):
   10218             :      *
   10219             :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
   10220             :      * has at most 9 decimal digits, so estimate it using double precision
   10221             :      * arithmetic, which will in fact almost certainly return the correct
   10222             :      * result with no further correction required.
   10223             :      */
   10224        4170 :     arg_int64 = arg->digits[0];
   10225       13314 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
   10226             :     {
   10227        9144 :         arg_int64 *= NBASE;
   10228        9144 :         if (src_idx < arg->ndigits)
   10229        7686 :             arg_int64 += arg->digits[src_idx];
   10230             :     }
   10231             : 
   10232        4170 :     s_int64 = (int64) sqrt((double) arg_int64);
   10233        4170 :     r_int64 = arg_int64 - s_int64 * s_int64;
   10234             : 
   10235             :     /*
   10236             :      * Use Newton's method to correct the result, if necessary.
   10237             :      *
   10238             :      * This uses integer division with truncation to compute the truncated
   10239             :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
   10240             :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
   10241             :      * If n+1 is a perfect square, the sequence will oscillate between the two
   10242             :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
   10243             :      * checking the remainder.
   10244             :      */
   10245        4170 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
   10246             :     {
   10247           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
   10248           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
   10249             :     }
   10250             : 
   10251             :     /*
   10252             :      * Iterations with src_ndigits <= 8:
   10253             :      *
   10254             :      * The next 1 or 2 iterations compute larger (outer) square roots with
   10255             :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
   10256             :      * input no longer does) and we can continue to compute using int64
   10257             :      * variables to avoid more expensive numeric computations.
   10258             :      *
   10259             :      * It is fairly easy to see that there is no risk of the intermediate
   10260             :      * values below overflowing 64-bit integers.  In the worst case, the
   10261             :      * previous iteration will have computed a 3-digit square root (of a
   10262             :      * 6-digit input less than NBASE^6 / 4), so at the start of this
   10263             :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
   10264             :      * less than 10^12.  In this case, blen will be 1, so numer will be less
   10265             :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
   10266             :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
   10267             :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
   10268             :      * in 64-bit integers.
   10269             :      */
   10270        4170 :     step--;
   10271       10566 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
   10272             :     {
   10273             :         int         b;
   10274             :         int         a0;
   10275             :         int         a1;
   10276             :         int         i;
   10277             :         int64       numer;
   10278             :         int64       denom;
   10279             :         int64       q;
   10280             :         int64       u;
   10281             : 
   10282        6396 :         blen = (src_ndigits - src_idx) / 2;
   10283             : 
   10284             :         /* Extract a1 and a0, and compute b */
   10285        6396 :         a0 = 0;
   10286        6396 :         a1 = 0;
   10287        6396 :         b = 1;
   10288             : 
   10289       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10290             :         {
   10291        6540 :             b *= NBASE;
   10292        6540 :             a1 *= NBASE;
   10293        6540 :             if (src_idx < arg->ndigits)
   10294        4800 :                 a1 += arg->digits[src_idx];
   10295             :         }
   10296             : 
   10297       12936 :         for (i = 0; i < blen; i++, src_idx++)
   10298             :         {
   10299        6540 :             a0 *= NBASE;
   10300        6540 :             if (src_idx < arg->ndigits)
   10301        4644 :                 a0 += arg->digits[src_idx];
   10302             :         }
   10303             : 
   10304             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10305        6396 :         numer = r_int64 * b + a1;
   10306        6396 :         denom = 2 * s_int64;
   10307        6396 :         q = numer / denom;
   10308        6396 :         u = numer - q * denom;
   10309             : 
   10310             :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10311        6396 :         s_int64 = s_int64 * b + q;
   10312        6396 :         r_int64 = u * b + a0 - q * q;
   10313             : 
   10314        6396 :         if (r_int64 < 0)
   10315             :         {
   10316             :             /* s is too large by 1; set r += s, s--, r += s */
   10317         210 :             r_int64 += s_int64;
   10318         210 :             s_int64--;
   10319         210 :             r_int64 += s_int64;
   10320             :         }
   10321             : 
   10322             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10323        6396 :         step--;
   10324             :     }
   10325             : 
   10326             :     /*
   10327             :      * On platforms with 128-bit integer support, we can further delay the
   10328             :      * need to use numeric variables.
   10329             :      */
   10330             : #ifdef HAVE_INT128
   10331        4170 :     if (step >= 0)
   10332             :     {
   10333             :         int128      s_int128;
   10334             :         int128      r_int128;
   10335             : 
   10336        4170 :         s_int128 = s_int64;
   10337        4170 :         r_int128 = r_int64;
   10338             : 
   10339             :         /*
   10340             :          * Iterations with src_ndigits <= 16:
   10341             :          *
   10342             :          * The result fits in an int128 (even though the input doesn't) so we
   10343             :          * use int128 variables to avoid more expensive numeric computations.
   10344             :          */
   10345        9048 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
   10346             :         {
   10347             :             int64       b;
   10348             :             int64       a0;
   10349             :             int64       a1;
   10350             :             int64       i;
   10351             :             int128      numer;
   10352             :             int128      denom;
   10353             :             int128      q;
   10354             :             int128      u;
   10355             : 
   10356        4878 :             blen = (src_ndigits - src_idx) / 2;
   10357             : 
   10358             :             /* Extract a1 and a0, and compute b */
   10359        4878 :             a0 = 0;
   10360        4878 :             a1 = 0;
   10361        4878 :             b = 1;
   10362             : 
   10363       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10364             :             {
   10365       11202 :                 b *= NBASE;
   10366       11202 :                 a1 *= NBASE;
   10367       11202 :                 if (src_idx < arg->ndigits)
   10368        6606 :                     a1 += arg->digits[src_idx];
   10369             :             }
   10370             : 
   10371       16080 :             for (i = 0; i < blen; i++, src_idx++)
   10372             :             {
   10373       11202 :                 a0 *= NBASE;
   10374       11202 :                 if (src_idx < arg->ndigits)
   10375        4470 :                     a0 += arg->digits[src_idx];
   10376             :             }
   10377             : 
   10378             :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10379        4878 :             numer = r_int128 * b + a1;
   10380        4878 :             denom = 2 * s_int128;
   10381        4878 :             q = numer / denom;
   10382        4878 :             u = numer - q * denom;
   10383             : 
   10384             :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
   10385        4878 :             s_int128 = s_int128 * b + q;
   10386        4878 :             r_int128 = u * b + a0 - q * q;
   10387             : 
   10388        4878 :             if (r_int128 < 0)
   10389             :             {
   10390             :                 /* s is too large by 1; set r += s, s--, r += s */
   10391         192 :                 r_int128 += s_int128;
   10392         192 :                 s_int128--;
   10393         192 :                 r_int128 += s_int128;
   10394             :             }
   10395             : 
   10396             :             Assert(src_idx == src_ndigits); /* All input digits consumed */
   10397        4878 :             step--;
   10398             :         }
   10399             : 
   10400             :         /*
   10401             :          * All remaining iterations require numeric variables.  Convert the
   10402             :          * integer values to NumericVar and continue.  Note that in the final
   10403             :          * iteration we don't need the remainder, so we can save a few cycles
   10404             :          * there by not fully computing it.
   10405             :          */
   10406        4170 :         int128_to_numericvar(s_int128, &s_var);
   10407        4170 :         if (step >= 0)
   10408        2724 :             int128_to_numericvar(r_int128, &r_var);
   10409             :     }
   10410             :     else
   10411             :     {
   10412           0 :         int64_to_numericvar(s_int64, &s_var);
   10413             :         /* step < 0, so we certainly don't need r */
   10414             :     }
   10415             : #else                           /* !HAVE_INT128 */
   10416             :     int64_to_numericvar(s_int64, &s_var);
   10417             :     if (step >= 0)
   10418             :         int64_to_numericvar(r_int64, &r_var);
   10419             : #endif                          /* HAVE_INT128 */
   10420             : 
   10421             :     /*
   10422             :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
   10423             :      * use numeric variables.
   10424             :      */
   10425        8688 :     while (step >= 0)
   10426             :     {
   10427             :         int         tmp_len;
   10428             : 
   10429        4518 :         src_ndigits = ndigits[step];
   10430        4518 :         blen = (src_ndigits - src_idx) / 2;
   10431             : 
   10432             :         /* Extract a1 and a0 */
   10433        4518 :         if (src_idx < arg->ndigits)
   10434             :         {
   10435        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10436        1512 :             alloc_var(&a1_var, tmp_len);
   10437        1512 :             memcpy(a1_var.digits, arg->digits + src_idx,
   10438             :                    tmp_len * sizeof(NumericDigit));
   10439        1512 :             a1_var.weight = blen - 1;
   10440        1512 :             a1_var.sign = NUMERIC_POS;
   10441        1512 :             a1_var.dscale = 0;
   10442        1512 :             strip_var(&a1_var);
   10443             :         }
   10444             :         else
   10445             :         {
   10446        3006 :             zero_var(&a1_var);
   10447        3006 :             a1_var.dscale = 0;
   10448             :         }
   10449        4518 :         src_idx += blen;
   10450             : 
   10451        4518 :         if (src_idx < arg->ndigits)
   10452             :         {
   10453        1512 :             tmp_len = Min(blen, arg->ndigits - src_idx);
   10454        1512 :             alloc_var(&a0_var, tmp_len);
   10455        1512 :             memcpy(a0_var.digits, arg->digits + src_idx,
   10456             :                    tmp_len * sizeof(NumericDigit));
   10457        1512 :             a0_var.weight = blen - 1;
   10458        1512 :             a0_var.sign = NUMERIC_POS;
   10459        1512 :             a0_var.dscale = 0;
   10460        1512 :             strip_var(&a0_var);
   10461             :         }
   10462             :         else
   10463             :         {
   10464        3006 :             zero_var(&a0_var);
   10465        3006 :             a0_var.dscale = 0;
   10466             :         }
   10467        4518 :         src_idx += blen;
   10468             : 
   10469             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
   10470        4518 :         set_var_from_var(&r_var, &q_var);
   10471        4518 :         q_var.weight += blen;
   10472        4518 :         add_var(&q_var, &a1_var, &q_var);
   10473        4518 :         add_var(&s_var, &s_var, &u_var);
   10474        4518 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
   10475             : 
   10476             :         /* Compute s = s*b + q */
   10477        4518 :         s_var.weight += blen;
   10478        4518 :         add_var(&s_var, &q_var, &s_var);
   10479             : 
   10480             :         /*
   10481             :          * Compute r = u*b + a0 - q^2.
   10482             :          *
   10483             :          * In the final iteration, we don't actually need r; we just need to
   10484             :          * know whether it is negative, so that we know whether to adjust s.
   10485             :          * So instead of the final subtraction we can just compare.
   10486             :          */
   10487        4518 :         u_var.weight += blen;
   10488        4518 :         add_var(&u_var, &a0_var, &u_var);
   10489        4518 :         mul_var(&q_var, &q_var, &q_var, 0);
   10490             : 
   10491        4518 :         if (step > 0)
   10492             :         {
   10493             :             /* Need r for later iterations */
   10494        1794 :             sub_var(&u_var, &q_var, &r_var);
   10495        1794 :             if (r_var.sign == NUMERIC_NEG)
   10496             :             {
   10497             :                 /* s is too large by 1; set r += s, s--, r += s */
   10498         120 :                 add_var(&r_var, &s_var, &r_var);
   10499         120 :                 sub_var(&s_var, &const_one, &s_var);
   10500         120 :                 add_var(&r_var, &s_var, &r_var);
   10501             :             }
   10502             :         }
   10503             :         else
   10504             :         {
   10505             :             /* Don't need r anymore, except to test if s is too large by 1 */
   10506        2724 :             if (cmp_var(&u_var, &q_var) < 0)
   10507          36 :                 sub_var(&s_var, &const_one, &s_var);
   10508             :         }
   10509             : 
   10510             :         Assert(src_idx == src_ndigits); /* All input digits consumed */
   10511        4518 :         step--;
   10512             :     }
   10513             : 
   10514             :     /*
   10515             :      * Construct the final result, rounding it to the requested precision.
   10516             :      */
   10517        4170 :     set_var_from_var(&s_var, result);
   10518        4170 :     result->weight = res_weight;
   10519        4170 :     result->sign = NUMERIC_POS;
   10520             : 
   10521             :     /* Round to target rscale (and set result->dscale) */
   10522        4170 :     round_var(result, rscale);
   10523             : 
   10524             :     /* Strip leading and trailing zeroes */
   10525        4170 :     strip_var(result);
   10526             : 
   10527        4170 :     free_var(&s_var);
   10528        4170 :     free_var(&r_var);
   10529        4170 :     free_var(&a0_var);
   10530        4170 :     free_var(&a1_var);
   10531        4170 :     free_var(&q_var);
   10532        4170 :     free_var(&u_var);
   10533             : }
   10534             : 
   10535             : 
   10536             : /*
   10537             :  * exp_var() -
   10538             :  *
   10539             :  *  Raise e to the power of x, computed to rscale fractional digits
   10540             :  */
   10541             : static void
   10542         180 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
   10543             : {
   10544             :     NumericVar  x;
   10545             :     NumericVar  elem;
   10546             :     int         ni;
   10547             :     double      val;
   10548             :     int         dweight;
   10549             :     int         ndiv2;
   10550             :     int         sig_digits;
   10551             :     int         local_rscale;
   10552             : 
   10553         180 :     init_var(&x);
   10554         180 :     init_var(&elem);
   10555             : 
   10556         180 :     set_var_from_var(arg, &x);
   10557             : 
   10558             :     /*
   10559             :      * Estimate the dweight of the result using floating point arithmetic, so
   10560             :      * that we can choose an appropriate local rscale for the calculation.
   10561             :      */
   10562         180 :     val = numericvar_to_double_no_overflow(&x);
   10563             : 
   10564             :     /* Guard against overflow/underflow */
   10565             :     /* If you change this limit, see also power_var()'s limit */
   10566         180 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
   10567             :     {
   10568           6 :         if (val > 0)
   10569           0 :             ereport(ERROR,
   10570             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   10571             :                      errmsg("value overflows numeric format")));
   10572           6 :         zero_var(result);
   10573           6 :         result->dscale = rscale;
   10574           6 :         return;
   10575             :     }
   10576             : 
   10577             :     /* decimal weight = log10(e^x) = x * log10(e) */
   10578         174 :     dweight = (int) (val * 0.434294481903252);
   10579             : 
   10580             :     /*
   10581             :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
   10582             :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
   10583             :      *
   10584             :      * Note that the overflow check above ensures that fabs(x) < 6000, which
   10585             :      * means that ndiv2 <= 20 here.
   10586             :      */
   10587         174 :     if (fabs(val) > 0.01)
   10588             :     {
   10589         144 :         ndiv2 = 1;
   10590         144 :         val /= 2;
   10591             : 
   10592        1818 :         while (fabs(val) > 0.01)
   10593             :         {
   10594        1674 :             ndiv2++;
   10595        1674 :             val /= 2;
   10596             :         }
   10597             : 
   10598         144 :         local_rscale = x.dscale + ndiv2;
   10599         144 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
   10600             :     }
   10601             :     else
   10602          30 :         ndiv2 = 0;
   10603             : 
   10604             :     /*
   10605             :      * Set the scale for the Taylor series expansion.  The final result has
   10606             :      * (dweight + rscale + 1) significant digits.  In addition, we have to
   10607             :      * raise the Taylor series result to the power 2^ndiv2, which introduces
   10608             :      * an error of up to around log10(2^ndiv2) digits, so work with this many
   10609             :      * extra digits of precision (plus a few more for good measure).
   10610             :      */
   10611         174 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
   10612         174 :     sig_digits = Max(sig_digits, 0) + 8;
   10613             : 
   10614         174 :     local_rscale = sig_digits - 1;
   10615             : 
   10616             :     /*
   10617             :      * Use the Taylor series
   10618             :      *
   10619             :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
   10620             :      *
   10621             :      * Given the limited range of x, this should converge reasonably quickly.
   10622             :      * We run the series until the terms fall below the local_rscale limit.
   10623             :      */
   10624         174 :     add_var(&const_one, &x, result);
   10625             : 
   10626         174 :     mul_var(&x, &x, &elem, local_rscale);
   10627         174 :     ni = 2;
   10628         174 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10629             : 
   10630        4992 :     while (elem.ndigits != 0)
   10631             :     {
   10632        4818 :         add_var(result, &elem, result);
   10633             : 
   10634        4818 :         mul_var(&elem, &x, &elem, local_rscale);
   10635        4818 :         ni++;
   10636        4818 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
   10637             :     }
   10638             : 
   10639             :     /*
   10640             :      * Compensate for the argument range reduction.  Since the weight of the
   10641             :      * result doubles with each multiplication, we can reduce the local rscale
   10642             :      * as we proceed.
   10643             :      */
   10644        1992 :     while (ndiv2-- > 0)
   10645             :     {
   10646        1818 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
   10647        1818 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10648        1818 :         mul_var(result, result, result, local_rscale);
   10649             :     }
   10650             : 
   10651             :     /* Round to requested rscale */
   10652         174 :     round_var(result, rscale);
   10653             : 
   10654         174 :     free_var(&x);
   10655         174 :     free_var(&elem);
   10656             : }
   10657             : 
   10658             : 
   10659             : /*
   10660             :  * Estimate the dweight of the most significant decimal digit of the natural
   10661             :  * logarithm of a number.
   10662             :  *
   10663             :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
   10664             :  * determine the appropriate rscale when computing natural logarithms.
   10665             :  *
   10666             :  * Note: many callers call this before range-checking the input.  Therefore,
   10667             :  * we must be robust against values that are invalid to apply ln() to.
   10668             :  * We don't wish to throw an error here, so just return zero in such cases.
   10669             :  */
   10670             : static int
   10671         738 : estimate_ln_dweight(const NumericVar *var)
   10672             : {
   10673             :     int         ln_dweight;
   10674             : 
   10675             :     /* Caller should fail on ln(negative), but for the moment return zero */
   10676         738 :     if (var->sign != NUMERIC_POS)
   10677          42 :         return 0;
   10678             : 
   10679        1314 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
   10680         618 :         cmp_var(var, &const_one_point_one) <= 0)
   10681          90 :     {
   10682             :         /*
   10683             :          * 0.9 <= var <= 1.1
   10684             :          *
   10685             :          * ln(var) has a negative weight (possibly very large).  To get a
   10686             :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
   10687             :          */
   10688             :         NumericVar  x;
   10689             : 
   10690          90 :         init_var(&x);
   10691          90 :         sub_var(var, &const_one, &x);
   10692             : 
   10693          90 :         if (x.ndigits > 0)
   10694             :         {
   10695             :             /* Use weight of most significant decimal digit of x */
   10696          42 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
   10697             :         }
   10698             :         else
   10699             :         {
   10700             :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
   10701          48 :             ln_dweight = 0;
   10702             :         }
   10703             : 
   10704          90 :         free_var(&x);
   10705             :     }
   10706             :     else
   10707             :     {
   10708             :         /*
   10709             :          * Estimate the logarithm using the first couple of digits from the
   10710             :          * input number.  This will give an accurate result whenever the input
   10711             :          * is not too close to 1.
   10712             :          */
   10713         606 :         if (var->ndigits > 0)
   10714             :         {
   10715             :             int         digits;
   10716             :             int         dweight;
   10717             :             double      ln_var;
   10718             : 
   10719         564 :             digits = var->digits[0];
   10720         564 :             dweight = var->weight * DEC_DIGITS;
   10721             : 
   10722         564 :             if (var->ndigits > 1)
   10723             :             {
   10724         342 :                 digits = digits * NBASE + var->digits[1];
   10725         342 :                 dweight -= DEC_DIGITS;
   10726             :             }
   10727             : 
   10728             :             /*----------
   10729             :              * We have var ~= digits * 10^dweight
   10730             :              * so ln(var) ~= ln(digits) + dweight * ln(10)
   10731             :              *----------
   10732             :              */
   10733         564 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
   10734         564 :             ln_dweight = (int) log10(fabs(ln_var));
   10735             :         }
   10736             :         else
   10737             :         {
   10738             :             /* Caller should fail on ln(0), but for the moment return zero */
   10739          42 :             ln_dweight = 0;
   10740             :         }
   10741             :     }
   10742             : 
   10743         696 :     return ln_dweight;
   10744             : }
   10745             : 
   10746             : 
   10747             : /*
   10748             :  * ln_var() -
   10749             :  *
   10750             :  *  Compute the natural log of x
   10751             :  */
   10752             : static void
   10753         834 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
   10754             : {
   10755             :     NumericVar  x;
   10756             :     NumericVar  xx;
   10757             :     int         ni;
   10758             :     NumericVar  elem;
   10759             :     NumericVar  fact;
   10760             :     int         nsqrt;
   10761             :     int         local_rscale;
   10762             :     int         cmp;
   10763             : 
   10764         834 :     cmp = cmp_var(arg, &const_zero);
   10765         834 :     if (cmp == 0)
   10766          42 :         ereport(ERROR,
   10767             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10768             :                  errmsg("cannot take logarithm of zero")));
   10769         792 :     else if (cmp < 0)
   10770          36 :         ereport(ERROR,
   10771             :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
   10772             :                  errmsg("cannot take logarithm of a negative number")));
   10773             : 
   10774         756 :     init_var(&x);
   10775         756 :     init_var(&xx);
   10776         756 :     init_var(&elem);
   10777         756 :     init_var(&fact);
   10778             : 
   10779         756 :     set_var_from_var(arg, &x);
   10780         756 :     set_var_from_var(&const_two, &fact);
   10781             : 
   10782             :     /*
   10783             :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
   10784             :      *
   10785             :      * The final logarithm will have up to around rscale+6 significant digits.
   10786             :      * Each sqrt() will roughly halve the weight of x, so adjust the local
   10787             :      * rscale as we work so that we keep this many significant digits at each
   10788             :      * step (plus a few more for good measure).
   10789             :      *
   10790             :      * Note that we allow local_rscale < 0 during this input reduction
   10791             :      * process, which implies rounding before the decimal point.  sqrt_var()
   10792             :      * explicitly supports this, and it significantly reduces the work
   10793             :      * required to reduce very large inputs to the required range.  Once the
   10794             :      * input reduction is complete, x.weight will be 0 and its display scale
   10795             :      * will be non-negative again.
   10796             :      */
   10797         756 :     nsqrt = 0;
   10798        1068 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
   10799             :     {
   10800         312 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10801         312 :         sqrt_var(&x, &x, local_rscale);
   10802         312 :         mul_var(&fact, &const_two, &fact, 0);
   10803         312 :         nsqrt++;
   10804             :     }
   10805        4128 :     while (cmp_var(&x, &const_one_point_one) >= 0)
   10806             :     {
   10807        3372 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
   10808        3372 :         sqrt_var(&x, &x, local_rscale);
   10809        3372 :         mul_var(&fact, &const_two, &fact, 0);
   10810        3372 :         nsqrt++;
   10811             :     }
   10812             : 
   10813             :     /*
   10814             :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
   10815             :      *
   10816             :      * z + z^3/3 + z^5/5 + ...
   10817             :      *
   10818             :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
   10819             :      * due to the above range-reduction of x.
   10820             :      *
   10821             :      * The convergence of this is not as fast as one would like, but is
   10822             :      * tolerable given that z is small.
   10823             :      *
   10824             :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
   10825             :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
   10826             :      * digits of precision (plus a few more for good measure).
   10827             :      */
   10828         756 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
   10829             : 
   10830         756 :     sub_var(&x, &const_one, result);
   10831         756 :     add_var(&x, &const_one, &elem);
   10832         756 :     div_var_fast(result, &elem, result, local_rscale, true);
   10833         756 :     set_var_from_var(result, &xx);
   10834         756 :     mul_var(result, result, &x, local_rscale);
   10835             : 
   10836         756 :     ni = 1;
   10837             : 
   10838             :     for (;;)
   10839             :     {
   10840       14022 :         ni += 2;
   10841       14022 :         mul_var(&xx, &x, &xx, local_rscale);
   10842       14022 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
   10843             : 
   10844       14022 :         if (elem.ndigits == 0)
   10845         756 :             break;
   10846             : 
   10847       13266 :         add_var(result, &elem, result);
   10848             : 
   10849       13266 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
   10850           0 :             break;
   10851             :     }
   10852             : 
   10853             :     /* Compensate for argument range reduction, round to requested rscale */
   10854         756 :     mul_var(result, &fact, result, rscale);
   10855             : 
   10856         756 :     free_var(&x);
   10857         756 :     free_var(&xx);
   10858         756 :     free_var(&elem);
   10859         756 :     free_var(&fact);
   10860         756 : }
   10861             : 
   10862             : 
   10863             : /*
   10864             :  * log_var() -
   10865             :  *
   10866             :  *  Compute the logarithm of num in a given base.
   10867             :  *
   10868             :  *  Note: this routine chooses dscale of the result.
   10869             :  */
   10870             : static void
   10871         216 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
   10872             : {
   10873             :     NumericVar  ln_base;
   10874             :     NumericVar  ln_num;
   10875             :     int         ln_base_dweight;
   10876             :     int         ln_num_dweight;
   10877             :     int         result_dweight;
   10878             :     int         rscale;
   10879             :     int         ln_base_rscale;
   10880             :     int         ln_num_rscale;
   10881             : 
   10882         216 :     init_var(&ln_base);
   10883         216 :     init_var(&ln_num);
   10884             : 
   10885             :     /* Estimated dweights of ln(base), ln(num) and the final result */
   10886         216 :     ln_base_dweight = estimate_ln_dweight(base);
   10887         216 :     ln_num_dweight = estimate_ln_dweight(num);
   10888         216 :     result_dweight = ln_num_dweight - ln_base_dweight;
   10889             : 
   10890             :     /*
   10891             :      * Select the scale of the result so that it will have at least
   10892             :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
   10893             :      * input's display scale.
   10894             :      */
   10895         216 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
   10896         216 :     rscale = Max(rscale, base->dscale);
   10897         216 :     rscale = Max(rscale, num->dscale);
   10898         216 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10899         216 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   10900             : 
   10901             :     /*
   10902             :      * Set the scales for ln(base) and ln(num) so that they each have more
   10903             :      * significant digits than the final result.
   10904             :      */
   10905         216 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
   10906         216 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10907             : 
   10908         216 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
   10909         216 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   10910             : 
   10911             :     /* Form natural logarithms */
   10912         216 :     ln_var(base, &ln_base, ln_base_rscale);
   10913         192 :     ln_var(num, &ln_num, ln_num_rscale);
   10914             : 
   10915             :     /* Divide and round to the required scale */
   10916         162 :     div_var_fast(&ln_num, &ln_base, result, rscale, true);
   10917             : 
   10918         156 :     free_var(&ln_num);
   10919         156 :     free_var(&ln_base);
   10920         156 : }
   10921             : 
   10922             : 
   10923             : /*
   10924             :  * power_var() -
   10925             :  *
   10926             :  *  Raise base to the power of exp
   10927             :  *
   10928             :  *  Note: this routine chooses dscale of the result.
   10929             :  */
   10930             : static void
   10931        1386 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
   10932             : {
   10933             :     int         res_sign;
   10934             :     NumericVar  abs_base;
   10935             :     NumericVar  ln_base;
   10936             :     NumericVar  ln_num;
   10937             :     int         ln_dweight;
   10938             :     int         rscale;
   10939             :     int         sig_digits;
   10940             :     int         local_rscale;
   10941             :     double      val;
   10942             : 
   10943             :     /* If exp can be represented as an integer, use power_var_int */
   10944        1386 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
   10945             :     {
   10946             :         /* exact integer, but does it fit in int? */
   10947             :         int64       expval64;
   10948             : 
   10949        1260 :         if (numericvar_to_int64(exp, &expval64))
   10950             :         {
   10951        1254 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
   10952             :             {
   10953             :                 /* Okay, use power_var_int */
   10954        1224 :                 power_var_int(base, (int) expval64, exp->dscale, result);
   10955        1212 :                 return;
   10956             :             }
   10957             :         }
   10958             :     }
   10959             : 
   10960             :     /*
   10961             :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
   10962             :      * handled by power_var_int().
   10963             :      */
   10964         162 :     if (cmp_var(base, &const_zero) == 0)
   10965             :     {
   10966          18 :         set_var_from_var(&const_zero, result);
   10967          18 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
   10968          18 :         return;
   10969             :     }
   10970             : 
   10971         144 :     init_var(&abs_base);
   10972         144 :     init_var(&ln_base);
   10973         144 :     init_var(&ln_num);
   10974             : 
   10975             :     /*
   10976             :      * If base is negative, insist that exp be an integer.  The result is then
   10977             :      * positive if exp is even and negative if exp is odd.
   10978             :      */
   10979         144 :     if (base->sign == NUMERIC_NEG)
   10980             :     {
   10981             :         /*
   10982             :          * Check that exp is an integer.  This error code is defined by the
   10983             :          * SQL standard, and matches other errors in numeric_power().
   10984             :          */
   10985          36 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
   10986          18 :             ereport(ERROR,
   10987             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
   10988             :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
   10989             : 
   10990             :         /* Test if exp is odd or even */
   10991          18 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
   10992          12 :             (exp->digits[exp->ndigits - 1] & 1))
   10993           6 :             res_sign = NUMERIC_NEG;
   10994             :         else
   10995          12 :             res_sign = NUMERIC_POS;
   10996             : 
   10997             :         /* Then work with abs(base) below */
   10998          18 :         set_var_from_var(base, &abs_base);
   10999          18 :         abs_base.sign = NUMERIC_POS;
   11000          18 :         base = &abs_base;
   11001             :     }
   11002             :     else
   11003         108 :         res_sign = NUMERIC_POS;
   11004             : 
   11005             :     /*----------
   11006             :      * Decide on the scale for the ln() calculation.  For this we need an
   11007             :      * estimate of the weight of the result, which we obtain by doing an
   11008             :      * initial low-precision calculation of exp * ln(base).
   11009             :      *
   11010             :      * We want result = e ^ (exp * ln(base))
   11011             :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
   11012             :      *
   11013             :      * We also perform a crude overflow test here so that we can exit early if
   11014             :      * the full-precision result is sure to overflow, and to guard against
   11015             :      * integer overflow when determining the scale for the real calculation.
   11016             :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
   11017             :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
   11018             :      * Since the values here are only approximations, we apply a small fuzz
   11019             :      * factor to this overflow test and let exp_var() determine the exact
   11020             :      * overflow threshold so that it is consistent for all inputs.
   11021             :      *----------
   11022             :      */
   11023         126 :     ln_dweight = estimate_ln_dweight(base);
   11024             : 
   11025             :     /*
   11026             :      * Set the scale for the low-precision calculation, computing ln(base) to
   11027             :      * around 8 significant digits.  Note that ln_dweight may be as small as
   11028             :      * -SHRT_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE here.
   11029             :      */
   11030         126 :     local_rscale = 8 - ln_dweight;
   11031         126 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11032             : 
   11033         126 :     ln_var(base, &ln_base, local_rscale);
   11034             : 
   11035         126 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11036             : 
   11037         126 :     val = numericvar_to_double_no_overflow(&ln_num);
   11038             : 
   11039             :     /* initial overflow/underflow test with fuzz factor */
   11040         126 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
   11041             :     {
   11042           6 :         if (val > 0)
   11043           0 :             ereport(ERROR,
   11044             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11045             :                      errmsg("value overflows numeric format")));
   11046           6 :         zero_var(result);
   11047           6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11048           6 :         return;
   11049             :     }
   11050             : 
   11051         120 :     val *= 0.434294481903252;   /* approximate decimal result weight */
   11052             : 
   11053             :     /* choose the result scale */
   11054         120 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
   11055         120 :     rscale = Max(rscale, base->dscale);
   11056         120 :     rscale = Max(rscale, exp->dscale);
   11057         120 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11058         120 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11059             : 
   11060             :     /* significant digits required in the result */
   11061         120 :     sig_digits = rscale + (int) val;
   11062         120 :     sig_digits = Max(sig_digits, 0);
   11063             : 
   11064             :     /* set the scale for the real exp * ln(base) calculation */
   11065         120 :     local_rscale = sig_digits - ln_dweight + 8;
   11066         120 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11067             : 
   11068             :     /* and do the real calculation */
   11069             : 
   11070         120 :     ln_var(base, &ln_base, local_rscale);
   11071             : 
   11072         120 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
   11073             : 
   11074         120 :     exp_var(&ln_num, result, rscale);
   11075             : 
   11076         120 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
   11077           6 :         result->sign = NUMERIC_NEG;
   11078             : 
   11079         120 :     free_var(&ln_num);
   11080         120 :     free_var(&ln_base);
   11081         120 :     free_var(&abs_base);
   11082             : }
   11083             : 
   11084             : /*
   11085             :  * power_var_int() -
   11086             :  *
   11087             :  *  Raise base to the power of exp, where exp is an integer.
   11088             :  *
   11089             :  *  Note: this routine chooses dscale of the result.
   11090             :  */
   11091             : static void
   11092        1224 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
   11093             :               NumericVar *result)
   11094             : {
   11095             :     double      f;
   11096             :     int         p;
   11097             :     int         i;
   11098             :     int         rscale;
   11099             :     int         sig_digits;
   11100             :     unsigned int mask;
   11101             :     bool        neg;
   11102             :     NumericVar  base_prod;
   11103             :     int         local_rscale;
   11104             : 
   11105             :     /*
   11106             :      * Choose the result scale.  For this we need an estimate of the decimal
   11107             :      * weight of the result, which we obtain by approximating using double
   11108             :      * precision arithmetic.
   11109             :      *
   11110             :      * We also perform crude overflow/underflow tests here so that we can exit
   11111             :      * early if the result is sure to overflow/underflow, and to guard against
   11112             :      * integer overflow when choosing the result scale.
   11113             :      */
   11114        1224 :     if (base->ndigits != 0)
   11115             :     {
   11116             :         /*----------
   11117             :          * Choose f (double) and p (int) such that base ~= f * 10^p.
   11118             :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
   11119             :          *----------
   11120             :          */
   11121        1194 :         f = base->digits[0];
   11122        1194 :         p = base->weight * DEC_DIGITS;
   11123             : 
   11124        1278 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
   11125             :         {
   11126          84 :             f = f * NBASE + base->digits[i];
   11127          84 :             p -= DEC_DIGITS;
   11128             :         }
   11129             : 
   11130        1194 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
   11131             :     }
   11132             :     else
   11133          30 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
   11134             : 
   11135             :     /* overflow/underflow tests with fuzz factors */
   11136        1224 :     if (f > (SHRT_MAX + 1) * DEC_DIGITS)
   11137          12 :         ereport(ERROR,
   11138             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11139             :                  errmsg("value overflows numeric format")));
   11140        1212 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
   11141             :     {
   11142          12 :         zero_var(result);
   11143          12 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
   11144         210 :         return;
   11145             :     }
   11146             : 
   11147             :     /*
   11148             :      * Choose the result scale in the same way as power_var(), so it has at
   11149             :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
   11150             :      * either input's display scale.
   11151             :      */
   11152        1200 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
   11153        1200 :     rscale = Max(rscale, base->dscale);
   11154        1200 :     rscale = Max(rscale, exp_dscale);
   11155        1200 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11156        1200 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
   11157             : 
   11158             :     /* Handle some common special cases, as well as corner cases */
   11159        1200 :     switch (exp)
   11160             :     {
   11161          72 :         case 0:
   11162             : 
   11163             :             /*
   11164             :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
   11165             :              * it as 1 because most programming languages do this. SQL:2003
   11166             :              * also requires a return value of 1.
   11167             :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
   11168             :              */
   11169          72 :             set_var_from_var(&const_one, result);
   11170          72 :             result->dscale = rscale; /* no need to round */
   11171          72 :             return;
   11172          48 :         case 1:
   11173          48 :             set_var_from_var(base, result);
   11174          48 :             round_var(result, rscale);
   11175          48 :             return;
   11176          30 :         case -1:
   11177          30 :             div_var(&const_one, base, result, rscale, true);
   11178          30 :             return;
   11179          48 :         case 2:
   11180          48 :             mul_var(base, base, result, rscale);
   11181          48 :             return;
   11182        1002 :         default:
   11183        1002 :             break;
   11184             :     }
   11185             : 
   11186             :     /* Handle the special case where the base is zero */
   11187        1002 :     if (base->ndigits == 0)
   11188             :     {
   11189           0 :         if (exp < 0)
   11190           0 :             ereport(ERROR,
   11191             :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
   11192             :                      errmsg("division by zero")));
   11193           0 :         zero_var(result);
   11194           0 :         result->dscale = rscale;
   11195           0 :         return;
   11196             :     }
   11197             : 
   11198             :     /*
   11199             :      * The general case repeatedly multiplies base according to the bit
   11200             :      * pattern of exp.
   11201             :      *
   11202             :      * The local rscale used for each multiplication is varied to keep a fixed
   11203             :      * number of significant digits, sufficient to give the required result
   11204             :      * scale.
   11205             :      */
   11206             : 
   11207             :     /*
   11208             :      * Approximate number of significant digits in the result.  Note that the
   11209             :      * underflow test above, together with the choice of rscale, ensures that
   11210             :      * this approximation is necessarily > 0.
   11211             :      */
   11212        1002 :     sig_digits = 1 + rscale + (int) f;
   11213             : 
   11214             :     /*
   11215             :      * The multiplications to produce the result may introduce an error of up
   11216             :      * to around log10(abs(exp)) digits, so work with this many extra digits
   11217             :      * of precision (plus a few more for good measure).
   11218             :      */
   11219        1002 :     sig_digits += (int) log(fabs((double) exp)) + 8;
   11220             : 
   11221             :     /*
   11222             :      * Now we can proceed with the multiplications.
   11223             :      */
   11224        1002 :     neg = (exp < 0);
   11225        1002 :     mask = abs(exp);
   11226             : 
   11227        1002 :     init_var(&base_prod);
   11228        1002 :     set_var_from_var(base, &base_prod);
   11229             : 
   11230        1002 :     if (mask & 1)
   11231         498 :         set_var_from_var(base, result);
   11232             :     else
   11233         504 :         set_var_from_var(&const_one, result);
   11234             : 
   11235        5064 :     while ((mask >>= 1) > 0)
   11236             :     {
   11237             :         /*
   11238             :          * Do the multiplications using rscales large enough to hold the
   11239             :          * results to the required number of significant digits, but don't
   11240             :          * waste time by exceeding the scales of the numbers themselves.
   11241             :          */
   11242        4062 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
   11243        4062 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
   11244        4062 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11245             : 
   11246        4062 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
   11247             : 
   11248        4062 :         if (mask & 1)
   11249             :         {
   11250        2652 :             local_rscale = sig_digits -
   11251        2652 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
   11252        2652 :             local_rscale = Min(local_rscale,
   11253             :                                base_prod.dscale + result->dscale);
   11254        2652 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
   11255             : 
   11256        2652 :             mul_var(&base_prod, result, result, local_rscale);
   11257             :         }
   11258             : 
   11259             :         /*
   11260             :          * When abs(base) > 1, the number of digits to the left of the decimal
   11261             :          * point in base_prod doubles at each iteration, so if exp is large we
   11262             :          * could easily spend large amounts of time and memory space doing the
   11263             :          * multiplications.  But once the weight exceeds what will fit in
   11264             :          * int16, the final result is guaranteed to overflow (or underflow, if
   11265             :          * exp < 0), so we can give up before wasting too many cycles.
   11266             :          */
   11267        4062 :         if (base_prod.weight > SHRT_MAX || result->weight > SHRT_MAX)
   11268             :         {
   11269             :             /* overflow, unless neg, in which case result should be 0 */
   11270           0 :             if (!neg)
   11271           0 :                 ereport(ERROR,
   11272             :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
   11273             :                          errmsg("value overflows numeric format")));
   11274           0 :             zero_var(result);
   11275           0 :             neg = false;
   11276           0 :             break;
   11277             :         }
   11278             :     }
   11279             : 
   11280        1002 :     free_var(&base_prod);
   11281             : 
   11282             :     /* Compensate for input sign, and round to requested rscale */
   11283        1002 :     if (neg)
   11284         480 :         div_var_fast(&const_one, result, result, rscale, true);
   11285             :     else
   11286         522 :         round_var(result, rscale);
   11287             : }
   11288             : 
   11289             : /*
   11290             :  * power_ten_int() -
   11291             :  *
   11292             :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
   11293             :  *  power_var_int(), this does no overflow/underflow checking or rounding.
   11294             :  */
   11295             : static void
   11296         216 : power_ten_int(int exp, NumericVar *result)
   11297             : {
   11298             :     /* Construct the result directly, starting from 10^0 = 1 */
   11299         216 :     set_var_from_var(&const_one, result);
   11300             : 
   11301             :     /* Scale needed to represent the result exactly */
   11302         216 :     result->dscale = exp < 0 ? -exp : 0;
   11303             : 
   11304             :     /* Base-NBASE weight of result and remaining exponent */
   11305         216 :     if (exp >= 0)
   11306         150 :         result->weight = exp / DEC_DIGITS;
   11307             :     else
   11308          66 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
   11309             : 
   11310         216 :     exp -= result->weight * DEC_DIGITS;
   11311             : 
   11312             :     /* Final adjustment of the result's single NBASE digit */
   11313         546 :     while (exp-- > 0)
   11314         330 :         result->digits[0] *= 10;
   11315         216 : }
   11316             : 
   11317             : /*
   11318             :  * random_var() - return a random value in the range [rmin, rmax].
   11319             :  */
   11320             : static void
   11321       33438 : random_var(pg_prng_state *state, const NumericVar *rmin,
   11322             :            const NumericVar *rmax, NumericVar *result)
   11323             : {
   11324             :     int         rscale;
   11325             :     NumericVar  rlen;
   11326             :     int         res_ndigits;
   11327             :     int         n;
   11328             :     int         pow10;
   11329             :     int         i;
   11330             :     uint64      rlen64;
   11331             :     int         rlen64_ndigits;
   11332             : 
   11333       33438 :     rscale = Max(rmin->dscale, rmax->dscale);
   11334             : 
   11335             :     /* Compute rlen = rmax - rmin and check the range bounds */
   11336       33438 :     init_var(&rlen);
   11337       33438 :     sub_var(rmax, rmin, &rlen);
   11338             : 
   11339       33438 :     if (rlen.sign == NUMERIC_NEG)
   11340           6 :         ereport(ERROR,
   11341             :                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
   11342             :                 errmsg("lower bound must be less than or equal to upper bound"));
   11343             : 
   11344             :     /* Special case for an empty range */
   11345       33432 :     if (rlen.ndigits == 0)
   11346             :     {
   11347          12 :         set_var_from_var(rmin, result);
   11348          12 :         result->dscale = rscale;
   11349          12 :         free_var(&rlen);
   11350          12 :         return;
   11351             :     }
   11352             : 
   11353             :     /*
   11354             :      * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
   11355             :      * and shift it to the required range by adding rmin.
   11356             :      */
   11357             : 
   11358             :     /* Required result digits */
   11359       33420 :     res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
   11360             : 
   11361             :     /*
   11362             :      * To get the required rscale, the final result digit must be a multiple
   11363             :      * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
   11364             :      */
   11365       33420 :     n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
   11366       33420 :     pow10 = 1;
   11367       87900 :     for (i = 0; i < n; i++)
   11368       54480 :         pow10 *= 10;
   11369             : 
   11370             :     /*
   11371             :      * To choose a random value uniformly from the range [0, rlen], we choose
   11372             :      * from the slightly larger range [0, rlen2], where rlen2 is formed from
   11373             :      * rlen by copying the first 4 NBASE digits, and setting all remaining
   11374             :      * decimal digits to "9".
   11375             :      *
   11376             :      * Without loss of generality, we can ignore the weight of rlen2 and treat
   11377             :      * it as a pure integer for the purposes of this discussion.  The process
   11378             :      * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
   11379             :      * is a 64-bit integer formed from the first 4 NBASE digits copied from
   11380             :      * rlen.  Since this trivially factors into smaller pieces that fit in
   11381             :      * 64-bit integers, the task of choosing a random value uniformly from the
   11382             :      * rlen2 + 1 possible values in [0, rlen2] is much simpler.
   11383             :      *
   11384             :      * If the random value selected is too large, it is rejected, and we try
   11385             :      * again until we get a result <= rlen, ensuring that the overall result
   11386             :      * is uniform (no particular value is any more likely than any other).
   11387             :      *
   11388             :      * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
   11389             :      * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
   11390             :      * when DEC_DIGITS is 4). Therefore the probability of needing to reject
   11391             :      * the value chosen and retry is less than 1e-13.
   11392             :      */
   11393       33420 :     rlen64 = (uint64) rlen.digits[0];
   11394       33420 :     rlen64_ndigits = 1;
   11395       76212 :     while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
   11396             :     {
   11397       42792 :         rlen64 *= NBASE;
   11398       42792 :         if (rlen64_ndigits < rlen.ndigits)
   11399        6612 :             rlen64 += rlen.digits[rlen64_ndigits];
   11400       42792 :         rlen64_ndigits++;
   11401             :     }
   11402             : 
   11403             :     /* Loop until we get a result <= rlen */
   11404             :     do
   11405             :     {
   11406             :         NumericDigit *res_digits;
   11407             :         uint64      rand;
   11408             :         int         whole_ndigits;
   11409             : 
   11410       33420 :         alloc_var(result, res_ndigits);
   11411       33420 :         result->sign = NUMERIC_POS;
   11412       33420 :         result->weight = rlen.weight;
   11413       33420 :         result->dscale = rscale;
   11414       33420 :         res_digits = result->digits;
   11415             : 
   11416             :         /*
   11417             :          * Set the first rlen64_ndigits using a random value in [0, rlen64].
   11418             :          *
   11419             :          * If this is the whole result, and rscale is not a multiple of
   11420             :          * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
   11421             :          * multiple of pow10.
   11422             :          */
   11423       33420 :         if (rlen64_ndigits == res_ndigits && pow10 != 1)
   11424       21132 :             rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
   11425             :         else
   11426       12288 :             rand = pg_prng_uint64_range(state, 0, rlen64);
   11427             : 
   11428      109632 :         for (i = rlen64_ndigits - 1; i >= 0; i--)
   11429             :         {
   11430       76212 :             res_digits[i] = (NumericDigit) (rand % NBASE);
   11431       76212 :             rand = rand / NBASE;
   11432             :         }
   11433             : 
   11434             :         /*
   11435             :          * Set the remaining digits to random values in range [0, NBASE),
   11436             :          * noting that the last digit needs to be a multiple of pow10.
   11437             :          */
   11438       33420 :         whole_ndigits = res_ndigits;
   11439       33420 :         if (pow10 != 1)
   11440       33210 :             whole_ndigits--;
   11441             : 
   11442             :         /* Set whole digits in groups of 4 for best performance */
   11443       33420 :         i = rlen64_ndigits;
   11444       33480 :         while (i < whole_ndigits - 3)
   11445             :         {
   11446          60 :             rand = pg_prng_uint64_range(state, 0,
   11447             :                                         (uint64) NBASE * NBASE * NBASE * NBASE - 1);
   11448          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11449          60 :             rand = rand / NBASE;
   11450          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11451          60 :             rand = rand / NBASE;
   11452          60 :             res_digits[i++] = (NumericDigit) (rand % NBASE);
   11453          60 :             rand = rand / NBASE;
   11454          60 :             res_digits[i++] = (NumericDigit) rand;
   11455             :         }
   11456             : 
   11457             :         /* Remaining whole digits */
   11458       33630 :         while (i < whole_ndigits)
   11459             :         {
   11460         210 :             rand = pg_prng_uint64_range(state, 0, NBASE - 1);
   11461         210 :             res_digits[i++] = (NumericDigit) rand;
   11462             :         }
   11463             : 
   11464             :         /* Final partial digit (multiple of pow10) */
   11465       33420 :         if (i < res_ndigits)
   11466             :         {
   11467       12078 :             rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
   11468       12078 :             res_digits[i] = (NumericDigit) rand;
   11469             :         }
   11470             : 
   11471             :         /* Remove leading/trailing zeroes */
   11472       33420 :         strip_var(result);
   11473             : 
   11474             :         /* If result > rlen, try again */
   11475             : 
   11476       33420 :     } while (cmp_var(result, &rlen) > 0);
   11477             : 
   11478             :     /* Offset the result to the required range */
   11479       33420 :     add_var(result, rmin, result);
   11480             : 
   11481       33420 :     free_var(&rlen);
   11482             : }
   11483             : 
   11484             : 
   11485             : /* ----------------------------------------------------------------------
   11486             :  *
   11487             :  * Following are the lowest level functions that operate unsigned
   11488             :  * on the variable level
   11489             :  *
   11490             :  * ----------------------------------------------------------------------
   11491             :  */
   11492             : 
   11493             : 
   11494             : /* ----------
   11495             :  * cmp_abs() -
   11496             :  *
   11497             :  *  Compare the absolute values of var1 and var2
   11498             :  *  Returns:    -1 for ABS(var1) < ABS(var2)
   11499             :  *              0  for ABS(var1) == ABS(var2)
   11500             :  *              1  for ABS(var1) > ABS(var2)
   11501             :  * ----------
   11502             :  */
   11503             : static int
   11504      361112 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
   11505             : {
   11506      722224 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
   11507      361112 :                           var2->digits, var2->ndigits, var2->weight);
   11508             : }
   11509             : 
   11510             : /* ----------
   11511             :  * cmp_abs_common() -
   11512             :  *
   11513             :  *  Main routine of cmp_abs(). This function can be used by both
   11514             :  *  NumericVar and Numeric.
   11515             :  * ----------
   11516             :  */
   11517             : static int
   11518     6231830 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
   11519             :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
   11520             : {
   11521     6231830 :     int         i1 = 0;
   11522     6231830 :     int         i2 = 0;
   11523             : 
   11524             :     /* Check any digits before the first common digit */
   11525             : 
   11526     6231830 :     while (var1weight > var2weight && i1 < var1ndigits)
   11527             :     {
   11528       30008 :         if (var1digits[i1++] != 0)
   11529       30008 :             return 1;
   11530           0 :         var1weight--;
   11531             :     }
   11532     6201822 :     while (var2weight > var1weight && i2 < var2ndigits)
   11533             :     {
   11534       32872 :         if (var2digits[i2++] != 0)
   11535       32872 :             return -1;
   11536           0 :         var2weight--;
   11537             :     }
   11538             : 
   11539             :     /* At this point, either w1 == w2 or we've run out of digits */
   11540             : 
   11541     6168950 :     if (var1weight == var2weight)
   11542             :     {
   11543    11499922 :         while (i1 < var1ndigits && i2 < var2ndigits)
   11544             :         {
   11545     7756264 :             int         stat = var1digits[i1++] - var2digits[i2++];
   11546             : 
   11547     7756264 :             if (stat)
   11548             :             {
   11549     2418904 :                 if (stat > 0)
   11550     1607210 :                     return 1;
   11551      811694 :                 return -1;
   11552             :             }
   11553             :         }
   11554             :     }
   11555             : 
   11556             :     /*
   11557             :      * At this point, we've run out of digits on one side or the other; so any
   11558             :      * remaining nonzero digits imply that side is larger
   11559             :      */
   11560     3750346 :     while (i1 < var1ndigits)
   11561             :     {
   11562        8362 :         if (var1digits[i1++] != 0)
   11563        8062 :             return 1;
   11564             :     }
   11565     3742164 :     while (i2 < var2ndigits)
   11566             :     {
   11567         994 :         if (var2digits[i2++] != 0)
   11568         814 :             return -1;
   11569             :     }
   11570             : 
   11571     3741170 :     return 0;
   11572             : }
   11573             : 
   11574             : 
   11575             : /*
   11576             :  * add_abs() -
   11577             :  *
   11578             :  *  Add the absolute values of two variables into result.
   11579             :  *  result might point to one of the operands without danger.
   11580             :  */
   11581             : static void
   11582      330724 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11583             : {
   11584             :     NumericDigit *res_buf;
   11585             :     NumericDigit *res_digits;
   11586             :     int         res_ndigits;
   11587             :     int         res_weight;
   11588             :     int         res_rscale,
   11589             :                 rscale1,
   11590             :                 rscale2;
   11591             :     int         res_dscale;
   11592             :     int         i,
   11593             :                 i1,
   11594             :                 i2;
   11595      330724 :     int         carry = 0;
   11596             : 
   11597             :     /* copy these values into local vars for speed in inner loop */
   11598      330724 :     int         var1ndigits = var1->ndigits;
   11599      330724 :     int         var2ndigits = var2->ndigits;
   11600      330724 :     NumericDigit *var1digits = var1->digits;
   11601      330724 :     NumericDigit *var2digits = var2->digits;
   11602             : 
   11603      330724 :     res_weight = Max(var1->weight, var2->weight) + 1;
   11604             : 
   11605      330724 :     res_dscale = Max(var1->dscale, var2->dscale);
   11606             : 
   11607             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11608      330724 :     rscale1 = var1->ndigits - var1->weight - 1;
   11609      330724 :     rscale2 = var2->ndigits - var2->weight - 1;
   11610      330724 :     res_rscale = Max(rscale1, rscale2);
   11611             : 
   11612      330724 :     res_ndigits = res_rscale + res_weight + 1;
   11613      330724 :     if (res_ndigits <= 0)
   11614           0 :         res_ndigits = 1;
   11615             : 
   11616      330724 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11617      330724 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11618      330724 :     res_digits = res_buf + 1;
   11619             : 
   11620      330724 :     i1 = res_rscale + var1->weight + 1;
   11621      330724 :     i2 = res_rscale + var2->weight + 1;
   11622     3318722 :     for (i = res_ndigits - 1; i >= 0; i--)
   11623             :     {
   11624     2987998 :         i1--;
   11625     2987998 :         i2--;
   11626     2987998 :         if (i1 >= 0 && i1 < var1ndigits)
   11627     1320378 :             carry += var1digits[i1];
   11628     2987998 :         if (i2 >= 0 && i2 < var2ndigits)
   11629     1038746 :             carry += var2digits[i2];
   11630             : 
   11631     2987998 :         if (carry >= NBASE)
   11632             :         {
   11633      234364 :             res_digits[i] = carry - NBASE;
   11634      234364 :             carry = 1;
   11635             :         }
   11636             :         else
   11637             :         {
   11638     2753634 :             res_digits[i] = carry;
   11639     2753634 :             carry = 0;
   11640             :         }
   11641             :     }
   11642             : 
   11643             :     Assert(carry == 0);         /* else we failed to allow for carry out */
   11644             : 
   11645      330724 :     digitbuf_free(result->buf);
   11646      330724 :     result->ndigits = res_ndigits;
   11647      330724 :     result->buf = res_buf;
   11648      330724 :     result->digits = res_digits;
   11649      330724 :     result->weight = res_weight;
   11650      330724 :     result->dscale = res_dscale;
   11651             : 
   11652             :     /* Remove leading/trailing zeroes */
   11653      330724 :     strip_var(result);
   11654      330724 : }
   11655             : 
   11656             : 
   11657             : /*
   11658             :  * sub_abs()
   11659             :  *
   11660             :  *  Subtract the absolute value of var2 from the absolute value of var1
   11661             :  *  and store in result. result might point to one of the operands
   11662             :  *  without danger.
   11663             :  *
   11664             :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
   11665             :  */
   11666             : static void
   11667      325320 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
   11668             : {
   11669             :     NumericDigit *res_buf;
   11670             :     NumericDigit *res_digits;
   11671             :     int         res_ndigits;
   11672             :     int         res_weight;
   11673             :     int         res_rscale,
   11674             :                 rscale1,
   11675             :                 rscale2;
   11676             :     int         res_dscale;
   11677             :     int         i,
   11678             :                 i1,
   11679             :                 i2;
   11680      325320 :     int         borrow = 0;
   11681             : 
   11682             :     /* copy these values into local vars for speed in inner loop */
   11683      325320 :     int         var1ndigits = var1->ndigits;
   11684      325320 :     int         var2ndigits = var2->ndigits;
   11685      325320 :     NumericDigit *var1digits = var1->digits;
   11686      325320 :     NumericDigit *var2digits = var2->digits;
   11687             : 
   11688      325320 :     res_weight = var1->weight;
   11689             : 
   11690      325320 :     res_dscale = Max(var1->dscale, var2->dscale);
   11691             : 
   11692             :     /* Note: here we are figuring rscale in base-NBASE digits */
   11693      325320 :     rscale1 = var1->ndigits - var1->weight - 1;
   11694      325320 :     rscale2 = var2->ndigits - var2->weight - 1;
   11695      325320 :     res_rscale = Max(rscale1, rscale2);
   11696             : 
   11697      325320 :     res_ndigits = res_rscale + res_weight + 1;
   11698      325320 :     if (res_ndigits <= 0)
   11699           0 :         res_ndigits = 1;
   11700             : 
   11701      325320 :     res_buf = digitbuf_alloc(res_ndigits + 1);
   11702      325320 :     res_buf[0] = 0;             /* spare digit for later rounding */
   11703      325320 :     res_digits = res_buf + 1;
   11704             : 
   11705      325320 :     i1 = res_rscale + var1->weight + 1;
   11706      325320 :     i2 = res_rscale + var2->weight + 1;
   11707     4521370 :     for (i = res_ndigits - 1; i >= 0; i--)
   11708             :     {
   11709     4196050 :         i1--;
   11710     4196050 :         i2--;
   11711     4196050 :         if (i1 >= 0 && i1 < var1ndigits)
   11712     3823386 :             borrow += var1digits[i1];
   11713     4196050 :         if (i2 >= 0 && i2 < var2ndigits)
   11714     3723276 :             borrow -= var2digits[i2];
   11715             : 
   11716     4196050 :         if (borrow < 0)
   11717             :         {
   11718      423478 :             res_digits[i] = borrow + NBASE;
   11719      423478 :             borrow = -1;
   11720             :         }
   11721             :         else
   11722             :         {
   11723     3772572 :             res_digits[i] = borrow;
   11724     3772572 :             borrow = 0;
   11725             :         }
   11726             :     }
   11727             : 
   11728             :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
   11729             : 
   11730      325320 :     digitbuf_free(result->buf);
   11731      325320 :     result->ndigits = res_ndigits;
   11732      325320 :     result->buf = res_buf;
   11733      325320 :     result->digits = res_digits;
   11734      325320 :     result->weight = res_weight;
   11735      325320 :     result->dscale = res_dscale;
   11736             : 
   11737             :     /* Remove leading/trailing zeroes */
   11738      325320 :     strip_var(result);
   11739      325320 : }
   11740             : 
   11741             : /*
   11742             :  * round_var
   11743             :  *
   11744             :  * Round the value of a variable to no more than rscale decimal digits
   11745             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11746             :  * rounding before the decimal point.
   11747             :  */
   11748             : static void
   11749     1028938 : round_var(NumericVar *var, int rscale)
   11750             : {
   11751     1028938 :     NumericDigit *digits = var->digits;
   11752             :     int         di;
   11753             :     int         ndigits;
   11754             :     int         carry;
   11755             : 
   11756     1028938 :     var->dscale = rscale;
   11757             : 
   11758             :     /* decimal digits wanted */
   11759     1028938 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11760             : 
   11761             :     /*
   11762             :      * If di = 0, the value loses all digits, but could round up to 1 if its
   11763             :      * first extra digit is >= 5.  If di < 0 the result must be 0.
   11764             :      */
   11765     1028938 :     if (di < 0)
   11766             :     {
   11767          74 :         var->ndigits = 0;
   11768          74 :         var->weight = 0;
   11769          74 :         var->sign = NUMERIC_POS;
   11770             :     }
   11771             :     else
   11772             :     {
   11773             :         /* NBASE digits wanted */
   11774     1028864 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11775             : 
   11776             :         /* 0, or number of decimal digits to keep in last NBASE digit */
   11777     1028864 :         di %= DEC_DIGITS;
   11778             : 
   11779     1028864 :         if (ndigits < var->ndigits ||
   11780      825510 :             (ndigits == var->ndigits && di > 0))
   11781             :         {
   11782      690146 :             var->ndigits = ndigits;
   11783             : 
   11784             : #if DEC_DIGITS == 1
   11785             :             /* di must be zero */
   11786             :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11787             : #else
   11788      690146 :             if (di == 0)
   11789      164782 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
   11790             :             else
   11791             :             {
   11792             :                 /* Must round within last NBASE digit */
   11793             :                 int         extra,
   11794             :                             pow10;
   11795             : 
   11796             : #if DEC_DIGITS == 4
   11797      525364 :                 pow10 = round_powers[di];
   11798             : #elif DEC_DIGITS == 2
   11799             :                 pow10 = 10;
   11800             : #else
   11801             : #error unsupported NBASE
   11802             : #endif
   11803      525364 :                 extra = digits[--ndigits] % pow10;
   11804      525364 :                 digits[ndigits] -= extra;
   11805      525364 :                 carry = 0;
   11806      525364 :                 if (extra >= pow10 / 2)
   11807             :                 {
   11808       19474 :                     pow10 += digits[ndigits];
   11809       19474 :                     if (pow10 >= NBASE)
   11810             :                     {
   11811         812 :                         pow10 -= NBASE;
   11812         812 :                         carry = 1;
   11813             :                     }
   11814       19474 :                     digits[ndigits] = pow10;
   11815             :                 }
   11816             :             }
   11817             : #endif
   11818             : 
   11819             :             /* Propagate carry if needed */
   11820      725526 :             while (carry)
   11821             :             {
   11822       35380 :                 carry += digits[--ndigits];
   11823       35380 :                 if (carry >= NBASE)
   11824             :                 {
   11825       24774 :                     digits[ndigits] = carry - NBASE;
   11826       24774 :                     carry = 1;
   11827             :                 }
   11828             :                 else
   11829             :                 {
   11830       10606 :                     digits[ndigits] = carry;
   11831       10606 :                     carry = 0;
   11832             :                 }
   11833             :             }
   11834             : 
   11835      690146 :             if (ndigits < 0)
   11836             :             {
   11837             :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
   11838             :                 Assert(var->digits > var->buf);
   11839          90 :                 var->digits--;
   11840          90 :                 var->ndigits++;
   11841          90 :                 var->weight++;
   11842             :             }
   11843             :         }
   11844             :     }
   11845     1028938 : }
   11846             : 
   11847             : /*
   11848             :  * trunc_var
   11849             :  *
   11850             :  * Truncate (towards zero) the value of a variable at rscale decimal digits
   11851             :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
   11852             :  * truncation before the decimal point.
   11853             :  */
   11854             : static void
   11855       61618 : trunc_var(NumericVar *var, int rscale)
   11856             : {
   11857             :     int         di;
   11858             :     int         ndigits;
   11859             : 
   11860       61618 :     var->dscale = rscale;
   11861             : 
   11862             :     /* decimal digits wanted */
   11863       61618 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
   11864             : 
   11865             :     /*
   11866             :      * If di <= 0, the value loses all digits.
   11867             :      */
   11868       61618 :     if (di <= 0)
   11869             :     {
   11870          54 :         var->ndigits = 0;
   11871          54 :         var->weight = 0;
   11872          54 :         var->sign = NUMERIC_POS;
   11873             :     }
   11874             :     else
   11875             :     {
   11876             :         /* NBASE digits wanted */
   11877       61564 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
   11878             : 
   11879       61564 :         if (ndigits <= var->ndigits)
   11880             :         {
   11881       61294 :             var->ndigits = ndigits;
   11882             : 
   11883             : #if DEC_DIGITS == 1
   11884             :             /* no within-digit stuff to worry about */
   11885             : #else
   11886             :             /* 0, or number of decimal digits to keep in last NBASE digit */
   11887       61294 :             di %= DEC_DIGITS;
   11888             : 
   11889       61294 :             if (di > 0)
   11890             :             {
   11891             :                 /* Must truncate within last NBASE digit */
   11892          82 :                 NumericDigit *digits = var->digits;
   11893             :                 int         extra,
   11894             :                             pow10;
   11895             : 
   11896             : #if DEC_DIGITS == 4
   11897          82 :                 pow10 = round_powers[di];
   11898             : #elif DEC_DIGITS == 2
   11899             :                 pow10 = 10;
   11900             : #else
   11901             : #error unsupported NBASE
   11902             : #endif
   11903          82 :                 extra = digits[--ndigits] % pow10;
   11904          82 :                 digits[ndigits] -= extra;
   11905             :             }
   11906             : #endif
   11907             :         }
   11908             :     }
   11909       61618 : }
   11910             : 
   11911             : /*
   11912             :  * strip_var
   11913             :  *
   11914             :  * Strip any leading and trailing zeroes from a numeric variable
   11915             :  */
   11916             : static void
   11917     2068774 : strip_var(NumericVar *var)
   11918             : {
   11919     2068774 :     NumericDigit *digits = var->digits;
   11920     2068774 :     int         ndigits = var->ndigits;
   11921             : 
   11922             :     /* Strip leading zeroes */
   11923     4729912 :     while (ndigits > 0 && *digits == 0)
   11924             :     {
   11925     2661138 :         digits++;
   11926     2661138 :         var->weight--;
   11927     2661138 :         ndigits--;
   11928             :     }
   11929             : 
   11930             :     /* Strip trailing zeroes */
   11931     2738552 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
   11932      669778 :         ndigits--;
   11933             : 
   11934             :     /* If it's zero, normalize the sign and weight */
   11935     2068774 :     if (ndigits == 0)
   11936             :     {
   11937       28406 :         var->sign = NUMERIC_POS;
   11938       28406 :         var->weight = 0;
   11939             :     }
   11940             : 
   11941     2068774 :     var->digits = digits;
   11942     2068774 :     var->ndigits = ndigits;
   11943     2068774 : }
   11944             : 
   11945             : 
   11946             : /* ----------------------------------------------------------------------
   11947             :  *
   11948             :  * Fast sum accumulator functions
   11949             :  *
   11950             :  * ----------------------------------------------------------------------
   11951             :  */
   11952             : 
   11953             : /*
   11954             :  * Reset the accumulator's value to zero.  The buffers to hold the digits
   11955             :  * are not free'd.
   11956             :  */
   11957             : static void
   11958          18 : accum_sum_reset(NumericSumAccum *accum)
   11959             : {
   11960             :     int         i;
   11961             : 
   11962          18 :     accum->dscale = 0;
   11963          66 :     for (i = 0; i < accum->ndigits; i++)
   11964             :     {
   11965          48 :         accum->pos_digits[i] = 0;
   11966          48 :         accum->neg_digits[i] = 0;
   11967             :     }
   11968          18 : }
   11969             : 
   11970             : /*
   11971             :  * Accumulate a new value.
   11972             :  */
   11973             : static void
   11974     2355656 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
   11975             : {
   11976             :     int32      *accum_digits;
   11977             :     int         i,
   11978             :                 val_i;
   11979             :     int         val_ndigits;
   11980             :     NumericDigit *val_digits;
   11981             : 
   11982             :     /*
   11983             :      * If we have accumulated too many values since the last carry
   11984             :      * propagation, do it now, to avoid overflowing.  (We could allow more
   11985             :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
   11986             :      * carry propagation.  But even with NBASE - 1, this needs to be done so
   11987             :      * seldom, that the performance difference is negligible.)
   11988             :      */
   11989     2355656 :     if (accum->num_uncarried == NBASE - 1)
   11990         180 :         accum_sum_carry(accum);
   11991             : 
   11992             :     /*
   11993             :      * Adjust the weight or scale of the old value, so that it can accommodate
   11994             :      * the new value.
   11995             :      */
   11996     2355656 :     accum_sum_rescale(accum, val);
   11997             : 
   11998             :     /* */
   11999     2355656 :     if (val->sign == NUMERIC_POS)
   12000     1754978 :         accum_digits = accum->pos_digits;
   12001             :     else
   12002      600678 :         accum_digits = accum->neg_digits;
   12003             : 
   12004             :     /* copy these values into local vars for speed in loop */
   12005     2355656 :     val_ndigits = val->ndigits;
   12006     2355656 :     val_digits = val->digits;
   12007             : 
   12008     2355656 :     i = accum->weight - val->weight;
   12009    11889788 :     for (val_i = 0; val_i < val_ndigits; val_i++)
   12010             :     {
   12011     9534132 :         accum_digits[i] += (int32) val_digits[val_i];
   12012     9534132 :         i++;
   12013             :     }
   12014             : 
   12015     2355656 :     accum->num_uncarried++;
   12016     2355656 : }
   12017             : 
   12018             : /*
   12019             :  * Propagate carries.
   12020             :  */
   12021             : static void
   12022      172734 : accum_sum_carry(NumericSumAccum *accum)
   12023             : {
   12024             :     int         i;
   12025             :     int         ndigits;
   12026             :     int32      *dig;
   12027             :     int32       carry;
   12028      172734 :     int32       newdig = 0;
   12029             : 
   12030             :     /*
   12031             :      * If no new values have been added since last carry propagation, nothing
   12032             :      * to do.
   12033             :      */
   12034      172734 :     if (accum->num_uncarried == 0)
   12035          72 :         return;
   12036             : 
   12037             :     /*
   12038             :      * We maintain that the weight of the accumulator is always one larger
   12039             :      * than needed to hold the current value, before carrying, to make sure
   12040             :      * there is enough space for the possible extra digit when carry is
   12041             :      * propagated.  We cannot expand the buffer here, unless we require
   12042             :      * callers of accum_sum_final() to switch to the right memory context.
   12043             :      */
   12044             :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12045             : 
   12046      172662 :     ndigits = accum->ndigits;
   12047             : 
   12048             :     /* Propagate carry in the positive sum */
   12049      172662 :     dig = accum->pos_digits;
   12050      172662 :     carry = 0;
   12051     2605462 :     for (i = ndigits - 1; i >= 0; i--)
   12052             :     {
   12053     2432800 :         newdig = dig[i] + carry;
   12054     2432800 :         if (newdig >= NBASE)
   12055             :         {
   12056      110796 :             carry = newdig / NBASE;
   12057      110796 :             newdig -= carry * NBASE;
   12058             :         }
   12059             :         else
   12060     2322004 :             carry = 0;
   12061     2432800 :         dig[i] = newdig;
   12062             :     }
   12063             :     /* Did we use up the digit reserved for carry propagation? */
   12064      172662 :     if (newdig > 0)
   12065        2626 :         accum->have_carry_space = false;
   12066             : 
   12067             :     /* And the same for the negative sum */
   12068      172662 :     dig = accum->neg_digits;
   12069      172662 :     carry = 0;
   12070     2605462 :     for (i = ndigits - 1; i >= 0; i--)
   12071             :     {
   12072     2432800 :         newdig = dig[i] + carry;
   12073     2432800 :         if (newdig >= NBASE)
   12074             :         {
   12075         198 :             carry = newdig / NBASE;
   12076         198 :             newdig -= carry * NBASE;
   12077             :         }
   12078             :         else
   12079     2432602 :             carry = 0;
   12080     2432800 :         dig[i] = newdig;
   12081             :     }
   12082      172662 :     if (newdig > 0)
   12083          30 :         accum->have_carry_space = false;
   12084             : 
   12085      172662 :     accum->num_uncarried = 0;
   12086             : }
   12087             : 
   12088             : /*
   12089             :  * Re-scale accumulator to accommodate new value.
   12090             :  *
   12091             :  * If the new value has more digits than the current digit buffers in the
   12092             :  * accumulator, enlarge the buffers.
   12093             :  */
   12094             : static void
   12095     2355656 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
   12096             : {
   12097     2355656 :     int         old_weight = accum->weight;
   12098     2355656 :     int         old_ndigits = accum->ndigits;
   12099             :     int         accum_ndigits;
   12100             :     int         accum_weight;
   12101             :     int         accum_rscale;
   12102             :     int         val_rscale;
   12103             : 
   12104     2355656 :     accum_weight = old_weight;
   12105     2355656 :     accum_ndigits = old_ndigits;
   12106             : 
   12107             :     /*
   12108             :      * Does the new value have a larger weight? If so, enlarge the buffers,
   12109             :      * and shift the existing value to the new weight, by adding leading
   12110             :      * zeros.
   12111             :      *
   12112             :      * We enforce that the accumulator always has a weight one larger than
   12113             :      * needed for the inputs, so that we have space for an extra digit at the
   12114             :      * final carry-propagation phase, if necessary.
   12115             :      */
   12116     2355656 :     if (val->weight >= accum_weight)
   12117             :     {
   12118      262176 :         accum_weight = val->weight + 1;
   12119      262176 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
   12120             :     }
   12121             : 
   12122             :     /*
   12123             :      * Even though the new value is small, we might've used up the space
   12124             :      * reserved for the carry digit in the last call to accum_sum_carry().  If
   12125             :      * so, enlarge to make room for another one.
   12126             :      */
   12127     2093480 :     else if (!accum->have_carry_space)
   12128             :     {
   12129          76 :         accum_weight++;
   12130          76 :         accum_ndigits++;
   12131             :     }
   12132             : 
   12133             :     /* Is the new value wider on the right side? */
   12134     2355656 :     accum_rscale = accum_ndigits - accum_weight - 1;
   12135     2355656 :     val_rscale = val->ndigits - val->weight - 1;
   12136     2355656 :     if (val_rscale > accum_rscale)
   12137      172192 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
   12138             : 
   12139     2355656 :     if (accum_ndigits != old_ndigits ||
   12140             :         accum_weight != old_weight)
   12141             :     {
   12142             :         int32      *new_pos_digits;
   12143             :         int32      *new_neg_digits;
   12144             :         int         weightdiff;
   12145             : 
   12146      262514 :         weightdiff = accum_weight - old_weight;
   12147             : 
   12148      262514 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
   12149      262514 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
   12150             : 
   12151      262514 :         if (accum->pos_digits)
   12152             :         {
   12153       90386 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
   12154             :                    old_ndigits * sizeof(int32));
   12155       90386 :             pfree(accum->pos_digits);
   12156             : 
   12157       90386 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
   12158             :                    old_ndigits * sizeof(int32));
   12159       90386 :             pfree(accum->neg_digits);
   12160             :         }
   12161             : 
   12162      262514 :         accum->pos_digits = new_pos_digits;
   12163      262514 :         accum->neg_digits = new_neg_digits;
   12164             : 
   12165      262514 :         accum->weight = accum_weight;
   12166      262514 :         accum->ndigits = accum_ndigits;
   12167             : 
   12168             :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
   12169      262514 :         accum->have_carry_space = true;
   12170             :     }
   12171             : 
   12172     2355656 :     if (val->dscale > accum->dscale)
   12173         300 :         accum->dscale = val->dscale;
   12174     2355656 : }
   12175             : 
   12176             : /*
   12177             :  * Return the current value of the accumulator.  This perform final carry
   12178             :  * propagation, and adds together the positive and negative sums.
   12179             :  *
   12180             :  * Unlike all the other routines, the caller is not required to switch to
   12181             :  * the memory context that holds the accumulator.
   12182             :  */
   12183             : static void
   12184      172554 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
   12185             : {
   12186             :     int         i;
   12187             :     NumericVar  pos_var;
   12188             :     NumericVar  neg_var;
   12189             : 
   12190      172554 :     if (accum->ndigits == 0)
   12191             :     {
   12192           0 :         set_var_from_var(&const_zero, result);
   12193           0 :         return;
   12194             :     }
   12195             : 
   12196             :     /* Perform final carry */
   12197      172554 :     accum_sum_carry(accum);
   12198             : 
   12199             :     /* Create NumericVars representing the positive and negative sums */
   12200      172554 :     init_var(&pos_var);
   12201      172554 :     init_var(&neg_var);
   12202             : 
   12203      172554 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
   12204      172554 :     pos_var.weight = neg_var.weight = accum->weight;
   12205      172554 :     pos_var.dscale = neg_var.dscale = accum->dscale;
   12206      172554 :     pos_var.sign = NUMERIC_POS;
   12207      172554 :     neg_var.sign = NUMERIC_NEG;
   12208             : 
   12209      172554 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
   12210      172554 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
   12211             : 
   12212     2604910 :     for (i = 0; i < accum->ndigits; i++)
   12213             :     {
   12214             :         Assert(accum->pos_digits[i] < NBASE);
   12215     2432356 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
   12216             : 
   12217             :         Assert(accum->neg_digits[i] < NBASE);
   12218     2432356 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
   12219             :     }
   12220             : 
   12221             :     /* And add them together */
   12222      172554 :     add_var(&pos_var, &neg_var, result);
   12223             : 
   12224             :     /* Remove leading/trailing zeroes */
   12225      172554 :     strip_var(result);
   12226             : }
   12227             : 
   12228             : /*
   12229             :  * Copy an accumulator's state.
   12230             :  *
   12231             :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
   12232             :  * freeing old values.
   12233             :  */
   12234             : static void
   12235          42 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
   12236             : {
   12237          42 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
   12238          42 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
   12239             : 
   12240          42 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
   12241          42 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
   12242          42 :     dst->num_uncarried = src->num_uncarried;
   12243          42 :     dst->ndigits = src->ndigits;
   12244          42 :     dst->weight = src->weight;
   12245          42 :     dst->dscale = src->dscale;
   12246          42 : }
   12247             : 
   12248             : /*
   12249             :  * Add the current value of 'accum2' into 'accum'.
   12250             :  */
   12251             : static void
   12252          24 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
   12253             : {
   12254             :     NumericVar  tmp_var;
   12255             : 
   12256          24 :     init_var(&tmp_var);
   12257             : 
   12258          24 :     accum_sum_final(accum2, &tmp_var);
   12259          24 :     accum_sum_add(accum, &tmp_var);
   12260             : 
   12261          24 :     free_var(&tmp_var);
   12262          24 : }

Generated by: LCOV version 1.14