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

Generated by: LCOV version 1.13