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