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