LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - numeric.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 94.0 % 3861 3628 20 65 142 6 74 2224 267 1063 150 2441 3 59
Current Date: 2023-04-08 17:13:01 Functions: 99.5 % 206 205 1 198 7 1 203 2
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 4 4 4
Legend: Lines: hit not hit (60,120] days: 90.8 % 240 218 19 1 2 9 206 3 22
(120,180] days: 97.7 % 44 43 1 43
(180,240] days: 100.0 % 9 9 9
(240..) days: 94.1 % 3564 3354 64 140 6 74 2215 5 1060 148 2219
Function coverage date bins:
(60,120] days: 75.0 % 4 3 3 1
(120,180] days: 100.0 % 4 4 4
(240..) days: 50.5 % 392 198 1 198 1 192

 Age         Owner                  TLA  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
 8335 tgl                       627 GIC       47288 : numeric_in(PG_FUNCTION_ARGS)
                                628                 : {
                                629           47288 :     char       *str = PG_GETARG_CSTRING(0);
                                630                 : #ifdef NOT_USED
                                631                 :     Oid         typelem = PG_GETARG_OID(1);
                                632                 : #endif
                                633           47288 :     int32       typmod = PG_GETARG_INT32(2);
  121 tgl                       634 GNC       47288 :     Node       *escontext = fcinfo->context;
                                635                 :     Numeric     res;
                                636                 :     const char *cp;
                                637                 :     const char *numstart;
                                638                 :     int         sign;
 5114 tgl                       639 ECB             : 
                                640                 :     /* Skip leading spaces */
 5114 tgl                       641 CBC       47288 :     cp = str;
 5114 tgl                       642 GIC       47480 :     while (*cp)
                                643                 :     {
                                644           47474 :         if (!isspace((unsigned char) *cp))
 5114 tgl                       645 CBC       47282 :             break;
                                646             192 :         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                 :      */
   76 dean.a.rasheed            654 GNC       47288 :     numstart = cp;
                                655           47288 :     sign = NUMERIC_POS;
                                656                 : 
                                657           47288 :     if (*cp == '+')
                                658              18 :         cp++;
                                659           47270 :     else if (*cp == '-')
                                660                 :     {
                                661            1727 :         sign = NUMERIC_NEG;
                                662            1727 :         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           47288 :     if (!isdigit((unsigned char) *cp) && *cp != '.')
                                673                 :     {
   76 dean.a.rasheed            674 ECB             :         /*
                                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                 :          */
   76 dean.a.rasheed            678 GNC         722 :         if (pg_strncasecmp(numstart, "NaN", 3) == 0)
                                679                 :         {
                                680             271 :             res = make_result(&const_nan);
                                681             271 :             cp = numstart + 3;
                                682                 :         }
                                683             451 :         else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
                                684                 :         {
                                685             156 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
                                686             156 :             cp += 8;
                                687                 :         }
                                688             295 :         else if (pg_strncasecmp(cp, "inf", 3) == 0)
                                689                 :         {
                                690             264 :             res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
                                691             264 :             cp += 3;
                                692                 :         }
                                693                 :         else
                                694              31 :             goto invalid_syntax;
   76 dean.a.rasheed            695 ECB             : 
                                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                 :          */
   76 dean.a.rasheed            703 GIC         712 :         while (*cp)
   76 dean.a.rasheed            704 ECB             :         {
   76 dean.a.rasheed            705 GIC          21 :             if (!isspace((unsigned char) *cp))
   76 dean.a.rasheed            706 UNC           0 :                 goto invalid_syntax;
   76 dean.a.rasheed            707 GIC          21 :             cp++;
                                708                 :         }
                                709                 : 
   76 dean.a.rasheed            710 GNC         691 :         if (!apply_typmod_special(res, typmod, escontext))
   76 dean.a.rasheed            711 UNC           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                 : 
 5114 tgl                       723 GNC       46566 :         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                 :          */
   76 dean.a.rasheed            729           46566 :         if (cp[0] == '0')
                                730                 :         {
                                731           12837 :             switch (cp[1])
                                732                 :             {
                                733              36 :                 case 'x':
                                734                 :                 case 'X':
                                735              36 :                     base = 16;
                                736              36 :                     break;
                                737              21 :                 case 'o':
                                738                 :                 case 'O':
                                739              21 :                     base = 8;
                                740              21 :                     break;
                                741              21 :                 case 'b':
                                742                 :                 case 'B':
                                743              21 :                     base = 2;
                                744              21 :                     break;
                                745           12759 :                 default:
                                746           12759 :                     base = 10;
                                747                 :             }
                                748                 :         }
                                749                 :         else
                                750           33729 :             base = 10;
                                751                 : 
                                752                 :         /* Parse the rest of the number and apply the sign */
                                753           46566 :         if (base == 10)
                                754                 :         {
                                755           46488 :             if (!set_var_from_str(str, cp, &value, &cp, escontext))
                                756              15 :                 PG_RETURN_NULL();
                                757           46464 :             value.sign = sign;
                                758                 :         }
                                759                 :         else
                                760                 :         {
                                761              78 :             if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
                                762                 :                                                       &value, &cp, escontext))
   76 dean.a.rasheed            763 UNC           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                 :          */
 5114 tgl                       770 GNC       46572 :         while (*cp)
                                771                 :         {
                                772              69 :             if (!isspace((unsigned char) *cp))
   76 dean.a.rasheed            773              30 :                 goto invalid_syntax;
 5114 tgl                       774              39 :             cp++;
                                775                 :         }
                                776                 : 
  121                           777           46503 :         if (!apply_typmod(&value, typmod, escontext))
                                778               6 :             PG_RETURN_NULL();
                                779                 : 
                                780           46497 :         res = make_result_opt_error(&value, &have_error);
                                781                 : 
                                782           46497 :         if (have_error)
                                783               9 :             ereturn(escontext, (Datum) 0,
                                784                 :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                785                 :                      errmsg("value overflows numeric format")));
                                786                 : 
 5114                           787           46488 :         free_var(&value);
                                788                 :     }
                                789                 : 
 8335 tgl                       790 GIC       47179 :     PG_RETURN_NUMERIC(res);
                                791                 : 
   76 dean.a.rasheed            792 GNC          61 : invalid_syntax:
                                793              61 :     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                 : 
 7324 tgl                       800 ECB             : /*
                                801                 :  * numeric_out() -
 8866 JanWieck                  802                 :  *
                                803                 :  *  Output function for numeric data type
                                804                 :  */
                                805                 : Datum
 8335 tgl                       806 CBC      389247 : numeric_out(PG_FUNCTION_ARGS)
 8866 JanWieck                  807 ECB             : {
 8335 tgl                       808 CBC      389247 :     Numeric     num = PG_GETARG_NUMERIC(0);
                                809                 :     NumericVar  x;
 8482 tgl                       810 ECB             :     char       *str;
 8866 JanWieck                  811                 : 
 8053 bruce                     812                 :     /*
                                813                 :      * Handle NaN and infinities
 8866 JanWieck                  814                 :      */
  991 tgl                       815 CBC      389247 :     if (NUMERIC_IS_SPECIAL(num))
  991 tgl                       816 ECB             :     {
  991 tgl                       817 CBC        1698 :         if (NUMERIC_IS_PINF(num))
  991 tgl                       818 GIC         478 :             PG_RETURN_CSTRING(pstrdup("Infinity"));
                                819            1220 :         else if (NUMERIC_IS_NINF(num))
                                820             287 :             PG_RETURN_CSTRING(pstrdup("-Infinity"));
  991 tgl                       821 ECB             :         else
  991 tgl                       822 GIC         933 :             PG_RETURN_CSTRING(pstrdup("NaN"));
                                823                 :     }
 8866 JanWieck                  824 ECB             : 
                                825                 :     /*
 8485 tgl                       826                 :      * Get the number in the variable format.
 8866 JanWieck                  827                 :      */
 3791 heikki.linnakangas        828 CBC      387549 :     init_var_from_num(num, &x);
                                829                 : 
 3791 heikki.linnakangas        830 GIC      387549 :     str = get_str_from_var(&x);
                                831                 : 
 8335 tgl                       832 CBC      387549 :     PG_RETURN_CSTRING(str);
                                833                 : }
 8866 JanWieck                  834 EUB             : 
                                835                 : /*
                                836                 :  * numeric_is_nan() -
                                837                 :  *
                                838                 :  *  Is Numeric value a NaN?
                                839                 :  */
                                840                 : bool
 4636 rhaas                     841 CBC        6547 : numeric_is_nan(Numeric num)
                                842                 : {
                                843            6547 :     return NUMERIC_IS_NAN(num);
 4636 rhaas                     844 ECB             : }
                                845                 : 
                                846                 : /*
                                847                 :  * numeric_is_inf() -
  991 tgl                       848                 :  *
                                849                 :  *  Is Numeric value an infinity?
                                850                 :  */
                                851                 : bool
  991 tgl                       852 GIC          15 : numeric_is_inf(Numeric num)
  991 tgl                       853 ECB             : {
  991 tgl                       854 CBC          15 :     return NUMERIC_IS_INF(num);
                                855                 : }
                                856                 : 
                                857                 : /*
  991 tgl                       858 ECB             :  * numeric_is_integral() -
                                859                 :  *
                                860                 :  *  Is Numeric value integral?
                                861                 :  */
                                862                 : static bool
  991 tgl                       863 CBC          33 : numeric_is_integral(Numeric num)
  991 tgl                       864 ECB             : {
                                865                 :     NumericVar  arg;
                                866                 : 
                                867                 :     /* Reject NaN, but infinities are considered integral */
  991 tgl                       868 GIC          33 :     if (NUMERIC_IS_SPECIAL(num))
                                869                 :     {
                                870              15 :         if (NUMERIC_IS_NAN(num))
  991 tgl                       871 UIC           0 :             return false;
  991 tgl                       872 GIC          15 :         return true;
                                873                 :     }
                                874                 : 
                                875                 :     /* Integral if there are no digits to the right of the decimal point */
                                876              18 :     init_var_from_num(num, &arg);
  991 tgl                       877 ECB             : 
  991 tgl                       878 GIC          18 :     return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
  991 tgl                       879 ECB             : }
                                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,
  622 dean.a.rasheed            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
  622 dean.a.rasheed            897 GIC         905 : make_numeric_typmod(int precision, int scale)
                                898                 : {
  622 dean.a.rasheed            899 CBC         905 :     return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
                                900                 : }
  622 dean.a.rasheed            901 ECB             : 
                                902                 : /*
                                903                 :  * Because of the offset, valid numeric typmods are at least VARHDRSZ
                                904                 :  */
                                905                 : static inline bool
  622 dean.a.rasheed            906 GIC       59150 : is_valid_numeric_typmod(int32 typmod)
                                907                 : {
                                908           59150 :     return typmod >= (int32) VARHDRSZ;
                                909                 : }
                                910                 : 
                                911                 : /*
  622 dean.a.rasheed            912 ECB             :  * numeric_typmod_precision() -
                                913                 :  *
                                914                 :  *  Extract the precision from a numeric typmod --- see make_numeric_typmod().
                                915                 :  */
                                916                 : static inline int
  622 dean.a.rasheed            917 GIC       12269 : numeric_typmod_precision(int32 typmod)
                                918                 : {
                                919           12269 :     return ((typmod - VARHDRSZ) >> 16) & 0xffff;
                                920                 : }
                                921                 : 
                                922                 : /*
  622 dean.a.rasheed            923 ECB             :  * 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
  622 dean.a.rasheed            932 GIC        8503 : numeric_typmod_scale(int32 typmod)
                                933                 : {
  622 dean.a.rasheed            934 CBC        8503 :     return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
                                935                 : }
                                936                 : 
                                937                 : /*
                                938                 :  * numeric_maximum_size() -
 4636 rhaas                     939 ECB             :  *
                                940                 :  *  Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
                                941                 :  */
 4636 rhaas                     942 EUB             : int32
 4631 rhaas                     943 CBC        3766 : numeric_maximum_size(int32 typmod)
                                944                 : {
                                945                 :     int         precision;
                                946                 :     int         numeric_digits;
 4636 rhaas                     947 ECB             : 
  622 dean.a.rasheed            948 GIC        3766 :     if (!is_valid_numeric_typmod(typmod))
 4636 rhaas                     949 LBC           0 :         return -1;
                                950                 : 
                                951                 :     /* precision (ie, max # of digits) is in upper bits of typmod */
  622 dean.a.rasheed            952 GIC        3766 :     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                 :      */
 4631 rhaas                     964            3766 :     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
 4631 rhaas                     968 ECB             :      * 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
 3260 bruce                     970                 :      * possible to use a short numeric header.  But our job here is to compute
                                971                 :      * the worst case.
                                972                 :      */
 4631 rhaas                     973 GIC        3766 :     return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
                                974                 : }
                                975                 : 
                                976                 : /*
 4990 tgl                       977 ECB             :  * numeric_out_sci() -
                                978                 :  *
                                979                 :  *  Output function for numeric data type in scientific notation.
                                980                 :  */
                                981                 : char *
 4990 tgl                       982 GIC         117 : numeric_out_sci(Numeric num, int scale)
                                983                 : {
                                984                 :     NumericVar  x;
                                985                 :     char       *str;
                                986                 : 
                                987                 :     /*
  991 tgl                       988 ECB             :      * Handle NaN and infinities
                                989                 :      */
  991 tgl                       990 CBC         117 :     if (NUMERIC_IS_SPECIAL(num))
                                991                 :     {
  991 tgl                       992 GIC           9 :         if (NUMERIC_IS_PINF(num))
                                993               3 :             return pstrdup("Infinity");
                                994               6 :         else if (NUMERIC_IS_NINF(num))
                                995               3 :             return pstrdup("-Infinity");
                                996                 :         else
                                997               3 :             return pstrdup("NaN");
                                998                 :     }
                                999                 : 
 3791 heikki.linnakangas       1000             108 :     init_var_from_num(num, &x);
                               1001                 : 
 4990 tgl                      1002             108 :     str = get_str_from_var_sci(&x, scale);
 4990 tgl                      1003 ECB             : 
 4990 tgl                      1004 GIC         108 :     return str;
 4990 tgl                      1005 ECB             : }
                               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.
 3304 andrew                   1014                 :  */
                               1015                 : char *
 3304 andrew                   1016 GIC        4983 : numeric_normalize(Numeric num)
                               1017                 : {
                               1018                 :     NumericVar  x;
 3304 andrew                   1019 ECB             :     char       *str;
 3076 tgl                      1020 EUB             :     int         last;
                               1021                 : 
                               1022                 :     /*
  991 tgl                      1023 ECB             :      * Handle NaN and infinities
                               1024                 :      */
  991 tgl                      1025 GIC        4983 :     if (NUMERIC_IS_SPECIAL(num))
                               1026                 :     {
  991 tgl                      1027 UIC           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                 : 
 3304 andrew                   1035 CBC        4983 :     init_var_from_num(num, &x);
                               1036                 : 
 3304 andrew                   1037 GIC        4983 :     str = get_str_from_var(&x);
                               1038                 : 
                               1039                 :     /* If there's no decimal point, there's certainly nothing to remove. */
 3076 tgl                      1040            4983 :     if (strchr(str, '.') != NULL)
                               1041                 :     {
                               1042                 :         /*
                               1043                 :          * Back up over trailing fractional zeroes.  Since there is a decimal
 3076 tgl                      1044 ECB             :          * point, this loop will terminate safely.
                               1045                 :          */
 3076 tgl                      1046 GIC          21 :         last = strlen(str) - 1;
                               1047              42 :         while (str[last] == '0')
                               1048              21 :             last--;
                               1049                 : 
                               1050                 :         /* We want to get rid of the decimal point too, if it's now last. */
                               1051              21 :         if (str[last] == '.')
                               1052              21 :             last--;
 3304 andrew                   1053 ECB             : 
                               1054                 :         /* Delete whatever we backed up over. */
 3076 tgl                      1055 GIC          21 :         str[last + 1] = '\0';
                               1056                 :     }
                               1057                 : 
 3304 andrew                   1058            4983 :     return str;
                               1059                 : }
                               1060                 : 
 7272 tgl                      1061 ECB             : /*
                               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
 7272 tgl                      1068 CBC          51 : numeric_recv(PG_FUNCTION_ARGS)
                               1069                 : {
 7272 tgl                      1070 GIC          51 :     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
 6385 bruce                    1071 ECB             : 
                               1072                 : #ifdef NOT_USED
 6482 tgl                      1073                 :     Oid         typelem = PG_GETARG_OID(1);
                               1074                 : #endif
 6482 tgl                      1075 CBC          51 :     int32       typmod = PG_GETARG_INT32(2);
                               1076                 :     NumericVar  value;
                               1077                 :     Numeric     res;
                               1078                 :     int         len,
                               1079                 :                 i;
                               1080                 : 
 7272 tgl                      1081 GIC          51 :     init_var(&value);
                               1082                 : 
                               1083              51 :     len = (uint16) pq_getmsgint(buf, sizeof(uint16));
                               1084                 : 
                               1085              51 :     alloc_var(&value, len);
                               1086                 : 
 7272 tgl                      1087 CBC          51 :     value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
                               1088                 :     /* we allow any int16 for weight --- OK? */
                               1089                 : 
 7272 tgl                      1090 GIC          51 :     value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
                               1091              51 :     if (!(value.sign == NUMERIC_POS ||
 7272 tgl                      1092 UIC           0 :           value.sign == NUMERIC_NEG ||
  991                          1093               0 :           value.sign == NUMERIC_NAN ||
                               1094               0 :           value.sign == NUMERIC_PINF ||
                               1095               0 :           value.sign == NUMERIC_NINF))
 7196 tgl                      1096 LBC           0 :         ereport(ERROR,
                               1097                 :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
 7132 peter_e                  1098 EUB             :                  errmsg("invalid sign in external \"numeric\" value")));
 7196 tgl                      1099                 : 
 7272 tgl                      1100 GBC          51 :     value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
 3051                          1101              51 :     if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
 3051 tgl                      1102 UIC           0 :         ereport(ERROR,
 3051 tgl                      1103 EUB             :                 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                               1104                 :                  errmsg("invalid scale in external \"numeric\" value")));
                               1105                 : 
 7272 tgl                      1106 CBC         137 :     for (i = 0; i < len; i++)
                               1107                 :     {
 7188 bruce                    1108              86 :         NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
                               1109                 : 
 7272 tgl                      1110 GIC          86 :         if (d < 0 || d >= NBASE)
 7196 tgl                      1111 LBC           0 :             ereport(ERROR,
                               1112                 :                     (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                               1113                 :                      errmsg("invalid digit in external \"numeric\" value")));
 7272 tgl                      1114 GIC          86 :         value.digits[i] = d;
                               1115                 :     }
                               1116                 : 
 3051 tgl                      1117 ECB             :     /*
                               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
  991                          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.
 3051                          1126                 :      */
  991 tgl                      1127 GIC          51 :     if (value.sign == NUMERIC_POS ||
  991 tgl                      1128 UIC           0 :         value.sign == NUMERIC_NEG)
  991 tgl                      1129 ECB             :     {
  991 tgl                      1130 GIC          51 :         trunc_var(&value, value.dscale);
                               1131                 : 
  121 tgl                      1132 GNC          51 :         (void) apply_typmod(&value, typmod, NULL);
                               1133                 : 
  991 tgl                      1134 GIC          51 :         res = make_result(&value);
                               1135                 :     }
                               1136                 :     else
                               1137                 :     {
                               1138                 :         /* apply_typmod_special wants us to make the Numeric first */
  991 tgl                      1139 LBC           0 :         res = make_result(&value);
                               1140                 : 
  121 tgl                      1141 UNC           0 :         (void) apply_typmod_special(res, typmod, NULL);
                               1142                 :     }
                               1143                 : 
 7272 tgl                      1144 GIC          51 :     free_var(&value);
                               1145                 : 
 7272 tgl                      1146 CBC          51 :     PG_RETURN_NUMERIC(res);
                               1147                 : }
                               1148                 : 
                               1149                 : /*
                               1150                 :  *      numeric_send            - converts numeric to binary format
                               1151                 :  */
 7272 tgl                      1152 ECB             : Datum
 7272 tgl                      1153 GIC          35 : numeric_send(PG_FUNCTION_ARGS)
 7272 tgl                      1154 ECB             : {
 7272 tgl                      1155 GIC          35 :     Numeric     num = PG_GETARG_NUMERIC(0);
 7272 tgl                      1156 ECB             :     NumericVar  x;
                               1157                 :     StringInfoData buf;
                               1158                 :     int         i;
                               1159                 : 
 3791 heikki.linnakangas       1160 GIC          35 :     init_var_from_num(num, &x);
 7272 tgl                      1161 ECB             : 
 7272 tgl                      1162 CBC          35 :     pq_begintypsend(&buf);
 7272 tgl                      1163 EUB             : 
 2006 andres                   1164 GBC          35 :     pq_sendint16(&buf, x.ndigits);
                               1165              35 :     pq_sendint16(&buf, x.weight);
                               1166              35 :     pq_sendint16(&buf, x.sign);
                               1167              35 :     pq_sendint16(&buf, x.dscale);
 7272 tgl                      1168 GIC          97 :     for (i = 0; i < x.ndigits; i++)
 2006 andres                   1169              62 :         pq_sendint16(&buf, x.digits[i]);
                               1170                 : 
 7272 tgl                      1171 CBC          35 :     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
 7272 tgl                      1172 ECB             : }
 7272 tgl                      1173 EUB             : 
                               1174                 : 
                               1175                 : /*
                               1176                 :  * numeric_support()
 4079 rhaas                    1177 ECB             :  *
                               1178                 :  * Planner support function for the numeric() length coercion function.
 1520 tgl                      1179                 :  *
                               1180                 :  * Flatten calls that solely represent increases in allowable precision.
                               1181                 :  * Scale changes mutate every datum, so they are unoptimizable.  Some values,
 1520 tgl                      1182 EUB             :  * 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                 :  */
 4079 rhaas                    1185 ECB             : Datum
 1520 tgl                      1186 GIC         258 : numeric_support(PG_FUNCTION_ARGS)
                               1187                 : {
                               1188             258 :     Node       *rawreq = (Node *) PG_GETARG_POINTER(0);
 4079 rhaas                    1189             258 :     Node       *ret = NULL;
                               1190                 : 
 1520 tgl                      1191             258 :     if (IsA(rawreq, SupportRequestSimplify))
                               1192                 :     {
                               1193             114 :         SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
                               1194             114 :         FuncExpr   *expr = req->fcall;
                               1195                 :         Node       *typmod;
                               1196                 : 
                               1197             114 :         Assert(list_length(expr->args) >= 2);
 4079 rhaas                    1198 ECB             : 
 1520 tgl                      1199 GBC         114 :         typmod = (Node *) lsecond(expr->args);
                               1200                 : 
 1058 tgl                      1201 CBC         114 :         if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
                               1202                 :         {
 1520                          1203             114 :             Node       *source = (Node *) linitial(expr->args);
 1520 tgl                      1204 GIC         114 :             int32       old_typmod = exprTypmod(source);
 1520 tgl                      1205 CBC         114 :             int32       new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
  622 dean.a.rasheed           1206 GIC         114 :             int32       old_scale = numeric_typmod_scale(old_typmod);
                               1207             114 :             int32       new_scale = numeric_typmod_scale(new_typmod);
                               1208             114 :             int32       old_precision = numeric_typmod_precision(old_typmod);
                               1209             114 :             int32       new_precision = numeric_typmod_precision(new_typmod);
 1520 tgl                      1210 EUB             : 
                               1211                 :             /*
  622 dean.a.rasheed           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
 1520 tgl                      1215 ECB             :              * precision is not decreasing.  See further notes in function
                               1216                 :              * header comment.
                               1217                 :              */
  622 dean.a.rasheed           1218 GIC         228 :             if (!is_valid_numeric_typmod(new_typmod) ||
                               1219             120 :                 (is_valid_numeric_typmod(old_typmod) &&
 1520 tgl                      1220               3 :                  new_scale == old_scale && new_precision >= old_precision))
                               1221               3 :                 ret = relabel_to_typmod(source, new_typmod);
                               1222                 :         }
                               1223                 :     }
 4079 rhaas                    1224 ECB             : 
 4079 rhaas                    1225 GIC         258 :     PG_RETURN_POINTER(ret);
 4079 rhaas                    1226 ECB             : }
                               1227                 : 
                               1228                 : /*
                               1229                 :  * numeric() -
                               1230                 :  *
 8866 JanWieck                 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
 8720 bruce                    1233                 :  *  scale of the attribute have to be applied on the value.
                               1234                 :  */
 8335 tgl                      1235                 : Datum
 5624 bruce                    1236 CBC        5880 : numeric     (PG_FUNCTION_ARGS)
 8866 JanWieck                 1237 ECB             : {
 8335 tgl                      1238 CBC        5880 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1239            5880 :     int32       typmod = PG_GETARG_INT32(1);
 8866 JanWieck                 1240 ECB             :     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                 :      */
  991 tgl                      1252 GIC        5880 :     if (NUMERIC_IS_SPECIAL(num))
                               1253                 :     {
  121 tgl                      1254 GNC         105 :         (void) apply_typmod_special(num, typmod, NULL);
  991 tgl                      1255 GIC          96 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               1256                 :     }
 8866 JanWieck                 1257 ECB             : 
                               1258                 :     /*
 6385 bruce                    1259                 :      * If the value isn't a valid type modifier, simply return a copy of the
                               1260                 :      * input value
                               1261                 :      */
  622 dean.a.rasheed           1262 CBC        5775 :     if (!is_valid_numeric_typmod(typmod))
  991 tgl                      1263 UIC           0 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
 8866 JanWieck                 1264 ECB             : 
 8053 bruce                    1265                 :     /*
                               1266                 :      * Get the precision and scale out of the typmod value
                               1267                 :      */
  622 dean.a.rasheed           1268 CBC        5775 :     precision = numeric_typmod_precision(typmod);
  622 dean.a.rasheed           1269 GIC        5775 :     scale = numeric_typmod_scale(typmod);
 7324 tgl                      1270 CBC        5775 :     maxdigits = precision - scale;
                               1271                 : 
  622 dean.a.rasheed           1272 ECB             :     /* The target display scale is non-negative */
  622 dean.a.rasheed           1273 GIC        5775 :     dscale = Max(scale, 0);
  622 dean.a.rasheed           1274 ECB             : 
 8053 bruce                    1275                 :     /*
 7324 tgl                      1276                 :      * If the number is certainly in bounds and due to the target scale no
 6385 bruce                    1277                 :      * rounding could be necessary, just make a copy of the input and modify
 4632 rhaas                    1278                 :      * its scale fields, unless the larger scale forces us to abandon the
 4382 bruce                    1279                 :      * short representation.  (Note we assume the existing dscale is
                               1280                 :      * honest...)
                               1281                 :      */
 4632 rhaas                    1282 GIC        5775 :     ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
                               1283            5775 :     if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
  622 dean.a.rasheed           1284            3565 :         && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
 4382 bruce                    1285 UIC           0 :             || !NUMERIC_IS_SHORT(num)))
                               1286                 :     {
  991 tgl                      1287 GIC        3565 :         new = duplicate_numeric(num);
 4632 rhaas                    1288            3565 :         if (NUMERIC_IS_SHORT(num))
 4632 rhaas                    1289 CBC        3565 :             new->choice.n_short.n_header =
                               1290            3565 :                 (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
  622 dean.a.rasheed           1291            3565 :                 | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
 4632 rhaas                    1292 ECB             :         else
 4632 rhaas                    1293 UIC           0 :             new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
  622 dean.a.rasheed           1294               0 :                 ((uint16) dscale & NUMERIC_DSCALE_MASK);
 8335 tgl                      1295 GIC        3565 :         PG_RETURN_NUMERIC(new);
 8866 JanWieck                 1296 ECB             :     }
                               1297                 : 
                               1298                 :     /*
                               1299                 :      * We really need to fiddle with things - unpack the number into a
                               1300                 :      * variable and let apply_typmod() do it.
                               1301                 :      */
 8866 JanWieck                 1302 GIC        2210 :     init_var(&var);
                               1303                 : 
                               1304            2210 :     set_var_from_num(num, &var);
  121 tgl                      1305 GNC        2210 :     (void) apply_typmod(&var, typmod, NULL);
 8866 JanWieck                 1306 GIC        2180 :     new = make_result(&var);
 8866 JanWieck                 1307 ECB             : 
 8866 JanWieck                 1308 GIC        2180 :     free_var(&var);
 8866 JanWieck                 1309 ECB             : 
 8335 tgl                      1310 CBC        2180 :     PG_RETURN_NUMERIC(new);
                               1311                 : }
                               1312                 : 
                               1313                 : Datum
 5944 tgl                      1314 GIC         911 : numerictypmodin(PG_FUNCTION_ARGS)
                               1315                 : {
 5624 bruce                    1316             911 :     ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
                               1317                 :     int32      *tl;
                               1318                 :     int         n;
                               1319                 :     int32       typmod;
                               1320                 : 
 5777 tgl                      1321             911 :     tl = ArrayGetIntegerTypmods(ta, &n);
                               1322                 : 
 5944 tgl                      1323 CBC         911 :     if (n == 2)
                               1324                 :     {
                               1325             903 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
 5944 tgl                      1326 LBC           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)));
  622 dean.a.rasheed           1330 GIC         903 :         if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
 5944 tgl                      1331 UIC           0 :             ereport(ERROR,
                               1332                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  622 dean.a.rasheed           1333 ECB             :                      errmsg("NUMERIC scale %d must be between %d and %d",
  622 dean.a.rasheed           1334 EUB             :                             tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
  622 dean.a.rasheed           1335 GIC         903 :         typmod = make_numeric_typmod(tl[0], tl[1]);
                               1336                 :     }
 5944 tgl                      1337               8 :     else if (n == 1)
                               1338                 :     {
 5944 tgl                      1339 CBC           2 :         if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
 5944 tgl                      1340 LBC           0 :             ereport(ERROR,
 5944 tgl                      1341 ECB             :                     (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 */
  622 dean.a.rasheed           1345 GIC           2 :         typmod = make_numeric_typmod(tl[0], 0);
                               1346                 :     }
                               1347                 :     else
                               1348                 :     {
 5944 tgl                      1349               6 :         ereport(ERROR,
                               1350                 :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               1351                 :                  errmsg("invalid NUMERIC type modifier")));
                               1352                 :         typmod = 0;             /* keep compiler quiet */
 5944 tgl                      1353 ECB             :     }
                               1354                 : 
 5944 tgl                      1355 CBC         905 :     PG_RETURN_INT32(typmod);
 5944 tgl                      1356 EUB             : }
                               1357                 : 
 5944 tgl                      1358 ECB             : Datum
 5944 tgl                      1359 CBC         188 : numerictypmodout(PG_FUNCTION_ARGS)
 5944 tgl                      1360 ECB             : {
 5624 bruce                    1361 CBC         188 :     int32       typmod = PG_GETARG_INT32(0);
                               1362             188 :     char       *res = (char *) palloc(64);
                               1363                 : 
  622 dean.a.rasheed           1364 GBC         188 :     if (is_valid_numeric_typmod(typmod))
 5944 tgl                      1365             188 :         snprintf(res, 64, "(%d,%d)",
  622 dean.a.rasheed           1366 ECB             :                  numeric_typmod_precision(typmod),
                               1367                 :                  numeric_typmod_scale(typmod));
                               1368                 :     else
 5944 tgl                      1369 UIC           0 :         *res = '\0';
                               1370                 : 
 5944 tgl                      1371 GIC         188 :     PG_RETURN_CSTRING(res);
                               1372                 : }
 5944 tgl                      1373 ECB             : 
                               1374                 : 
 8866 JanWieck                 1375                 : /* ----------------------------------------------------------------------
                               1376                 :  *
 8445 tgl                      1377                 :  * Sign manipulation, rounding and the like
                               1378                 :  *
 8866 JanWieck                 1379                 :  * ----------------------------------------------------------------------
                               1380                 :  */
                               1381                 : 
                               1382                 : Datum
 8289 tgl                      1383 GIC         630 : numeric_abs(PG_FUNCTION_ARGS)
                               1384                 : {
 8289 tgl                      1385 CBC         630 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1386                 :     Numeric     res;
 8866 JanWieck                 1387 ECB             : 
                               1388                 :     /*
                               1389                 :      * Do it the easy way directly on the packed format
                               1390                 :      */
  991 tgl                      1391 GIC         630 :     res = duplicate_numeric(num);
 8866 JanWieck                 1392 ECB             : 
 4632 rhaas                    1393 GIC         630 :     if (NUMERIC_IS_SHORT(num))
 4632 rhaas                    1394 CBC         597 :         res->choice.n_short.n_header =
 4632 rhaas                    1395 GIC         597 :             num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
  991 tgl                      1396 CBC          33 :     else if (NUMERIC_IS_SPECIAL(num))
  991 tgl                      1397 EUB             :     {
                               1398                 :         /* This changes -Inf to Inf, and doesn't affect NaN */
  991 tgl                      1399 GIC           9 :         res->choice.n_short.n_header =
                               1400               9 :             num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
  991 tgl                      1401 ECB             :     }
 4632 rhaas                    1402 EUB             :     else
 4632 rhaas                    1403 GIC          24 :         res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
                               1404                 : 
 8289 tgl                      1405             630 :     PG_RETURN_NUMERIC(res);
 8866 JanWieck                 1406 ECB             : }
                               1407                 : 
                               1408                 : 
                               1409                 : Datum
 8289 tgl                      1410 CBC         427 : numeric_uminus(PG_FUNCTION_ARGS)
 8445 tgl                      1411 EUB             : {
 8289 tgl                      1412 GIC         427 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1413                 :     Numeric     res;
                               1414                 : 
                               1415                 :     /*
 8445 tgl                      1416 ECB             :      * Do it the easy way directly on the packed format
                               1417                 :      */
  991 tgl                      1418 GIC         427 :     res = duplicate_numeric(num);
                               1419                 : 
  991 tgl                      1420 CBC         427 :     if (NUMERIC_IS_SPECIAL(num))
                               1421                 :     {
                               1422                 :         /* Flip the sign, if it's Inf or -Inf */
  991 tgl                      1423 GIC          63 :         if (!NUMERIC_IS_NAN(num))
                               1424              42 :             res->choice.n_short.n_header =
                               1425              42 :                 num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
  991 tgl                      1426 ECB             :     }
                               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.
 8445                          1432                 :      */
  991 tgl                      1433 CBC         364 :     else if (NUMERIC_NDIGITS(num) != 0)
                               1434                 :     {
 8445 tgl                      1435 ECB             :         /* Else, flip the sign */
 4632 rhaas                    1436 CBC         307 :         if (NUMERIC_IS_SHORT(num))
 4632 rhaas                    1437 GIC         307 :             res->choice.n_short.n_header =
                               1438             307 :                 num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
 4632 rhaas                    1439 UIC           0 :         else if (NUMERIC_SIGN(num) == NUMERIC_POS)
 4632 rhaas                    1440 UBC           0 :             res->choice.n_long.n_sign_dscale =
 4632 rhaas                    1441 UIC           0 :                 NUMERIC_NEG | NUMERIC_DSCALE(num);
 8445 tgl                      1442 ECB             :         else
 4632 rhaas                    1443 UIC           0 :             res->choice.n_long.n_sign_dscale =
                               1444               0 :                 NUMERIC_POS | NUMERIC_DSCALE(num);
                               1445                 :     }
                               1446                 : 
 8289 tgl                      1447 GIC         427 :     PG_RETURN_NUMERIC(res);
                               1448                 : }
                               1449                 : 
                               1450                 : 
                               1451                 : Datum
 7976 bruce                    1452             243 : numeric_uplus(PG_FUNCTION_ARGS)
                               1453                 : {
 7976 bruce                    1454 CBC         243 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1455                 : 
  991 tgl                      1456             243 :     PG_RETURN_NUMERIC(duplicate_numeric(num));
                               1457                 : }
                               1458                 : 
                               1459                 : 
                               1460                 : /*
                               1461                 :  * numeric_sign_internal() -
  991 tgl                      1462 ECB             :  *
                               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
  991 tgl                      1468 GIC        1527 : numeric_sign_internal(Numeric num)
                               1469                 : {
  991 tgl                      1470 CBC        1527 :     if (NUMERIC_IS_SPECIAL(num))
  991 tgl                      1471 ECB             :     {
  991 tgl                      1472 GIC         156 :         Assert(!NUMERIC_IS_NAN(num));
                               1473                 :         /* Must be Inf or -Inf */
  991 tgl                      1474 CBC         156 :         if (NUMERIC_IS_PINF(num))
  991 tgl                      1475 GIC          93 :             return 1;
  991 tgl                      1476 ECB             :         else
  991 tgl                      1477 GIC          63 :             return -1;
                               1478                 :     }
                               1479                 : 
                               1480                 :     /*
  991 tgl                      1481 ECB             :      * 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                 :      */
  991 tgl                      1485 GIC        1371 :     else if (NUMERIC_NDIGITS(num) == 0)
                               1486             111 :         return 0;
                               1487            1260 :     else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
                               1488             303 :         return -1;
  991 tgl                      1489 ECB             :     else
  991 tgl                      1490 GIC         957 :         return 1;
 7976 bruce                    1491 ECB             : }
                               1492                 : 
                               1493                 : /*
 7477                          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
 8289 tgl                      1500 GIC          24 : numeric_sign(PG_FUNCTION_ARGS)
                               1501                 : {
                               1502              24 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1503                 : 
 8053 bruce                    1504 ECB             :     /*
                               1505                 :      * Handle NaN (infinities can be handled normally)
                               1506                 :      */
 8866 JanWieck                 1507 CBC          24 :     if (NUMERIC_IS_NAN(num))
 8289 tgl                      1508               3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
 8866 JanWieck                 1509 ECB             : 
  991 tgl                      1510 GBC          21 :     switch (numeric_sign_internal(num))
 8866 JanWieck                 1511 EUB             :     {
  991 tgl                      1512 GBC           3 :         case 0:
  991 tgl                      1513 GIC           3 :             PG_RETURN_NUMERIC(make_result(&const_zero));
  991 tgl                      1514 GBC           9 :         case 1:
                               1515               9 :             PG_RETURN_NUMERIC(make_result(&const_one));
  991 tgl                      1516 GIC           9 :         case -1:
                               1517               9 :             PG_RETURN_NUMERIC(make_result(&const_minus_one));
 8866 JanWieck                 1518 ECB             :     }
                               1519                 : 
  991 tgl                      1520 UIC           0 :     Assert(false);
                               1521                 :     return (Datum) 0;
                               1522                 : }
 8866 JanWieck                 1523 ECB             : 
                               1524                 : 
 7324 tgl                      1525                 : /*
                               1526                 :  * numeric_round() -
 8866 JanWieck                 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
 8335 tgl                      1533 GIC        3751 : numeric_round(PG_FUNCTION_ARGS)
                               1534                 : {
                               1535            3751 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1536            3751 :     int32       scale = PG_GETARG_INT32(1);
                               1537                 :     Numeric     res;
                               1538                 :     NumericVar  arg;
 8866 JanWieck                 1539 ECB             : 
                               1540                 :     /*
  991 tgl                      1541                 :      * Handle NaN and infinities
                               1542                 :      */
  991 tgl                      1543 CBC        3751 :     if (NUMERIC_IS_SPECIAL(num))
  991 tgl                      1544 GIC          48 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
 8866 JanWieck                 1545 ECB             : 
 8053 bruce                    1546                 :     /*
                               1547                 :      * Limit the scale value to avoid possible overflow in calculations
 8427 tgl                      1548                 :      */
 7494 tgl                      1549 GIC        3703 :     scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
                               1550            3703 :     scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
                               1551                 : 
                               1552                 :     /*
                               1553                 :      * Unpack the argument and round it at the proper digit position
                               1554                 :      */
 8427                          1555            3703 :     init_var(&arg);
 8427 tgl                      1556 CBC        3703 :     set_var_from_num(num, &arg);
 8427 tgl                      1557 ECB             : 
 7324 tgl                      1558 CBC        3703 :     round_var(&arg, scale);
 8427 tgl                      1559 ECB             : 
                               1560                 :     /* We don't allow negative output dscale */
 7324 tgl                      1561 CBC        3703 :     if (scale < 0)
 7324 tgl                      1562 GIC          90 :         arg.dscale = 0;
                               1563                 : 
                               1564                 :     /*
                               1565                 :      * Return the rounded result
                               1566                 :      */
 8427                          1567            3703 :     res = make_result(&arg);
                               1568                 : 
                               1569            3703 :     free_var(&arg);
 8335                          1570            3703 :     PG_RETURN_NUMERIC(res);
 8866 JanWieck                 1571 ECB             : }
                               1572                 : 
                               1573                 : 
                               1574                 : /*
                               1575                 :  * numeric_trunc() -
                               1576                 :  *
                               1577                 :  *  Truncate a value to have 'scale' digits after the decimal point.
 8427 tgl                      1578                 :  *  We allow negative 'scale', implying a truncation before the decimal
                               1579                 :  *  point --- Oracle interprets truncation that way.
                               1580                 :  */
 8335                          1581                 : Datum
 8335 tgl                      1582 GIC         193 : numeric_trunc(PG_FUNCTION_ARGS)
 8866 JanWieck                 1583 ECB             : {
 8335 tgl                      1584 CBC         193 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1585             193 :     int32       scale = PG_GETARG_INT32(1);
 8720 bruce                    1586 ECB             :     Numeric     res;
                               1587                 :     NumericVar  arg;
 8866 JanWieck                 1588                 : 
                               1589                 :     /*
                               1590                 :      * Handle NaN and infinities
 8866 JanWieck                 1591 EUB             :      */
  991 tgl                      1592 GIC         193 :     if (NUMERIC_IS_SPECIAL(num))
                               1593              18 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               1594                 : 
                               1595                 :     /*
                               1596                 :      * Limit the scale value to avoid possible overflow in calculations
                               1597                 :      */
 7494                          1598             175 :     scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
                               1599             175 :     scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
                               1600                 : 
                               1601                 :     /*
                               1602                 :      * Unpack the argument and truncate it at the proper digit position
                               1603                 :      */
 8866 JanWieck                 1604 CBC         175 :     init_var(&arg);
 8866 JanWieck                 1605 GIC         175 :     set_var_from_num(num, &arg);
 8866 JanWieck                 1606 ECB             : 
 7324 tgl                      1607 CBC         175 :     trunc_var(&arg, scale);
                               1608                 : 
                               1609                 :     /* We don't allow negative output dscale */
 7324 tgl                      1610 GIC         175 :     if (scale < 0)
 7324 tgl                      1611 UIC           0 :         arg.dscale = 0;
                               1612                 : 
                               1613                 :     /*
 8866 JanWieck                 1614 ECB             :      * Return the truncated result
                               1615                 :      */
 8866 JanWieck                 1616 GIC         175 :     res = make_result(&arg);
                               1617                 : 
                               1618             175 :     free_var(&arg);
 8335 tgl                      1619             175 :     PG_RETURN_NUMERIC(res);
 8866 JanWieck                 1620 ECB             : }
                               1621                 : 
                               1622                 : 
                               1623                 : /*
                               1624                 :  * numeric_ceil() -
                               1625                 :  *
                               1626                 :  *  Return the smallest integer greater than or equal to the argument
                               1627                 :  */
                               1628                 : Datum
 8289 tgl                      1629 CBC         111 : numeric_ceil(PG_FUNCTION_ARGS)
                               1630                 : {
 8289 tgl                      1631 GIC         111 :     Numeric     num = PG_GETARG_NUMERIC(0);
 8866 JanWieck                 1632 ECB             :     Numeric     res;
                               1633                 :     NumericVar  result;
                               1634                 : 
                               1635                 :     /*
                               1636                 :      * Handle NaN and infinities
                               1637                 :      */
  991 tgl                      1638 CBC         111 :     if (NUMERIC_IS_SPECIAL(num))
  991 tgl                      1639 GIC           9 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
 8866 JanWieck                 1640 ECB             : 
 3791 heikki.linnakangas       1641 CBC         102 :     init_var_from_num(num, &result);
 8866 JanWieck                 1642 GIC         102 :     ceil_var(&result, &result);
                               1643                 : 
                               1644             102 :     res = make_result(&result);
                               1645             102 :     free_var(&result);
                               1646                 : 
 8289 tgl                      1647             102 :     PG_RETURN_NUMERIC(res);
                               1648                 : }
                               1649                 : 
                               1650                 : 
                               1651                 : /*
                               1652                 :  * numeric_floor() -
 8866 JanWieck                 1653 ECB             :  *
                               1654                 :  *  Return the largest integer equal to or less than the argument
                               1655                 :  */
 8289 tgl                      1656                 : Datum
 8289 tgl                      1657 GIC          63 : numeric_floor(PG_FUNCTION_ARGS)
                               1658                 : {
                               1659              63 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               1660                 :     Numeric     res;
                               1661                 :     NumericVar  result;
                               1662                 : 
  991 tgl                      1663 ECB             :     /*
                               1664                 :      * Handle NaN and infinities
                               1665                 :      */
  991 tgl                      1666 GIC          63 :     if (NUMERIC_IS_SPECIAL(num))
                               1667               9 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               1668                 : 
 3791 heikki.linnakangas       1669 CBC          54 :     init_var_from_num(num, &result);
 8866 JanWieck                 1670              54 :     floor_var(&result, &result);
                               1671                 : 
 8866 JanWieck                 1672 GIC          54 :     res = make_result(&result);
                               1673              54 :     free_var(&result);
                               1674                 : 
 8289 tgl                      1675 CBC          54 :     PG_RETURN_NUMERIC(res);
 8866 JanWieck                 1676 ECB             : }
                               1677                 : 
 3071 fujii                    1678                 : 
                               1679                 : /*
                               1680                 :  * generate_series_numeric() -
                               1681                 :  *
 2969 tgl                      1682 EUB             :  *  Generate series of numeric.
                               1683                 :  */
                               1684                 : Datum
 3071 fujii                    1685 GIC         108 : generate_series_numeric(PG_FUNCTION_ARGS)
                               1686                 : {
 3071 fujii                    1687 CBC         108 :     return generate_series_step_numeric(fcinfo);
                               1688                 : }
 3071 fujii                    1689 ECB             : 
                               1690                 : Datum
 3071 fujii                    1691 GIC         210 : generate_series_step_numeric(PG_FUNCTION_ARGS)
                               1692                 : {
                               1693                 :     generate_series_numeric_fctx *fctx;
                               1694                 :     FuncCallContext *funcctx;
                               1695                 :     MemoryContext oldcontext;
                               1696                 : 
                               1697             210 :     if (SRF_IS_FIRSTCALL())
                               1698                 :     {
                               1699              69 :         Numeric     start_num = PG_GETARG_NUMERIC(0);
 3071 fujii                    1700 CBC          69 :         Numeric     stop_num = PG_GETARG_NUMERIC(1);
 3071 fujii                    1701 GIC          69 :         NumericVar  steploc = const_one;
 3071 fujii                    1702 ECB             : 
                               1703                 :         /* Reject NaN and infinities in start and stop values */
  991 tgl                      1704 GIC          69 :         if (NUMERIC_IS_SPECIAL(start_num))
                               1705                 :         {
                               1706               6 :             if (NUMERIC_IS_NAN(start_num))
                               1707               3 :                 ereport(ERROR,
                               1708                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  991 tgl                      1709 ECB             :                          errmsg("start value cannot be NaN")));
                               1710                 :             else
  991 tgl                      1711 GIC           3 :                 ereport(ERROR,
  991 tgl                      1712 ECB             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               1713                 :                          errmsg("start value cannot be infinity")));
                               1714                 :         }
  991 tgl                      1715 CBC          63 :         if (NUMERIC_IS_SPECIAL(stop_num))
  991 tgl                      1716 ECB             :         {
  991 tgl                      1717 GIC           6 :             if (NUMERIC_IS_NAN(stop_num))
  991 tgl                      1718 CBC           3 :                 ereport(ERROR,
                               1719                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               1720                 :                          errmsg("stop value cannot be NaN")));
                               1721                 :             else
  991 tgl                      1722 GIC           3 :                 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 */
 3071 fujii                    1728 CBC          57 :         if (PG_NARGS() == 3)
                               1729                 :         {
 2969 tgl                      1730              27 :             Numeric     step_num = PG_GETARG_NUMERIC(2);
                               1731                 : 
  991 tgl                      1732 GIC          27 :             if (NUMERIC_IS_SPECIAL(step_num))
                               1733                 :             {
                               1734               6 :                 if (NUMERIC_IS_NAN(step_num))
                               1735               3 :                     ereport(ERROR,
                               1736                 :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  991 tgl                      1737 ECB             :                              errmsg("step size cannot be NaN")));
                               1738                 :                 else
  991 tgl                      1739 GIC           3 :                     ereport(ERROR,
  991 tgl                      1740 ECB             :                             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               1741                 :                              errmsg("step size cannot be infinity")));
                               1742                 :             }
 3071 fujii                    1743                 : 
 3071 fujii                    1744 CBC          21 :             init_var_from_num(step_num, &steploc);
                               1745                 : 
                               1746              21 :             if (cmp_var(&steploc, &const_zero) == 0)
 3071 fujii                    1747 GIC           3 :                 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              48 :         funcctx = SRF_FIRSTCALL_INIT();
                               1754                 : 
                               1755                 :         /*
 3071 fujii                    1756 ECB             :          * Switch to memory context appropriate for multiple function calls.
                               1757                 :          */
 3071 fujii                    1758 CBC          48 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
                               1759                 : 
                               1760                 :         /* allocate memory for user context */
                               1761                 :         fctx = (generate_series_numeric_fctx *)
                               1762              48 :             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
 3034 fujii                    1768 ECB             :          * them in the per-call context.
                               1769                 :          */
 3034 fujii                    1770 CBC          48 :         init_var(&fctx->current);
                               1771              48 :         init_var(&fctx->stop);
 3071                          1772              48 :         init_var(&fctx->step);
                               1773                 : 
 3034 fujii                    1774 GIC          48 :         set_var_from_num(start_num, &fctx->current);
 3034 fujii                    1775 CBC          48 :         set_var_from_num(stop_num, &fctx->stop);
 3071 fujii                    1776 GIC          48 :         set_var_from_var(&steploc, &fctx->step);
 3071 fujii                    1777 ECB             : 
 3071 fujii                    1778 CBC          48 :         funcctx->user_fctx = fctx;
 3071 fujii                    1779 GIC          48 :         MemoryContextSwitchTo(oldcontext);
                               1780                 :     }
                               1781                 : 
 3071 fujii                    1782 ECB             :     /* stuff done on every call of the function */
 3071 fujii                    1783 GIC         189 :     funcctx = SRF_PERCALL_SETUP();
                               1784                 : 
                               1785                 :     /*
 3071 fujii                    1786 ECB             :      * Get the saved state and use current state as the result of this
                               1787                 :      * iteration.
                               1788                 :      */
 3071 fujii                    1789 CBC         189 :     fctx = funcctx->user_fctx;
                               1790                 : 
 3071 fujii                    1791 GIC         366 :     if ((fctx->step.sign == NUMERIC_POS &&
                               1792             177 :          cmp_var(&fctx->current, &fctx->stop) <= 0) ||
 3071 fujii                    1793 CBC          69 :         (fctx->step.sign == NUMERIC_NEG &&
 3071 fujii                    1794 GIC          12 :          cmp_var(&fctx->current, &fctx->stop) >= 0))
                               1795                 :     {
 2969 tgl                      1796             141 :         Numeric     result = make_result(&fctx->current);
                               1797                 : 
                               1798                 :         /* switch to memory context appropriate for iteration calculation */
 3071 fujii                    1799 CBC         141 :         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
                               1800                 : 
 3071 fujii                    1801 ECB             :         /* increment current in preparation for next iteration */
 3071 fujii                    1802 GIC         141 :         add_var(&fctx->current, &fctx->step, &fctx->current);
 3071 fujii                    1803 CBC         141 :         MemoryContextSwitchTo(oldcontext);
                               1804                 : 
 3071 fujii                    1805 ECB             :         /* do when there is more left to send */
 3071 fujii                    1806 CBC         141 :         SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
                               1807                 :     }
                               1808                 :     else
                               1809                 :         /* do when there is no more left */
                               1810              48 :         SRF_RETURN_DONE(funcctx);
                               1811                 : }
                               1812                 : 
                               1813                 : 
                               1814                 : /*
 5927 neilc                    1815 ECB             :  * Implements the numeric version of the width_bucket() function
                               1816                 :  * defined by SQL2003. See also width_bucket_float8().
 6904                          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
 6904 neilc                    1828 GIC         390 : width_bucket_numeric(PG_FUNCTION_ARGS)
 6904 neilc                    1829 ECB             : {
 6904 neilc                    1830 GIC         390 :     Numeric     operand = PG_GETARG_NUMERIC(0);
                               1831             390 :     Numeric     bound1 = PG_GETARG_NUMERIC(1);
                               1832             390 :     Numeric     bound2 = PG_GETARG_NUMERIC(2);
 6904 neilc                    1833 CBC         390 :     int32       count = PG_GETARG_INT32(3);
                               1834                 :     NumericVar  count_var;
                               1835                 :     NumericVar  result_var;
                               1836                 :     int32       result;
                               1837                 : 
 6904 neilc                    1838 GIC         390 :     if (count <= 0)
                               1839               6 :         ereport(ERROR,
                               1840                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
 6385 bruce                    1841 ECB             :                  errmsg("count must be greater than zero")));
 6904 neilc                    1842                 : 
  991 tgl                      1843 CBC         384 :     if (NUMERIC_IS_SPECIAL(operand) ||
  991 tgl                      1844 GIC         375 :         NUMERIC_IS_SPECIAL(bound1) ||
  991 tgl                      1845 CBC         372 :         NUMERIC_IS_SPECIAL(bound2))
  991 tgl                      1846 ECB             :     {
  991 tgl                      1847 CBC          18 :         if (NUMERIC_IS_NAN(operand) ||
  991 tgl                      1848 GIC          15 :             NUMERIC_IS_NAN(bound1) ||
  991 tgl                      1849 CBC          15 :             NUMERIC_IS_NAN(bound2))
                               1850               3 :             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 */
  913                          1854              15 :         if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
  991 tgl                      1855 GIC           9 :             ereport(ERROR,
                               1856                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
                               1857                 :                      errmsg("lower and upper bounds must be finite")));
                               1858                 :     }
                               1859                 : 
 6904 neilc                    1860 CBC         372 :     init_var(&result_var);
 6904 neilc                    1861 GIC         372 :     init_var(&count_var);
 6904 neilc                    1862 ECB             : 
                               1863                 :     /* Convert 'count' to a numeric, for ease of use later */
 2942 andres                   1864 CBC         372 :     int64_to_numericvar((int64) count, &count_var);
 6904 neilc                    1865 ECB             : 
 6904 neilc                    1866 GIC         372 :     switch (cmp_numerics(bound1, bound2))
 6904 neilc                    1867 ECB             :     {
 6904 neilc                    1868 GIC           3 :         case 0:
                               1869               3 :             ereport(ERROR,
 2118 tgl                      1870 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
                               1871                 :                      errmsg("lower bound cannot equal upper bound")));
                               1872                 :             break;
 6904 neilc                    1873                 : 
 6797 bruce                    1874                 :             /* bound1 < bound2 */
 6904 neilc                    1875 GIC         273 :         case -1:
                               1876             273 :             if (cmp_numerics(operand, bound1) < 0)
 6904 neilc                    1877 CBC          57 :                 set_var_from_var(&const_zero, &result_var);
 6904 neilc                    1878 GIC         216 :             else if (cmp_numerics(operand, bound2) >= 0)
                               1879              54 :                 add_var(&count_var, &const_one, &result_var);
                               1880                 :             else
  913 tgl                      1881 CBC         162 :                 compute_bucket(operand, bound1, bound2, &count_var, false,
                               1882                 :                                &result_var);
 6904 neilc                    1883 GIC         273 :             break;
                               1884                 : 
                               1885                 :             /* bound1 > bound2 */
                               1886              96 :         case 1:
                               1887              96 :             if (cmp_numerics(operand, bound1) > 0)
                               1888               6 :                 set_var_from_var(&const_zero, &result_var);
                               1889              90 :             else if (cmp_numerics(operand, bound2) <= 0)
                               1890              12 :                 add_var(&count_var, &const_one, &result_var);
                               1891                 :             else
  913 tgl                      1892              78 :                 compute_bucket(operand, bound1, bound2, &count_var, true,
                               1893                 :                                &result_var);
 6904 neilc                    1894              96 :             break;
                               1895                 :     }
                               1896                 : 
                               1897                 :     /* if result exceeds the range of a legal int4, we ereport here */
 1485 akorotkov                1898             369 :     if (!numericvar_to_int32(&result_var, &result))
 1485 akorotkov                1899 LBC           0 :         ereport(ERROR,
                               1900                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 1485 akorotkov                1901 ECB             :                  errmsg("integer out of range")));
 6904 neilc                    1902                 : 
 6904 neilc                    1903 CBC         369 :     free_var(&count_var);
                               1904             369 :     free_var(&result_var);
                               1905                 : 
 6904 neilc                    1906 GIC         369 :     PG_RETURN_INT32(result);
                               1907                 : }
                               1908                 : 
 6904 neilc                    1909 ECB             : /*
                               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
 6904 neilc                    1916 CBC         240 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
                               1917                 :                const NumericVar *count_var, bool reversed_bounds,
  913 tgl                      1918 ECB             :                NumericVar *result_var)
 6904 neilc                    1919                 : {
 6797 bruce                    1920                 :     NumericVar  bound1_var;
                               1921                 :     NumericVar  bound2_var;
                               1922                 :     NumericVar  operand_var;
                               1923                 : 
 3791 heikki.linnakangas       1924 GIC         240 :     init_var_from_num(bound1, &bound1_var);
 3791 heikki.linnakangas       1925 CBC         240 :     init_var_from_num(bound2, &bound2_var);
                               1926             240 :     init_var_from_num(operand, &operand_var);
                               1927                 : 
  913 tgl                      1928 GIC         240 :     if (!reversed_bounds)
                               1929                 :     {
 6904 neilc                    1930             162 :         sub_var(&operand_var, &bound1_var, &operand_var);
 6904 neilc                    1931 CBC         162 :         sub_var(&bound2_var, &bound1_var, &bound2_var);
 6904 neilc                    1932 ECB             :     }
                               1933                 :     else
                               1934                 :     {
 6904 neilc                    1935 CBC          78 :         sub_var(&bound1_var, &operand_var, &operand_var);
  913 tgl                      1936 GIC          78 :         sub_var(&bound1_var, &bound2_var, &bound2_var);
 6904 neilc                    1937 ECB             :     }
                               1938                 : 
  913 tgl                      1939 CBC         240 :     mul_var(&operand_var, count_var, &operand_var,
                               1940             240 :             operand_var.dscale + count_var->dscale);
  913 tgl                      1941 GIC         240 :     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                 :      */
    9 tgl                      1949 GNC         240 :     if (cmp_var(result_var, count_var) >= 0)
                               1950               6 :         set_var_from_var(count_var, result_var);
                               1951                 :     else
                               1952                 :     {
                               1953             234 :         add_var(result_var, &const_one, result_var);
                               1954             234 :         floor_var(result_var, result_var);
                               1955                 :     }
                               1956                 : 
 6904 neilc                    1957 CBC         240 :     free_var(&bound1_var);
                               1958             240 :     free_var(&bound2_var);
                               1959             240 :     free_var(&operand_var);
 6797 bruce                    1960             240 : }
 8866 JanWieck                 1961 ECB             : 
                               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
 8289 tgl                      1968                 :  * need to be so careful.
 2929 rhaas                    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
 2929 rhaas                    1981 EUB             :  * 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                 :  *
 2929 rhaas                    1985 ECB             :  * 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                 :  * ----------------------------------------------------------------------
 8866 JanWieck                 1998                 :  */
                               1999                 : 
                               2000                 : /*
                               2001                 :  * Sort support strategy routine.
                               2002                 :  */
                               2003                 : Datum
 2929 rhaas                    2004 GIC         463 : numeric_sortsupport(PG_FUNCTION_ARGS)
                               2005                 : {
 2929 rhaas                    2006 CBC         463 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
 2929 rhaas                    2007 ECB             : 
 2929 rhaas                    2008 CBC         463 :     ssup->comparator = numeric_fast_cmp;
                               2009                 : 
                               2010             463 :     if (ssup->abbreviate)
                               2011                 :     {
 2929 rhaas                    2012 ECB             :         NumericSortSupport *nss;
 2929 rhaas                    2013 CBC         111 :         MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
                               2014                 : 
 2929 rhaas                    2015 GIC         111 :         nss = palloc(sizeof(NumericSortSupport));
                               2016                 : 
 2929 rhaas                    2017 ECB             :         /*
                               2018                 :          * palloc a buffer for handling unaligned packed values in addition to
                               2019                 :          * the support struct
                               2020                 :          */
 2929 rhaas                    2021 CBC         111 :         nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
 2929 rhaas                    2022 ECB             : 
 2929 rhaas                    2023 CBC         111 :         nss->input_count = 0;
 2929 rhaas                    2024 GIC         111 :         nss->estimating = true;
                               2025             111 :         initHyperLogLog(&nss->abbr_card, 10);
                               2026                 : 
                               2027             111 :         ssup->ssup_extra = nss;
                               2028                 : 
                               2029             111 :         ssup->abbrev_full_comparator = ssup->comparator;
                               2030             111 :         ssup->comparator = numeric_cmp_abbrev;
 2929 rhaas                    2031 CBC         111 :         ssup->abbrev_converter = numeric_abbrev_convert;
                               2032             111 :         ssup->abbrev_abort = numeric_abbrev_abort;
                               2033                 : 
 2929 rhaas                    2034 GIC         111 :         MemoryContextSwitchTo(oldcontext);
 2929 rhaas                    2035 ECB             :     }
                               2036                 : 
 2929 rhaas                    2037 GIC         463 :     PG_RETURN_VOID();
                               2038                 : }
 2929 rhaas                    2039 ECB             : 
                               2040                 : /*
                               2041                 :  * Abbreviate a numeric datum, handling NaNs and detoasting
                               2042                 :  * (must not leak memory!)
                               2043                 :  */
                               2044                 : static Datum
 2929 rhaas                    2045 GIC         443 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
                               2046                 : {
                               2047             443 :     NumericSortSupport *nss = ssup->ssup_extra;
                               2048             443 :     void       *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
                               2049                 :     Numeric     value;
                               2050                 :     Datum       result;
                               2051                 : 
                               2052             443 :     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             443 :     if (VARATT_IS_SHORT(original_varatt))
                               2059                 :     {
                               2060             408 :         void       *buf = nss->buf;
                               2061             408 :         Size        sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
                               2062                 : 
                               2063             408 :         Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
                               2064                 : 
                               2065             408 :         SET_VARSIZE(buf, VARHDRSZ + sz);
                               2066             408 :         memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
                               2067                 : 
                               2068             408 :         value = (Numeric) buf;
                               2069                 :     }
                               2070                 :     else
                               2071              35 :         value = (Numeric) original_varatt;
                               2072                 : 
  991 tgl                      2073             443 :     if (NUMERIC_IS_SPECIAL(value))
                               2074                 :     {
                               2075              75 :         if (NUMERIC_IS_PINF(value))
                               2076              24 :             result = NUMERIC_ABBREV_PINF;
                               2077              51 :         else if (NUMERIC_IS_NINF(value))
                               2078              24 :             result = NUMERIC_ABBREV_NINF;
                               2079                 :         else
                               2080              27 :             result = NUMERIC_ABBREV_NAN;
                               2081                 :     }
                               2082                 :     else
                               2083                 :     {
                               2084                 :         NumericVar  var;
                               2085                 : 
 2929 rhaas                    2086 CBC         368 :         init_var_from_num(value, &var);
                               2087                 : 
                               2088             368 :         result = numeric_abbrev_convert_var(&var, nss);
                               2089                 :     }
 2929 rhaas                    2090 ECB             : 
                               2091                 :     /* should happen only for external/compressed toasts */
 2929 rhaas                    2092 CBC         443 :     if ((Pointer) original_varatt != DatumGetPointer(original_datum))
 2929 rhaas                    2093 UIC           0 :         pfree(original_varatt);
                               2094                 : 
 2929 rhaas                    2095 CBC         443 :     return result;
                               2096                 : }
 2929 rhaas                    2097 ECB             : 
                               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
 2929 rhaas                    2107 CBC           3 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
                               2108                 : {
                               2109               3 :     NumericSortSupport *nss = ssup->ssup_extra;
                               2110                 :     double      abbr_card;
 2929 rhaas                    2111 ECB             : 
 2929 rhaas                    2112 CBC           3 :     if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
                               2113               3 :         return false;
 2929 rhaas                    2114 ECB             : 
 2929 rhaas                    2115 UIC           0 :     abbr_card = estimateHyperLogLog(&nss->abbr_card);
 2929 rhaas                    2116 ECB             : 
                               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                 :      */
 2929 rhaas                    2123 UIC           0 :     if (abbr_card > 100000.0)
                               2124                 :     {
                               2125                 : #ifdef TRACE_SORT
                               2126               0 :         if (trace_sort)
 2929 rhaas                    2127 LBC           0 :             elog(LOG,
                               2128                 :                  "numeric_abbrev: estimation ends at cardinality %f"
 2929 rhaas                    2129 ECB             :                  " after " INT64_FORMAT " values (%d rows)",
                               2130                 :                  abbr_card, nss->input_count, memtupcount);
                               2131                 : #endif
 2929 rhaas                    2132 UIC           0 :         nss->estimating = false;
                               2133               0 :         return false;
 2929 rhaas                    2134 ECB             :     }
                               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                 :      */
 2929 rhaas                    2145 LBC           0 :     if (abbr_card < nss->input_count / 10000.0 + 0.5)
                               2146                 :     {
 2929 rhaas                    2147 ECB             : #ifdef TRACE_SORT
 2929 rhaas                    2148 LBC           0 :         if (trace_sort)
 2929 rhaas                    2149 UIC           0 :             elog(LOG,
 2929 rhaas                    2150 ECB             :                  "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
 2929 rhaas                    2155 LBC           0 :         return true;
                               2156                 :     }
 2929 rhaas                    2157 ECB             : 
                               2158                 : #ifdef TRACE_SORT
 2929 rhaas                    2159 LBC           0 :     if (trace_sort)
                               2160               0 :         elog(LOG,
                               2161                 :              "numeric_abbrev: cardinality %f"
 2929 rhaas                    2162 ECB             :              " after " INT64_FORMAT " values (%d rows)",
                               2163                 :              abbr_card, nss->input_count, memtupcount);
                               2164                 : #endif
                               2165                 : 
 2929 rhaas                    2166 UIC           0 :     return false;
                               2167                 : }
 2929 rhaas                    2168 ECB             : 
                               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                 :  *
 2929 rhaas                    2175 EUB             :  * 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
 2929 rhaas                    2177 ECB             :  * be worth the effort.
                               2178                 :  */
                               2179                 : static int
 2929 rhaas                    2180 GIC     2345834 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
                               2181                 : {
                               2182         2345834 :     Numeric     nx = DatumGetNumeric(x);
                               2183         2345834 :     Numeric     ny = DatumGetNumeric(y);
                               2184                 :     int         result;
                               2185                 : 
                               2186         2345834 :     result = cmp_numerics(nx, ny);
                               2187                 : 
                               2188         2345834 :     if ((Pointer) nx != DatumGetPointer(x))
 2929 rhaas                    2189 CBC       86331 :         pfree(nx);
 2929 rhaas                    2190 GIC     2345834 :     if ((Pointer) ny != DatumGetPointer(y))
 2929 rhaas                    2191 CBC       86328 :         pfree(ny);
                               2192                 : 
 2929 rhaas                    2193 GIC     2345834 :     return result;
 2929 rhaas                    2194 ECB             : }
                               2195                 : 
                               2196                 : /*
 2929 rhaas                    2197 EUB             :  * 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
 2929 rhaas                    2202 GIC         463 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
                               2203                 : {
                               2204                 :     /*
 2929 rhaas                    2205 EUB             :      * NOTE WELL: this is intentionally backwards, because the abbreviation is
                               2206                 :      * negated relative to the original value, to handle NaN/infinity cases.
                               2207                 :      */
 2929 rhaas                    2208 GBC         463 :     if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
                               2209              60 :         return 1;
 2929 rhaas                    2210 GIC         403 :     if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
                               2211             370 :         return -1;
                               2212              33 :     return 0;
                               2213                 : }
 2929 rhaas                    2214 EUB             : 
                               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
 2929 rhaas                    2262 ECB             : 
                               2263                 : static Datum
 2037 andres                   2264 CBC         368 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
 2929 rhaas                    2265 ECB             : {
 2929 rhaas                    2266 GIC         368 :     int         ndigits = var->ndigits;
                               2267             368 :     int         weight = var->weight;
 2929 rhaas                    2268 ECB             :     int64       result;
                               2269                 : 
 2929 rhaas                    2270 CBC         368 :     if (ndigits == 0 || weight < -44)
 2929 rhaas                    2271 ECB             :     {
 2929 rhaas                    2272 CBC          26 :         result = 0;
 2929 rhaas                    2273 ECB             :     }
 2929 rhaas                    2274 GIC         342 :     else if (weight > 83)
 2929 rhaas                    2275 ECB             :     {
 2929 rhaas                    2276 GIC           6 :         result = PG_INT64_MAX;
                               2277                 :     }
                               2278                 :     else
                               2279                 :     {
                               2280             336 :         result = ((int64) (weight + 44) << 56);
                               2281                 : 
                               2282             336 :         switch (ndigits)
                               2283                 :         {
 2929 rhaas                    2284 LBC           0 :             default:
 2929 rhaas                    2285 UIC           0 :                 result |= ((int64) var->digits[3]);
                               2286                 :                 /* FALLTHROUGH */
 2929 rhaas                    2287 GIC           2 :             case 3:
                               2288               2 :                 result |= ((int64) var->digits[2]) << 14;
                               2289                 :                 /* FALLTHROUGH */
 2929 rhaas                    2290 CBC          80 :             case 2:
                               2291              80 :                 result |= ((int64) var->digits[1]) << 28;
 2929 rhaas                    2292 ECB             :                 /* FALLTHROUGH */
 2929 rhaas                    2293 CBC         336 :             case 1:
                               2294             336 :                 result |= ((int64) var->digits[0]) << 42;
 2929 rhaas                    2295 GIC         336 :                 break;
                               2296                 :         }
                               2297                 :     }
                               2298                 : 
                               2299                 :     /* the abbrev is negated relative to the original */
                               2300             368 :     if (var->sign == NUMERIC_POS)
                               2301             319 :         result = -result;
                               2302                 : 
                               2303             368 :     if (nss->estimating)
                               2304                 :     {
                               2305             368 :         uint32      tmp = ((uint32) result
                               2306             368 :                            ^ (uint32) ((uint64) result >> 32));
                               2307                 : 
                               2308             368 :         addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
                               2309                 :     }
                               2310                 : 
 2928                          2311             368 :     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                 : 
 2929 rhaas                    2346 ECB             :         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                 :         }
 2929 rhaas                    2366 EUB             :         else
                               2367                 :         {
                               2368                 :             NumericDigit nxt2 = (ndigits > 2) ? var->digits[2] : 0;
 2929 rhaas                    2369 ECB             : 
                               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                 : 
 2928                          2388                 :     return NumericAbbrevGetDatum(result);
                               2389                 : }
 2929                          2390                 : 
                               2391                 : #endif                          /* NUMERIC_ABBREV_BITS == 32 */
                               2392                 : 
                               2393                 : /*
                               2394                 :  * Ordinary (non-sortsupport) comparisons follow.
                               2395                 :  */
                               2396                 : 
                               2397                 : Datum
 8289 tgl                      2398 GIC      468176 : numeric_cmp(PG_FUNCTION_ARGS)
                               2399                 : {
                               2400          468176 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2401          468176 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2402                 :     int         result;
                               2403                 : 
 8011                          2404          468176 :     result = cmp_numerics(num1, num2);
                               2405                 : 
 8289                          2406          468176 :     PG_FREE_IF_COPY(num1, 0);
                               2407          468176 :     PG_FREE_IF_COPY(num2, 1);
                               2408                 : 
                               2409          468176 :     PG_RETURN_INT32(result);
                               2410                 : }
                               2411                 : 
                               2412                 : 
                               2413                 : Datum
                               2414          317512 : numeric_eq(PG_FUNCTION_ARGS)
                               2415                 : {
                               2416          317512 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2417          317512 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2418                 :     bool        result;
                               2419                 : 
 8011                          2420          317512 :     result = cmp_numerics(num1, num2) == 0;
                               2421                 : 
 8289                          2422          317512 :     PG_FREE_IF_COPY(num1, 0);
                               2423          317512 :     PG_FREE_IF_COPY(num2, 1);
                               2424                 : 
                               2425          317512 :     PG_RETURN_BOOL(result);
                               2426                 : }
                               2427                 : 
                               2428                 : Datum
                               2429            2661 : numeric_ne(PG_FUNCTION_ARGS)
                               2430                 : {
                               2431            2661 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2432            2661 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2433                 :     bool        result;
                               2434                 : 
 8011                          2435            2661 :     result = cmp_numerics(num1, num2) != 0;
                               2436                 : 
 8289                          2437            2661 :     PG_FREE_IF_COPY(num1, 0);
                               2438            2661 :     PG_FREE_IF_COPY(num2, 1);
                               2439                 : 
                               2440            2661 :     PG_RETURN_BOOL(result);
                               2441                 : }
                               2442                 : 
                               2443                 : Datum
                               2444           18620 : numeric_gt(PG_FUNCTION_ARGS)
                               2445                 : {
                               2446           18620 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2447           18620 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2448                 :     bool        result;
                               2449                 : 
 8011                          2450           18620 :     result = cmp_numerics(num1, num2) > 0;
                               2451                 : 
 8289                          2452           18620 :     PG_FREE_IF_COPY(num1, 0);
                               2453           18620 :     PG_FREE_IF_COPY(num2, 1);
                               2454                 : 
                               2455           18620 :     PG_RETURN_BOOL(result);
                               2456                 : }
                               2457                 : 
                               2458                 : Datum
                               2459            8364 : numeric_ge(PG_FUNCTION_ARGS)
                               2460                 : {
                               2461            8364 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2462            8364 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2463                 :     bool        result;
                               2464                 : 
 8011                          2465            8364 :     result = cmp_numerics(num1, num2) >= 0;
                               2466                 : 
 8289                          2467            8364 :     PG_FREE_IF_COPY(num1, 0);
                               2468            8364 :     PG_FREE_IF_COPY(num2, 1);
                               2469                 : 
                               2470            8364 :     PG_RETURN_BOOL(result);
                               2471                 : }
                               2472                 : 
                               2473                 : Datum
                               2474           53158 : numeric_lt(PG_FUNCTION_ARGS)
                               2475                 : {
                               2476           53158 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2477           53158 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2478                 :     bool        result;
                               2479                 : 
 8011 tgl                      2480 CBC       53158 :     result = cmp_numerics(num1, num2) < 0;
                               2481                 : 
 8289                          2482           53158 :     PG_FREE_IF_COPY(num1, 0);
                               2483           53158 :     PG_FREE_IF_COPY(num2, 1);
                               2484                 : 
 8289 tgl                      2485 GIC       53158 :     PG_RETURN_BOOL(result);
 8289 tgl                      2486 ECB             : }
                               2487                 : 
                               2488                 : Datum
 8289 tgl                      2489 CBC        8246 : numeric_le(PG_FUNCTION_ARGS)
                               2490                 : {
                               2491            8246 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
 8289 tgl                      2492 GIC        8246 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2493                 :     bool        result;
                               2494                 : 
 8011                          2495            8246 :     result = cmp_numerics(num1, num2) <= 0;
 8011 tgl                      2496 ECB             : 
 8011 tgl                      2497 GIC        8246 :     PG_FREE_IF_COPY(num1, 0);
 8011 tgl                      2498 CBC        8246 :     PG_FREE_IF_COPY(num2, 1);
 8011 tgl                      2499 ECB             : 
 8011 tgl                      2500 GIC        8246 :     PG_RETURN_BOOL(result);
                               2501                 : }
 8011 tgl                      2502 ECB             : 
                               2503                 : static int
 8011 tgl                      2504 CBC     3223747 : cmp_numerics(Numeric num1, Numeric num2)
 8011 tgl                      2505 ECB             : {
                               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
  991                          2511                 :      * a consistent sort order.
                               2512                 :      */
  991 tgl                      2513 CBC     3223747 :     if (NUMERIC_IS_SPECIAL(num1))
 8011 tgl                      2514 ECB             :     {
  991 tgl                      2515 GIC        4450 :         if (NUMERIC_IS_NAN(num1))
                               2516                 :         {
  991 tgl                      2517 CBC        4405 :             if (NUMERIC_IS_NAN(num2))
  991 tgl                      2518 GIC         574 :                 result = 0;     /* NAN = NAN */
  991 tgl                      2519 ECB             :             else
  991 tgl                      2520 CBC        3831 :                 result = 1;     /* NAN > non-NAN */
                               2521                 :         }
                               2522              45 :         else if (NUMERIC_IS_PINF(num1))
                               2523                 :         {
  991 tgl                      2524 GIC          36 :             if (NUMERIC_IS_NAN(num2))
  991 tgl                      2525 UIC           0 :                 result = -1;    /* PINF < NAN */
  991 tgl                      2526 CBC          36 :             else if (NUMERIC_IS_PINF(num2))
  991 tgl                      2527 GIC           3 :                 result = 0;     /* PINF = PINF */
  991 tgl                      2528 ECB             :             else
  991 tgl                      2529 CBC          33 :                 result = 1;     /* PINF > anything else */
                               2530                 :         }
                               2531                 :         else                    /* num1 must be NINF */
  991 tgl                      2532 ECB             :         {
  991 tgl                      2533 GIC           9 :             if (NUMERIC_IS_NINF(num2))
  991 tgl                      2534 CBC           3 :                 result = 0;     /* NINF = NINF */
  991 tgl                      2535 ECB             :             else
  991 tgl                      2536 GIC           6 :                 result = -1;    /* NINF < anything else */
  991 tgl                      2537 ECB             :         }
                               2538                 :     }
  991 tgl                      2539 GIC     3219297 :     else if (NUMERIC_IS_SPECIAL(num2))
                               2540                 :     {
  991 tgl                      2541 CBC        5628 :         if (NUMERIC_IS_NINF(num2))
  991 tgl                      2542 GIC           6 :             result = 1;         /* normal > NINF */
  991 tgl                      2543 ECB             :         else
  991 tgl                      2544 CBC        5622 :             result = -1;        /* normal < NAN or PINF */
                               2545                 :     }
                               2546                 :     else
 8289 tgl                      2547 ECB             :     {
 6270 bruce                    2548 GIC     6427872 :         result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
 4632 rhaas                    2549 CBC     3213821 :                                 NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
 6270 bruce                    2550         3213669 :                                 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
 4632 rhaas                    2551 GIC     3214051 :                                 NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
 8289 tgl                      2552 ECB             :     }
                               2553                 : 
 8011 tgl                      2554 GIC     3223747 :     return result;
                               2555                 : }
 8866 JanWieck                 2556 ECB             : 
                               2557                 : /*
 1870 tgl                      2558                 :  * in_range support function for numeric.
                               2559                 :  */
                               2560                 : Datum
 1870 tgl                      2561 GIC         576 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
 1870 tgl                      2562 ECB             : {
 1870 tgl                      2563 GIC         576 :     Numeric     val = PG_GETARG_NUMERIC(0);
 1870 tgl                      2564 CBC         576 :     Numeric     base = PG_GETARG_NUMERIC(1);
                               2565             576 :     Numeric     offset = PG_GETARG_NUMERIC(2);
 1870 tgl                      2566 GIC         576 :     bool        sub = PG_GETARG_BOOL(3);
 1870 tgl                      2567 CBC         576 :     bool        less = PG_GETARG_BOOL(4);
                               2568                 :     bool        result;
                               2569                 : 
                               2570                 :     /*
  991 tgl                      2571 ECB             :      * Reject negative (including -Inf) or NaN offset.  Negative is per spec,
                               2572                 :      * and NaN is because appropriate semantics for that seem non-obvious.
 1870                          2573                 :      */
  991 tgl                      2574 CBC         576 :     if (NUMERIC_IS_NAN(offset) ||
  991 tgl                      2575 GIC         573 :         NUMERIC_IS_NINF(offset) ||
                               2576             573 :         NUMERIC_SIGN(offset) == NUMERIC_NEG)
 1870 tgl                      2577 CBC           3 :         ereport(ERROR,
                               2578                 :                 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
 1870 tgl                      2579 ECB             :                  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                 :      */
 1870 tgl                      2586 CBC         573 :     if (NUMERIC_IS_NAN(val))
                               2587                 :     {
 1870 tgl                      2588 GIC          93 :         if (NUMERIC_IS_NAN(base))
                               2589              30 :             result = true;      /* NAN = NAN */
                               2590                 :         else
                               2591              63 :             result = !less;     /* NAN > non-NAN */
                               2592                 :     }
                               2593             480 :     else if (NUMERIC_IS_NAN(base))
                               2594                 :     {
 1870 tgl                      2595 CBC          63 :         result = less;          /* non-NAN < NAN */
                               2596                 :     }
  991 tgl                      2597 ECB             : 
                               2598                 :     /*
                               2599                 :      * Deal with infinite offset (necessarily +Inf, at this point).
                               2600                 :      */
  991 tgl                      2601 GIC         417 :     else if (NUMERIC_IS_SPECIAL(offset))
  991 tgl                      2602 ECB             :     {
  991 tgl                      2603 GIC         210 :         Assert(NUMERIC_IS_PINF(offset));
  991 tgl                      2604 CBC         210 :         if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
                               2605                 :         {
  991 tgl                      2606 ECB             :             /*
  991 tgl                      2607 EUB             :              * base +/- offset would produce NaN, so return true for any val
  991 tgl                      2608 ECB             :              * (see in_range_float8_float8() for reasoning).
                               2609                 :              */
  991 tgl                      2610 GIC          87 :             result = true;
  991 tgl                      2611 ECB             :         }
  991 tgl                      2612 GIC         123 :         else if (sub)
                               2613                 :         {
                               2614                 :             /* base - offset must be -inf */
  991 tgl                      2615 CBC          75 :             if (less)
                               2616              27 :                 result = NUMERIC_IS_NINF(val);  /* only -inf is <= sum */
                               2617                 :             else
                               2618              48 :                 result = true;  /* any val is >= sum */
                               2619                 :         }
                               2620                 :         else
  991 tgl                      2621 ECB             :         {
                               2622                 :             /* base + offset must be +inf */
  991 tgl                      2623 CBC          48 :             if (less)
  991 tgl                      2624 LBC           0 :                 result = true;  /* any val is <= sum */
                               2625                 :             else
  991 tgl                      2626 CBC          48 :                 result = NUMERIC_IS_PINF(val);  /* only +inf is >= sum */
                               2627                 :         }
                               2628                 :     }
                               2629                 : 
  991 tgl                      2630 ECB             :     /*
                               2631                 :      * Deal with cases where val and/or base is infinite.  The offset, being
                               2632                 :      * now known finite, cannot affect the conclusion.
                               2633                 :      */
  991 tgl                      2634 GIC         207 :     else if (NUMERIC_IS_SPECIAL(val))
                               2635                 :     {
  991 tgl                      2636 CBC          39 :         if (NUMERIC_IS_PINF(val))
                               2637                 :         {
  991 tgl                      2638 GIC          18 :             if (NUMERIC_IS_PINF(base))
                               2639              12 :                 result = true;  /* PINF = PINF */
                               2640                 :             else
                               2641               6 :                 result = !less; /* PINF > any other non-NAN */
                               2642                 :         }
  991 tgl                      2643 ECB             :         else                    /* val must be NINF */
                               2644                 :         {
  991 tgl                      2645 CBC          21 :             if (NUMERIC_IS_NINF(base))
                               2646              15 :                 result = true;  /* NINF = NINF */
  991 tgl                      2647 ECB             :             else
  991 tgl                      2648 CBC           6 :                 result = less;  /* NINF < anything else */
  991 tgl                      2649 ECB             :         }
                               2650                 :     }
  991 tgl                      2651 GIC         168 :     else if (NUMERIC_IS_SPECIAL(base))
                               2652                 :     {
                               2653              12 :         if (NUMERIC_IS_NINF(base))
                               2654               6 :             result = !less;     /* normal > NINF */
                               2655                 :         else
  991 tgl                      2656 CBC           6 :             result = less;      /* normal < PINF */
  991 tgl                      2657 ECB             :     }
 1870                          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                 : 
 1870 tgl                      2670 CBC         156 :         init_var_from_num(val, &valv);
                               2671             156 :         init_var_from_num(base, &basev);
 1870 tgl                      2672 GIC         156 :         init_var_from_num(offset, &offsetv);
 1870 tgl                      2673 CBC         156 :         init_var(&sum);
                               2674                 : 
                               2675             156 :         if (sub)
 1870 tgl                      2676 GIC          78 :             sub_var(&basev, &offsetv, &sum);
 1870 tgl                      2677 ECB             :         else
 1870 tgl                      2678 GIC          78 :             add_var(&basev, &offsetv, &sum);
                               2679                 : 
                               2680             156 :         if (less)
                               2681              78 :             result = (cmp_var(&valv, &sum) <= 0);
                               2682                 :         else
 1870 tgl                      2683 CBC          78 :             result = (cmp_var(&valv, &sum) >= 0);
                               2684                 : 
                               2685             156 :         free_var(&sum);
 1870 tgl                      2686 ECB             :     }
                               2687                 : 
 1870 tgl                      2688 GIC         573 :     PG_FREE_IF_COPY(val, 0);
                               2689             573 :     PG_FREE_IF_COPY(base, 1);
                               2690             573 :     PG_FREE_IF_COPY(offset, 2);
                               2691                 : 
 1870 tgl                      2692 CBC         573 :     PG_RETURN_BOOL(result);
                               2693                 : }
 1870 tgl                      2694 ECB             : 
                               2695                 : Datum
 5815 neilc                    2696 GIC      296013 : hash_numeric(PG_FUNCTION_ARGS)
 5815 neilc                    2697 ECB             : {
 5624 bruce                    2698 CBC      296013 :     Numeric     key = PG_GETARG_NUMERIC(0);
                               2699                 :     Datum       digit_hash;
 5624 bruce                    2700 ECB             :     Datum       result;
                               2701                 :     int         weight;
                               2702                 :     int         start_offset;
                               2703                 :     int         end_offset;
                               2704                 :     int         i;
                               2705                 :     int         hash_len;
 4382 bruce                    2706 EUB             :     NumericDigit *digits;
                               2707                 : 
  991 tgl                      2708 ECB             :     /* If it's NaN or infinity, don't try to hash the rest of the fields */
  991 tgl                      2709 GIC      296013 :     if (NUMERIC_IS_SPECIAL(key))
 5815 neilc                    2710 UIC           0 :         PG_RETURN_UINT32(0);
                               2711                 : 
 4632 rhaas                    2712 GIC      296013 :     weight = NUMERIC_WEIGHT(key);
 5815 neilc                    2713          296013 :     start_offset = 0;
 5624 bruce                    2714          296013 :     end_offset = 0;
                               2715                 : 
 5815 neilc                    2716 ECB             :     /*
                               2717                 :      * Omit any leading or trailing zeros from the input to the hash. The
 5624 bruce                    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.
 5815 neilc                    2721                 :      */
 4632 rhaas                    2722 GIC      296013 :     digits = NUMERIC_DIGITS(key);
 5815 neilc                    2723 CBC      296013 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
                               2724                 :     {
 4632 rhaas                    2725 GIC      295266 :         if (digits[i] != (NumericDigit) 0)
 5815 neilc                    2726          295266 :             break;
 5815 neilc                    2727 ECB             : 
 5815 neilc                    2728 LBC           0 :         start_offset++;
                               2729                 : 
 5815 neilc                    2730 ECB             :         /*
                               2731                 :          * The weight is effectively the # of digits before the decimal point,
                               2732                 :          * so decrement it for each leading zero we skip.
                               2733                 :          */
 5815 neilc                    2734 UIC           0 :         weight--;
 5815 neilc                    2735 ECB             :     }
                               2736                 : 
                               2737                 :     /*
 5624 bruce                    2738                 :      * If there are no non-zero digits, then the value of the number is zero,
                               2739                 :      * regardless of any other fields.
                               2740                 :      */
 5815 neilc                    2741 GIC      296013 :     if (NUMERIC_NDIGITS(key) == start_offset)
                               2742             747 :         PG_RETURN_UINT32(-1);
                               2743                 : 
                               2744          295266 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
                               2745                 :     {
 4632 rhaas                    2746          295266 :         if (digits[i] != (NumericDigit) 0)
 5815 neilc                    2747          295266 :             break;
                               2748                 : 
 5815 neilc                    2749 UIC           0 :         end_offset++;
                               2750                 :     }
                               2751                 : 
 5815 neilc                    2752 ECB             :     /* If we get here, there should be at least one non-zero digit */
 5815 neilc                    2753 CBC      295266 :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
 5815 neilc                    2754 ECB             : 
                               2755                 :     /*
                               2756                 :      * Note that we don't hash on the Numeric's scale, since two numerics can
 5624 bruce                    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.
 5815 neilc                    2760                 :      */
 5815 neilc                    2761 GIC      295266 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
 5815 neilc                    2762 CBC      295266 :     digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
 5624 bruce                    2763 ECB             :                           hash_len * sizeof(NumericDigit));
                               2764                 : 
 5815 neilc                    2765                 :     /* Mix in the weight, via XOR */
 5815 neilc                    2766 GIC      295266 :     result = digit_hash ^ weight;
 5815 neilc                    2767 ECB             : 
 5815 neilc                    2768 GIC      295266 :     PG_RETURN_DATUM(result);
                               2769                 : }
 5815 neilc                    2770 ECB             : 
 2047 rhaas                    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
 2047 rhaas                    2776 GIC          42 : hash_numeric_extended(PG_FUNCTION_ARGS)
                               2777                 : {
 2047 rhaas                    2778 CBC          42 :     Numeric     key = PG_GETARG_NUMERIC(0);
 2047 rhaas                    2779 GIC          42 :     uint64      seed = PG_GETARG_INT64(1);
 2047 rhaas                    2780 ECB             :     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 */
  991 tgl                      2790 GIC          42 :     if (NUMERIC_IS_SPECIAL(key))
 2047 rhaas                    2791 LBC           0 :         PG_RETURN_UINT64(seed);
 2047 rhaas                    2792 EUB             : 
 2047 rhaas                    2793 GIC          42 :     weight = NUMERIC_WEIGHT(key);
 2047 rhaas                    2794 CBC          42 :     start_offset = 0;
                               2795              42 :     end_offset = 0;
 2047 rhaas                    2796 ECB             : 
 2047 rhaas                    2797 GIC          42 :     digits = NUMERIC_DIGITS(key);
                               2798              42 :     for (i = 0; i < NUMERIC_NDIGITS(key); i++)
                               2799                 :     {
                               2800              36 :         if (digits[i] != (NumericDigit) 0)
                               2801              36 :             break;
                               2802                 : 
 2047 rhaas                    2803 UIC           0 :         start_offset++;
 2047 rhaas                    2804 ECB             : 
 2047 rhaas                    2805 LBC           0 :         weight--;
                               2806                 :     }
 2047 rhaas                    2807 ECB             : 
 2047 rhaas                    2808 CBC          42 :     if (NUMERIC_NDIGITS(key) == start_offset)
 2047 rhaas                    2809 GIC           6 :         PG_RETURN_UINT64(seed - 1);
 2047 rhaas                    2810 EUB             : 
 2047 rhaas                    2811 GIC          36 :     for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
                               2812                 :     {
                               2813              36 :         if (digits[i] != (NumericDigit) 0)
                               2814              36 :             break;
                               2815                 : 
 2047 rhaas                    2816 UBC           0 :         end_offset++;
                               2817                 :     }
                               2818                 : 
 2047 rhaas                    2819 GIC          36 :     Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
                               2820                 : 
                               2821              36 :     hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
                               2822              36 :     digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
 2047 rhaas                    2823 CBC          36 :                                                       + start_offset),
 2047 rhaas                    2824 ECB             :                                    hash_len * sizeof(NumericDigit),
                               2825                 :                                    seed);
                               2826                 : 
 2046 rhaas                    2827 GIC          36 :     result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
 2047 rhaas                    2828 ECB             : 
 2047 rhaas                    2829 CBC          36 :     PG_RETURN_DATUM(result);
                               2830                 : }
 2047 rhaas                    2831 EUB             : 
                               2832                 : 
                               2833                 : /* ----------------------------------------------------------------------
                               2834                 :  *
 7324 tgl                      2835 ECB             :  * Basic arithmetic functions
                               2836                 :  *
                               2837                 :  * ----------------------------------------------------------------------
                               2838                 :  */
                               2839                 : 
                               2840                 : 
                               2841                 : /*
                               2842                 :  * numeric_add() -
 8866 JanWieck                 2843                 :  *
                               2844                 :  *  Add two numerics
                               2845                 :  */
                               2846                 : Datum
 8289 tgl                      2847 GIC      125968 : numeric_add(PG_FUNCTION_ARGS)
 8866 JanWieck                 2848 ECB             : {
 8289 tgl                      2849 GIC      125968 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
 8289 tgl                      2850 CBC      125968 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2851                 :     Numeric     res;
                               2852                 : 
 1485 akorotkov                2853 GIC      125968 :     res = numeric_add_opt_error(num1, num2, NULL);
                               2854                 : 
                               2855          125968 :     PG_RETURN_NUMERIC(res);
                               2856                 : }
                               2857                 : 
 1485 akorotkov                2858 ECB             : /*
                               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
 1485 akorotkov                2866 GIC      126391 : numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
                               2867                 : {
                               2868                 :     NumericVar  arg1;
                               2869                 :     NumericVar  arg2;
                               2870                 :     NumericVar  result;
                               2871                 :     Numeric     res;
 8866 JanWieck                 2872 ECB             : 
 8053 bruce                    2873 EUB             :     /*
                               2874                 :      * Handle NaN and infinities
 8866 JanWieck                 2875 ECB             :      */
  991 tgl                      2876 CBC      126391 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
  991 tgl                      2877 ECB             :     {
  991 tgl                      2878 GIC          99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
  991 tgl                      2879 CBC          39 :             return make_result(&const_nan);
                               2880              60 :         if (NUMERIC_IS_PINF(num1))
                               2881                 :         {
                               2882              18 :             if (NUMERIC_IS_NINF(num2))
                               2883               3 :                 return make_result(&const_nan); /* Inf + -Inf */
                               2884                 :             else
  991 tgl                      2885 GBC          15 :                 return make_result(&const_pinf);
                               2886                 :         }
                               2887              42 :         if (NUMERIC_IS_NINF(num1))
                               2888                 :         {
  991 tgl                      2889 GIC          18 :             if (NUMERIC_IS_PINF(num2))
  991 tgl                      2890 CBC           3 :                 return make_result(&const_nan); /* -Inf + Inf */
  991 tgl                      2891 ECB             :             else
  991 tgl                      2892 GIC          15 :                 return make_result(&const_ninf);
  991 tgl                      2893 ECB             :         }
                               2894                 :         /* by here, num1 must be finite, so num2 is not */
  991 tgl                      2895 CBC          24 :         if (NUMERIC_IS_PINF(num2))
                               2896              12 :             return make_result(&const_pinf);
  991 tgl                      2897 GIC          12 :         Assert(NUMERIC_IS_NINF(num2));
  991 tgl                      2898 GBC          12 :         return make_result(&const_ninf);
                               2899                 :     }
                               2900                 : 
 8053 bruce                    2901 ECB             :     /*
                               2902                 :      * Unpack the values, let add_var() compute the result and return it.
 8866 JanWieck                 2903                 :      */
 3791 heikki.linnakangas       2904 CBC      126292 :     init_var_from_num(num1, &arg1);
                               2905          126292 :     init_var_from_num(num2, &arg2);
                               2906                 : 
 3791 heikki.linnakangas       2907 GIC      126292 :     init_var(&result);
 8866 JanWieck                 2908          126292 :     add_var(&arg1, &arg2, &result);
 7324 tgl                      2909 ECB             : 
 1485 akorotkov                2910 GIC      126292 :     res = make_result_opt_error(&result, have_error);
 8866 JanWieck                 2911 ECB             : 
 8866 JanWieck                 2912 GIC      126292 :     free_var(&result);
                               2913                 : 
 1485 akorotkov                2914          126292 :     return res;
                               2915                 : }
                               2916                 : 
                               2917                 : 
                               2918                 : /*
                               2919                 :  * numeric_sub() -
                               2920                 :  *
                               2921                 :  *  Subtract one numeric from another
                               2922                 :  */
                               2923                 : Datum
 8289 tgl                      2924           27016 : numeric_sub(PG_FUNCTION_ARGS)
                               2925                 : {
                               2926           27016 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               2927           27016 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               2928                 :     Numeric     res;
 1485 akorotkov                2929 ECB             : 
 1485 akorotkov                2930 GIC       27016 :     res = numeric_sub_opt_error(num1, num2, NULL);
 1485 akorotkov                2931 ECB             : 
 1485 akorotkov                2932 CBC       27016 :     PG_RETURN_NUMERIC(res);
                               2933                 : }
                               2934                 : 
 1485 akorotkov                2935 ECB             : 
                               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
 1485 akorotkov                2944 GIC       27043 : numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
                               2945                 : {
                               2946                 :     NumericVar  arg1;
                               2947                 :     NumericVar  arg2;
 8866 JanWieck                 2948 ECB             :     NumericVar  result;
                               2949                 :     Numeric     res;
                               2950                 : 
                               2951                 :     /*
                               2952                 :      * Handle NaN and infinities
                               2953                 :      */
  991 tgl                      2954 GIC       27043 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
                               2955                 :     {
                               2956            1205 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
                               2957            1145 :             return make_result(&const_nan);
  991 tgl                      2958 CBC          60 :         if (NUMERIC_IS_PINF(num1))
                               2959                 :         {
                               2960              18 :             if (NUMERIC_IS_PINF(num2))
                               2961               3 :                 return make_result(&const_nan); /* Inf - Inf */
  991 tgl                      2962 ECB             :             else
  991 tgl                      2963 GIC          15 :                 return make_result(&const_pinf);
  991 tgl                      2964 ECB             :         }
  991 tgl                      2965 CBC          42 :         if (NUMERIC_IS_NINF(num1))
                               2966                 :         {
                               2967              18 :             if (NUMERIC_IS_NINF(num2))
  991 tgl                      2968 GIC           3 :                 return make_result(&const_nan); /* -Inf - -Inf */
  991 tgl                      2969 ECB             :             else
  991 tgl                      2970 GIC          15 :                 return make_result(&const_ninf);
  991 tgl                      2971 ECB             :         }
                               2972                 :         /* by here, num1 must be finite, so num2 is not */
  991 tgl                      2973 GIC          24 :         if (NUMERIC_IS_PINF(num2))
  991 tgl                      2974 CBC          12 :             return make_result(&const_ninf);
  991 tgl                      2975 GIC          12 :         Assert(NUMERIC_IS_NINF(num2));
                               2976              12 :         return make_result(&const_pinf);
  991 tgl                      2977 ECB             :     }
 8866 JanWieck                 2978                 : 
 8053 bruce                    2979                 :     /*
 7324 tgl                      2980                 :      * Unpack the values, let sub_var() compute the result and return it.
                               2981                 :      */
 3791 heikki.linnakangas       2982 GIC       25838 :     init_var_from_num(num1, &arg1);
                               2983           25838 :     init_var_from_num(num2, &arg2);
                               2984                 : 
                               2985           25838 :     init_var(&result);
 8866 JanWieck                 2986 CBC       25838 :     sub_var(&arg1, &arg2, &result);
 7324 tgl                      2987 ECB             : 
 1485 akorotkov                2988 GIC       25838 :     res = make_result_opt_error(&result, have_error);
 8866 JanWieck                 2989 ECB             : 
 8866 JanWieck                 2990 CBC       25838 :     free_var(&result);
                               2991                 : 
 1485 akorotkov                2992           25838 :     return res;
                               2993                 : }
 8866 JanWieck                 2994 ECB             : 
                               2995                 : 
 7324 tgl                      2996                 : /*
                               2997                 :  * numeric_mul() -
                               2998                 :  *
                               2999                 :  *  Calculate the product of two numerics
                               3000                 :  */
                               3001                 : Datum
 8289 tgl                      3002 GIC      244830 : numeric_mul(PG_FUNCTION_ARGS)
                               3003                 : {
                               3004          244830 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3005          244830 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
 1485 akorotkov                3006 ECB             :     Numeric     res;
                               3007                 : 
 1485 akorotkov                3008 CBC      244830 :     res = numeric_mul_opt_error(num1, num2, NULL);
 1485 akorotkov                3009 ECB             : 
 1485 akorotkov                3010 GIC      244830 :     PG_RETURN_NUMERIC(res);
                               3011                 : }
 1485 akorotkov                3012 ECB             : 
                               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
 1485 akorotkov                3022 GIC      244836 : numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
                               3023                 : {
                               3024                 :     NumericVar  arg1;
                               3025                 :     NumericVar  arg2;
 8866 JanWieck                 3026 ECB             :     NumericVar  result;
                               3027                 :     Numeric     res;
                               3028                 : 
                               3029                 :     /*
                               3030                 :      * Handle NaN and infinities
                               3031                 :      */
  991 tgl                      3032 GIC      244836 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
                               3033                 :     {
                               3034              99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
                               3035              39 :             return make_result(&const_nan);
  991 tgl                      3036 CBC          60 :         if (NUMERIC_IS_PINF(num1))
                               3037                 :         {
                               3038              18 :             switch (numeric_sign_internal(num2))
  991 tgl                      3039 ECB             :             {
  991 tgl                      3040 CBC           3 :                 case 0:
  991 tgl                      3041 GIC           3 :                     return make_result(&const_nan); /* Inf * 0 */
  991 tgl                      3042 CBC           9 :                 case 1:
                               3043               9 :                     return make_result(&const_pinf);
  991 tgl                      3044 GIC           6 :                 case -1:
  991 tgl                      3045 CBC           6 :                     return make_result(&const_ninf);
                               3046                 :             }
  991 tgl                      3047 LBC           0 :             Assert(false);
                               3048                 :         }
  991 tgl                      3049 CBC          42 :         if (NUMERIC_IS_NINF(num1))
  991 tgl                      3050 ECB             :         {
  991 tgl                      3051 GIC          18 :             switch (numeric_sign_internal(num2))
  991 tgl                      3052 ECB             :             {
  991 tgl                      3053 GIC           3 :                 case 0:
                               3054               3 :                     return make_result(&const_nan); /* -Inf * 0 */
  991 tgl                      3055 CBC           9 :                 case 1:
                               3056               9 :                     return make_result(&const_ninf);
                               3057               6 :                 case -1:
                               3058               6 :                     return make_result(&const_pinf);
                               3059                 :             }
  991 tgl                      3060 UIC           0 :             Assert(false);
                               3061                 :         }
                               3062                 :         /* by here, num1 must be finite, so num2 is not */
  991 tgl                      3063 GIC          24 :         if (NUMERIC_IS_PINF(num2))
  991 tgl                      3064 ECB             :         {
  991 tgl                      3065 CBC          12 :             switch (numeric_sign_internal(num1))
                               3066                 :             {
                               3067               3 :                 case 0:
                               3068               3 :                     return make_result(&const_nan); /* 0 * Inf */
  991 tgl                      3069 GIC           6 :                 case 1:
  991 tgl                      3070 CBC           6 :                     return make_result(&const_pinf);
  991 tgl                      3071 GIC           3 :                 case -1:
  991 tgl                      3072 CBC           3 :                     return make_result(&const_ninf);
                               3073                 :             }
  991 tgl                      3074 LBC           0 :             Assert(false);
                               3075                 :         }
  991 tgl                      3076 GIC          12 :         Assert(NUMERIC_IS_NINF(num2));
                               3077              12 :         switch (numeric_sign_internal(num1))
                               3078                 :         {
                               3079               3 :             case 0:
                               3080               3 :                 return make_result(&const_nan); /* 0 * -Inf */
                               3081               6 :             case 1:
                               3082               6 :                 return make_result(&const_ninf);
                               3083               3 :             case -1:
  991 tgl                      3084 CBC           3 :                 return make_result(&const_pinf);
                               3085                 :         }
  991 tgl                      3086 LBC           0 :         Assert(false);
  991 tgl                      3087 ECB             :     }
                               3088                 : 
                               3089                 :     /*
 7324                          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
 6385 bruce                    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                 :      */
 3791 heikki.linnakangas       3100 GIC      244737 :     init_var_from_num(num1, &arg1);
                               3101          244737 :     init_var_from_num(num2, &arg2);
                               3102                 : 
                               3103          244737 :     init_var(&result);
 7324 tgl                      3104 CBC      244737 :     mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
                               3105                 : 
  638 dean.a.rasheed           3106 GIC      244737 :     if (result.dscale > NUMERIC_DSCALE_MAX)
                               3107               3 :         round_var(&result, NUMERIC_DSCALE_MAX);
                               3108                 : 
 1485 akorotkov                3109          244737 :     res = make_result_opt_error(&result, have_error);
                               3110                 : 
 8866 JanWieck                 3111          244737 :     free_var(&result);
                               3112                 : 
 1485 akorotkov                3113          244737 :     return res;
 8866 JanWieck                 3114 ECB             : }
                               3115                 : 
                               3116                 : 
 7324 tgl                      3117                 : /*
 8866 JanWieck                 3118                 :  * numeric_div() -
                               3119                 :  *
                               3120                 :  *  Divide one numeric into another
                               3121                 :  */
 8289 tgl                      3122                 : Datum
 8289 tgl                      3123 CBC       60494 : numeric_div(PG_FUNCTION_ARGS)
 8866 JanWieck                 3124 ECB             : {
 8289 tgl                      3125 CBC       60494 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3126           60494 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
 1485 akorotkov                3127 ECB             :     Numeric     res;
                               3128                 : 
 1485 akorotkov                3129 GBC       60494 :     res = numeric_div_opt_error(num1, num2, NULL);
                               3130                 : 
 1485 akorotkov                3131 CBC       60478 :     PG_RETURN_NUMERIC(res);
                               3132                 : }
 1485 akorotkov                3133 ECB             : 
                               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                 :  */
 1485 akorotkov                3142 EUB             : Numeric
 1485 akorotkov                3143 GIC       60914 : numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
                               3144                 : {
 8866 JanWieck                 3145 ECB             :     NumericVar  arg1;
                               3146                 :     NumericVar  arg2;
                               3147                 :     NumericVar  result;
                               3148                 :     Numeric     res;
 7324 tgl                      3149                 :     int         rscale;
 8866 JanWieck                 3150                 : 
 1343 michael                  3151 CBC       60914 :     if (have_error)
                               3152              24 :         *have_error = false;
 1343 michael                  3153 ECB             : 
 8053 bruce                    3154                 :     /*
                               3155                 :      * Handle NaN and infinities
 8866 JanWieck                 3156 EUB             :      */
  991 tgl                      3157 GIC       60914 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
  991 tgl                      3158 ECB             :     {
  991 tgl                      3159 CBC          99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
  991 tgl                      3160 GIC          39 :             return make_result(&const_nan);
  991 tgl                      3161 CBC          60 :         if (NUMERIC_IS_PINF(num1))
  991 tgl                      3162 ECB             :         {
  991 tgl                      3163 CBC          18 :             if (NUMERIC_IS_SPECIAL(num2))
                               3164               6 :                 return make_result(&const_nan); /* Inf / [-]Inf */
                               3165              12 :             switch (numeric_sign_internal(num2))
  991 tgl                      3166 ECB             :             {
  991 tgl                      3167 GIC           3 :                 case 0:
  991 tgl                      3168 GBC           3 :                     if (have_error)
                               3169                 :                     {
  991 tgl                      3170 UIC           0 :                         *have_error = true;
                               3171               0 :                         return NULL;
                               3172                 :                     }
  991 tgl                      3173 GIC           3 :                     ereport(ERROR,
                               3174                 :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
                               3175                 :                              errmsg("division by zero")));
                               3176                 :                     break;
                               3177               6 :                 case 1:
                               3178               6 :                     return make_result(&const_pinf);
                               3179               3 :                 case -1:
                               3180               3 :                     return make_result(&const_ninf);
                               3181                 :             }
  991 tgl                      3182 LBC           0 :             Assert(false);
  991 tgl                      3183 ECB             :         }
  991 tgl                      3184 GIC          42 :         if (NUMERIC_IS_NINF(num1))
  991 tgl                      3185 ECB             :         {
  991 tgl                      3186 CBC          18 :             if (NUMERIC_IS_SPECIAL(num2))
  991 tgl                      3187 GIC           6 :                 return make_result(&const_nan); /* -Inf / [-]Inf */
  991 tgl                      3188 CBC          12 :             switch (numeric_sign_internal(num2))
  991 tgl                      3189 ECB             :             {
  991 tgl                      3190 GIC           3 :                 case 0:
  991 tgl                      3191 CBC           3 :                     if (have_error)
                               3192                 :                     {
  991 tgl                      3193 LBC           0 :                         *have_error = true;
  991 tgl                      3194 UIC           0 :                         return NULL;
  991 tgl                      3195 ECB             :                     }
  991 tgl                      3196 GIC           3 :                     ereport(ERROR,
                               3197                 :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
                               3198                 :                              errmsg("division by zero")));
                               3199                 :                     break;
                               3200               6 :                 case 1:
                               3201               6 :                     return make_result(&const_ninf);
                               3202               3 :                 case -1:
                               3203               3 :                     return make_result(&const_pinf);
                               3204                 :             }
  991 tgl                      3205 LBC           0 :             Assert(false);
                               3206                 :         }
  991 tgl                      3207 ECB             :         /* 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                 :          */
  991 tgl                      3214 GIC          24 :         return make_result(&const_zero);
                               3215                 :     }
                               3216                 : 
                               3217                 :     /*
                               3218                 :      * Unpack the arguments
                               3219                 :      */
 3791 heikki.linnakangas       3220           60815 :     init_var_from_num(num1, &arg1);
                               3221           60815 :     init_var_from_num(num2, &arg2);
                               3222                 : 
                               3223           60815 :     init_var(&result);
                               3224                 : 
 8053 bruce                    3225 ECB             :     /*
                               3226                 :      * Select scale for division result
                               3227                 :      */
 7324 tgl                      3228 GIC       60815 :     rscale = select_div_scale(&arg1, &arg2);
                               3229                 : 
                               3230                 :     /*
                               3231                 :      * If "have_error" is provided, check for division by zero here
                               3232                 :      */
 1485 akorotkov                3233 CBC       60815 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
 1485 akorotkov                3234 ECB             :     {
 1485 akorotkov                3235 GIC           6 :         *have_error = true;
                               3236               6 :         return NULL;
                               3237                 :     }
                               3238                 : 
 7324 tgl                      3239 ECB             :     /*
                               3240                 :      * Do the divide and return the result
                               3241                 :      */
 6518 bruce                    3242 CBC       60809 :     div_var(&arg1, &arg2, &result, rscale, true);
 8866 JanWieck                 3243 ECB             : 
 1485 akorotkov                3244 GIC       60790 :     res = make_result_opt_error(&result, have_error);
 8866 JanWieck                 3245 ECB             : 
 8866 JanWieck                 3246 CBC       60790 :     free_var(&result);
 8866 JanWieck                 3247 ECB             : 
 1485 akorotkov                3248 GIC       60790 :     return res;
 8866 JanWieck                 3249 ECB             : }
                               3250                 : 
                               3251                 : 
 5483 tgl                      3252 EUB             : /*
                               3253                 :  * numeric_div_trunc() -
                               3254                 :  *
 5483 tgl                      3255 ECB             :  *  Divide one numeric into another, truncating the result to an integer
                               3256                 :  */
                               3257                 : Datum
 5483 tgl                      3258 GIC         600 : numeric_div_trunc(PG_FUNCTION_ARGS)
 5483 tgl                      3259 ECB             : {
 5483 tgl                      3260 CBC         600 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3261             600 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
 5483 tgl                      3262 ECB             :     NumericVar  arg1;
                               3263                 :     NumericVar  arg2;
 5483 tgl                      3264 EUB             :     NumericVar  result;
                               3265                 :     Numeric     res;
 5483 tgl                      3266 ECB             : 
                               3267                 :     /*
  991                          3268                 :      * Handle NaN and infinities
                               3269                 :      */
  991 tgl                      3270 CBC         600 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
                               3271                 :     {
                               3272              99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
                               3273              39 :             PG_RETURN_NUMERIC(make_result(&const_nan));
  991 tgl                      3274 GIC          60 :         if (NUMERIC_IS_PINF(num1))
  991 tgl                      3275 EUB             :         {
  991 tgl                      3276 GBC          18 :             if (NUMERIC_IS_SPECIAL(num2))
  991 tgl                      3277 GIC           6 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
  991 tgl                      3278 CBC          12 :             switch (numeric_sign_internal(num2))
                               3279                 :             {
  991 tgl                      3280 GIC           3 :                 case 0:
                               3281               3 :                     ereport(ERROR,
  991 tgl                      3282 ECB             :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
                               3283                 :                              errmsg("division by zero")));
                               3284                 :                     break;
  991 tgl                      3285 CBC           6 :                 case 1:
  991 tgl                      3286 GIC           6 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
  991 tgl                      3287 GBC           3 :                 case -1:
  991 tgl                      3288 GIC           3 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
                               3289                 :             }
  991 tgl                      3290 UIC           0 :             Assert(false);
                               3291                 :         }
  991 tgl                      3292 GIC          42 :         if (NUMERIC_IS_NINF(num1))
                               3293                 :         {
                               3294              18 :             if (NUMERIC_IS_SPECIAL(num2))
                               3295               6 :                 PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
  991 tgl                      3296 CBC          12 :             switch (numeric_sign_internal(num2))
                               3297                 :             {
  991 tgl                      3298 GIC           3 :                 case 0:
                               3299               3 :                     ereport(ERROR,
                               3300                 :                             (errcode(ERRCODE_DIVISION_BY_ZERO),
                               3301                 :                              errmsg("division by zero")));
  991 tgl                      3302 ECB             :                     break;
  991 tgl                      3303 CBC           6 :                 case 1:
  991 tgl                      3304 GIC           6 :                     PG_RETURN_NUMERIC(make_result(&const_ninf));
  991 tgl                      3305 CBC           3 :                 case -1:
  991 tgl                      3306 GIC           3 :                     PG_RETURN_NUMERIC(make_result(&const_pinf));
                               3307                 :             }
  991 tgl                      3308 UIC           0 :             Assert(false);
                               3309                 :         }
  991 tgl                      3310 ECB             :         /* 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                 :          */
  991 tgl                      3317 CBC          24 :         PG_RETURN_NUMERIC(make_result(&const_zero));
  991 tgl                      3318 ECB             :     }
                               3319                 : 
                               3320                 :     /*
                               3321                 :      * Unpack the arguments
                               3322                 :      */
 3791 heikki.linnakangas       3323 GIC         501 :     init_var_from_num(num1, &arg1);
 3791 heikki.linnakangas       3324 CBC         501 :     init_var_from_num(num2, &arg2);
                               3325                 : 
                               3326             501 :     init_var(&result);
                               3327                 : 
 5483 tgl                      3328 ECB             :     /*
                               3329                 :      * Do the divide and return the result
                               3330                 :      */
 5483 tgl                      3331 GIC         501 :     div_var(&arg1, &arg2, &result, 0, false);
                               3332                 : 
                               3333             498 :     res = make_result(&result);
                               3334                 : 
                               3335             498 :     free_var(&result);
                               3336                 : 
                               3337             498 :     PG_RETURN_NUMERIC(res);
                               3338                 : }
                               3339                 : 
 5483 tgl                      3340 ECB             : 
                               3341                 : /*
 8866 JanWieck                 3342                 :  * numeric_mod() -
                               3343                 :  *
                               3344                 :  *  Calculate the modulo of two numerics
                               3345                 :  */
                               3346                 : Datum
 8289 tgl                      3347 GIC       26283 : numeric_mod(PG_FUNCTION_ARGS)
                               3348                 : {
                               3349           26283 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3350           26283 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               3351                 :     Numeric     res;
 1485 akorotkov                3352 ECB             : 
 1485 akorotkov                3353 GIC       26283 :     res = numeric_mod_opt_error(num1, num2, NULL);
 1485 akorotkov                3354 ECB             : 
 1485 akorotkov                3355 CBC       26274 :     PG_RETURN_NUMERIC(res);
 1485 akorotkov                3356 ECB             : }
                               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
 1485 akorotkov                3367 CBC       26289 : numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
 1485 akorotkov                3368 ECB             : {
                               3369                 :     Numeric     res;
 8866 JanWieck                 3370                 :     NumericVar  arg1;
                               3371                 :     NumericVar  arg2;
 8866 JanWieck                 3372 EUB             :     NumericVar  result;
                               3373                 : 
 1343 michael                  3374 CBC       26289 :     if (have_error)
 1343 michael                  3375 UIC           0 :         *have_error = false;
 1343 michael                  3376 ECB             : 
  991 tgl                      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                 :      */
  991 tgl                      3382 GIC       26289 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
                               3383                 :     {
                               3384              99 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
  991 tgl                      3385 CBC          39 :             return make_result(&const_nan);
                               3386              60 :         if (NUMERIC_IS_INF(num1))
  991 tgl                      3387 ECB             :         {
  991 tgl                      3388 CBC          36 :             if (numeric_sign_internal(num2) == 0)
                               3389                 :             {
  991 tgl                      3390 GBC           6 :                 if (have_error)
                               3391                 :                 {
  991 tgl                      3392 UIC           0 :                     *have_error = true;
                               3393               0 :                     return NULL;
                               3394                 :                 }
  991 tgl                      3395 GIC           6 :                 ereport(ERROR,
                               3396                 :                         (errcode(ERRCODE_DIVISION_BY_ZERO),
                               3397                 :                          errmsg("division by zero")));
                               3398                 :             }
  991 tgl                      3399 ECB             :             /* Inf % any nonzero = NaN */
  991 tgl                      3400 GIC          30 :             return make_result(&const_nan);
                               3401                 :         }
                               3402                 :         /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
                               3403              24 :         return duplicate_numeric(num1);
                               3404                 :     }
 8866 JanWieck                 3405 ECB             : 
 3791 heikki.linnakangas       3406 CBC       26190 :     init_var_from_num(num1, &arg1);
 3791 heikki.linnakangas       3407 GIC       26190 :     init_var_from_num(num2, &arg2);
 8866 JanWieck                 3408 ECB             : 
 3791 heikki.linnakangas       3409 GIC       26190 :     init_var(&result);
                               3410                 : 
                               3411                 :     /*
                               3412                 :      * If "have_error" is provided, check for division by zero here
 1485 akorotkov                3413 ECB             :      */
 1485 akorotkov                3414 GIC       26190 :     if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0))
 1485 akorotkov                3415 ECB             :     {
 1485 akorotkov                3416 UIC           0 :         *have_error = true;
 1485 akorotkov                3417 LBC           0 :         return NULL;
                               3418                 :     }
 1485 akorotkov                3419 ECB             : 
 8866 JanWieck                 3420 GIC       26190 :     mod_var(&arg1, &arg2, &result);
                               3421                 : 
 1485 akorotkov                3422           26184 :     res = make_result_opt_error(&result, NULL);
                               3423                 : 
 8866 JanWieck                 3424           26184 :     free_var(&result);
                               3425                 : 
 1485 akorotkov                3426           26184 :     return res;
                               3427                 : }
                               3428                 : 
 8866 JanWieck                 3429 ECB             : 
                               3430                 : /*
                               3431                 :  * numeric_inc() -
                               3432                 :  *
                               3433                 :  *  Increment a number by one
                               3434                 :  */
 8289 tgl                      3435                 : Datum
 8289 tgl                      3436 GIC          24 : numeric_inc(PG_FUNCTION_ARGS)
 8866 JanWieck                 3437 ECB             : {
 8289 tgl                      3438 GIC          24 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               3439                 :     NumericVar  arg;
                               3440                 :     Numeric     res;
                               3441                 : 
                               3442                 :     /*
                               3443                 :      * Handle NaN and infinities
                               3444                 :      */
  991                          3445              24 :     if (NUMERIC_IS_SPECIAL(num))
                               3446               9 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               3447                 : 
                               3448                 :     /*
 8866 JanWieck                 3449 ECB             :      * Compute the result and return it
                               3450                 :      */
 3791 heikki.linnakangas       3451 GIC          15 :     init_var_from_num(num, &arg);
                               3452                 : 
 8866 JanWieck                 3453              15 :     add_var(&arg, &const_one, &arg);
                               3454                 : 
                               3455              15 :     res = make_result(&arg);
 8866 JanWieck                 3456 ECB             : 
 8866 JanWieck                 3457 GBC          15 :     free_var(&arg);
                               3458                 : 
 8289 tgl                      3459 GIC          15 :     PG_RETURN_NUMERIC(res);
                               3460                 : }
                               3461                 : 
                               3462                 : 
                               3463                 : /*
 8866 JanWieck                 3464 ECB             :  * numeric_smaller() -
                               3465                 :  *
                               3466                 :  *  Return the smaller of two numbers
                               3467                 :  */
 8289 tgl                      3468                 : Datum
 8289 tgl                      3469 GIC         102 : numeric_smaller(PG_FUNCTION_ARGS)
 8866 JanWieck                 3470 ECB             : {
 8289 tgl                      3471 GIC         102 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
 8289 tgl                      3472 CBC         102 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               3473                 : 
 8053 bruce                    3474 EUB             :     /*
 6385                          3475                 :      * Use cmp_numerics so that this will agree with the comparison operators,
                               3476                 :      * particularly as regards comparisons involving NaN.
 8866 JanWieck                 3477 ECB             :      */
 7193 tgl                      3478 GIC         102 :     if (cmp_numerics(num1, num2) < 0)
                               3479              42 :         PG_RETURN_NUMERIC(num1);
                               3480                 :     else
                               3481              60 :         PG_RETURN_NUMERIC(num2);
 8866 JanWieck                 3482 ECB             : }
                               3483                 : 
                               3484                 : 
 7324 tgl                      3485                 : /*
                               3486                 :  * numeric_larger() -
                               3487                 :  *
 8866 JanWieck                 3488                 :  *  Return the larger of two numbers
                               3489                 :  */
                               3490                 : Datum
 8289 tgl                      3491 CBC          27 : numeric_larger(PG_FUNCTION_ARGS)
                               3492                 : {
 8289 tgl                      3493 GIC          27 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3494              27 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               3495                 : 
 8053 bruce                    3496 ECB             :     /*
                               3497                 :      * Use cmp_numerics so that this will agree with the comparison operators,
 6385 bruce                    3498 EUB             :      * particularly as regards comparisons involving NaN.
 8866 JanWieck                 3499                 :      */
 7193 tgl                      3500 GIC          27 :     if (cmp_numerics(num1, num2) > 0)
                               3501              18 :         PG_RETURN_NUMERIC(num1);
 8866 JanWieck                 3502 ECB             :     else
 7193 tgl                      3503 GIC           9 :         PG_RETURN_NUMERIC(num2);
 8866 JanWieck                 3504 ECB             : }
                               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
 1170 dean.a.rasheed           3518                 :  */
                               3519                 : Datum
 1170 dean.a.rasheed           3520 CBC         108 : numeric_gcd(PG_FUNCTION_ARGS)
                               3521                 : {
 1170 dean.a.rasheed           3522 GIC         108 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3523             108 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               3524                 :     NumericVar  arg1;
                               3525                 :     NumericVar  arg2;
                               3526                 :     NumericVar  result;
 1170 dean.a.rasheed           3527 ECB             :     Numeric     res;
                               3528                 : 
                               3529                 :     /*
                               3530                 :      * Handle NaN and infinities: we consider the result to be NaN in all such
                               3531                 :      * cases.
                               3532                 :      */
  991 tgl                      3533 CBC         108 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
 1170 dean.a.rasheed           3534 GIC          48 :         PG_RETURN_NUMERIC(make_result(&const_nan));
 1170 dean.a.rasheed           3535 ECB             : 
                               3536                 :     /*
                               3537                 :      * Unpack the arguments
                               3538                 :      */
 1170 dean.a.rasheed           3539 CBC          60 :     init_var_from_num(num1, &arg1);
 1170 dean.a.rasheed           3540 GIC          60 :     init_var_from_num(num2, &arg2);
 1170 dean.a.rasheed           3541 ECB             : 
 1170 dean.a.rasheed           3542 GIC          60 :     init_var(&result);
                               3543                 : 
                               3544                 :     /*
                               3545                 :      * Find the GCD and return the result
                               3546                 :      */
                               3547              60 :     gcd_var(&arg1, &arg2, &result);
                               3548                 : 
                               3549              60 :     res = make_result(&result);
                               3550                 : 
 1170 dean.a.rasheed           3551 CBC          60 :     free_var(&result);
                               3552                 : 
                               3553              60 :     PG_RETURN_NUMERIC(res);
 1170 dean.a.rasheed           3554 ECB             : }
                               3555                 : 
                               3556                 : 
                               3557                 : /*
                               3558                 :  * numeric_lcm() -
                               3559                 :  *
                               3560                 :  *  Calculate the least common multiple of two numerics
                               3561                 :  */
                               3562                 : Datum
 1170 dean.a.rasheed           3563 CBC         123 : numeric_lcm(PG_FUNCTION_ARGS)
                               3564                 : {
 1170 dean.a.rasheed           3565 GIC         123 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3566             123 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               3567                 :     NumericVar  arg1;
                               3568                 :     NumericVar  arg2;
                               3569                 :     NumericVar  result;
                               3570                 :     Numeric     res;
                               3571                 : 
                               3572                 :     /*
  991 tgl                      3573 ECB             :      * Handle NaN and infinities: we consider the result to be NaN in all such
                               3574                 :      * cases.
 1170 dean.a.rasheed           3575                 :      */
  991 tgl                      3576 CBC         123 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
 1170 dean.a.rasheed           3577 GIC          48 :         PG_RETURN_NUMERIC(make_result(&const_nan));
                               3578                 : 
                               3579                 :     /*
                               3580                 :      * Unpack the arguments
                               3581                 :      */
 1170 dean.a.rasheed           3582 CBC          75 :     init_var_from_num(num1, &arg1);
                               3583              75 :     init_var_from_num(num2, &arg2);
                               3584                 : 
                               3585              75 :     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                 :      */
 1170 dean.a.rasheed           3597 GIC          75 :     if (arg1.ndigits == 0 || arg2.ndigits == 0)
                               3598              24 :         set_var_from_var(&const_zero, &result);
                               3599                 :     else
                               3600                 :     {
                               3601              51 :         gcd_var(&arg1, &arg2, &result);
 1170 dean.a.rasheed           3602 CBC          51 :         div_var(&arg1, &result, &result, 0, false);
 1170 dean.a.rasheed           3603 GIC          51 :         mul_var(&arg2, &result, &result, arg2.dscale);
 1170 dean.a.rasheed           3604 CBC          51 :         result.sign = NUMERIC_POS;
 1170 dean.a.rasheed           3605 ECB             :     }
                               3606                 : 
 1170 dean.a.rasheed           3607 GIC          75 :     result.dscale = Max(arg1.dscale, arg2.dscale);
                               3608                 : 
                               3609              75 :     res = make_result(&result);
                               3610                 : 
                               3611              72 :     free_var(&result);
                               3612                 : 
                               3613              72 :     PG_RETURN_NUMERIC(res);
                               3614                 : }
 1170 dean.a.rasheed           3615 ECB             : 
                               3616                 : 
                               3617                 : /*
                               3618                 :  * numeric_fac()
                               3619                 :  *
                               3620                 :  * Compute factorial
 7069 bruce                    3621                 :  */
                               3622                 : Datum
 7069 bruce                    3623 GIC          21 : numeric_fac(PG_FUNCTION_ARGS)
 7069 bruce                    3624 ECB             : {
 7069 bruce                    3625 GIC          21 :     int64       num = PG_GETARG_INT64(0);
                               3626                 :     Numeric     res;
                               3627                 :     NumericVar  fact;
                               3628                 :     NumericVar  result;
 7069 bruce                    3629 ECB             : 
 1025 peter                    3630 GIC          21 :     if (num < 0)
 1025 peter                    3631 CBC           3 :         ereport(ERROR,
                               3632                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 1025 peter                    3633 ECB             :                  errmsg("factorial of a negative number is undefined")));
 7068 tgl                      3634 GIC          18 :     if (num <= 1)
 7068 tgl                      3635 ECB             :     {
 7069 bruce                    3636 GIC           3 :         res = make_result(&const_one);
                               3637               3 :         PG_RETURN_NUMERIC(res);
                               3638                 :     }
                               3639                 :     /* Fail immediately if the result would overflow */
 5783 tgl                      3640              15 :     if (num > 32177)
                               3641               3 :         ereport(ERROR,
                               3642                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               3643                 :                  errmsg("value overflows numeric format")));
                               3644                 : 
 7069 bruce                    3645 CBC          12 :     init_var(&fact);
 7069 bruce                    3646 GIC          12 :     init_var(&result);
 7069 bruce                    3647 ECB             : 
 2942 andres                   3648 CBC          12 :     int64_to_numericvar(num, &result);
                               3649                 : 
 7068 tgl                      3650 GIC         147 :     for (num = num - 1; num > 1; num--)
                               3651                 :     {
                               3652                 :         /* this loop can take awhile, so allow it to be interrupted */
 5783                          3653             135 :         CHECK_FOR_INTERRUPTS();
                               3654                 : 
 2942 andres                   3655             135 :         int64_to_numericvar(num, &fact);
                               3656                 : 
 7068 tgl                      3657             135 :         mul_var(&result, &fact, &result, 0);
 7069 bruce                    3658 ECB             :     }
                               3659                 : 
 7068 tgl                      3660 GIC          12 :     res = make_result(&result);
                               3661                 : 
 7069 bruce                    3662              12 :     free_var(&fact);
                               3663              12 :     free_var(&result);
 7069 bruce                    3664 ECB             : 
 7069 bruce                    3665 CBC          12 :     PG_RETURN_NUMERIC(res);
                               3666                 : }
 7069 bruce                    3667 ECB             : 
                               3668                 : 
                               3669                 : /*
                               3670                 :  * numeric_sqrt() -
                               3671                 :  *
                               3672                 :  *  Compute the square root of a numeric.
                               3673                 :  */
                               3674                 : Datum
 8289 tgl                      3675 GIC          75 : numeric_sqrt(PG_FUNCTION_ARGS)
                               3676                 : {
                               3677              75 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               3678                 :     Numeric     res;
 8720 bruce                    3679 ECB             :     NumericVar  arg;
                               3680                 :     NumericVar  result;
                               3681                 :     int         sweight;
                               3682                 :     int         rscale;
 8866 JanWieck                 3683                 : 
 8053 bruce                    3684                 :     /*
  991 tgl                      3685                 :      * Handle NaN and infinities
 8866 JanWieck                 3686                 :      */
  991 tgl                      3687 GIC          75 :     if (NUMERIC_IS_SPECIAL(num))
                               3688                 :     {
  991 tgl                      3689 ECB             :         /* error should match that in sqrt_var() */
  991 tgl                      3690 GIC           9 :         if (NUMERIC_IS_NINF(num))
  991 tgl                      3691 CBC           3 :             ereport(ERROR,
                               3692                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
  991 tgl                      3693 ECB             :                      errmsg("cannot take square root of a negative number")));
                               3694                 :         /* For NAN or PINF, just duplicate the input */
  991 tgl                      3695 CBC           6 :         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                 :      */
 3791 heikki.linnakangas       3703 GIC          66 :     init_var_from_num(num, &arg);
                               3704                 : 
 3791 heikki.linnakangas       3705 CBC          66 :     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)
   66 dean.a.rasheed           3715 GNC          66 :     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                 : 
 7324 tgl                      3723 GIC          66 :     rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
                               3724              66 :     rscale = Max(rscale, arg.dscale);
 7324 tgl                      3725 CBC          66 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
                               3726              66 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                               3727                 : 
                               3728                 :     /*
 7494 tgl                      3729 ECB             :      * Let sqrt_var() do the calculation and return the result.
                               3730                 :      */
 7324 tgl                      3731 CBC          66 :     sqrt_var(&arg, &result, rscale);
 8866 JanWieck                 3732 ECB             : 
 8866 JanWieck                 3733 GIC          63 :     res = make_result(&result);
                               3734                 : 
 8866 JanWieck                 3735 CBC          63 :     free_var(&result);
 8866 JanWieck                 3736 ECB             : 
 8289 tgl                      3737 GIC          63 :     PG_RETURN_NUMERIC(res);
                               3738                 : }
                               3739                 : 
 8866 JanWieck                 3740 ECB             : 
 7324 tgl                      3741                 : /*
                               3742                 :  * numeric_exp() -
 8866 JanWieck                 3743                 :  *
                               3744                 :  *  Raise e to the power of x
                               3745                 :  */
                               3746                 : Datum
 8289 tgl                      3747 GIC          39 : numeric_exp(PG_FUNCTION_ARGS)
 8866 JanWieck                 3748 ECB             : {
 8289 tgl                      3749 GIC          39 :     Numeric     num = PG_GETARG_NUMERIC(0);
 8720 bruce                    3750 ECB             :     Numeric     res;
                               3751                 :     NumericVar  arg;
                               3752                 :     NumericVar  result;
                               3753                 :     int         rscale;
                               3754                 :     double      val;
 8866 JanWieck                 3755                 : 
                               3756                 :     /*
  991 tgl                      3757                 :      * Handle NaN and infinities
 8866 JanWieck                 3758                 :      */
  991 tgl                      3759 GIC          39 :     if (NUMERIC_IS_SPECIAL(num))
  991 tgl                      3760 ECB             :     {
                               3761                 :         /* Per POSIX, exp(-Inf) is zero */
  991 tgl                      3762 GIC           9 :         if (NUMERIC_IS_NINF(num))
                               3763               3 :             PG_RETURN_NUMERIC(make_result(&const_zero));
                               3764                 :         /* For NAN or PINF, just duplicate the input */
                               3765               6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               3766                 :     }
                               3767                 : 
                               3768                 :     /*
                               3769                 :      * Unpack the argument and determine the result scale.  We choose a scale
 6385 bruce                    3770 ECB             :      * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
                               3771                 :      * case not less than the input's dscale.
 8866 JanWieck                 3772                 :      */
 3791 heikki.linnakangas       3773 GIC          30 :     init_var_from_num(num, &arg);
                               3774                 : 
                               3775              30 :     init_var(&result);
                               3776                 : 
                               3777                 :     /* convert input to float8, ignoring overflow */
 7324 tgl                      3778              30 :     val = numericvar_to_double_no_overflow(&arg);
                               3779                 : 
                               3780                 :     /*
                               3781                 :      * log10(result) = num * log10(e), so this is approximately the decimal
 6385 bruce                    3782 ECB             :      * weight of the result:
                               3783                 :      */
 7494 tgl                      3784 GIC          30 :     val *= 0.434294481903252;
 7494 tgl                      3785 ECB             : 
                               3786                 :     /* limit to something that won't cause integer overflow */
 7494 tgl                      3787 GIC          30 :     val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
                               3788              30 :     val = Min(val, NUMERIC_MAX_RESULT_SCALE);
                               3789                 : 
 7324 tgl                      3790 CBC          30 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
 7324 tgl                      3791 GIC          30 :     rscale = Max(rscale, arg.dscale);
                               3792              30 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
                               3793              30 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                               3794                 : 
                               3795                 :     /*
                               3796                 :      * Let exp_var() do the calculation and return the result.
                               3797                 :      */
 7324 tgl                      3798 CBC          30 :     exp_var(&arg, &result, rscale);
                               3799                 : 
 8866 JanWieck                 3800              30 :     res = make_result(&result);
                               3801                 : 
 8866 JanWieck                 3802 GIC          30 :     free_var(&result);
                               3803                 : 
 8289 tgl                      3804              30 :     PG_RETURN_NUMERIC(res);
                               3805                 : }
                               3806                 : 
                               3807                 : 
                               3808                 : /*
                               3809                 :  * numeric_ln() -
 8866 JanWieck                 3810 ECB             :  *
                               3811                 :  *  Compute the natural logarithm of x
                               3812                 :  */
                               3813                 : Datum
 8289 tgl                      3814 GIC          99 : numeric_ln(PG_FUNCTION_ARGS)
                               3815                 : {
                               3816              99 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               3817                 :     Numeric     res;
 8720 bruce                    3818 ECB             :     NumericVar  arg;
                               3819                 :     NumericVar  result;
 2703 tgl                      3820                 :     int         ln_dweight;
 7324                          3821                 :     int         rscale;
                               3822                 : 
                               3823                 :     /*
                               3824                 :      * Handle NaN and infinities
                               3825                 :      */
  991 tgl                      3826 CBC          99 :     if (NUMERIC_IS_SPECIAL(num))
                               3827                 :     {
                               3828               9 :         if (NUMERIC_IS_NINF(num))
  991 tgl                      3829 GIC           3 :             ereport(ERROR,
  991 tgl                      3830 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
                               3831                 :                      errmsg("cannot take logarithm of a negative number")));
                               3832                 :         /* For NAN or PINF, just duplicate the input */
  991 tgl                      3833 GIC           6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               3834                 :     }
                               3835                 : 
 3791 heikki.linnakangas       3836              90 :     init_var_from_num(num, &arg);
 8866 JanWieck                 3837              90 :     init_var(&result);
                               3838                 : 
                               3839                 :     /* Estimated dweight of logarithm */
 2703 tgl                      3840              90 :     ln_dweight = estimate_ln_dweight(&arg);
                               3841                 : 
 2703 tgl                      3842 CBC          90 :     rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
 7324 tgl                      3843 GIC          90 :     rscale = Max(rscale, arg.dscale);
 7324 tgl                      3844 CBC          90 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
 7324 tgl                      3845 GIC          90 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                               3846                 : 
                               3847              90 :     ln_var(&arg, &result, rscale);
                               3848                 : 
 8866 JanWieck                 3849              78 :     res = make_result(&result);
                               3850                 : 
                               3851              78 :     free_var(&result);
                               3852                 : 
 8289 tgl                      3853              78 :     PG_RETURN_NUMERIC(res);
 8866 JanWieck                 3854 ECB             : }
                               3855                 : 
                               3856                 : 
 7324 tgl                      3857                 : /*
 8445                          3858                 :  * numeric_log() -
                               3859                 :  *
 8866 JanWieck                 3860                 :  *  Compute the logarithm of x in a given base
                               3861                 :  */
                               3862                 : Datum
 8289 tgl                      3863 GIC         171 : numeric_log(PG_FUNCTION_ARGS)
                               3864                 : {
                               3865             171 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
                               3866             171 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
                               3867                 :     Numeric     res;
 8720 bruce                    3868 ECB             :     NumericVar  arg1;
                               3869                 :     NumericVar  arg2;
                               3870                 :     NumericVar  result;
                               3871                 : 
                               3872                 :     /*
  991 tgl                      3873                 :      * Handle NaN and infinities
                               3874                 :      */
  991 tgl                      3875 GIC         171 :     if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
                               3876                 :     {
                               3877                 :         int         sign1,
                               3878                 :                     sign2;
  991 tgl                      3879 ECB             : 
  991 tgl                      3880 GIC          63 :         if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
                               3881              27 :             PG_RETURN_NUMERIC(make_result(&const_nan));
  991 tgl                      3882 ECB             :         /* fail on negative inputs including -Inf, as log_var would */
  991 tgl                      3883 CBC          36 :         sign1 = numeric_sign_internal(num1);
  991 tgl                      3884 GIC          36 :         sign2 = numeric_sign_internal(num2);
  991 tgl                      3885 CBC          36 :         if (sign1 < 0 || sign2 < 0)
                               3886              12 :             ereport(ERROR,
  991 tgl                      3887 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
                               3888                 :                      errmsg("cannot take logarithm of a negative number")));
                               3889                 :         /* fail on zero inputs, as log_var would */
  991 tgl                      3890 GIC          24 :         if (sign1 == 0 || sign2 == 0)
                               3891               3 :             ereport(ERROR,
                               3892                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
  991 tgl                      3893 ECB             :                      errmsg("cannot take logarithm of zero")));
  991 tgl                      3894 GIC          21 :         if (NUMERIC_IS_PINF(num1))
  991 tgl                      3895 ECB             :         {
                               3896                 :             /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
  991 tgl                      3897 CBC           9 :             if (NUMERIC_IS_PINF(num2))
  991 tgl                      3898 GIC           3 :                 PG_RETURN_NUMERIC(make_result(&const_nan));
  991 tgl                      3899 ECB             :             /* log(Inf, finite-positive) is zero (we don't throw underflow) */
  991 tgl                      3900 GIC           6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
                               3901                 :         }
                               3902              12 :         Assert(NUMERIC_IS_PINF(num2));
                               3903                 :         /* log(finite-positive, Inf) is Inf */
                               3904              12 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
                               3905                 :     }
                               3906                 : 
                               3907                 :     /*
                               3908                 :      * Initialize things
 8866 JanWieck                 3909 ECB             :      */
 3791 heikki.linnakangas       3910 GIC         108 :     init_var_from_num(num1, &arg1);
 3791 heikki.linnakangas       3911 CBC         108 :     init_var_from_num(num2, &arg2);
 8866 JanWieck                 3912 GIC         108 :     init_var(&result);
                               3913                 : 
                               3914                 :     /*
                               3915                 :      * Call log_var() to compute and return the result; note it handles scale
                               3916                 :      * selection itself.
                               3917                 :      */
                               3918             108 :     log_var(&arg1, &arg2, &result);
                               3919                 : 
                               3920              78 :     res = make_result(&result);
 8866 JanWieck                 3921 ECB             : 
 8866 JanWieck                 3922 GIC          78 :     free_var(&result);
 8866 JanWieck                 3923 ECB             : 
 8289 tgl                      3924 CBC          78 :     PG_RETURN_NUMERIC(res);
                               3925                 : }
                               3926                 : 
                               3927                 : 
 7324 tgl                      3928 ECB             : /*
                               3929                 :  * numeric_power() -
                               3930                 :  *
  991                          3931                 :  *  Raise x to the power of y
 8866 JanWieck                 3932                 :  */
                               3933                 : Datum
 8289 tgl                      3934 GIC         693 : numeric_power(PG_FUNCTION_ARGS)
 8866 JanWieck                 3935 ECB             : {
 8289 tgl                      3936 GIC         693 :     Numeric     num1 = PG_GETARG_NUMERIC(0);
 8289 tgl                      3937 CBC         693 :     Numeric     num2 = PG_GETARG_NUMERIC(1);
 8720 bruce                    3938 ECB             :     Numeric     res;
                               3939                 :     NumericVar  arg1;
                               3940                 :     NumericVar  arg2;
                               3941                 :     NumericVar  result;
  991 tgl                      3942                 :     int         sign1,
                               3943                 :                 sign2;
 8866 JanWieck                 3944                 : 
                               3945                 :     /*
  991 tgl                      3946                 :      * Handle NaN and infinities
                               3947                 :      */
  991 tgl                      3948 CBC         693 :     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                 :          */
  991 tgl                      3955 GIC         117 :         if (NUMERIC_IS_NAN(num1))
                               3956                 :         {
                               3957              27 :             if (!NUMERIC_IS_SPECIAL(num2))
  991 tgl                      3958 ECB             :             {
  991 tgl                      3959 GIC          18 :                 init_var_from_num(num2, &arg2);
  991 tgl                      3960 CBC          18 :                 if (cmp_var(&arg2, &const_zero) == 0)
                               3961               6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
                               3962                 :             }
  991 tgl                      3963 GIC          21 :             PG_RETURN_NUMERIC(make_result(&const_nan));
                               3964                 :         }
                               3965              90 :         if (NUMERIC_IS_NAN(num2))
                               3966                 :         {
                               3967              21 :             if (!NUMERIC_IS_SPECIAL(num1))
                               3968                 :             {
                               3969              18 :                 init_var_from_num(num1, &arg1);
  991 tgl                      3970 CBC          18 :                 if (cmp_var(&arg1, &const_one) == 0)
  991 tgl                      3971 GIC           6 :                     PG_RETURN_NUMERIC(make_result(&const_one));
                               3972                 :             }
                               3973              15 :             PG_RETURN_NUMERIC(make_result(&const_nan));
                               3974                 :         }
  991 tgl                      3975 ECB             :         /* At least one input is infinite, but error rules still apply */
  991 tgl                      3976 CBC          69 :         sign1 = numeric_sign_internal(num1);
  991 tgl                      3977 GIC          69 :         sign2 = numeric_sign_internal(num2);
  991 tgl                      3978 CBC          69 :         if (sign1 == 0 && sign2 < 0)
                               3979               3 :             ereport(ERROR,
  991 tgl                      3980 ECB             :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
                               3981                 :                      errmsg("zero raised to a negative power is undefined")));
  991 tgl                      3982 GIC          66 :         if (sign1 < 0 && !numeric_is_integral(num2))
                               3983               3 :             ereport(ERROR,
                               3984                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
  991 tgl                      3985 ECB             :                      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                 :          */
  991 tgl                      3992 CBC          63 :         if (!NUMERIC_IS_SPECIAL(num1))
 1788 tgl                      3993 ECB             :         {
  991 tgl                      3994 GIC          21 :             init_var_from_num(num1, &arg1);
  991 tgl                      3995 CBC          21 :             if (cmp_var(&arg1, &const_one) == 0)
 1788 tgl                      3996 GIC           3 :                 PG_RETURN_NUMERIC(make_result(&const_one));
 1788 tgl                      3997 ECB             :         }
                               3998                 : 
  991                          3999                 :         /*
                               4000                 :          * For any value of x, if y is [-]0, 1.0 shall be returned.
                               4001                 :          */
  991 tgl                      4002 GIC          60 :         if (sign2 == 0)
 1788                          4003               6 :             PG_RETURN_NUMERIC(make_result(&const_one));
                               4004                 : 
  991 tgl                      4005 ECB             :         /*
                               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                 :          */
  991 tgl                      4011 GIC          54 :         if (sign1 == 0 && sign2 > 0)
                               4012               3 :             PG_RETURN_NUMERIC(make_result(&const_zero));
  991 tgl                      4013 ECB             : 
                               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                 :          */
  991 tgl                      4025 GIC          51 :         if (NUMERIC_IS_INF(num2))
                               4026                 :         {
                               4027                 :             bool        abs_x_gt_one;
                               4028                 : 
  991 tgl                      4029 CBC          27 :             if (NUMERIC_IS_SPECIAL(num1))
  991 tgl                      4030 GIC          12 :                 abs_x_gt_one = true;    /* x is either Inf or -Inf */
  991 tgl                      4031 ECB             :             else
                               4032                 :             {
  991 tgl                      4033 GIC          15 :                 init_var_from_num(num1, &arg1);
                               4034              15 :                 if (cmp_var(&arg1, &const_minus_one) == 0)
                               4035               3 :                     PG_RETURN_NUMERIC(make_result(&const_one));
                               4036              12 :                 arg1.sign = NUMERIC_POS;    /* now arg1 = abs(x) */
                               4037              12 :                 abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
                               4038                 :             }
                               4039              24 :             if (abs_x_gt_one == (sign2 > 0))
                               4040              15 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
                               4041                 :             else
                               4042               9 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
  991 tgl                      4043 ECB             :         }
                               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                 :          */
  991 tgl                      4050 CBC          24 :         if (NUMERIC_IS_PINF(num1))
                               4051                 :         {
                               4052              12 :             if (sign2 > 0)
  991 tgl                      4053 GIC           9 :                 PG_RETURN_NUMERIC(make_result(&const_pinf));
  991 tgl                      4054 ECB             :             else
  991 tgl                      4055 CBC           3 :                 PG_RETURN_NUMERIC(make_result(&const_zero));
  991 tgl                      4056 ECB             :         }
                               4057                 : 
  991 tgl                      4058 CBC          12 :         Assert(NUMERIC_IS_NINF(num1));
                               4059                 : 
  991 tgl                      4060 ECB             :         /*
                               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                 :          */
  991 tgl                      4065 CBC          12 :         if (sign2 < 0)
                               4066               6 :             PG_RETURN_NUMERIC(make_result(&const_zero));
                               4067                 : 
  991 tgl                      4068 ECB             :         /*
                               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                 :          */
  991 tgl                      4072 CBC           6 :         init_var_from_num(num2, &arg2);
                               4073               6 :         if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
                               4074               6 :             (arg2.digits[arg2.ndigits - 1] & 1))
  991 tgl                      4075 GIC           3 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
                               4076                 :         else
  991 tgl                      4077 CBC           3 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
  991 tgl                      4078 ECB             :     }
                               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                 :      */
  991 tgl                      4087 CBC         576 :     sign1 = numeric_sign_internal(num1);
  991 tgl                      4088 GIC         576 :     sign2 = numeric_sign_internal(num2);
  991 tgl                      4089 ECB             : 
  991 tgl                      4090 CBC         576 :     if (sign1 == 0 && sign2 < 0)
 6902 neilc                    4091               6 :         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
  991 tgl                      4097 ECB             :      */
  991 tgl                      4098 CBC         570 :     init_var(&result);
  991 tgl                      4099 GIC         570 :     init_var_from_num(num1, &arg1);
                               4100             570 :     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                 :      */
 8866 JanWieck                 4106 CBC         570 :     power_var(&arg1, &arg2, &result);
 8866 JanWieck                 4107 ECB             : 
 8866 JanWieck                 4108 GIC         555 :     res = make_result(&result);
                               4109                 : 
                               4110             555 :     free_var(&result);
                               4111                 : 
 8289 tgl                      4112             555 :     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                 :  */
 2651 alvherre                 4120 ECB             : Datum
 2651 alvherre                 4121 GIC          54 : numeric_scale(PG_FUNCTION_ARGS)
                               4122                 : {
                               4123              54 :     Numeric     num = PG_GETARG_NUMERIC(0);
 2651 alvherre                 4124 ECB             : 
  991 tgl                      4125 CBC          54 :     if (NUMERIC_IS_SPECIAL(num))
 2651 alvherre                 4126 GIC           9 :         PG_RETURN_NULL();
                               4127                 : 
 2651 alvherre                 4128 CBC          45 :     PG_RETURN_INT32(NUMERIC_DSCALE(num));
 2651 alvherre                 4129 ECB             : }
                               4130                 : 
 1189 tgl                      4131                 : /*
                               4132                 :  * Calculate minimum scale for value.
                               4133                 :  */
                               4134                 : static int
 1189 tgl                      4135 CBC          63 : get_min_scale(NumericVar *var)
                               4136                 : {
 1189 tgl                      4137 ECB             :     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                 :      */
 1189 tgl                      4145 CBC          63 :     last_digit_pos = var->ndigits - 1;
 1189 tgl                      4146 GIC          63 :     while (last_digit_pos >= 0 &&
 1189 tgl                      4147 CBC          51 :            var->digits[last_digit_pos] == 0)
 1189 tgl                      4148 LBC           0 :         last_digit_pos--;
                               4149                 : 
 1189 tgl                      4150 CBC          63 :     if (last_digit_pos >= 0)
                               4151                 :     {
                               4152                 :         /* compute min_scale assuming that last ndigit has no zeroes */
                               4153              51 :         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                 :          */
 1189 tgl                      4159 GIC          51 :         if (min_scale > 0)
 1189 tgl                      4160 ECB             :         {
                               4161                 :             /*
                               4162                 :              * Reduce min_scale if trailing digit(s) in last NumericDigit are
                               4163                 :              * zero.
                               4164                 :              */
 1189 tgl                      4165 GIC          33 :             NumericDigit last_digit = var->digits[last_digit_pos];
                               4166                 : 
 1189 tgl                      4167 CBC          99 :             while (last_digit % 10 == 0)
 1189 tgl                      4168 ECB             :             {
 1189 tgl                      4169 CBC          66 :                 min_scale--;
                               4170              66 :                 last_digit /= 10;
                               4171                 :             }
 1189 tgl                      4172 ECB             :         }
                               4173                 :         else
 1189 tgl                      4174 GIC          18 :             min_scale = 0;
                               4175                 :     }
                               4176                 :     else
                               4177              12 :         min_scale = 0;          /* result if input is zero */
                               4178                 : 
                               4179              63 :     return min_scale;
                               4180                 : }
                               4181                 : 
 1189 tgl                      4182 ECB             : /*
                               4183                 :  * Returns minimum scale required to represent supplied value without loss.
                               4184                 :  */
                               4185                 : Datum
 1189 tgl                      4186 CBC          36 : numeric_min_scale(PG_FUNCTION_ARGS)
                               4187                 : {
 1189 tgl                      4188 GIC          36 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4189                 :     NumericVar  arg;
                               4190                 :     int         min_scale;
                               4191                 : 
  991                          4192              36 :     if (NUMERIC_IS_SPECIAL(num))
 1189 tgl                      4193 CBC           6 :         PG_RETURN_NULL();
 1189 tgl                      4194 ECB             : 
 1189 tgl                      4195 CBC          30 :     init_var_from_num(num, &arg);
 1189 tgl                      4196 GIC          30 :     min_scale = get_min_scale(&arg);
                               4197              30 :     free_var(&arg);
                               4198                 : 
                               4199              30 :     PG_RETURN_INT32(min_scale);
                               4200                 : }
 1189 tgl                      4201 ECB             : 
                               4202                 : /*
                               4203                 :  * Reduce scale of numeric value to represent supplied value without loss.
                               4204                 :  */
                               4205                 : Datum
 1189 tgl                      4206 GIC          39 : numeric_trim_scale(PG_FUNCTION_ARGS)
 1189 tgl                      4207 ECB             : {
 1189 tgl                      4208 GIC          39 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4209                 :     Numeric     res;
                               4210                 :     NumericVar  result;
                               4211                 : 
  991                          4212              39 :     if (NUMERIC_IS_SPECIAL(num))
                               4213               6 :         PG_RETURN_NUMERIC(duplicate_numeric(num));
                               4214                 : 
 1189                          4215              33 :     init_var_from_num(num, &result);
 1189 tgl                      4216 CBC          33 :     result.dscale = get_min_scale(&result);
 1189 tgl                      4217 GIC          33 :     res = make_result(&result);
 1189 tgl                      4218 CBC          33 :     free_var(&result);
                               4219                 : 
                               4220              33 :     PG_RETURN_NUMERIC(res);
 1189 tgl                      4221 ECB             : }
                               4222                 : 
 8866 JanWieck                 4223                 : 
                               4224                 : /* ----------------------------------------------------------------------
                               4225                 :  *
                               4226                 :  * Type conversion functions
                               4227                 :  *
                               4228                 :  * ----------------------------------------------------------------------
                               4229                 :  */
 8445 tgl                      4230                 : 
                               4231                 : Numeric
  942 peter                    4232 GIC      906490 : int64_to_numeric(int64 val)
                               4233                 : {
                               4234                 :     Numeric     res;
                               4235                 :     NumericVar  result;
                               4236                 : 
 8866 JanWieck                 4237          906490 :     init_var(&result);
                               4238                 : 
  942 peter                    4239          906490 :     int64_to_numericvar(val, &result);
 7324 tgl                      4240 ECB             : 
 8866 JanWieck                 4241 CBC      906490 :     res = make_result(&result);
 8866 JanWieck                 4242 ECB             : 
 8866 JanWieck                 4243 GBC      906490 :     free_var(&result);
                               4244                 : 
  942 peter                    4245 CBC      906490 :     return res;
                               4246                 : }
                               4247                 : 
  733 peter                    4248 ECB             : /*
                               4249                 :  * Convert val1/(10**log10val2) to numeric.  This is much faster than normal
                               4250                 :  * numeric division.
                               4251                 :  */
                               4252                 : Numeric
  733 peter                    4253 GIC       14600 : int64_div_fast_to_numeric(int64 val1, int log10val2)
  733 peter                    4254 ECB             : {
                               4255                 :     Numeric     res;
                               4256                 :     NumericVar  result;
                               4257                 :     int         rscale;
                               4258                 :     int         w;
                               4259                 :     int         m;
                               4260                 : 
   65 dean.a.rasheed           4261 GIC       14600 :     init_var(&result);
   65 dean.a.rasheed           4262 ECB             : 
                               4263                 :     /* result scale */
   65 dean.a.rasheed           4264 CBC       14600 :     rscale = log10val2 < 0 ? 0 : log10val2;
   65 dean.a.rasheed           4265 ECB             : 
                               4266                 :     /* how much to decrease the weight by */
  733 peter                    4267 GIC       14600 :     w = log10val2 / DEC_DIGITS;
                               4268                 :     /* how much is left to divide by */
  733 peter                    4269 CBC       14600 :     m = log10val2 % DEC_DIGITS;
   65 dean.a.rasheed           4270 GIC       14600 :     if (m < 0)
                               4271                 :     {
   65 dean.a.rasheed           4272 LBC           0 :         m += DEC_DIGITS;
   65 dean.a.rasheed           4273 UIC           0 :         w--;
   65 dean.a.rasheed           4274 ECB             :     }
                               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                 :      */
  733 peter                    4281 CBC       14600 :     if (m > 0)
                               4282                 :     {
   66 dean.a.rasheed           4283 ECB             : #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
   65                          4288                 :         static const int pow10[] = {1};
                               4289                 : #else
   66                          4290                 : #error unsupported NBASE
                               4291                 : #endif
   65 dean.a.rasheed           4292 CBC       14600 :         int64       factor = pow10[DEC_DIGITS - m];
                               4293                 :         int64       new_val1;
  733 peter                    4294 ECB             : 
                               4295                 :         StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
                               4296                 : 
   65 dean.a.rasheed           4297 GIC       14600 :         if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
                               4298                 :         {
                               4299                 : #ifdef HAVE_INT128
                               4300                 :             /* do the multiplication using 128-bit integers */
   65 dean.a.rasheed           4301 ECB             :             int128      tmp;
                               4302                 : 
   65 dean.a.rasheed           4303 CBC           6 :             tmp = (int128) val1 * (int128) factor;
                               4304                 : 
   65 dean.a.rasheed           4305 GIC           6 :             int128_to_numericvar(tmp, &result);
                               4306                 : #else
   65 dean.a.rasheed           4307 ECB             :             /* 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
   65 dean.a.rasheed           4320 GIC       14594 :             int64_to_numericvar(new_val1, &result);
                               4321                 : 
  733 peter                    4322           14600 :         w++;
                               4323                 :     }
                               4324                 :     else
   65 dean.a.rasheed           4325 UIC           0 :         int64_to_numericvar(val1, &result);
                               4326                 : 
  733 peter                    4327 CBC       14600 :     result.weight -= w;
   65 dean.a.rasheed           4328 GIC       14600 :     result.dscale = rscale;
                               4329                 : 
  733 peter                    4330           14600 :     res = make_result(&result);
                               4331                 : 
  733 peter                    4332 CBC       14600 :     free_var(&result);
                               4333                 : 
                               4334           14600 :     return res;
                               4335                 : }
  733 peter                    4336 ECB             : 
                               4337                 : Datum
  942 peter                    4338 CBC      760051 : int4_numeric(PG_FUNCTION_ARGS)
                               4339                 : {
                               4340          760051 :     int32       val = PG_GETARG_INT32(0);
                               4341                 : 
  942 peter                    4342 GIC      760051 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
                               4343                 : }
                               4344                 : 
                               4345                 : int32
 1485 akorotkov                4346            2777 : numeric_int4_opt_error(Numeric num, bool *have_error)
                               4347                 : {
 8482 tgl                      4348 ECB             :     NumericVar  x;
                               4349                 :     int32       result;
                               4350                 : 
 1343 michael                  4351 GIC        2777 :     if (have_error)
                               4352             144 :         *have_error = false;
                               4353                 : 
  991 tgl                      4354            2777 :     if (NUMERIC_IS_SPECIAL(num))
                               4355                 :     {
 1485 akorotkov                4356 CBC           9 :         if (have_error)
                               4357                 :         {
 1485 akorotkov                4358 UIC           0 :             *have_error = true;
 1485 akorotkov                4359 LBC           0 :             return 0;
                               4360                 :         }
                               4361                 :         else
 1485 akorotkov                4362 ECB             :         {
  991 tgl                      4363 GIC           9 :             if (NUMERIC_IS_NAN(num))
  991 tgl                      4364 CBC           3 :                 ereport(ERROR,
  991 tgl                      4365 ECB             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                               4366                 :                          errmsg("cannot convert NaN to %s", "integer")));
  991 tgl                      4367 EUB             :             else
  991 tgl                      4368 GBC           6 :                 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 */
 3791 heikki.linnakangas       4375 GIC        2768 :     init_var_from_num(num, &x);
 1485 akorotkov                4376 ECB             : 
 1485 akorotkov                4377 GIC        2768 :     if (!numericvar_to_int32(&x, &result))
                               4378                 :     {
                               4379              18 :         if (have_error)
                               4380                 :         {
                               4381              12 :             *have_error = true;
                               4382              12 :             return 0;
                               4383                 :         }
                               4384                 :         else
                               4385                 :         {
                               4386               6 :             ereport(ERROR,
 1485 akorotkov                4387 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               4388                 :                      errmsg("integer out of range")));
                               4389                 :         }
                               4390                 :     }
                               4391                 : 
 1485 akorotkov                4392 CBC        2750 :     return result;
                               4393                 : }
                               4394                 : 
                               4395                 : Datum
 1485 akorotkov                4396 GIC        2633 : numeric_int4(PG_FUNCTION_ARGS)
                               4397                 : {
 1485 akorotkov                4398 CBC        2633 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4399                 : 
                               4400            2633 :     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
 1485 akorotkov                4409 GIC        3137 : numericvar_to_int32(const NumericVar *var, int32 *result)
                               4410                 : {
                               4411                 :     int64       val;
                               4412                 : 
 2942 andres                   4413            3137 :     if (!numericvar_to_int64(var, &val))
 1485 akorotkov                4414 UIC           0 :         return false;
 8482 tgl                      4415 ECB             : 
  611 dean.a.rasheed           4416 GIC        3137 :     if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
  611 dean.a.rasheed           4417 CBC          18 :         return false;
                               4418                 : 
                               4419                 :     /* Down-convert to int4 */
 1485 akorotkov                4420 GBC        3119 :     *result = (int32) val;
                               4421                 : 
  611 dean.a.rasheed           4422 CBC        3119 :     return true;
 8866 JanWieck                 4423 ECB             : }
                               4424                 : 
 8301 tgl                      4425                 : Datum
 8301 tgl                      4426 GIC        6378 : int8_numeric(PG_FUNCTION_ARGS)
 8445 tgl                      4427 ECB             : {
 7324 tgl                      4428 GIC        6378 :     int64       val = PG_GETARG_INT64(0);
 8445 tgl                      4429 ECB             : 
  942 peter                    4430 GIC        6378 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
                               4431                 : }
                               4432                 : 
 8445 tgl                      4433 ECB             : 
                               4434                 : Datum
 8289 tgl                      4435 CBC         258 : numeric_int8(PG_FUNCTION_ARGS)
                               4436                 : {
                               4437             258 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4438                 :     NumericVar  x;
                               4439                 :     int64       result;
                               4440                 : 
  991                          4441             258 :     if (NUMERIC_IS_SPECIAL(num))
                               4442                 :     {
  991 tgl                      4443 GIC           9 :         if (NUMERIC_IS_NAN(num))
                               4444               3 :             ereport(ERROR,
                               4445                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  651 peter                    4446 ECB             :                      errmsg("cannot convert NaN to %s", "bigint")));
  991 tgl                      4447                 :         else
  991 tgl                      4448 GIC           6 :             ereport(ERROR,
  991 tgl                      4449 ECB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                               4450                 :                      errmsg("cannot convert infinity to %s", "bigint")));
                               4451                 :     }
                               4452                 : 
 7324 tgl                      4453 EUB             :     /* Convert to variable format and thence to int8 */
 3791 heikki.linnakangas       4454 GBC         249 :     init_var_from_num(num, &x);
                               4455                 : 
 2942 andres                   4456 GIC         249 :     if (!numericvar_to_int64(&x, &result))
 7196 tgl                      4457              24 :         ereport(ERROR,
 7196 tgl                      4458 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 6761                          4459                 :                  errmsg("bigint out of range")));
                               4460                 : 
 7324 tgl                      4461 GIC         225 :     PG_RETURN_INT64(result);
                               4462                 : }
 8445 tgl                      4463 ECB             : 
                               4464                 : 
                               4465                 : Datum
 8343 tgl                      4466 GIC           3 : int2_numeric(PG_FUNCTION_ARGS)
                               4467                 : {
                               4468               3 :     int16       val = PG_GETARG_INT16(0);
                               4469                 : 
  942 peter                    4470 CBC           3 :     PG_RETURN_NUMERIC(int64_to_numeric(val));
                               4471                 : }
 8445 tgl                      4472 ECB             : 
                               4473                 : 
 8343                          4474                 : Datum
 8343 tgl                      4475 GIC          48 : numeric_int2(PG_FUNCTION_ARGS)
 8445 tgl                      4476 ECB             : {
 8343 tgl                      4477 CBC          48 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4478                 :     NumericVar  x;
                               4479                 :     int64       val;
                               4480                 :     int16       result;
 8445 tgl                      4481 ECB             : 
  991 tgl                      4482 GIC          48 :     if (NUMERIC_IS_SPECIAL(num))
                               4483                 :     {
                               4484               9 :         if (NUMERIC_IS_NAN(num))
                               4485               3 :             ereport(ERROR,
                               4486                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  651 peter                    4487 ECB             :                      errmsg("cannot convert NaN to %s", "smallint")));
                               4488                 :         else
  991 tgl                      4489 GIC           6 :             ereport(ERROR,
                               4490                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  651 peter                    4491 ECB             :                      errmsg("cannot convert infinity to %s", "smallint")));
                               4492                 :     }
 8445 tgl                      4493                 : 
                               4494                 :     /* Convert to variable format and thence to int8 */
 3791 heikki.linnakangas       4495 CBC          39 :     init_var_from_num(num, &x);
                               4496                 : 
 2942 andres                   4497 GIC          39 :     if (!numericvar_to_int64(&x, &val))
 7196 tgl                      4498 UIC           0 :         ereport(ERROR,
                               4499                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               4500                 :                  errmsg("smallint out of range")));
                               4501                 : 
  611 dean.a.rasheed           4502 GIC          39 :     if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
 7196 tgl                      4503               6 :         ereport(ERROR,
 7196 tgl                      4504 ECB             :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               4505                 :                  errmsg("smallint out of range")));
                               4506                 : 
                               4507                 :     /* Down-convert to int2 */
  611 dean.a.rasheed           4508 CBC          33 :     result = (int16) val;
  611 dean.a.rasheed           4509 EUB             : 
 7324 tgl                      4510 GIC          33 :     PG_RETURN_INT16(result);
 8445 tgl                      4511 ECB             : }
                               4512                 : 
                               4513                 : 
                               4514                 : Datum
 8289 tgl                      4515 CBC         417 : float8_numeric(PG_FUNCTION_ARGS)
                               4516                 : {
                               4517             417 :     float8      val = PG_GETARG_FLOAT8(0);
                               4518                 :     Numeric     res;
                               4519                 :     NumericVar  result;
                               4520                 :     char        buf[DBL_DIG + 100];
                               4521                 :     const char *endptr;
 8866 JanWieck                 4522 ECB             : 
 8289 tgl                      4523 GIC         417 :     if (isnan(val))
 8289 tgl                      4524 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
                               4525                 : 
 2020                          4526             414 :     if (isinf(val))
                               4527                 :     {
  991 tgl                      4528 GIC           6 :         if (val < 0)
                               4529               3 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
                               4530                 :         else
  991 tgl                      4531 CBC           3 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
                               4532                 :     }
 2020 tgl                      4533 ECB             : 
 2020 tgl                      4534 GIC         408 :     snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
                               4535                 : 
 8866 JanWieck                 4536             408 :     init_var(&result);
 8866 JanWieck                 4537 ECB             : 
                               4538                 :     /* Assume we need not worry about leading/trailing spaces */
  121 tgl                      4539 GNC         408 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
 5114 tgl                      4540 ECB             : 
 8866 JanWieck                 4541 GIC         408 :     res = make_result(&result);
                               4542                 : 
                               4543             408 :     free_var(&result);
 8866 JanWieck                 4544 ECB             : 
 8289 tgl                      4545 GIC         408 :     PG_RETURN_NUMERIC(res);
                               4546                 : }
                               4547                 : 
                               4548                 : 
                               4549                 : Datum
 8289 tgl                      4550 CBC      259429 : numeric_float8(PG_FUNCTION_ARGS)
                               4551                 : {
                               4552          259429 :     Numeric     num = PG_GETARG_NUMERIC(0);
 8720 bruce                    4553 ECB             :     char       *tmp;
                               4554                 :     Datum       result;
                               4555                 : 
  991 tgl                      4556 GIC      259429 :     if (NUMERIC_IS_SPECIAL(num))
  991 tgl                      4557 ECB             :     {
  991 tgl                      4558 GIC          39 :         if (NUMERIC_IS_PINF(num))
                               4559              12 :             PG_RETURN_FLOAT8(get_float8_infinity());
                               4560              27 :         else if (NUMERIC_IS_NINF(num))
                               4561              12 :             PG_RETURN_FLOAT8(-get_float8_infinity());
  991 tgl                      4562 ECB             :         else
  991 tgl                      4563 GIC          15 :             PG_RETURN_FLOAT8(get_float8_nan());
  991 tgl                      4564 ECB             :     }
                               4565                 : 
 8335 tgl                      4566 CBC      259390 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
                               4567                 :                                               NumericGetDatum(num)));
                               4568                 : 
 8286 tgl                      4569 GIC      259390 :     result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
                               4570                 : 
 8866 JanWieck                 4571 CBC      259390 :     pfree(tmp);
                               4572                 : 
 8286 tgl                      4573          259390 :     PG_RETURN_DATUM(result);
                               4574                 : }
                               4575                 : 
                               4576                 : 
                               4577                 : /*
 2293 peter_e                  4578 ECB             :  * Convert numeric to float8; if out of range, return +/- HUGE_VAL
                               4579                 :  *
                               4580                 :  * (internal helper function, not directly callable from SQL)
                               4581                 :  */
                               4582                 : Datum
 7848 tgl                      4583 GIC        1433 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
                               4584                 : {
 7848 tgl                      4585 CBC        1433 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4586                 :     double      val;
                               4587                 : 
  991 tgl                      4588 GIC        1433 :     if (NUMERIC_IS_SPECIAL(num))
                               4589                 :     {
  991 tgl                      4590 UIC           0 :         if (NUMERIC_IS_PINF(num))
  991 tgl                      4591 LBC           0 :             val = HUGE_VAL;
  991 tgl                      4592 UIC           0 :         else if (NUMERIC_IS_NINF(num))
  991 tgl                      4593 LBC           0 :             val = -HUGE_VAL;
  991 tgl                      4594 EUB             :         else
  991 tgl                      4595 UIC           0 :             val = get_float8_nan();
                               4596                 :     }
                               4597                 :     else
  991 tgl                      4598 ECB             :     {
                               4599                 :         NumericVar  x;
                               4600                 : 
  991 tgl                      4601 GIC        1433 :         init_var_from_num(num, &x);
                               4602            1433 :         val = numericvar_to_double_no_overflow(&x);
                               4603                 :     }
 7848 tgl                      4604 ECB             : 
 7848 tgl                      4605 GIC        1433 :     PG_RETURN_FLOAT8(val);
 7848 tgl                      4606 ECB             : }
                               4607                 : 
                               4608                 : Datum
 8289 tgl                      4609 GIC       10788 : float4_numeric(PG_FUNCTION_ARGS)
                               4610                 : {
 8289 tgl                      4611 CBC       10788 :     float4      val = PG_GETARG_FLOAT4(0);
                               4612                 :     Numeric     res;
 8866 JanWieck                 4613 ECB             :     NumericVar  result;
                               4614                 :     char        buf[FLT_DIG + 100];
                               4615                 :     const char *endptr;
                               4616                 : 
 8289 tgl                      4617 GIC       10788 :     if (isnan(val))
                               4618               3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
                               4619                 : 
 2020 tgl                      4620 CBC       10785 :     if (isinf(val))
  991 tgl                      4621 ECB             :     {
  991 tgl                      4622 GIC           6 :         if (val < 0)
  991 tgl                      4623 CBC           3 :             PG_RETURN_NUMERIC(make_result(&const_ninf));
                               4624                 :         else
                               4625               3 :             PG_RETURN_NUMERIC(make_result(&const_pinf));
  991 tgl                      4626 ECB             :     }
                               4627                 : 
 2020 tgl                      4628 CBC       10779 :     snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
                               4629                 : 
 8866 JanWieck                 4630 GIC       10779 :     init_var(&result);
 8866 JanWieck                 4631 ECB             : 
                               4632                 :     /* Assume we need not worry about leading/trailing spaces */
  121 tgl                      4633 GNC       10779 :     (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
                               4634                 : 
 8866 JanWieck                 4635 GIC       10779 :     res = make_result(&result);
 8866 JanWieck                 4636 ECB             : 
 8866 JanWieck                 4637 GIC       10779 :     free_var(&result);
 8866 JanWieck                 4638 ECB             : 
 8289 tgl                      4639 GIC       10779 :     PG_RETURN_NUMERIC(res);
 8866 JanWieck                 4640 ECB             : }
                               4641                 : 
                               4642                 : 
                               4643                 : Datum
 8289 tgl                      4644 GIC        1090 : numeric_float4(PG_FUNCTION_ARGS)
                               4645                 : {
                               4646            1090 :     Numeric     num = PG_GETARG_NUMERIC(0);
 8720 bruce                    4647 ECB             :     char       *tmp;
                               4648                 :     Datum       result;
 8866 JanWieck                 4649                 : 
  991 tgl                      4650 GIC        1090 :     if (NUMERIC_IS_SPECIAL(num))
                               4651                 :     {
                               4652              39 :         if (NUMERIC_IS_PINF(num))
  991 tgl                      4653 CBC          12 :             PG_RETURN_FLOAT4(get_float4_infinity());
  991 tgl                      4654 GIC          27 :         else if (NUMERIC_IS_NINF(num))
  991 tgl                      4655 CBC          12 :             PG_RETURN_FLOAT4(-get_float4_infinity());
  991 tgl                      4656 ECB             :         else
  991 tgl                      4657 CBC          15 :             PG_RETURN_FLOAT4(get_float4_nan());
  991 tgl                      4658 ECB             :     }
                               4659                 : 
 8335 tgl                      4660 CBC        1051 :     tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
                               4661                 :                                               NumericGetDatum(num)));
                               4662                 : 
 8286                          4663            1051 :     result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
                               4664                 : 
 8866 JanWieck                 4665 GIC        1051 :     pfree(tmp);
 8866 JanWieck                 4666 ECB             : 
 8286 tgl                      4667 GIC        1051 :     PG_RETURN_DATUM(result);
 8866 JanWieck                 4668 ECB             : }
                               4669                 : 
                               4670                 : 
                               4671                 : Datum
 1013 fujii                    4672 GIC          45 : numeric_pg_lsn(PG_FUNCTION_ARGS)
                               4673                 : {
                               4674              45 :     Numeric     num = PG_GETARG_NUMERIC(0);
                               4675                 :     NumericVar  x;
                               4676                 :     XLogRecPtr  result;
                               4677                 : 
  991 tgl                      4678              45 :     if (NUMERIC_IS_SPECIAL(num))
                               4679                 :     {
  991 tgl                      4680 CBC           3 :         if (NUMERIC_IS_NAN(num))
  991 tgl                      4681 GIC           3 :             ereport(ERROR,
  991 tgl                      4682 ECB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                               4683                 :                      errmsg("cannot convert NaN to %s", "pg_lsn")));
                               4684                 :         else
  991 tgl                      4685 LBC           0 :             ereport(ERROR,
                               4686                 :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  651 peter                    4687 EUB             :                      errmsg("cannot convert infinity to %s", "pg_lsn")));
  991 tgl                      4688                 :     }
 1013 fujii                    4689                 : 
                               4690                 :     /* Convert to variable format and thence to pg_lsn */
 1013 fujii                    4691 GIC          42 :     init_var_from_num(num, &x);
 1013 fujii                    4692 EUB             : 
 1013 fujii                    4693 GIC          42 :     if (!numericvar_to_uint64(&x, (uint64 *) &result))
                               4694              12 :         ereport(ERROR,
                               4695                 :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                               4696                 :                  errmsg("pg_lsn out of range")));
                               4697                 : 
 1013 fujii                    4698 CBC          30 :     PG_RETURN_LSN(result);
 1013 fujii                    4699 ECB             : }
                               4700                 : 
                               4701                 : 
 8301 tgl                      4702                 : /* ----------------------------------------------------------------------
                               4703                 :  *
                               4704                 :  * Aggregate functions
                               4705                 :  *
 3431                          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                 :  * ----------------------------------------------------------------------
 8301                          4714                 :  */
                               4715                 : 
                               4716                 : typedef struct NumericAggState
 3431                          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 */
 2410 heikki.linnakangas       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 */
  991 tgl                      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;
 8301                          4730                 : 
                               4731                 : #define NA_TOTAL_COUNT(na) \
  991                          4732                 :     ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
                               4733                 : 
 3431                          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 *
 3431 tgl                      4739 GIC       85568 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
                               4740                 : {
 3431 tgl                      4741 ECB             :     NumericAggState *state;
                               4742                 :     MemoryContext agg_context;
                               4743                 :     MemoryContext old_context;
                               4744                 : 
 3431 tgl                      4745 GIC       85568 :     if (!AggCheckCallContext(fcinfo, &agg_context))
 3431 tgl                      4746 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
 3431 tgl                      4747 ECB             : 
 3431 tgl                      4748 GIC       85568 :     old_context = MemoryContextSwitchTo(agg_context);
 3431 tgl                      4749 ECB             : 
 3431 tgl                      4750 CBC       85568 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
                               4751           85568 :     state->calcSumX2 = calcSumX2;
                               4752           85568 :     state->agg_context = agg_context;
                               4753                 : 
                               4754           85568 :     MemoryContextSwitchTo(old_context);
                               4755                 : 
 3431 tgl                      4756 GIC       85568 :     return state;
 8301 tgl                      4757 ECB             : }
                               4758                 : 
                               4759                 : /*
 2481                          4760                 :  * Like makeNumericAggState(), but allocate the state in the current memory
                               4761                 :  * context.
                               4762                 :  */
                               4763                 : static NumericAggState *
 2481 tgl                      4764 CBC          40 : makeNumericAggStateCurrentContext(bool calcSumX2)
                               4765                 : {
                               4766                 :     NumericAggState *state;
                               4767                 : 
 2481 tgl                      4768 GIC          40 :     state = (NumericAggState *) palloc0(sizeof(NumericAggState));
 2481 tgl                      4769 CBC          40 :     state->calcSumX2 = calcSumX2;
 2481 tgl                      4770 GIC          40 :     state->agg_context = CurrentMemoryContext;
 2481 tgl                      4771 ECB             : 
 2481 tgl                      4772 GIC          40 :     return state;
                               4773                 : }
                               4774                 : 
 5895 bruce                    4775 ECB             : /*
                               4776                 :  * Accumulate a new input value for numeric aggregate functions.
                               4777                 :  */
 3431 tgl                      4778                 : static void
 3431 tgl                      4779 GIC     1056776 : do_numeric_accum(NumericAggState *state, Numeric newval)
                               4780                 : {
                               4781                 :     NumericVar  X;
 3431 tgl                      4782 EUB             :     NumericVar  X2;
                               4783                 :     MemoryContext old_context;
                               4784                 : 
                               4785                 :     /* Count NaN/infinity inputs separately from all else */
  991 tgl                      4786 GIC     1056776 :     if (NUMERIC_IS_SPECIAL(newval))
                               4787                 :     {
  991 tgl                      4788 CBC          81 :         if (NUMERIC_IS_PINF(newval))
  991 tgl                      4789 GIC          36 :             state->pInfcount++;
  991 tgl                      4790 CBC          45 :         else if (NUMERIC_IS_NINF(newval))
                               4791              18 :             state->nInfcount++;
                               4792                 :         else
  991 tgl                      4793 GIC          27 :             state->NaNcount++;
 3431                          4794              81 :         return;
 3431 tgl                      4795 ECB             :     }
                               4796                 : 
                               4797                 :     /* load processed number in short-lived context */
 3431 tgl                      4798 GIC     1056695 :     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                 :      */
 3284                          4804         1056695 :     if (X.dscale > state->maxScale)
                               4805                 :     {
                               4806              78 :         state->maxScale = X.dscale;
                               4807              78 :         state->maxScaleCount = 1;
                               4808                 :     }
                               4809         1056617 :     else if (X.dscale == state->maxScale)
                               4810         1056599 :         state->maxScaleCount++;
                               4811                 : 
                               4812                 :     /* if we need X^2, calculate that in short-lived context */
 3431                          4813         1056695 :     if (state->calcSumX2)
                               4814                 :     {
                               4815          120366 :         init_var(&X2);
                               4816          120366 :         mul_var(&X, &X, &X2, X.dscale * 2);
                               4817                 :     }
                               4818                 : 
                               4819                 :     /* The rest of this needs to work in the aggregate context */
                               4820         1056695 :     old_context = MemoryContextSwitchTo(state->agg_context);
                               4821                 : 
 2410 heikki.linnakangas       4822         1056695 :     state->N++;
                               4823                 : 
                               4824                 :     /* Accumulate sums */
                               4825         1056695 :     accum_sum_add(&(state->sumX), &X);
                               4826                 : 
                               4827         1056695 :     if (state->calcSumX2)
                               4828          120366 :         accum_sum_add(&(state->sumX2), &X2);
                               4829                 : 
 3431 tgl                      4830         1056695 :     MemoryContextSwitchTo(old_context);
                               4831                 : }
                               4832                 : 
                               4833                 : /*
                               4834                 :  * Attempt to remove an input value from the aggregated state.
                               4835                 :  *
 3284 tgl                      4836 ECB             :  * 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
 3284 tgl                      4843 EUB             :  * have been zero if we'd really aggregated only 2.
                               4844                 :  *
 3284 tgl                      4845 ECB             :  * 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
 3284 tgl                      4849 CBC         171 : do_numeric_discard(NumericAggState *state, Numeric newval)
                               4850                 : {
 3284 tgl                      4851 ECB             :     NumericVar  X;
                               4852                 :     NumericVar  X2;
                               4853                 :     MemoryContext old_context;
                               4854                 : 
                               4855                 :     /* Count NaN/infinity inputs separately from all else */
  991 tgl                      4856 GIC         171 :     if (NUMERIC_IS_SPECIAL(newval))
                               4857                 :     {
                               4858               3 :         if (NUMERIC_IS_PINF(newval))
  991 tgl                      4859 UIC           0 :             state->pInfcount--;
  991 tgl                      4860 GIC           3 :         else if (NUMERIC_IS_NINF(newval))
  991 tgl                      4861 LBC           0 :             state->nInfcount--;
                               4862                 :         else
  991 tgl                      4863 GIC           3 :             state->NaNcount--;
 3284                          4864               3 :         return true;
 3284 tgl                      4865 ECB             :     }
                               4866                 : 
                               4867                 :     /* load processed number in short-lived context */
 3284 tgl                      4868 GIC         168 :     init_var_from_num(newval, &X);
 3284 tgl                      4869 ECB             : 
                               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                 :      */
 3284 tgl                      4877 GIC         168 :     if (X.dscale == state->maxScale)
                               4878                 :     {
                               4879             168 :         if (state->maxScaleCount > 1 || state->maxScale == 0)
                               4880                 :         {
                               4881                 :             /*
                               4882                 :              * Some remaining inputs have same dscale, or dscale hasn't gotten
 3260 bruce                    4883 ECB             :              * above zero anyway
                               4884                 :              */
 3284 tgl                      4885 CBC         159 :             state->maxScaleCount--;
 3284 tgl                      4886 ECB             :         }
 3284 tgl                      4887 CBC           9 :         else if (state->N == 1)
 3284 tgl                      4888 ECB             :         {
                               4889                 :             /* No remaining non-NaN inputs at all, so reset maxScale */
 3284 tgl                      4890 CBC           6 :             state->maxScale = 0;
                               4891               6 :             state->maxScaleCount = 0;
                               4892                 :         }
                               4893                 :         else
                               4894                 :         {
 3284 tgl                      4895 ECB             :             /* Correct new maxScale is uncertain, must fail */
 3284 tgl                      4896 GIC           3 :             return false;
                               4897                 :         }
                               4898                 :     }
                               4899                 : 
                               4900                 :     /* if we need X^2, calculate that in short-lived context */
 3284 tgl                      4901 CBC         165 :     if (state->calcSumX2)
                               4902                 :     {
                               4903             144 :         init_var(&X2);
                               4904             144 :         mul_var(&X, &X, &X2, X.dscale * 2);
                               4905                 :     }
 3284 tgl                      4906 ECB             : 
                               4907                 :     /* The rest of this needs to work in the aggregate context */
 3284 tgl                      4908 GIC         165 :     old_context = MemoryContextSwitchTo(state->agg_context);
                               4909                 : 
 3284 tgl                      4910 CBC         165 :     if (state->N-- > 1)
                               4911                 :     {
 2410 heikki.linnakangas       4912 ECB             :         /* Negate X, to subtract it from the sum */
 2410 heikki.linnakangas       4913 CBC         156 :         X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
 2410 heikki.linnakangas       4914 GIC         156 :         accum_sum_add(&(state->sumX), &X);
                               4915                 : 
 3284 tgl                      4916             156 :         if (state->calcSumX2)
 2410 heikki.linnakangas       4917 ECB             :         {
                               4918                 :             /* Negate X^2. X^2 is always positive */
 2410 heikki.linnakangas       4919 CBC         144 :             X2.sign = NUMERIC_NEG;
 2410 heikki.linnakangas       4920 GIC         144 :             accum_sum_add(&(state->sumX2), &X2);
                               4921                 :         }
 3284 tgl                      4922 ECB             :     }
                               4923                 :     else
                               4924                 :     {
 2410 heikki.linnakangas       4925                 :         /* Zero the sums */
 3284 tgl                      4926 GIC           9 :         Assert(state->N == 0);
 2410 heikki.linnakangas       4927 ECB             : 
 2410 heikki.linnakangas       4928 GIC           9 :         accum_sum_reset(&state->sumX);
                               4929               9 :         if (state->calcSumX2)
 2410 heikki.linnakangas       4930 UIC           0 :             accum_sum_reset(&state->sumX2);
                               4931                 :     }
                               4932                 : 
 3284 tgl                      4933 GIC         165 :     MemoryContextSwitchTo(old_context);
                               4934                 : 
                               4935             165 :     return true;
                               4936                 : }
                               4937                 : 
                               4938                 : /*
                               4939                 :  * Generic transition function for numeric aggregates that require sumX2.
                               4940                 :  */
                               4941                 : Datum
 8301                          4942             321 : numeric_accum(PG_FUNCTION_ARGS)
                               4943                 : {
                               4944                 :     NumericAggState *state;
                               4945                 : 
 3431 tgl                      4946 CBC         321 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               4947                 : 
                               4948                 :     /* Create the state data on the first call */
 3284 tgl                      4949 GIC         321 :     if (state == NULL)
                               4950              87 :         state = makeNumericAggState(fcinfo, true);
                               4951                 : 
                               4952             321 :     if (!PG_ARGISNULL(1))
 3431 tgl                      4953 CBC         312 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
                               4954                 : 
                               4955             321 :     PG_RETURN_POINTER(state);
 8301 tgl                      4956 EUB             : }
 8301 tgl                      4957 ECB             : 
 2560 rhaas                    4958 EUB             : /*
                               4959                 :  * Generic combine function for numeric aggregates which require sumX2
 2560 rhaas                    4960 ECB             :  */
                               4961                 : Datum
 2560 rhaas                    4962 GIC          17 : numeric_combine(PG_FUNCTION_ARGS)
                               4963                 : {
                               4964                 :     NumericAggState *state1;
 2495 rhaas                    4965 ECB             :     NumericAggState *state2;
                               4966                 :     MemoryContext agg_context;
                               4967                 :     MemoryContext old_context;
                               4968                 : 
 2560 rhaas                    4969 GIC          17 :     if (!AggCheckCallContext(fcinfo, &agg_context))
 2560 rhaas                    4970 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               4971                 : 
 2560 rhaas                    4972 GIC          17 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               4973              17 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
 2560 rhaas                    4974 ECB             : 
 2560 rhaas                    4975 GIC          17 :     if (state2 == NULL)
 2560 rhaas                    4976 LBC           0 :         PG_RETURN_POINTER(state1);
                               4977                 : 
                               4978                 :     /* manually copy all fields from state2 to state1 */
 2560 rhaas                    4979 GIC          17 :     if (state1 == NULL)
                               4980                 :     {
                               4981               9 :         old_context = MemoryContextSwitchTo(agg_context);
 2560 rhaas                    4982 ECB             : 
 2481 tgl                      4983 GIC           9 :         state1 = makeNumericAggStateCurrentContext(true);
 2560 rhaas                    4984 CBC           9 :         state1->N = state2->N;
 2560 rhaas                    4985 GIC           9 :         state1->NaNcount = state2->NaNcount;
  991 tgl                      4986               9 :         state1->pInfcount = state2->pInfcount;
  991 tgl                      4987 CBC           9 :         state1->nInfcount = state2->nInfcount;
 2560 rhaas                    4988               9 :         state1->maxScale = state2->maxScale;
 2560 rhaas                    4989 GIC           9 :         state1->maxScaleCount = state2->maxScaleCount;
                               4990                 : 
 2410 heikki.linnakangas       4991               9 :         accum_sum_copy(&state1->sumX, &state2->sumX);
                               4992               9 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
 2560 rhaas                    4993 ECB             : 
 2560 rhaas                    4994 GIC           9 :         MemoryContextSwitchTo(old_context);
                               4995                 : 
                               4996               9 :         PG_RETURN_POINTER(state1);
                               4997                 :     }
 2560 rhaas                    4998 ECB             : 
 1032 tgl                      4999 GIC           8 :     state1->N += state2->N;
 1032 tgl                      5000 CBC           8 :     state1->NaNcount += state2->NaNcount;
  991                          5001               8 :     state1->pInfcount += state2->pInfcount;
  991 tgl                      5002 GIC           8 :     state1->nInfcount += state2->nInfcount;
                               5003                 : 
 2560 rhaas                    5004               8 :     if (state2->N > 0)
 2560 rhaas                    5005 ECB             :     {
                               5006                 :         /*
 2495                          5007                 :          * These are currently only needed for moving aggregates, but let's do
                               5008                 :          * the right thing anyway...
                               5009                 :          */
 2560 rhaas                    5010 CBC           8 :         if (state2->maxScale > state1->maxScale)
 2560 rhaas                    5011 ECB             :         {
 2560 rhaas                    5012 UIC           0 :             state1->maxScale = state2->maxScale;
 2560 rhaas                    5013 LBC           0 :             state1->maxScaleCount = state2->maxScaleCount;
                               5014                 :         }
 2560 rhaas                    5015 GIC           8 :         else if (state2->maxScale == state1->maxScale)
 2560 rhaas                    5016 CBC           8 :             state1->maxScaleCount += state2->maxScaleCount;
 2560 rhaas                    5017 ECB             : 
                               5018                 :         /* The rest of this needs to work in the aggregate context */
 2560 rhaas                    5019 GIC           8 :         old_context = MemoryContextSwitchTo(agg_context);
                               5020                 : 
                               5021                 :         /* Accumulate sums */
 2410 heikki.linnakangas       5022               8 :         accum_sum_combine(&state1->sumX, &state2->sumX);
 2410 heikki.linnakangas       5023 CBC           8 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
                               5024                 : 
 2560 rhaas                    5025               8 :         MemoryContextSwitchTo(old_context);
 2560 rhaas                    5026 ECB             :     }
 2560 rhaas                    5027 GBC           8 :     PG_RETURN_POINTER(state1);
                               5028                 : }
                               5029                 : 
 5895 bruce                    5030 ECB             : /*
                               5031                 :  * Generic transition function for numeric aggregates that don't require sumX2.
                               5032                 :  */
                               5033                 : Datum
 5895 bruce                    5034 GIC      936404 : numeric_avg_accum(PG_FUNCTION_ARGS)
                               5035                 : {
                               5036                 :     NumericAggState *state;
                               5037                 : 
 3431 tgl                      5038          936404 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
 3431 tgl                      5039 ECB             : 
                               5040                 :     /* Create the state data on the first call */
 3284 tgl                      5041 GIC      936404 :     if (state == NULL)
                               5042           85452 :         state = makeNumericAggState(fcinfo, false);
 3431 tgl                      5043 ECB             : 
 3284 tgl                      5044 GIC      936404 :     if (!PG_ARGISNULL(1))
 3431                          5045          936374 :         do_numeric_accum(state, PG_GETARG_NUMERIC(1));
 3284 tgl                      5046 ECB             : 
 3284 tgl                      5047 CBC      936404 :     PG_RETURN_POINTER(state);
                               5048                 : }
 3284 tgl                      5049 ECB             : 
 2560 rhaas                    5050                 : /*
                               5051                 :  * Combine function for numeric aggregates which don't require sumX2
                               5052                 :  */
                               5053                 : Datum
 2560 rhaas                    5054 GIC          11 : numeric_avg_combine(PG_FUNCTION_ARGS)
                               5055                 : {
                               5056                 :     NumericAggState *state1;
                               5057                 :     NumericAggState *state2;
                               5058                 :     MemoryContext agg_context;
 2495 rhaas                    5059 ECB             :     MemoryContext old_context;
                               5060                 : 
 2560 rhaas                    5061 GIC          11 :     if (!AggCheckCallContext(fcinfo, &agg_context))
 2560 rhaas                    5062 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5063                 : 
 2560 rhaas                    5064 GIC          11 :     state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               5065              11 :     state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
 2560 rhaas                    5066 ECB             : 
 2560 rhaas                    5067 GBC          11 :     if (state2 == NULL)
 2560 rhaas                    5068 UIC           0 :         PG_RETURN_POINTER(state1);
 2560 rhaas                    5069 ECB             : 
                               5070                 :     /* manually copy all fields from state2 to state1 */
 2560 rhaas                    5071 GIC          11 :     if (state1 == NULL)
 2560 rhaas                    5072 ECB             :     {
 2560 rhaas                    5073 GBC           3 :         old_context = MemoryContextSwitchTo(agg_context);
                               5074                 : 
 2481 tgl                      5075 GIC           3 :         state1 = makeNumericAggStateCurrentContext(false);
 2560 rhaas                    5076 CBC           3 :         state1->N = state2->N;
 2560 rhaas                    5077 GIC           3 :         state1->NaNcount = state2->NaNcount;
  991 tgl                      5078 CBC           3 :         state1->pInfcount = state2->pInfcount;
  991 tgl                      5079 GIC           3 :         state1->nInfcount = state2->nInfcount;
 2560 rhaas                    5080 CBC           3 :         state1->maxScale = state2->maxScale;
                               5081               3 :         state1->maxScaleCount = state2->maxScaleCount;
 2560 rhaas                    5082 ECB             : 
 2410 heikki.linnakangas       5083 CBC           3 :         accum_sum_copy(&state1->sumX, &state2->sumX);
 2560 rhaas                    5084 ECB             : 
 2560 rhaas                    5085 CBC           3 :         MemoryContextSwitchTo(old_context);
 2560 rhaas                    5086 ECB             : 
 2560 rhaas                    5087 GIC           3 :         PG_RETURN_POINTER(state1);
 2560 rhaas                    5088 ECB             :     }
                               5089                 : 
 1032 tgl                      5090 GIC           8 :     state1->N += state2->N;
 1032 tgl                      5091 CBC           8 :     state1->NaNcount += state2->NaNcount;
  991 tgl                      5092 GIC           8 :     state1->pInfcount += state2->pInfcount;
  991 tgl                      5093 CBC           8 :     state1->nInfcount += state2->nInfcount;
                               5094                 : 
 2560 rhaas                    5095 GIC           8 :     if (state2->N > 0)
 2560 rhaas                    5096 ECB             :     {
                               5097                 :         /*
 2495                          5098                 :          * These are currently only needed for moving aggregates, but let's do
                               5099                 :          * the right thing anyway...
                               5100                 :          */
 2560 rhaas                    5101 CBC           8 :         if (state2->maxScale > state1->maxScale)
                               5102                 :         {
 2560 rhaas                    5103 UIC           0 :             state1->maxScale = state2->maxScale;
                               5104               0 :             state1->maxScaleCount = state2->maxScaleCount;
                               5105                 :         }
 2560 rhaas                    5106 GIC           8 :         else if (state2->maxScale == state1->maxScale)
 2560 rhaas                    5107 CBC           8 :             state1->maxScaleCount += state2->maxScaleCount;
                               5108                 : 
 2560 rhaas                    5109 EUB             :         /* The rest of this needs to work in the aggregate context */
 2560 rhaas                    5110 GBC           8 :         old_context = MemoryContextSwitchTo(agg_context);
                               5111                 : 
 2560 rhaas                    5112 ECB             :         /* Accumulate sums */
 2410 heikki.linnakangas       5113 CBC           8 :         accum_sum_combine(&state1->sumX, &state2->sumX);
                               5114                 : 
 2560 rhaas                    5115 GIC           8 :         MemoryContextSwitchTo(old_context);
 2560 rhaas                    5116 ECB             :     }
 2560 rhaas                    5117 GIC           8 :     PG_RETURN_POINTER(state1);
                               5118                 : }
 2560 rhaas                    5119 ECB             : 
                               5120                 : /*
                               5121                 :  * numeric_avg_serialize
                               5122                 :  *      Serialize NumericAggState for numeric aggregates that don't require
                               5123                 :  *      sumX2.
                               5124                 :  */
                               5125                 : Datum
 2560 rhaas                    5126 GIC          11 : numeric_avg_serialize(PG_FUNCTION_ARGS)
                               5127                 : {
                               5128                 :     NumericAggState *state;
                               5129                 :     StringInfoData buf;
                               5130                 :     bytea      *result;
 2410 heikki.linnakangas       5131 ECB             :     NumericVar  tmp_var;
                               5132                 : 
                               5133                 :     /* Ensure we disallow calling when not in aggregate context */
 2560 rhaas                    5134 GIC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5135 LBC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5136                 : 
 2560 rhaas                    5137 GIC          11 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
 2560 rhaas                    5138 ECB             : 
 2410 heikki.linnakangas       5139 CBC          11 :     init_var(&tmp_var);
                               5140                 : 
 2560 rhaas                    5141              11 :     pq_begintypsend(&buf);
 2560 rhaas                    5142 ECB             : 
                               5143                 :     /* N */
 2560 rhaas                    5144 CBC          11 :     pq_sendint64(&buf, state->N);
                               5145                 : 
                               5146                 :     /* sumX */
  643 dean.a.rasheed           5147 GIC          11 :     accum_sum_final(&state->sumX, &tmp_var);
                               5148              11 :     numericvar_serialize(&buf, &tmp_var);
                               5149                 : 
                               5150                 :     /* maxScale */
 2006 andres                   5151 CBC          11 :     pq_sendint32(&buf, state->maxScale);
                               5152                 : 
                               5153                 :     /* maxScaleCount */
 2560 rhaas                    5154 GIC          11 :     pq_sendint64(&buf, state->maxScaleCount);
                               5155                 : 
                               5156                 :     /* NaNcount */
                               5157              11 :     pq_sendint64(&buf, state->NaNcount);
 2560 rhaas                    5158 ECB             : 
  991 tgl                      5159 EUB             :     /* pInfcount */
  991 tgl                      5160 GIC          11 :     pq_sendint64(&buf, state->pInfcount);
  991 tgl                      5161 ECB             : 
                               5162                 :     /* nInfcount */
  991 tgl                      5163 GIC          11 :     pq_sendint64(&buf, state->nInfcount);
  991 tgl                      5164 ECB             : 
 2560 rhaas                    5165 GBC          11 :     result = pq_endtypsend(&buf);
                               5166                 : 
  643 dean.a.rasheed           5167 GIC          11 :     free_var(&tmp_var);
  643 dean.a.rasheed           5168 ECB             : 
 2560 rhaas                    5169 GIC          11 :     PG_RETURN_BYTEA_P(result);
 2560 rhaas                    5170 ECB             : }
                               5171                 : 
                               5172                 : /*
                               5173                 :  * numeric_avg_deserialize
 2482 tgl                      5174                 :  *      Deserialize bytea into NumericAggState for numeric aggregates that
                               5175                 :  *      don't require sumX2.
 2560 rhaas                    5176                 :  */
                               5177                 : Datum
 2560 rhaas                    5178 CBC          11 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
                               5179                 : {
 2482 tgl                      5180 ECB             :     bytea      *sstate;
                               5181                 :     NumericAggState *result;
 2495 rhaas                    5182                 :     StringInfoData buf;
                               5183                 :     NumericVar  tmp_var;
 2560                          5184                 : 
 2560 rhaas                    5185 GIC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5186 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
 2560 rhaas                    5187 ECB             : 
 2219 noah                     5188 CBC          11 :     sstate = PG_GETARG_BYTEA_PP(0);
 2482 tgl                      5189 ECB             : 
  643 dean.a.rasheed           5190 CBC          11 :     init_var(&tmp_var);
                               5191                 : 
 2560 rhaas                    5192 ECB             :     /*
                               5193                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
                               5194                 :      * standard recv-function infrastructure.
                               5195                 :      */
 2560 rhaas                    5196 GIC          11 :     initStringInfo(&buf);
 2219 noah                     5197              22 :     appendBinaryStringInfo(&buf,
 2219 noah                     5198 CBC          22 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
                               5199                 : 
 2481 tgl                      5200 GBC          11 :     result = makeNumericAggStateCurrentContext(false);
 2560 rhaas                    5201 EUB             : 
                               5202                 :     /* N */
 2560 rhaas                    5203 CBC          11 :     result->N = pq_getmsgint64(&buf);
 2560 rhaas                    5204 ECB             : 
                               5205                 :     /* sumX */
  643 dean.a.rasheed           5206 GIC          11 :     numericvar_deserialize(&buf, &tmp_var);
 2410 heikki.linnakangas       5207 CBC          11 :     accum_sum_add(&(result->sumX), &tmp_var);
                               5208                 : 
                               5209                 :     /* maxScale */
 2560 rhaas                    5210              11 :     result->maxScale = pq_getmsgint(&buf, 4);
                               5211                 : 
 2560 rhaas                    5212 ECB             :     /* maxScaleCount */
 2560 rhaas                    5213 GIC          11 :     result->maxScaleCount = pq_getmsgint64(&buf);
 2560 rhaas                    5214 ECB             : 
                               5215                 :     /* NaNcount */
 2560 rhaas                    5216 GIC          11 :     result->NaNcount = pq_getmsgint64(&buf);
                               5217                 : 
                               5218                 :     /* pInfcount */
  991 tgl                      5219              11 :     result->pInfcount = pq_getmsgint64(&buf);
                               5220                 : 
                               5221                 :     /* nInfcount */
                               5222              11 :     result->nInfcount = pq_getmsgint64(&buf);
  991 tgl                      5223 ECB             : 
 2560 rhaas                    5224 GIC          11 :     pq_getmsgend(&buf);
                               5225              11 :     pfree(buf.data);
                               5226                 : 
  643 dean.a.rasheed           5227              11 :     free_var(&tmp_var);
                               5228                 : 
 2560 rhaas                    5229              11 :     PG_RETURN_POINTER(result);
                               5230                 : }
 2560 rhaas                    5231 ECB             : 
 2560 rhaas                    5232 EUB             : /*
                               5233                 :  * numeric_serialize
 2560 rhaas                    5234 ECB             :  *      Serialization function for NumericAggState for numeric aggregates that
                               5235                 :  *      require sumX2.
                               5236                 :  */
                               5237                 : Datum
 2560 rhaas                    5238 CBC          17 : numeric_serialize(PG_FUNCTION_ARGS)
                               5239                 : {
                               5240                 :     NumericAggState *state;
 2495 rhaas                    5241 ECB             :     StringInfoData buf;
                               5242                 :     bytea      *result;
                               5243                 :     NumericVar  tmp_var;
 2560                          5244                 : 
                               5245                 :     /* Ensure we disallow calling when not in aggregate context */
 2560 rhaas                    5246 GIC          17 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5247 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
 2560 rhaas                    5248 ECB             : 
 2560 rhaas                    5249 GIC          17 :     state = (NumericAggState *) PG_GETARG_POINTER(0);
                               5250                 : 
 2410 heikki.linnakangas       5251 CBC          17 :     init_var(&tmp_var);
                               5252                 : 
 2560 rhaas                    5253 GIC          17 :     pq_begintypsend(&buf);
 2560 rhaas                    5254 ECB             : 
                               5255                 :     /* N */
 2560 rhaas                    5256 GIC          17 :     pq_sendint64(&buf, state->N);
 2560 rhaas                    5257 ECB             : 
                               5258                 :     /* sumX */
  643 dean.a.rasheed           5259 GIC          17 :     accum_sum_final(&state->sumX, &tmp_var);
  643 dean.a.rasheed           5260 CBC          17 :     numericvar_serialize(&buf, &tmp_var);
                               5261                 : 
 2560 rhaas                    5262 ECB             :     /* sumX2 */
  643 dean.a.rasheed           5263 GIC          17 :     accum_sum_final(&state->sumX2, &tmp_var);
  643 dean.a.rasheed           5264 CBC          17 :     numericvar_serialize(&buf, &tmp_var);
                               5265                 : 
 2560 rhaas                    5266 ECB             :     /* maxScale */
 2006 andres                   5267 GIC          17 :     pq_sendint32(&buf, state->maxScale);
                               5268                 : 
                               5269                 :     /* maxScaleCount */
 2560 rhaas                    5270              17 :     pq_sendint64(&buf, state->maxScaleCount);
                               5271                 : 
                               5272                 :     /* NaNcount */
                               5273              17 :     pq_sendint64(&buf, state->NaNcount);
                               5274                 : 
  991 tgl                      5275 ECB             :     /* pInfcount */
  991 tgl                      5276 GIC          17 :     pq_sendint64(&buf, state->pInfcount);
                               5277                 : 
                               5278                 :     /* nInfcount */
                               5279              17 :     pq_sendint64(&buf, state->nInfcount);
                               5280                 : 
 2560 rhaas                    5281              17 :     result = pq_endtypsend(&buf);
 2560 rhaas                    5282 ECB             : 
  643 dean.a.rasheed           5283 GBC          17 :     free_var(&tmp_var);
                               5284                 : 
 2560 rhaas                    5285 CBC          17 :     PG_RETURN_BYTEA_P(result);
                               5286                 : }
 2560 rhaas                    5287 ECB             : 
                               5288                 : /*
                               5289                 :  * numeric_deserialize
                               5290                 :  *      Deserialization function for NumericAggState for numeric aggregates that
                               5291                 :  *      require sumX2.
                               5292                 :  */
                               5293                 : Datum
 2560 rhaas                    5294 CBC          17 : numeric_deserialize(PG_FUNCTION_ARGS)
 2560 rhaas                    5295 ECB             : {
                               5296                 :     bytea      *sstate;
 2495                          5297                 :     NumericAggState *result;
                               5298                 :     StringInfoData buf;
                               5299                 :     NumericVar  tmp_var;
 2560                          5300                 : 
 2560 rhaas                    5301 GIC          17 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5302 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
 2560 rhaas                    5303 ECB             : 
 2219 noah                     5304 CBC          17 :     sstate = PG_GETARG_BYTEA_PP(0);
                               5305                 : 
  643 dean.a.rasheed           5306 GIC          17 :     init_var(&tmp_var);
  643 dean.a.rasheed           5307 ECB             : 
                               5308                 :     /*
                               5309                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
 2481 tgl                      5310                 :      * standard recv-function infrastructure.
                               5311                 :      */
 2560 rhaas                    5312 GIC          17 :     initStringInfo(&buf);
 2219 noah                     5313 CBC          34 :     appendBinaryStringInfo(&buf,
 2219 noah                     5314 GIC          34 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
                               5315                 : 
 2481 tgl                      5316 CBC          17 :     result = makeNumericAggStateCurrentContext(false);
                               5317                 : 
                               5318                 :     /* N */
 2560 rhaas                    5319              17 :     result->N = pq_getmsgint64(&buf);
                               5320                 : 
 2560 rhaas                    5321 ECB             :     /* sumX */
  643 dean.a.rasheed           5322 CBC          17 :     numericvar_deserialize(&buf, &tmp_var);
  643 dean.a.rasheed           5323 GIC          17 :     accum_sum_add(&(result->sumX), &tmp_var);
 2560 rhaas                    5324 ECB             : 
                               5325                 :     /* sumX2 */
  643 dean.a.rasheed           5326 CBC          17 :     numericvar_deserialize(&buf, &tmp_var);
  643 dean.a.rasheed           5327 GIC          17 :     accum_sum_add(&(result->sumX2), &tmp_var);
                               5328                 : 
                               5329                 :     /* maxScale */
 2560 rhaas                    5330              17 :     result->maxScale = pq_getmsgint(&buf, 4);
                               5331                 : 
                               5332                 :     /* maxScaleCount */
                               5333              17 :     result->maxScaleCount = pq_getmsgint64(&buf);
                               5334                 : 
 2560 rhaas                    5335 ECB             :     /* NaNcount */
 2560 rhaas                    5336 GIC          17 :     result->NaNcount = pq_getmsgint64(&buf);
                               5337                 : 
                               5338                 :     /* pInfcount */
  991 tgl                      5339              17 :     result->pInfcount = pq_getmsgint64(&buf);
                               5340                 : 
                               5341                 :     /* nInfcount */
                               5342              17 :     result->nInfcount = pq_getmsgint64(&buf);
  991 tgl                      5343 ECB             : 
 2560 rhaas                    5344 GBC          17 :     pq_getmsgend(&buf);
 2560 rhaas                    5345 GIC          17 :     pfree(buf.data);
 2560 rhaas                    5346 ECB             : 
  643 dean.a.rasheed           5347 GIC          17 :     free_var(&tmp_var);
  643 dean.a.rasheed           5348 ECB             : 
 2560 rhaas                    5349 GIC          17 :     PG_RETURN_POINTER(result);
 2560 rhaas                    5350 ECB             : }
                               5351                 : 
                               5352                 : /*
 3284 tgl                      5353                 :  * Generic inverse transition function for numeric aggregates
                               5354                 :  * (with or without requirement for X^2).
                               5355                 :  */
                               5356                 : Datum
 3284 tgl                      5357 CBC         114 : numeric_accum_inv(PG_FUNCTION_ARGS)
                               5358                 : {
                               5359                 :     NumericAggState *state;
 3284 tgl                      5360 ECB             : 
 3284 tgl                      5361 CBC         114 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               5362                 : 
                               5363                 :     /* Should not get here with no state */
                               5364             114 :     if (state == NULL)
 3284 tgl                      5365 UIC           0 :         elog(ERROR, "numeric_accum_inv called with NULL state");
                               5366                 : 
 3284 tgl                      5367 CBC         114 :     if (!PG_ARGISNULL(1))
                               5368                 :     {
                               5369                 :         /* If we fail to perform the inverse transition, return NULL */
                               5370              99 :         if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
 3284 tgl                      5371 GIC           3 :             PG_RETURN_NULL();
                               5372                 :     }
 5895 bruce                    5373 ECB             : 
 3431 tgl                      5374 GIC         111 :     PG_RETURN_POINTER(state);
                               5375                 : }
 5895 bruce                    5376 ECB             : 
                               5377                 : 
 8301 tgl                      5378                 : /*
                               5379                 :  * Integer data types in general use Numeric accumulators to share code
 2942 andres                   5380                 :  * and avoid risk of overflow.
                               5381                 :  *
                               5382                 :  * However for performance reasons optimized special-purpose accumulator
                               5383                 :  * routines are used when possible.
                               5384                 :  *
                               5385                 :  * On platforms with 128-bit integer support, the 128-bit routines will be
                               5386                 :  * used when sum(X) or sum(X*X) fit into 128-bit.
                               5387                 :  *
                               5388                 :  * For 16 and 32 bit inputs, the N and sum(X) fit into 64-bit so the 64-bit
                               5389                 :  * accumulators will be used for SUM and AVG of these data types.
                               5390                 :  */
                               5391                 : 
                               5392                 : #ifdef HAVE_INT128
                               5393                 : typedef struct Int128AggState
                               5394                 : {
                               5395                 :     bool        calcSumX2;      /* if true, calculate sumX2 */
                               5396                 :     int64       N;              /* count of processed numbers */
                               5397                 :     int128      sumX;           /* sum of processed numbers */
 2878 bruce                    5398                 :     int128      sumX2;          /* sum of squares of processed numbers */
 2942 andres                   5399 EUB             : } Int128AggState;
                               5400                 : 
 2942 andres                   5401 ECB             : /*
                               5402                 :  * Prepare state data for a 128-bit aggregate function that needs to compute
                               5403                 :  * sum, count and optionally sum of squares of the input.
                               5404                 :  */
                               5405                 : static Int128AggState *
 2942 andres                   5406 GIC         322 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
                               5407                 : {
                               5408                 :     Int128AggState *state;
 2942 andres                   5409 ECB             :     MemoryContext agg_context;
                               5410                 :     MemoryContext old_context;
                               5411                 : 
 2942 andres                   5412 GIC         322 :     if (!AggCheckCallContext(fcinfo, &agg_context))
 2942 andres                   5413 LBC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5414                 : 
 2942 andres                   5415 GIC         322 :     old_context = MemoryContextSwitchTo(agg_context);
 2942 andres                   5416 ECB             : 
 2942 andres                   5417 GIC         322 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
                               5418             322 :     state->calcSumX2 = calcSumX2;
 2942 andres                   5419 ECB             : 
 2942 andres                   5420 CBC         322 :     MemoryContextSwitchTo(old_context);
                               5421                 : 
 2942 andres                   5422 GIC         322 :     return state;
 2942 andres                   5423 ECB             : }
                               5424                 : 
                               5425                 : /*
                               5426                 :  * Like makeInt128AggState(), but allocate the state in the current memory
 2481 tgl                      5427                 :  * context.
                               5428                 :  */
                               5429                 : static Int128AggState *
 2481 tgl                      5430 CBC          19 : makeInt128AggStateCurrentContext(bool calcSumX2)
                               5431                 : {
                               5432                 :     Int128AggState *state;
 2481 tgl                      5433 ECB             : 
 2481 tgl                      5434 GIC          19 :     state = (Int128AggState *) palloc0(sizeof(Int128AggState));
                               5435              19 :     state->calcSumX2 = calcSumX2;
 2481 tgl                      5436 ECB             : 
 2481 tgl                      5437 GIC          19 :     return state;
                               5438                 : }
 2481 tgl                      5439 ECB             : 
                               5440                 : /*
 2942 andres                   5441                 :  * Accumulate a new input value for 128-bit aggregate functions.
                               5442                 :  */
                               5443                 : static void
 2942 andres                   5444 CBC      276265 : do_int128_accum(Int128AggState *state, int128 newval)
                               5445                 : {
                               5446          276265 :     if (state->calcSumX2)
 2942 andres                   5447 GIC      121180 :         state->sumX2 += newval * newval;
                               5448                 : 
                               5449          276265 :     state->sumX += newval;
                               5450          276265 :     state->N++;
                               5451          276265 : }
                               5452                 : 
                               5453                 : /*
 2942 andres                   5454 ECB             :  * Remove an input value from the aggregated state.
                               5455                 :  */
                               5456                 : static void
 2942 andres                   5457 GIC         156 : do_int128_discard(Int128AggState *state, int128 newval)
 2942 andres                   5458 ECB             : {
 2942 andres                   5459 GIC         156 :     if (state->calcSumX2)
                               5460             144 :         state->sumX2 -= newval * newval;
 2942 andres                   5461 ECB             : 
 2942 andres                   5462 GBC         156 :     state->sumX -= newval;
 2942 andres                   5463 GIC         156 :     state->N--;
 2942 andres                   5464 CBC         156 : }
                               5465                 : 
                               5466                 : typedef Int128AggState PolyNumAggState;
 2942 andres                   5467 ECB             : #define makePolyNumAggState makeInt128AggState
 2481 tgl                      5468                 : #define makePolyNumAggStateCurrentContext makeInt128AggStateCurrentContext
                               5469                 : #else
                               5470                 : typedef NumericAggState PolyNumAggState;
 2942 andres                   5471                 : #define makePolyNumAggState makeNumericAggState
                               5472                 : #define makePolyNumAggStateCurrentContext makeNumericAggStateCurrentContext
                               5473                 : #endif
                               5474                 : 
                               5475                 : Datum
 8301 tgl                      5476 GIC          99 : int2_accum(PG_FUNCTION_ARGS)
                               5477                 : {
                               5478                 :     PolyNumAggState *state;
                               5479                 : 
 2942 andres                   5480              99 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5481                 : 
                               5482                 :     /* Create the state data on the first call */
 3284 tgl                      5483              99 :     if (state == NULL)
 2942 andres                   5484              18 :         state = makePolyNumAggState(fcinfo, true);
                               5485                 : 
 3431 tgl                      5486              99 :     if (!PG_ARGISNULL(1))
                               5487                 :     {
                               5488                 : #ifdef HAVE_INT128
 2940 andres                   5489              90 :         do_int128_accum(state, (int128) PG_GETARG_INT16(1));
                               5490                 : #else
                               5491                 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1)));
                               5492                 : #endif
                               5493                 :     }
                               5494                 : 
 3431 tgl                      5495              99 :     PG_RETURN_POINTER(state);
                               5496                 : }
                               5497                 : 
                               5498                 : Datum
 8301                          5499          121099 : int4_accum(PG_FUNCTION_ARGS)
                               5500                 : {
                               5501                 :     PolyNumAggState *state;
                               5502                 : 
 2942 andres                   5503 CBC      121099 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5504                 : 
                               5505                 :     /* Create the state data on the first call */
 3284 tgl                      5506 GIC      121099 :     if (state == NULL)
 2942 andres                   5507              36 :         state = makePolyNumAggState(fcinfo, true);
                               5508                 : 
 3431 tgl                      5509 CBC      121099 :     if (!PG_ARGISNULL(1))
 3431 tgl                      5510 EUB             :     {
                               5511                 : #ifdef HAVE_INT128
 2942 andres                   5512 CBC      121090 :         do_int128_accum(state, (int128) PG_GETARG_INT32(1));
                               5513                 : #else
  942 peter                    5514 ECB             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1)));
 2942 andres                   5515                 : #endif
                               5516                 :     }
 8301 tgl                      5517                 : 
 3431 tgl                      5518 GIC      121099 :     PG_RETURN_POINTER(state);
 8301 tgl                      5519 ECB             : }
                               5520                 : 
                               5521                 : Datum
 8301 tgl                      5522 GIC      120099 : int8_accum(PG_FUNCTION_ARGS)
                               5523                 : {
                               5524                 :     NumericAggState *state;
                               5525                 : 
 3431                          5526          120099 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
 3431 tgl                      5527 ECB             : 
                               5528                 :     /* Create the state data on the first call */
 3284 tgl                      5529 GIC      120099 :     if (state == NULL)
                               5530              29 :         state = makeNumericAggState(fcinfo, true);
 3284 tgl                      5531 ECB             : 
 3431 tgl                      5532 CBC      120099 :     if (!PG_ARGISNULL(1))
  942 peter                    5533 GIC      120090 :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
 3431 tgl                      5534 ECB             : 
 3431 tgl                      5535 GIC      120099 :     PG_RETURN_POINTER(state);
                               5536                 : }
                               5537                 : 
                               5538                 : /*
                               5539                 :  * Combine function for numeric aggregates which require sumX2
                               5540                 :  */
 2560 rhaas                    5541 ECB             : Datum
 2560 rhaas                    5542 GIC           8 : numeric_poly_combine(PG_FUNCTION_ARGS)
 2560 rhaas                    5543 ECB             : {
                               5544                 :     PolyNumAggState *state1;
                               5545                 :     PolyNumAggState *state2;
 2495                          5546                 :     MemoryContext agg_context;
                               5547                 :     MemoryContext old_context;
 2560                          5548                 : 
 2560 rhaas                    5549 GIC           8 :     if (!AggCheckCallContext(fcinfo, &agg_context))
 2560 rhaas                    5550 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5551                 : 
 2560 rhaas                    5552 GIC           8 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5553               8 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
 2560 rhaas                    5554 ECB             : 
 2560 rhaas                    5555 GIC           8 :     if (state2 == NULL)
 2560 rhaas                    5556 LBC           0 :         PG_RETURN_POINTER(state1);
 2560 rhaas                    5557 ECB             : 
                               5558                 :     /* manually copy all fields from state2 to state1 */
 2560 rhaas                    5559 CBC           8 :     if (state1 == NULL)
 2560 rhaas                    5560 ECB             :     {
 2560 rhaas                    5561 CBC           3 :         old_context = MemoryContextSwitchTo(agg_context);
                               5562                 : 
 2560 rhaas                    5563 GIC           3 :         state1 = makePolyNumAggState(fcinfo, true);
                               5564               3 :         state1->N = state2->N;
                               5565                 : 
                               5566                 : #ifdef HAVE_INT128
                               5567               3 :         state1->sumX = state2->sumX;
                               5568               3 :         state1->sumX2 = state2->sumX2;
                               5569                 : #else
                               5570                 :         accum_sum_copy(&state1->sumX, &state2->sumX);
                               5571                 :         accum_sum_copy(&state1->sumX2, &state2->sumX2);
                               5572                 : #endif
 2560 rhaas                    5573 ECB             : 
 2560 rhaas                    5574 GIC           3 :         MemoryContextSwitchTo(old_context);
                               5575                 : 
                               5576               3 :         PG_RETURN_POINTER(state1);
 2560 rhaas                    5577 ECB             :     }
                               5578                 : 
 2560 rhaas                    5579 GIC           5 :     if (state2->N > 0)
 2560 rhaas                    5580 ECB             :     {
 2560 rhaas                    5581 CBC           5 :         state1->N += state2->N;
                               5582                 : 
 2560 rhaas                    5583 ECB             : #ifdef HAVE_INT128
 2560 rhaas                    5584 GIC           5 :         state1->sumX += state2->sumX;
                               5585               5 :         state1->sumX2 += state2->sumX2;
 2560 rhaas                    5586 ECB             : #else
                               5587                 :         /* The rest of this needs to work in the aggregate context */
                               5588                 :         old_context = MemoryContextSwitchTo(agg_context);
                               5589                 : 
                               5590                 :         /* Accumulate sums */
                               5591                 :         accum_sum_combine(&state1->sumX, &state2->sumX);
 2410 heikki.linnakangas       5592                 :         accum_sum_combine(&state1->sumX2, &state2->sumX2);
                               5593                 : 
                               5594                 :         MemoryContextSwitchTo(old_context);
                               5595                 : #endif
 2560 rhaas                    5596                 : 
                               5597                 :     }
 2560 rhaas                    5598 GIC           5 :     PG_RETURN_POINTER(state1);
                               5599                 : }
 2560 rhaas                    5600 ECB             : 
                               5601                 : /*
                               5602                 :  * numeric_poly_serialize
 2482 tgl                      5603                 :  *      Serialize PolyNumAggState into bytea for aggregate functions which
                               5604                 :  *      require sumX2.
                               5605                 :  */
 2560 rhaas                    5606                 : Datum
 2560 rhaas                    5607 GIC           8 : numeric_poly_serialize(PG_FUNCTION_ARGS)
                               5608                 : {
 2495 rhaas                    5609 ECB             :     PolyNumAggState *state;
                               5610                 :     StringInfoData buf;
                               5611                 :     bytea      *result;
                               5612                 :     NumericVar  tmp_var;
                               5613                 : 
                               5614                 :     /* Ensure we disallow calling when not in aggregate context */
 2560 rhaas                    5615 CBC           8 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5616 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5617                 : 
 2560 rhaas                    5618 GIC           8 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
 2560 rhaas                    5619 ECB             : 
                               5620                 :     /*
                               5621                 :      * If the platform supports int128 then sumX and sumX2 will be a 128 bit
                               5622                 :      * integer type. Here we'll convert that into a numeric type so that the
                               5623                 :      * combine state is in the same format for both int128 enabled machines
                               5624                 :      * and machines which don't support that type. The logic here is that one
                               5625                 :      * day we might like to send these over to another server for further
                               5626                 :      * processing and we want a standard format to work with.
                               5627                 :      */
                               5628                 : 
  643 dean.a.rasheed           5629 CBC           8 :     init_var(&tmp_var);
 2560 rhaas                    5630 ECB             : 
 2560 rhaas                    5631 GIC           8 :     pq_begintypsend(&buf);
 2560 rhaas                    5632 ECB             : 
                               5633                 :     /* N */
 2560 rhaas                    5634 GIC           8 :     pq_sendint64(&buf, state->N);
                               5635                 : 
                               5636                 :     /* sumX */
                               5637                 : #ifdef HAVE_INT128
  643 dean.a.rasheed           5638               8 :     int128_to_numericvar(state->sumX, &tmp_var);
  643 dean.a.rasheed           5639 ECB             : #else
                               5640                 :     accum_sum_final(&state->sumX, &tmp_var);
                               5641                 : #endif
  643 dean.a.rasheed           5642 GIC           8 :     numericvar_serialize(&buf, &tmp_var);
                               5643                 : 
                               5644                 :     /* sumX2 */
                               5645                 : #ifdef HAVE_INT128
  643 dean.a.rasheed           5646 CBC           8 :     int128_to_numericvar(state->sumX2, &tmp_var);
  643 dean.a.rasheed           5647 EUB             : #else
                               5648                 :     accum_sum_final(&state->sumX2, &tmp_var);
  643 dean.a.rasheed           5649 ECB             : #endif
  643 dean.a.rasheed           5650 CBC           8 :     numericvar_serialize(&buf, &tmp_var);
                               5651                 : 
 2560 rhaas                    5652               8 :     result = pq_endtypsend(&buf);
 2560 rhaas                    5653 EUB             : 
  643 dean.a.rasheed           5654 GIC           8 :     free_var(&tmp_var);
                               5655                 : 
 2560 rhaas                    5656 CBC           8 :     PG_RETURN_BYTEA_P(result);
                               5657                 : }
 2560 rhaas                    5658 ECB             : 
                               5659                 : /*
                               5660                 :  * numeric_poly_deserialize
 2482 tgl                      5661                 :  *      Deserialize PolyNumAggState from bytea for aggregate functions which
                               5662                 :  *      require sumX2.
                               5663                 :  */
 2560 rhaas                    5664                 : Datum
 2560 rhaas                    5665 CBC           8 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
                               5666                 : {
                               5667                 :     bytea      *sstate;
                               5668                 :     PolyNumAggState *result;
                               5669                 :     StringInfoData buf;
                               5670                 :     NumericVar  tmp_var;
 2560 rhaas                    5671 ECB             : 
 2560 rhaas                    5672 GIC           8 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5673 LBC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5674                 : 
 2219 noah                     5675 GIC           8 :     sstate = PG_GETARG_BYTEA_PP(0);
 2482 tgl                      5676 ECB             : 
  643 dean.a.rasheed           5677 GIC           8 :     init_var(&tmp_var);
  643 dean.a.rasheed           5678 ECB             : 
                               5679                 :     /*
                               5680                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
 2481 tgl                      5681                 :      * standard recv-function infrastructure.
 2560 rhaas                    5682                 :      */
 2560 rhaas                    5683 GIC           8 :     initStringInfo(&buf);
 2219 noah                     5684              16 :     appendBinaryStringInfo(&buf,
                               5685              16 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
                               5686                 : 
 2481 tgl                      5687               8 :     result = makePolyNumAggStateCurrentContext(false);
                               5688                 : 
                               5689                 :     /* N */
 2560 rhaas                    5690               8 :     result->N = pq_getmsgint64(&buf);
                               5691                 : 
                               5692                 :     /* sumX */
  643 dean.a.rasheed           5693               8 :     numericvar_deserialize(&buf, &tmp_var);
                               5694                 : #ifdef HAVE_INT128
  643 dean.a.rasheed           5695 CBC           8 :     numericvar_to_int128(&tmp_var, &result->sumX);
                               5696                 : #else
                               5697                 :     accum_sum_add(&result->sumX, &tmp_var);
                               5698                 : #endif
                               5699                 : 
                               5700                 :     /* sumX2 */
  643 dean.a.rasheed           5701 GIC           8 :     numericvar_deserialize(&buf, &tmp_var);
                               5702                 : #ifdef HAVE_INT128
                               5703               8 :     numericvar_to_int128(&tmp_var, &result->sumX2);
 2560 rhaas                    5704 ECB             : #else
                               5705                 :     accum_sum_add(&result->sumX2, &tmp_var);
                               5706                 : #endif
                               5707                 : 
 2560 rhaas                    5708 GIC           8 :     pq_getmsgend(&buf);
                               5709               8 :     pfree(buf.data);
                               5710                 : 
  643 dean.a.rasheed           5711               8 :     free_var(&tmp_var);
  643 dean.a.rasheed           5712 ECB             : 
 2560 rhaas                    5713 GBC           8 :     PG_RETURN_POINTER(result);
                               5714                 : }
 2560 rhaas                    5715 ECB             : 
                               5716                 : /*
                               5717                 :  * Transition function for int8 input when we don't need sumX2.
                               5718                 :  */
                               5719                 : Datum
 5895 bruce                    5720 GIC      155559 : int8_avg_accum(PG_FUNCTION_ARGS)
                               5721                 : {
                               5722                 :     PolyNumAggState *state;
                               5723                 : 
 2942 andres                   5724          155559 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5725                 : 
 3284 tgl                      5726 ECB             :     /* Create the state data on the first call */
 3284 tgl                      5727 GIC      155559 :     if (state == NULL)
 2942 andres                   5728 CBC         259 :         state = makePolyNumAggState(fcinfo, false);
                               5729                 : 
 3431 tgl                      5730 GIC      155559 :     if (!PG_ARGISNULL(1))
 3431 tgl                      5731 ECB             :     {
                               5732                 : #ifdef HAVE_INT128
 2942 andres                   5733 GIC      155085 :         do_int128_accum(state, (int128) PG_GETARG_INT64(1));
                               5734                 : #else
  942 peter                    5735 ECB             :         do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
                               5736                 : #endif
                               5737                 :     }
                               5738                 : 
 3284 tgl                      5739 CBC      155559 :     PG_RETURN_POINTER(state);
                               5740                 : }
                               5741                 : 
                               5742                 : /*
 2560 rhaas                    5743 ECB             :  * Combine function for PolyNumAggState for aggregates which don't require
                               5744                 :  * sumX2
                               5745                 :  */
                               5746                 : Datum
 2560 rhaas                    5747 CBC          11 : int8_avg_combine(PG_FUNCTION_ARGS)
                               5748                 : {
 2495 rhaas                    5749 ECB             :     PolyNumAggState *state1;
                               5750                 :     PolyNumAggState *state2;
                               5751                 :     MemoryContext agg_context;
                               5752                 :     MemoryContext old_context;
 2560                          5753                 : 
 2560 rhaas                    5754 GIC          11 :     if (!AggCheckCallContext(fcinfo, &agg_context))
 2560 rhaas                    5755 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               5756                 : 
 2560 rhaas                    5757 GIC          11 :     state1 = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5758              11 :     state2 = PG_ARGISNULL(1) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(1);
                               5759                 : 
                               5760              11 :     if (state2 == NULL)
 2560 rhaas                    5761 UIC           0 :         PG_RETURN_POINTER(state1);
 2560 rhaas                    5762 ECB             : 
                               5763                 :     /* manually copy all fields from state2 to state1 */
 2560 rhaas                    5764 GIC          11 :     if (state1 == NULL)
                               5765                 :     {
                               5766               6 :         old_context = MemoryContextSwitchTo(agg_context);
                               5767                 : 
                               5768               6 :         state1 = makePolyNumAggState(fcinfo, false);
 2560 rhaas                    5769 CBC           6 :         state1->N = state2->N;
 2560 rhaas                    5770 EUB             : 
                               5771                 : #ifdef HAVE_INT128
 2560 rhaas                    5772 CBC           6 :         state1->sumX = state2->sumX;
                               5773                 : #else
 2410 heikki.linnakangas       5774 ECB             :         accum_sum_copy(&state1->sumX, &state2->sumX);
                               5775                 : #endif
 2560 rhaas                    5776 GIC           6 :         MemoryContextSwitchTo(old_context);
                               5777                 : 
                               5778               6 :         PG_RETURN_POINTER(state1);
                               5779                 :     }
 2560 rhaas                    5780 ECB             : 
 2560 rhaas                    5781 CBC           5 :     if (state2->N > 0)
 2560 rhaas                    5782 ECB             :     {
 2560 rhaas                    5783 GIC           5 :         state1->N += state2->N;
 2560 rhaas                    5784 ECB             : 
                               5785                 : #ifdef HAVE_INT128
 2560 rhaas                    5786 GIC           5 :         state1->sumX += state2->sumX;
 2560 rhaas                    5787 ECB             : #else
                               5788                 :         /* The rest of this needs to work in the aggregate context */
                               5789                 :         old_context = MemoryContextSwitchTo(agg_context);
                               5790                 : 
                               5791                 :         /* Accumulate sums */
 2410 heikki.linnakangas       5792                 :         accum_sum_combine(&state1->sumX, &state2->sumX);
                               5793                 : 
                               5794                 :         MemoryContextSwitchTo(old_context);
                               5795                 : #endif
                               5796                 : 
                               5797                 :     }
 2560 rhaas                    5798 CBC           5 :     PG_RETURN_POINTER(state1);
                               5799                 : }
 2560 rhaas                    5800 ECB             : 
                               5801                 : /*
                               5802                 :  * int8_avg_serialize
                               5803                 :  *      Serialize PolyNumAggState into bytea using the standard
                               5804                 :  *      recv-function infrastructure.
                               5805                 :  */
                               5806                 : Datum
 2560 rhaas                    5807 GIC          11 : int8_avg_serialize(PG_FUNCTION_ARGS)
 2560 rhaas                    5808 ECB             : {
                               5809                 :     PolyNumAggState *state;
 2495                          5810                 :     StringInfoData buf;
                               5811                 :     bytea      *result;
                               5812                 :     NumericVar  tmp_var;
                               5813                 : 
                               5814                 :     /* Ensure we disallow calling when not in aggregate context */
 2560 rhaas                    5815 GIC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5816 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
 2560 rhaas                    5817 ECB             : 
 2560 rhaas                    5818 GIC          11 :     state = (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5819                 : 
                               5820                 :     /*
 2560 rhaas                    5821 ECB             :      * If the platform supports int128 then sumX will be a 128 integer type.
                               5822                 :      * Here we'll convert that into a numeric type so that the combine state
                               5823                 :      * is in the same format for both int128 enabled machines and machines
                               5824                 :      * which don't support that type. The logic here is that one day we might
                               5825                 :      * like to send these over to another server for further processing and we
                               5826                 :      * want a standard format to work with.
                               5827                 :      */
                               5828                 : 
  643 dean.a.rasheed           5829 GIC          11 :     init_var(&tmp_var);
 2560 rhaas                    5830 ECB             : 
 2560 rhaas                    5831 GIC          11 :     pq_begintypsend(&buf);
                               5832                 : 
                               5833                 :     /* N */
                               5834              11 :     pq_sendint64(&buf, state->N);
                               5835                 : 
 2560 rhaas                    5836 ECB             :     /* sumX */
                               5837                 : #ifdef HAVE_INT128
  643 dean.a.rasheed           5838 GIC          11 :     int128_to_numericvar(state->sumX, &tmp_var);
                               5839                 : #else
                               5840                 :     accum_sum_final(&state->sumX, &tmp_var);
                               5841                 : #endif
                               5842              11 :     numericvar_serialize(&buf, &tmp_var);
                               5843                 : 
 2560 rhaas                    5844 CBC          11 :     result = pq_endtypsend(&buf);
                               5845                 : 
  643 dean.a.rasheed           5846 GIC          11 :     free_var(&tmp_var);
                               5847                 : 
 2560 rhaas                    5848              11 :     PG_RETURN_BYTEA_P(result);
                               5849                 : }
                               5850                 : 
 2560 rhaas                    5851 ECB             : /*
 2560 rhaas                    5852 EUB             :  * int8_avg_deserialize
                               5853                 :  *      Deserialize bytea back into PolyNumAggState.
 2560 rhaas                    5854 ECB             :  */
                               5855                 : Datum
 2560 rhaas                    5856 GIC          11 : int8_avg_deserialize(PG_FUNCTION_ARGS)
 2560 rhaas                    5857 ECB             : {
 2482 tgl                      5858 EUB             :     bytea      *sstate;
                               5859                 :     PolyNumAggState *result;
                               5860                 :     StringInfoData buf;
  643 dean.a.rasheed           5861 ECB             :     NumericVar  tmp_var;
                               5862                 : 
 2560 rhaas                    5863 CBC          11 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    5864 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
 2560 rhaas                    5865 ECB             : 
 2219 noah                     5866 CBC          11 :     sstate = PG_GETARG_BYTEA_PP(0);
                               5867                 : 
  643 dean.a.rasheed           5868 GIC          11 :     init_var(&tmp_var);
  643 dean.a.rasheed           5869 ECB             : 
                               5870                 :     /*
                               5871                 :      * Copy the bytea into a StringInfo so that we can "receive" it using the
                               5872                 :      * standard recv-function infrastructure.
 2560 rhaas                    5873                 :      */
 2560 rhaas                    5874 GIC          11 :     initStringInfo(&buf);
 2219 noah                     5875 CBC          22 :     appendBinaryStringInfo(&buf,
 2219 noah                     5876 GIC          22 :                            VARDATA_ANY(sstate), VARSIZE_ANY_EXHDR(sstate));
                               5877                 : 
 2481 tgl                      5878 CBC          11 :     result = makePolyNumAggStateCurrentContext(false);
                               5879                 : 
 2560 rhaas                    5880 ECB             :     /* N */
 2560 rhaas                    5881 GIC          11 :     result->N = pq_getmsgint64(&buf);
                               5882                 : 
 2560 rhaas                    5883 ECB             :     /* sumX */
  643 dean.a.rasheed           5884 GIC          11 :     numericvar_deserialize(&buf, &tmp_var);
                               5885                 : #ifdef HAVE_INT128
                               5886              11 :     numericvar_to_int128(&tmp_var, &result->sumX);
                               5887                 : #else
                               5888                 :     accum_sum_add(&result->sumX, &tmp_var);
                               5889                 : #endif
                               5890                 : 
 2560 rhaas                    5891              11 :     pq_getmsgend(&buf);
                               5892              11 :     pfree(buf.data);
                               5893                 : 
  643 dean.a.rasheed           5894              11 :     free_var(&tmp_var);
  643 dean.a.rasheed           5895 ECB             : 
 2560 rhaas                    5896 GIC          11 :     PG_RETURN_POINTER(result);
                               5897                 : }
                               5898                 : 
                               5899                 : /*
                               5900                 :  * Inverse transition functions to go with the above.
                               5901                 :  */
                               5902                 : 
                               5903                 : Datum
 3284 tgl                      5904 CBC          81 : int2_accum_inv(PG_FUNCTION_ARGS)
                               5905                 : {
                               5906                 :     PolyNumAggState *state;
                               5907                 : 
 2942 andres                   5908 GIC          81 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5909                 : 
                               5910                 :     /* Should not get here with no state */
 3284 tgl                      5911              81 :     if (state == NULL)
 3284 tgl                      5912 LBC           0 :         elog(ERROR, "int2_accum_inv called with NULL state");
 3284 tgl                      5913 EUB             : 
 3284 tgl                      5914 GIC          81 :     if (!PG_ARGISNULL(1))
 3284 tgl                      5915 ECB             :     {
                               5916                 : #ifdef HAVE_INT128
 2942 andres                   5917 GIC          72 :         do_int128_discard(state, (int128) PG_GETARG_INT16(1));
                               5918                 : #else
                               5919                 :         /* Should never fail, all inputs have dscale 0 */
                               5920                 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1))))
                               5921                 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
                               5922                 : #endif
                               5923                 :     }
                               5924                 : 
 3431 tgl                      5925              81 :     PG_RETURN_POINTER(state);
 5895 bruce                    5926 ECB             : }
                               5927                 : 
 3284 tgl                      5928                 : Datum
 3284 tgl                      5929 GIC          81 : int4_accum_inv(PG_FUNCTION_ARGS)
                               5930                 : {
 2942 andres                   5931 ECB             :     PolyNumAggState *state;
                               5932                 : 
 2942 andres                   5933 GIC          81 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5934                 : 
 3284 tgl                      5935 ECB             :     /* Should not get here with no state */
 3284 tgl                      5936 GIC          81 :     if (state == NULL)
 3284 tgl                      5937 UIC           0 :         elog(ERROR, "int4_accum_inv called with NULL state");
                               5938                 : 
 3284 tgl                      5939 CBC          81 :     if (!PG_ARGISNULL(1))
                               5940                 :     {
 2942 andres                   5941 ECB             : #ifdef HAVE_INT128
 2942 andres                   5942 GIC          72 :         do_int128_discard(state, (int128) PG_GETARG_INT32(1));
 2942 andres                   5943 ECB             : #else
                               5944                 :         /* Should never fail, all inputs have dscale 0 */
  942 peter                    5945                 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1))))
                               5946                 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
                               5947                 : #endif
                               5948                 :     }
                               5949                 : 
 3284 tgl                      5950 GIC          81 :     PG_RETURN_POINTER(state);
                               5951                 : }
                               5952                 : 
 3284 tgl                      5953 ECB             : Datum
 3284 tgl                      5954 GIC          81 : int8_accum_inv(PG_FUNCTION_ARGS)
                               5955                 : {
                               5956                 :     NumericAggState *state;
                               5957                 : 
                               5958              81 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               5959                 : 
 3284 tgl                      5960 ECB             :     /* Should not get here with no state */
 3284 tgl                      5961 GBC          81 :     if (state == NULL)
 3284 tgl                      5962 UIC           0 :         elog(ERROR, "int8_accum_inv called with NULL state");
 3284 tgl                      5963 ECB             : 
 3284 tgl                      5964 GIC          81 :     if (!PG_ARGISNULL(1))
 3284 tgl                      5965 ECB             :     {
                               5966                 :         /* Should never fail, all inputs have dscale 0 */
  942 peter                    5967 GIC          72 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
 3284 tgl                      5968 UIC           0 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
                               5969                 :     }
                               5970                 : 
 3284 tgl                      5971 CBC          81 :     PG_RETURN_POINTER(state);
 3284 tgl                      5972 ECB             : }
 5895 bruce                    5973                 : 
                               5974                 : Datum
 2942 andres                   5975 CBC          18 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
                               5976                 : {
                               5977                 :     PolyNumAggState *state;
 2942 andres                   5978 ECB             : 
 2942 andres                   5979 GIC          18 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               5980                 : 
 2942 andres                   5981 ECB             :     /* Should not get here with no state */
 2942 andres                   5982 GIC          18 :     if (state == NULL)
 2942 andres                   5983 LBC           0 :         elog(ERROR, "int8_avg_accum_inv called with NULL state");
                               5984                 : 
 2942 andres                   5985 GIC          18 :     if (!PG_ARGISNULL(1))
                               5986                 :     {
                               5987                 : #ifdef HAVE_INT128
 2942 andres                   5988 CBC          12 :         do_int128_discard(state, (int128) PG_GETARG_INT64(1));
 2942 andres                   5989 ECB             : #else
                               5990                 :         /* Should never fail, all inputs have dscale 0 */
  942 peter                    5991                 :         if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
                               5992                 :             elog(ERROR, "do_numeric_discard failed unexpectedly");
 2942 andres                   5993                 : #endif
                               5994                 :     }
                               5995                 : 
 2942 andres                   5996 GIC          18 :     PG_RETURN_POINTER(state);
                               5997                 : }
                               5998                 : 
                               5999                 : Datum
                               6000             371 : numeric_poly_sum(PG_FUNCTION_ARGS)
 2942 andres                   6001 ECB             : {
                               6002                 : #ifdef HAVE_INT128
                               6003                 :     PolyNumAggState *state;
                               6004                 :     Numeric     res;
 2878 bruce                    6005                 :     NumericVar  result;
                               6006                 : 
 2942 andres                   6007 GIC         371 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
 2942 andres                   6008 ECB             : 
 2942 andres                   6009 EUB             :     /* If there were no non-null inputs, return NULL */
 2942 andres                   6010 GIC         371 :     if (state == NULL || state->N == 0)
 2942 andres                   6011 CBC          12 :         PG_RETURN_NULL();
                               6012                 : 
 2942 andres                   6013 GIC         359 :     init_var(&result);
 2942 andres                   6014 ECB             : 
 2942 andres                   6015 GIC         359 :     int128_to_numericvar(state->sumX, &result);
                               6016                 : 
                               6017             359 :     res = make_result(&result);
                               6018                 : 
                               6019             359 :     free_var(&result);
                               6020                 : 
                               6021             359 :     PG_RETURN_NUMERIC(res);
 2942 andres                   6022 ECB             : #else
                               6023                 :     return numeric_sum(fcinfo);
                               6024                 : #endif
                               6025                 : }
                               6026                 : 
                               6027                 : Datum
 2942 andres                   6028 GIC          18 : numeric_poly_avg(PG_FUNCTION_ARGS)
                               6029                 : {
 2942 andres                   6030 ECB             : #ifdef HAVE_INT128
                               6031                 :     PolyNumAggState *state;
                               6032                 :     NumericVar  result;
 2878 bruce                    6033                 :     Datum       countd,
 2878 bruce                    6034 EUB             :                 sumd;
                               6035                 : 
 2942 andres                   6036 CBC          18 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               6037                 : 
                               6038                 :     /* If there were no non-null inputs, return NULL */
                               6039              18 :     if (state == NULL || state->N == 0)
 2942 andres                   6040 GIC           9 :         PG_RETURN_NULL();
                               6041                 : 
                               6042               9 :     init_var(&result);
                               6043                 : 
                               6044               9 :     int128_to_numericvar(state->sumX, &result);
                               6045                 : 
  942 peter                    6046               9 :     countd = NumericGetDatum(int64_to_numeric(state->N));
 2942 andres                   6047 CBC           9 :     sumd = NumericGetDatum(make_result(&result));
                               6048                 : 
 2942 andres                   6049 GIC           9 :     free_var(&result);
                               6050                 : 
 2942 andres                   6051 CBC           9 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
                               6052                 : #else
                               6053                 :     return numeric_avg(fcinfo);
                               6054                 : #endif
 2942 andres                   6055 ECB             : }
                               6056                 : 
                               6057                 : Datum
 8301 tgl                      6058 CBC          39 : numeric_avg(PG_FUNCTION_ARGS)
 8301 tgl                      6059 EUB             : {
                               6060                 :     NumericAggState *state;
 3431 tgl                      6061 ECB             :     Datum       N_datum;
                               6062                 :     Datum       sumX_datum;
                               6063                 :     NumericVar  sumX_var;
                               6064                 : 
 3431 tgl                      6065 GBC          39 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               6066                 : 
                               6067                 :     /* If there were no non-null inputs, return NULL */
  991 tgl                      6068 CBC          39 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
 3431 tgl                      6069 GIC           9 :         PG_RETURN_NULL();
                               6070                 : 
 3260 bruce                    6071              30 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
 3431 tgl                      6072 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
                               6073                 : 
                               6074                 :     /* adding plus and minus infinities gives NaN */
  991 tgl                      6075 GIC          27 :     if (state->pInfcount > 0 && state->nInfcount > 0)
  991 tgl                      6076 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
  991 tgl                      6077 GIC          24 :     if (state->pInfcount > 0)
                               6078               9 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
  991 tgl                      6079 CBC          15 :     if (state->nInfcount > 0)
  991 tgl                      6080 GBC           3 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
                               6081                 : 
  942 peter                    6082 CBC          12 :     N_datum = NumericGetDatum(int64_to_numeric(state->N));
                               6083                 : 
 2410 heikki.linnakangas       6084 GIC          12 :     init_var(&sumX_var);
 2410 heikki.linnakangas       6085 CBC          12 :     accum_sum_final(&state->sumX, &sumX_var);
 2410 heikki.linnakangas       6086 GIC          12 :     sumX_datum = NumericGetDatum(make_result(&sumX_var));
                               6087              12 :     free_var(&sumX_var);
                               6088                 : 
 3431 tgl                      6089              12 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
                               6090                 : }
                               6091                 : 
                               6092                 : Datum
 3431 tgl                      6093 CBC       85453 : numeric_sum(PG_FUNCTION_ARGS)
                               6094                 : {
                               6095                 :     NumericAggState *state;
                               6096                 :     NumericVar  sumX_var;
 2410 heikki.linnakangas       6097 ECB             :     Numeric     result;
                               6098                 : 
 3431 tgl                      6099 GIC       85453 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               6100                 : 
                               6101                 :     /* If there were no non-null inputs, return NULL */
  991                          6102           85453 :     if (state == NULL || NA_TOTAL_COUNT(state) == 0)
 8301                          6103               9 :         PG_RETURN_NULL();
 8301 tgl                      6104 ECB             : 
 3260 bruce                    6105 GIC       85444 :     if (state->NaNcount > 0)  /* there was at least one NaN input */
 3431 tgl                      6106               9 :         PG_RETURN_NUMERIC(make_result(&const_nan));
 3431 tgl                      6107 ECB             : 
  991                          6108                 :     /* adding plus and minus infinities gives NaN */
  991 tgl                      6109 GIC       85435 :     if (state->pInfcount > 0 && state->nInfcount > 0)
  991 tgl                      6110 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_nan));
  991 tgl                      6111 GIC       85432 :     if (state->pInfcount > 0)
  991 tgl                      6112 CBC           9 :         PG_RETURN_NUMERIC(make_result(&const_pinf));
  991 tgl                      6113 GIC       85423 :     if (state->nInfcount > 0)
  991 tgl                      6114 CBC           3 :         PG_RETURN_NUMERIC(make_result(&const_ninf));
                               6115                 : 
 2410 heikki.linnakangas       6116           85420 :     init_var(&sumX_var);
 2410 heikki.linnakangas       6117 GIC       85420 :     accum_sum_final(&state->sumX, &sumX_var);
 2410 heikki.linnakangas       6118 CBC       85420 :     result = make_result(&sumX_var);
 2410 heikki.linnakangas       6119 GIC       85420 :     free_var(&sumX_var);
                               6120                 : 
                               6121           85420 :     PG_RETURN_NUMERIC(result);
                               6122                 : }
                               6123                 : 
                               6124                 : /*
 6239 neilc                    6125 ECB             :  * Workhorse routine for the standard deviance and variance
                               6126                 :  * aggregates. 'state' is aggregate's transition state.
                               6127                 :  * 'variance' specifies whether we should calculate the
                               6128                 :  * variance or the standard deviation. 'sample' indicates whether the
                               6129                 :  * caller is interested in the sample or the population
                               6130                 :  * variance/stddev.
                               6131                 :  *
                               6132                 :  * If appropriate variance statistic is undefined for the input,
                               6133                 :  * *is_null is set to true and NULL is returned.
                               6134                 :  */
                               6135                 : static Numeric
 3431 tgl                      6136 CBC         493 : numeric_stddev_internal(NumericAggState *state,
 6239 neilc                    6137 ECB             :                         bool variance, bool sample,
                               6138                 :                         bool *is_null)
 8301 tgl                      6139                 : {
                               6140                 :     Numeric     res;
                               6141                 :     NumericVar  vN,
                               6142                 :                 vsumX,
                               6143                 :                 vsumX2,
                               6144                 :                 vNminus1;
                               6145                 :     int64       totCount;
 7324                          6146                 :     int         rscale;
                               6147                 : 
 1030                          6148                 :     /*
                               6149                 :      * Sample stddev and variance are undefined when N <= 1; population stddev
                               6150                 :      * is undefined when N == 0.  Return NULL in either case (note that NaNs
                               6151                 :      * and infinities count as normal inputs for this purpose).
                               6152                 :      */
  991 tgl                      6153 GIC         493 :     if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
                               6154                 :     {
 1030 tgl                      6155 LBC           0 :         *is_null = true;
 1030 tgl                      6156 UIC           0 :         return NULL;
                               6157                 :     }
                               6158                 : 
 1030 tgl                      6159 GIC         493 :     if (sample && totCount <= 1)
                               6160                 :     {
 3431                          6161              66 :         *is_null = true;
 3431 tgl                      6162 CBC          66 :         return NULL;
                               6163                 :     }
                               6164                 : 
 6239 neilc                    6165             427 :     *is_null = false;
 6239 neilc                    6166 ECB             : 
                               6167                 :     /*
  991 tgl                      6168                 :      * Deal with NaN and infinity cases.  By analogy to the behavior of the
                               6169                 :      * float8 functions, any infinity input produces NaN output.
                               6170                 :      */
  991 tgl                      6171 GIC         427 :     if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
 6239 neilc                    6172 CBC          27 :         return make_result(&const_nan);
 8301 tgl                      6173 ECB             : 
 1030                          6174                 :     /* OK, normal calculation applies */
 3431 tgl                      6175 CBC         400 :     init_var(&vN);
                               6176             400 :     init_var(&vsumX);
                               6177             400 :     init_var(&vsumX2);
                               6178                 : 
 2942 andres                   6179             400 :     int64_to_numericvar(state->N, &vN);
 2410 heikki.linnakangas       6180 GIC         400 :     accum_sum_final(&(state->sumX), &vsumX);
 2410 heikki.linnakangas       6181 CBC         400 :     accum_sum_final(&(state->sumX2), &vsumX2);
 8301 tgl                      6182 ECB             : 
 7293 tgl                      6183 CBC         400 :     init_var(&vNminus1);
                               6184             400 :     sub_var(&vN, &const_one, &vNminus1);
                               6185                 : 
 7324 tgl                      6186 ECB             :     /* compute rscale for mul_var calls */
 7324 tgl                      6187 GIC         400 :     rscale = vsumX.dscale * 2;
                               6188                 : 
                               6189             400 :     mul_var(&vsumX, &vsumX, &vsumX, rscale);    /* vsumX = sumX * sumX */
 2118 tgl                      6190 CBC         400 :     mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
 6031 bruce                    6191 GIC         400 :     sub_var(&vsumX2, &vsumX, &vsumX2);  /* N * sumX2 - sumX * sumX */
                               6192                 : 
 7789 tgl                      6193             400 :     if (cmp_var(&vsumX2, &const_zero) <= 0)
                               6194                 :     {
                               6195                 :         /* Watch out for roundoff error producing a negative numerator */
 7789 tgl                      6196 CBC          40 :         res = make_result(&const_zero);
                               6197                 :     }
                               6198                 :     else
 7789 tgl                      6199 ECB             :     {
 5753 tgl                      6200 CBC         360 :         if (sample)
 2118 tgl                      6201 GIC         246 :             mul_var(&vN, &vNminus1, &vNminus1, 0);  /* N * (N - 1) */
 5753 tgl                      6202 ECB             :         else
 5624 bruce                    6203 CBC         114 :             mul_var(&vN, &vN, &vNminus1, 0);    /* N * N */
 7324 tgl                      6204 GIC         360 :         rscale = select_div_scale(&vsumX2, &vNminus1);
 2118                          6205             360 :         div_var(&vsumX2, &vNminus1, &vsumX, rscale, true);  /* variance */
 6239 neilc                    6206 CBC         360 :         if (!variance)
 6031 bruce                    6207             189 :             sqrt_var(&vsumX, &vsumX, rscale);   /* stddev */
 7789 tgl                      6208 ECB             : 
 7789 tgl                      6209 CBC         360 :         res = make_result(&vsumX);
 7789 tgl                      6210 ECB             :     }
 8301                          6211                 : 
 8301 tgl                      6212 GIC         400 :     free_var(&vNminus1);
 8301 tgl                      6213 CBC         400 :     free_var(&vsumX);
                               6214             400 :     free_var(&vsumX2);
 8301 tgl                      6215 ECB             : 
 6239 neilc                    6216 CBC         400 :     return res;
                               6217                 : }
 8301 tgl                      6218 ECB             : 
                               6219                 : Datum
 6239 neilc                    6220 GIC          90 : numeric_var_samp(PG_FUNCTION_ARGS)
                               6221                 : {
                               6222                 :     NumericAggState *state;
                               6223                 :     Numeric     res;
                               6224                 :     bool        is_null;
                               6225                 : 
 3431 tgl                      6226              90 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               6227                 : 
                               6228              90 :     res = numeric_stddev_internal(state, true, true, &is_null);
                               6229                 : 
 6239 neilc                    6230              90 :     if (is_null)
 7293 tgl                      6231              21 :         PG_RETURN_NULL();
                               6232                 :     else
 6239 neilc                    6233 CBC          69 :         PG_RETURN_NUMERIC(res);
                               6234                 : }
                               6235                 : 
                               6236                 : Datum
 6239 neilc                    6237 GIC          87 : numeric_stddev_samp(PG_FUNCTION_ARGS)
                               6238                 : {
                               6239                 :     NumericAggState *state;
                               6240                 :     Numeric     res;
                               6241                 :     bool        is_null;
                               6242                 : 
 3431 tgl                      6243              87 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               6244                 : 
                               6245              87 :     res = numeric_stddev_internal(state, false, true, &is_null);
                               6246                 : 
 6239 neilc                    6247              87 :     if (is_null)
                               6248              21 :         PG_RETURN_NULL();
                               6249                 :     else
 6239 neilc                    6250 CBC          66 :         PG_RETURN_NUMERIC(res);
                               6251                 : }
 7494 tgl                      6252 EUB             : 
 6239 neilc                    6253                 : Datum
 6239 neilc                    6254 GIC          57 : numeric_var_pop(PG_FUNCTION_ARGS)
                               6255                 : {
 3431 tgl                      6256 ECB             :     NumericAggState *state;
                               6257                 :     Numeric     res;
 6031 bruce                    6258                 :     bool        is_null;
 8301 tgl                      6259                 : 
 3431 tgl                      6260 GIC          57 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
                               6261                 : 
 3431 tgl                      6262 CBC          57 :     res = numeric_stddev_internal(state, true, false, &is_null);
                               6263                 : 
 6239 neilc                    6264 GIC          57 :     if (is_null)
 6239 neilc                    6265 UIC           0 :         PG_RETURN_NULL();
                               6266                 :     else
 6239 neilc                    6267 GIC          57 :         PG_RETURN_NUMERIC(res);
 6239 neilc                    6268 ECB             : }
 7789 tgl                      6269                 : 
                               6270                 : Datum
 6239 neilc                    6271 GIC          48 : numeric_stddev_pop(PG_FUNCTION_ARGS)
 6239 neilc                    6272 ECB             : {
 3431 tgl                      6273                 :     NumericAggState *state;
 6031 bruce                    6274                 :     Numeric     res;
                               6275                 :     bool        is_null;
 8301 tgl                      6276                 : 
 3431 tgl                      6277 CBC          48 :     state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
 3431 tgl                      6278 ECB             : 
 3431 tgl                      6279 GIC          48 :     res = numeric_stddev_internal(state, false, false, &is_null);
 8301 tgl                      6280 ECB             : 
 6239 neilc                    6281 CBC          48 :     if (is_null)
 6239 neilc                    6282 UIC           0 :         PG_RETURN_NULL();
                               6283                 :     else
 6239 neilc                    6284 CBC          48 :         PG_RETURN_NUMERIC(res);
                               6285                 : }
 8301 tgl                      6286 ECB             : 
 2942 andres                   6287                 : #ifdef HAVE_INT128
                               6288                 : static Numeric
 2942 andres                   6289 GIC         211 : numeric_poly_stddev_internal(Int128AggState *state,
 2878 bruce                    6290 ECB             :                              bool variance, bool sample,
                               6291                 :                              bool *is_null)
                               6292                 : {
 2942 andres                   6293                 :     NumericAggState numstate;
                               6294                 :     Numeric     res;
                               6295                 : 
                               6296                 :     /* Initialize an empty agg state */
 2410 heikki.linnakangas       6297 CBC         211 :     memset(&numstate, 0, sizeof(NumericAggState));
 2942 andres                   6298 ECB             : 
 2942 andres                   6299 GIC         211 :     if (state)
 2942 andres                   6300 ECB             :     {
 2410 heikki.linnakangas       6301                 :         NumericVar  tmp_var;
                               6302                 : 
 2942 andres                   6303 CBC         211 :         numstate.N = state->N;
 2410 heikki.linnakangas       6304 ECB             : 
 2410 heikki.linnakangas       6305 GIC         211 :         init_var(&tmp_var);
 2410 heikki.linnakangas       6306 ECB             : 
 2410 heikki.linnakangas       6307 GIC         211 :         int128_to_numericvar(state->sumX, &tmp_var);
                               6308             211 :         accum_sum_add(&numstate.sumX, &tmp_var);
 2410 heikki.linnakangas       6309 ECB             : 
 2410 heikki.linnakangas       6310 CBC         211 :         int128_to_numericvar(state->sumX2, &tmp_var);
                               6311             211 :         accum_sum_add(&numstate.sumX2, &tmp_var);
                               6312                 : 
                               6313             211 :         free_var(&tmp_var);
                               6314                 :     }
                               6315                 : 
 2942 andres                   6316 GIC         211 :     res = numeric_stddev_internal(&numstate, variance, sample, is_null);
 2942 andres                   6317 ECB             : 
 2410 heikki.linnakangas       6318 GIC         211 :     if (numstate.sumX.ndigits > 0)
                               6319                 :     {
                               6320             211 :         pfree(numstate.sumX.pos_digits);
                               6321             211 :         pfree(numstate.sumX.neg_digits);
                               6322                 :     }
 2410 heikki.linnakangas       6323 CBC         211 :     if (numstate.sumX2.ndigits > 0)
                               6324                 :     {
                               6325             211 :         pfree(numstate.sumX2.pos_digits);
 2410 heikki.linnakangas       6326 GIC         211 :         pfree(numstate.sumX2.neg_digits);
 2410 heikki.linnakangas       6327 ECB             :     }
 2942 andres                   6328                 : 
 2942 andres                   6329 GIC         211 :     return res;
 2942 andres                   6330 ECB             : }
                               6331                 : #endif
                               6332                 : 
                               6333                 : Datum
 2942 andres                   6334 CBC          63 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
                               6335                 : {
                               6336                 : #ifdef HAVE_INT128
                               6337                 :     PolyNumAggState *state;
                               6338                 :     Numeric     res;
                               6339                 :     bool        is_null;
 2942 andres                   6340 ECB             : 
 2942 andres                   6341 GIC          63 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
 2942 andres                   6342 ECB             : 
 2942 andres                   6343 GIC          63 :     res = numeric_poly_stddev_internal(state, true, true, &is_null);
 2942 andres                   6344 ECB             : 
 2942 andres                   6345 CBC          63 :     if (is_null)
 2942 andres                   6346 GIC          12 :         PG_RETURN_NULL();
 2942 andres                   6347 ECB             :     else
 2942 andres                   6348 GIC          51 :         PG_RETURN_NUMERIC(res);
                               6349                 : #else
                               6350                 :     return numeric_var_samp(fcinfo);
 2942 andres                   6351 ECB             : #endif
                               6352                 : }
                               6353                 : 
                               6354                 : Datum
 2942 andres                   6355 GIC          82 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
                               6356                 : {
 2942 andres                   6357 ECB             : #ifdef HAVE_INT128
                               6358                 :     PolyNumAggState *state;
 2878 bruce                    6359                 :     Numeric     res;
                               6360                 :     bool        is_null;
 2942 andres                   6361                 : 
 2942 andres                   6362 GBC          82 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               6363                 : 
 2942 andres                   6364 CBC          82 :     res = numeric_poly_stddev_internal(state, false, true, &is_null);
                               6365                 : 
 2942 andres                   6366 GIC          82 :     if (is_null)
                               6367              12 :         PG_RETURN_NULL();
 2942 andres                   6368 ECB             :     else
 2942 andres                   6369 GIC          70 :         PG_RETURN_NUMERIC(res);
                               6370                 : #else
                               6371                 :     return numeric_stddev_samp(fcinfo);
                               6372                 : #endif
                               6373                 : }
 2942 andres                   6374 ECB             : 
                               6375                 : Datum
 2942 andres                   6376 CBC          30 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
                               6377                 : {
 2942 andres                   6378 ECB             : #ifdef HAVE_INT128
 2878 bruce                    6379 EUB             :     PolyNumAggState *state;
                               6380                 :     Numeric     res;
 2878 bruce                    6381 ECB             :     bool        is_null;
                               6382                 : 
 2942 andres                   6383 GIC          30 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
                               6384                 : 
                               6385              30 :     res = numeric_poly_stddev_internal(state, true, false, &is_null);
 2942 andres                   6386 ECB             : 
 2942 andres                   6387 GIC          30 :     if (is_null)
 2942 andres                   6388 UIC           0 :         PG_RETURN_NULL();
                               6389                 :     else
 2942 andres                   6390 GIC          30 :         PG_RETURN_NUMERIC(res);
                               6391                 : #else
                               6392                 :     return numeric_var_pop(fcinfo);
                               6393                 : #endif
 2942 andres                   6394 ECB             : }
                               6395                 : 
                               6396                 : Datum
 2942 andres                   6397 GIC          36 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
                               6398                 : {
                               6399                 : #ifdef HAVE_INT128
 2878 bruce                    6400 ECB             :     PolyNumAggState *state;
                               6401                 :     Numeric     res;
                               6402                 :     bool        is_null;
                               6403                 : 
 2942 andres                   6404 CBC          36 :     state = PG_ARGISNULL(0) ? NULL : (PolyNumAggState *) PG_GETARG_POINTER(0);
 2942 andres                   6405 ECB             : 
 2942 andres                   6406 GIC          36 :     res = numeric_poly_stddev_internal(state, false, false, &is_null);
 2942 andres                   6407 ECB             : 
 2942 andres                   6408 CBC          36 :     if (is_null)
 2942 andres                   6409 UIC           0 :         PG_RETURN_NULL();
 2942 andres                   6410 ECB             :     else
 2942 andres                   6411 GIC          36 :         PG_RETURN_NUMERIC(res);
                               6412                 : #else
 2942 andres                   6413 ECB             :     return numeric_stddev_pop(fcinfo);
                               6414                 : #endif
                               6415                 : }
                               6416                 : 
 8301 tgl                      6417                 : /*
                               6418                 :  * SUM transition functions for integer datatypes.
                               6419                 :  *
 7908                          6420                 :  * To avoid overflow, we use accumulators wider than the input datatype.
                               6421                 :  * A Numeric accumulator is needed for int8 input; for int4 and int2
                               6422                 :  * inputs, we use int8 accumulators which should be sufficient for practical
                               6423                 :  * purposes.  (The latter two therefore don't really belong in this file,
                               6424                 :  * but we keep them here anyway.)
                               6425                 :  *
 3641 peter_e                  6426                 :  * Because SQL defines the SUM() of no values to be NULL, not zero,
                               6427                 :  * the initial condition of the transition data value needs to be NULL. This
                               6428                 :  * means we can't rely on ExecAgg to automatically insert the first non-null
                               6429                 :  * data value into the transition data: it doesn't know how to do the type
                               6430                 :  * conversion.  The upshot is that these routines have to be marked non-strict
 7908 tgl                      6431                 :  * and handle substitution of the first non-null input themselves.
                               6432                 :  *
                               6433                 :  * Note: these functions are used only in plain aggregation mode.
                               6434                 :  * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
                               6435                 :  */
                               6436                 : 
                               6437                 : Datum
 8301 tgl                      6438 CBC          12 : int2_sum(PG_FUNCTION_ARGS)
                               6439                 : {
 7908 tgl                      6440 ECB             :     int64       newval;
                               6441                 : 
 8301 tgl                      6442 CBC          12 :     if (PG_ARGISNULL(0))
 8301 tgl                      6443 ECB             :     {
                               6444                 :         /* No non-null input seen so far... */
 8301 tgl                      6445 CBC           3 :         if (PG_ARGISNULL(1))
 8301 tgl                      6446 UIC           0 :             PG_RETURN_NULL();   /* still no non-null */
                               6447                 :         /* This is the first non-null input. */
 7908 tgl                      6448 GIC           3 :         newval = (int64) PG_GETARG_INT16(1);
                               6449               3 :         PG_RETURN_INT64(newval);
                               6450                 :     }
                               6451                 : 
 6577 neilc                    6452 ECB             :     /*
                               6453                 :      * If we're invoked as an aggregate, we can cheat and modify our first
                               6454                 :      * parameter in-place to avoid palloc overhead. If not, we need to return
                               6455                 :      * the new value of the transition variable. (If int8 is pass-by-value,
                               6456                 :      * then of course this is useless as well as incorrect, so just ifdef it
                               6457                 :      * out.)
                               6458                 :      */
 5466 tgl                      6459                 : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
                               6460                 :     if (AggCheckCallContext(fcinfo, NULL))
 6577 neilc                    6461                 :     {
                               6462                 :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
 8301 tgl                      6463                 : 
 6577 neilc                    6464                 :         /* Leave the running sum unchanged in the new input is null */
                               6465                 :         if (!PG_ARGISNULL(1))
                               6466                 :             *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
                               6467                 : 
                               6468                 :         PG_RETURN_POINTER(oldsum);
                               6469                 :     }
                               6470                 :     else
                               6471                 : #endif
                               6472                 :     {
 6577 neilc                    6473 CBC           9 :         int64       oldsum = PG_GETARG_INT64(0);
                               6474                 : 
                               6475                 :         /* Leave sum unchanged if new input is null. */
 6577 neilc                    6476 GIC           9 :         if (PG_ARGISNULL(1))
 6577 neilc                    6477 UIC           0 :             PG_RETURN_INT64(oldsum);
                               6478                 : 
                               6479                 :         /* OK to do the addition. */
 6577 neilc                    6480 CBC           9 :         newval = oldsum + (int64) PG_GETARG_INT16(1);
                               6481                 : 
                               6482               9 :         PG_RETURN_INT64(newval);
                               6483                 :     }
 8301 tgl                      6484 ECB             : }
 8301 tgl                      6485 EUB             : 
                               6486                 : Datum
 8301 tgl                      6487 CBC     1697126 : int4_sum(PG_FUNCTION_ARGS)
                               6488                 : {
                               6489                 :     int64       newval;
                               6490                 : 
 8301 tgl                      6491 GIC     1697126 :     if (PG_ARGISNULL(0))
                               6492                 :     {
                               6493                 :         /* No non-null input seen so far... */
 8301 tgl                      6494 CBC       43227 :         if (PG_ARGISNULL(1))
 8301 tgl                      6495 GIC         493 :             PG_RETURN_NULL();   /* still no non-null */
                               6496                 :         /* This is the first non-null input. */
 7908                          6497           42734 :         newval = (int64) PG_GETARG_INT32(1);
                               6498           42734 :         PG_RETURN_INT64(newval);
                               6499                 :     }
                               6500                 : 
 6577 neilc                    6501 ECB             :     /*
                               6502                 :      * If we're invoked as an aggregate, we can cheat and modify our first
 6385 bruce                    6503                 :      * parameter in-place to avoid palloc overhead. If not, we need to return
                               6504                 :      * the new value of the transition variable. (If int8 is pass-by-value,
 5050                          6505                 :      * then of course this is useless as well as incorrect, so just ifdef it
 5050 bruce                    6506 EUB             :      * out.)
                               6507                 :      */
 5466 tgl                      6508 ECB             : #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
                               6509                 :     if (AggCheckCallContext(fcinfo, NULL))
                               6510                 :     {
                               6511                 :         int64      *oldsum = (int64 *) PG_GETARG_POINTER(0);
                               6512                 : 
                               6513                 :         /* Leave the running sum unchanged in the new input is null */
                               6514                 :         if (!PG_ARGISNULL(1))
                               6515                 :             *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
                               6516                 : 
                               6517                 :         PG_RETURN_POINTER(oldsum);
                               6518                 :     }
                               6519                 :     else
                               6520                 : #endif
                               6521                 :     {
 6577 neilc                    6522 GIC     1653899 :         int64       oldsum = PG_GETARG_INT64(0);
                               6523                 : 
                               6524                 :         /* Leave sum unchanged if new input is null. */
                               6525         1653899 :         if (PG_ARGISNULL(1))
                               6526             437 :             PG_RETURN_INT64(oldsum);
                               6527                 : 
                               6528                 :         /* OK to do the addition. */
                               6529         1653462 :         newval = oldsum + (int64) PG_GETARG_INT32(1);
                               6530                 : 
                               6531         1653462 :         PG_RETURN_INT64(newval);
                               6532                 :     }
                               6533                 : }
                               6534                 : 
 3431 tgl                      6535 ECB             : /*
                               6536                 :  * Note: this function is obsolete, it's no longer used for SUM(int8).
                               6537                 :  */
                               6538                 : Datum
 8301 tgl                      6539 LBC           0 : int8_sum(PG_FUNCTION_ARGS)
                               6540                 : {
                               6541                 :     Numeric     oldsum;
 8301 tgl                      6542 ECB             : 
 8301 tgl                      6543 UBC           0 :     if (PG_ARGISNULL(0))
                               6544                 :     {
 8301 tgl                      6545 ECB             :         /* No non-null input seen so far... */
 8301 tgl                      6546 LBC           0 :         if (PG_ARGISNULL(1))
 8301 tgl                      6547 UIC           0 :             PG_RETURN_NULL();   /* still no non-null */
                               6548                 :         /* This is the first non-null input. */
  942 peter                    6549               0 :         PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
                               6550                 :     }
                               6551                 : 
                               6552                 :     /*
                               6553                 :      * Note that we cannot special-case the aggregate case here, as we do for
                               6554                 :      * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
                               6555                 :      * our first parameter in-place.
                               6556                 :      */
                               6557                 : 
 8301 tgl                      6558               0 :     oldsum = PG_GETARG_NUMERIC(0);
                               6559                 : 
                               6560                 :     /* Leave sum unchanged if new input is null. */
                               6561               0 :     if (PG_ARGISNULL(1))
                               6562               0 :         PG_RETURN_NUMERIC(oldsum);
                               6563                 : 
                               6564                 :     /* OK to do the addition. */
 8289                          6565               0 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
                               6566                 :                                         NumericGetDatum(oldsum),
                               6567                 :                                         NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
                               6568                 : }
                               6569                 : 
 8301 tgl                      6570 ECB             : 
                               6571                 : /*
                               6572                 :  * Routines for avg(int2) and avg(int4).  The transition datatype
 7908                          6573                 :  * is a two-element int8 array, holding count and sum.
 3284 tgl                      6574 EUB             :  *
                               6575                 :  * These functions are also used for sum(int2) and sum(int4) when
                               6576                 :  * operating in moving-aggregate mode, since for correct inverse transitions
 3284 tgl                      6577 ECB             :  * we need to count the inputs.
                               6578                 :  */
 7908                          6579                 : 
                               6580                 : typedef struct Int8TransTypeData
                               6581                 : {
                               6582                 :     int64       count;
                               6583                 :     int64       sum;
                               6584                 : } Int8TransTypeData;
                               6585                 : 
                               6586                 : Datum
 7908 tgl                      6587 GIC          21 : int2_avg_accum(PG_FUNCTION_ARGS)
 7908 tgl                      6588 ECB             : {
                               6589                 :     ArrayType  *transarray;
 7908 tgl                      6590 GIC          21 :     int16       newval = PG_GETARG_INT16(1);
 7908 tgl                      6591 ECB             :     Int8TransTypeData *transdata;
                               6592                 : 
                               6593                 :     /*
 4808                          6594                 :      * If we're invoked as an aggregate, we can cheat and modify our first
 6385 bruce                    6595                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
                               6596                 :      * a copy of it before scribbling on it.
                               6597                 :      */
 4808 tgl                      6598 GIC          21 :     if (AggCheckCallContext(fcinfo, NULL))
 6579 neilc                    6599              21 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
                               6600                 :     else
 6579 neilc                    6601 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
                               6602                 : 
 6352 tgl                      6603 GIC          21 :     if (ARR_HASNULL(transarray) ||
                               6604              21 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 7196 tgl                      6605 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
                               6606                 : 
 6579 neilc                    6607 GIC          21 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
 7908 tgl                      6608              21 :     transdata->count++;
                               6609              21 :     transdata->sum += newval;
                               6610                 : 
                               6611              21 :     PG_RETURN_ARRAYTYPE_P(transarray);
                               6612                 : }
                               6613                 : 
                               6614                 : Datum
                               6615         1326402 : int4_avg_accum(PG_FUNCTION_ARGS)
                               6616                 : {
                               6617                 :     ArrayType  *transarray;
                               6618         1326402 :     int32       newval = PG_GETARG_INT32(1);
 7908 tgl                      6619 ECB             :     Int8TransTypeData *transdata;
                               6620                 : 
                               6621                 :     /*
 4808                          6622                 :      * If we're invoked as an aggregate, we can cheat and modify our first
 6385 bruce                    6623                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
                               6624                 :      * a copy of it before scribbling on it.
                               6625                 :      */
 4808 tgl                      6626 CBC     1326402 :     if (AggCheckCallContext(fcinfo, NULL))
 6579 neilc                    6627 GIC     1326402 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
 6579 neilc                    6628 ECB             :     else
 6579 neilc                    6629 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
                               6630                 : 
 6352 tgl                      6631 GIC     1326402 :     if (ARR_HASNULL(transarray) ||
                               6632         1326402 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 7196 tgl                      6633 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
                               6634                 : 
 6579 neilc                    6635 GIC     1326402 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
 7908 tgl                      6636 GBC     1326402 :     transdata->count++;
 7908 tgl                      6637 GIC     1326402 :     transdata->sum += newval;
                               6638                 : 
                               6639         1326402 :     PG_RETURN_ARRAYTYPE_P(transarray);
 7908 tgl                      6640 EUB             : }
                               6641                 : 
                               6642                 : Datum
 2560 rhaas                    6643 GBC        1973 : int4_avg_combine(PG_FUNCTION_ARGS)
 2560 rhaas                    6644 EUB             : {
                               6645                 :     ArrayType  *transarray1;
                               6646                 :     ArrayType  *transarray2;
                               6647                 :     Int8TransTypeData *state1;
                               6648                 :     Int8TransTypeData *state2;
                               6649                 : 
 2560 rhaas                    6650 GIC        1973 :     if (!AggCheckCallContext(fcinfo, NULL))
 2560 rhaas                    6651 UIC           0 :         elog(ERROR, "aggregate function called in non-aggregate context");
                               6652                 : 
 2560 rhaas                    6653 GIC        1973 :     transarray1 = PG_GETARG_ARRAYTYPE_P(0);
                               6654            1973 :     transarray2 = PG_GETARG_ARRAYTYPE_P(1);
 2560 rhaas                    6655 EUB             : 
 2560 rhaas                    6656 GIC        1973 :     if (ARR_HASNULL(transarray1) ||
                               6657            1973 :         ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 2560 rhaas                    6658 UBC           0 :         elog(ERROR, "expected 2-element int8 array");
 2560 rhaas                    6659 EUB             : 
 2560 rhaas                    6660 GIC        1973 :     if (ARR_HASNULL(transarray2) ||
                               6661            1973 :         ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 2560 rhaas                    6662 UBC           0 :         elog(ERROR, "expected 2-element int8 array");
                               6663                 : 
 2560 rhaas                    6664 GIC        1973 :     state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
                               6665            1973 :     state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
                               6666                 : 
                               6667            1973 :     state1->count += state2->count;
                               6668            1973 :     state1->sum += state2->sum;
                               6669                 : 
                               6670            1973 :     PG_RETURN_ARRAYTYPE_P(transarray1);
                               6671                 : }
                               6672                 : 
                               6673                 : Datum
 3284 tgl                      6674               6 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
                               6675                 : {
                               6676                 :     ArrayType  *transarray;
                               6677               6 :     int16       newval = PG_GETARG_INT16(1);
                               6678                 :     Int8TransTypeData *transdata;
                               6679                 : 
                               6680                 :     /*
                               6681                 :      * If we're invoked as an aggregate, we can cheat and modify our first
                               6682                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
                               6683                 :      * a copy of it before scribbling on it.
 3284 tgl                      6684 ECB             :      */
 3284 tgl                      6685 GIC           6 :     if (AggCheckCallContext(fcinfo, NULL))
                               6686               6 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
 3284 tgl                      6687 ECB             :     else
 3284 tgl                      6688 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
                               6689                 : 
 3284 tgl                      6690 GIC           6 :     if (ARR_HASNULL(transarray) ||
                               6691               6 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 3284 tgl                      6692 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
                               6693                 : 
 3284 tgl                      6694 GIC           6 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
 3284 tgl                      6695 CBC           6 :     transdata->count--;
                               6696               6 :     transdata->sum -= newval;
                               6697                 : 
 3284 tgl                      6698 GBC           6 :     PG_RETURN_ARRAYTYPE_P(transarray);
                               6699                 : }
 3284 tgl                      6700 ECB             : 
                               6701                 : Datum
 3284 tgl                      6702 GBC         726 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
                               6703                 : {
 3284 tgl                      6704 ECB             :     ArrayType  *transarray;
 3284 tgl                      6705 CBC         726 :     int32       newval = PG_GETARG_INT32(1);
 3284 tgl                      6706 ECB             :     Int8TransTypeData *transdata;
                               6707                 : 
                               6708                 :     /*
                               6709                 :      * If we're invoked as an aggregate, we can cheat and modify our first
                               6710                 :      * parameter in-place to reduce palloc overhead. Otherwise we need to make
                               6711                 :      * a copy of it before scribbling on it.
                               6712                 :      */
 3284 tgl                      6713 GIC         726 :     if (AggCheckCallContext(fcinfo, NULL))
                               6714             726 :         transarray = PG_GETARG_ARRAYTYPE_P(0);
 3284 tgl                      6715 ECB             :     else
 3284 tgl                      6716 UIC           0 :         transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
                               6717                 : 
 3284 tgl                      6718 GIC         726 :     if (ARR_HASNULL(transarray) ||
                               6719             726 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 3284 tgl                      6720 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
                               6721                 : 
 3284 tgl                      6722 GIC         726 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
 3284 tgl                      6723 CBC         726 :     transdata->count--;
                               6724             726 :     transdata->sum -= newval;
                               6725                 : 
 3284 tgl                      6726 GBC         726 :     PG_RETURN_ARRAYTYPE_P(transarray);
                               6727                 : }
 3284 tgl                      6728 ECB             : 
 7908                          6729                 : Datum
 7908 tgl                      6730 GBC        5363 : int8_avg(PG_FUNCTION_ARGS)
                               6731                 : {
 7908 tgl                      6732 CBC        5363 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
 7908 tgl                      6733 ECB             :     Int8TransTypeData *transdata;
                               6734                 :     Datum       countd,
                               6735                 :                 sumd;
                               6736                 : 
 6352 tgl                      6737 GIC        5363 :     if (ARR_HASNULL(transarray) ||
                               6738            5363 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 7196 tgl                      6739 UIC           0 :         elog(ERROR, "expected 2-element int8 array");
 7908 tgl                      6740 CBC        5363 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
                               6741                 : 
                               6742                 :     /* SQL defines AVG of no values to be NULL */
 7908 tgl                      6743 GIC        5363 :     if (transdata->count == 0)
                               6744              59 :         PG_RETURN_NULL();
                               6745                 : 
  942 peter                    6746            5304 :     countd = NumericGetDatum(int64_to_numeric(transdata->count));
  942 peter                    6747 CBC        5304 :     sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
 7908 tgl                      6748 EUB             : 
 7908 tgl                      6749 GIC        5304 :     PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
 7908 tgl                      6750 ECB             : }
                               6751                 : 
                               6752                 : /*
 3284                          6753                 :  * SUM(int2) and SUM(int4) both return int8, so we can use this
                               6754                 :  * final function for both.
 3284 tgl                      6755 EUB             :  */
                               6756                 : Datum
 3284 tgl                      6757 CBC        2766 : int2int4_sum(PG_FUNCTION_ARGS)
 3284 tgl                      6758 ECB             : {
 3284 tgl                      6759 GBC        2766 :     ArrayType  *transarray = PG_GETARG_ARRAYTYPE_P(0);
                               6760                 :     Int8TransTypeData *transdata;
 3284 tgl                      6761 ECB             : 
 3284 tgl                      6762 CBC        2766 :     if (ARR_HASNULL(transarray) ||
 3284 tgl                      6763 GIC        2766 :         ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
 3284 tgl                      6764 LBC           0 :         elog(ERROR, "expected 2-element int8 array");
 3284 tgl                      6765 CBC        2766 :     transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
                               6766                 : 
 3284 tgl                      6767 ECB             :     /* SQL defines SUM of no values to be NULL */
 3284 tgl                      6768 GIC        2766 :     if (transdata->count == 0)
                               6769             249 :         PG_RETURN_NULL();
                               6770                 : 
 3284 tgl                      6771 CBC        2517 :     PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
                               6772                 : }
                               6773                 : 
 7908 tgl                      6774 ECB             : 
                               6775                 : /* ----------------------------------------------------------------------
                               6776                 :  *
                               6777                 :  * Debug support
                               6778                 :  *
                               6779                 :  * ----------------------------------------------------------------------
                               6780                 :  */
                               6781                 : 
 8866 JanWieck                 6782                 : #ifdef NUMERIC_DEBUG
                               6783                 : 
                               6784                 : /*
 8866 JanWieck                 6785 EUB             :  * dump_numeric() - Dump a value in the db storage format for debugging
                               6786                 :  */
 8866 JanWieck                 6787 ECB             : static void
 7324 tgl                      6788                 : dump_numeric(const char *str, Numeric num)
 8866 JanWieck                 6789 EUB             : {
                               6790                 :     NumericDigit *digits = NUMERIC_DIGITS(num);
 7324 tgl                      6791 ECB             :     int         ndigits;
 8720 bruce                    6792                 :     int         i;
 8866 JanWieck                 6793                 : 
                               6794                 :     ndigits = NUMERIC_NDIGITS(num);
 7324 tgl                      6795                 : 
                               6796                 :     printf("%s: NUMERIC w=%d d=%d ", str,
                               6797                 :            NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
                               6798                 :     switch (NUMERIC_SIGN(num))
 8866 JanWieck                 6799                 :     {
                               6800                 :         case NUMERIC_POS:
                               6801                 :             printf("POS");
 8720 bruce                    6802                 :             break;
                               6803                 :         case NUMERIC_NEG:
                               6804                 :             printf("NEG");
                               6805                 :             break;
                               6806                 :         case NUMERIC_NAN:
                               6807                 :             printf("NaN");
                               6808                 :             break;
                               6809                 :         case NUMERIC_PINF:
  991 tgl                      6810                 :             printf("Infinity");
                               6811                 :             break;
                               6812                 :         case NUMERIC_NINF:
  991 tgl                      6813 EUB             :             printf("-Infinity");
                               6814                 :             break;
 8720 bruce                    6815 ECB             :         default:
                               6816                 :             printf("SIGN=0x%x", NUMERIC_SIGN(num));
 8720 bruce                    6817 EUB             :             break;
                               6818                 :     }
 8866 JanWieck                 6819 ECB             : 
 7324 tgl                      6820                 :     for (i = 0; i < ndigits; i++)
                               6821                 :         printf(" %0*d", DEC_DIGITS, digits[i]);
                               6822                 :     printf("\n");
 8866 JanWieck                 6823                 : }
                               6824                 : 
                               6825                 : 
                               6826                 : /*
                               6827                 :  * dump_var() - Dump a value in the variable format for debugging
                               6828                 :  */
                               6829                 : static void
                               6830                 : dump_var(const char *str, NumericVar *var)
                               6831                 : {
                               6832                 :     int         i;
                               6833                 : 
 7324 tgl                      6834                 :     printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
 8866 JanWieck                 6835                 :     switch (var->sign)
 8866 JanWieck                 6836 EUB             :     {
 8720 bruce                    6837 ECB             :         case NUMERIC_POS:
                               6838                 :             printf("POS");
                               6839                 :             break;
                               6840                 :         case NUMERIC_NEG:
                               6841                 :             printf("NEG");
                               6842                 :             break;
                               6843                 :         case NUMERIC_NAN:
                               6844                 :             printf("NaN");
                               6845                 :             break;
  991 tgl                      6846                 :         case NUMERIC_PINF:
                               6847                 :             printf("Infinity");
                               6848                 :             break;
                               6849                 :         case NUMERIC_NINF:
                               6850                 :             printf("-Infinity");
                               6851                 :             break;
                               6852                 :         default:
                               6853                 :             printf("SIGN=0x%x", var->sign);
 8720 bruce                    6854                 :             break;
                               6855                 :     }
 8866 JanWieck                 6856                 : 
                               6857                 :     for (i = 0; i < var->ndigits; i++)
                               6858                 :         printf(" %0*d", DEC_DIGITS, var->digits[i]);
 8720 bruce                    6859                 : 
 8866 JanWieck                 6860                 :     printf("\n");
 8866 JanWieck                 6861 EUB             : }
 2118 tgl                      6862 ECB             : #endif                          /* NUMERIC_DEBUG */
                               6863                 : 
                               6864                 : 
 7324                          6865                 : /* ----------------------------------------------------------------------
                               6866                 :  *
                               6867                 :  * Local functions follow
                               6868                 :  *
                               6869                 :  * In general, these do not support "special" (NaN or infinity) inputs;
                               6870                 :  * callers should handle those possibilities first.
                               6871                 :  * (There are one or two exceptions, noted in their header comments.)
                               6872                 :  *
                               6873                 :  * ----------------------------------------------------------------------
                               6874                 :  */
                               6875                 : 
                               6876                 : 
                               6877                 : /*
                               6878                 :  * alloc_var() -
                               6879                 :  *
                               6880                 :  *  Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
                               6881                 :  */
                               6882                 : static void
 8482 tgl                      6883 GIC     1409144 : alloc_var(NumericVar *var, int ndigits)
                               6884                 : {
                               6885         1409144 :     digitbuf_free(var->buf);
                               6886         1409144 :     var->buf = digitbuf_alloc(ndigits + 1);
 7188 bruce                    6887         1409144 :     var->buf[0] = 0;         /* spare digit for rounding */
 8482 tgl                      6888         1409144 :     var->digits = var->buf + 1;
                               6889         1409144 :     var->ndigits = ndigits;
 8866 JanWieck                 6890         1409144 : }
                               6891                 : 
                               6892                 : 
                               6893                 : /*
                               6894                 :  * free_var() -
                               6895                 :  *
                               6896                 :  *  Return the digit buffer of a variable to the free pool
                               6897                 :  */
                               6898                 : static void
 8720 bruce                    6899         1610031 : free_var(NumericVar *var)
                               6900                 : {
 8482 tgl                      6901         1610031 :     digitbuf_free(var->buf);
                               6902         1610031 :     var->buf = NULL;
                               6903         1610031 :     var->digits = NULL;
 8866 JanWieck                 6904         1610031 :     var->sign = NUMERIC_NAN;
                               6905         1610031 : }
                               6906                 : 
                               6907                 : 
                               6908                 : /*
                               6909                 :  * zero_var() -
                               6910                 :  *
                               6911                 :  *  Set a variable to ZERO.
                               6912                 :  *  Note: its dscale is not touched.
                               6913                 :  */
                               6914                 : static void
 8482 tgl                      6915           20247 : zero_var(NumericVar *var)
                               6916                 : {
                               6917           20247 :     digitbuf_free(var->buf);
                               6918           20247 :     var->buf = NULL;
                               6919           20247 :     var->digits = NULL;
                               6920           20247 :     var->ndigits = 0;
                               6921           20247 :     var->weight = 0;         /* by convention; doesn't really matter */
                               6922           20247 :     var->sign = NUMERIC_POS; /* anything but NAN... */
 8866 JanWieck                 6923           20247 : }
                               6924                 : 
                               6925                 : 
                               6926                 : /*
                               6927                 :  * set_var_from_str()
                               6928                 :  *
                               6929                 :  *  Parse a string and put the number into a variable
                               6930                 :  *
                               6931                 :  * This function does not handle leading or trailing spaces.  It returns
                               6932                 :  * the end+1 position parsed into *endptr, so that caller can check for
                               6933                 :  * trailing spaces/garbage if deemed necessary.
                               6934                 :  *
                               6935                 :  * cp is the place to actually start parsing; str is what to use in error
                               6936                 :  * reports.  (Typically cp would be the same except advanced over spaces.)
                               6937                 :  *
                               6938                 :  * Returns true on success, false on failure (if escontext points to an
                               6939                 :  * ErrorSaveContext; otherwise errors are thrown).
                               6940                 :  */
                               6941                 : static bool
  121 tgl                      6942 GNC       57675 : set_var_from_str(const char *str, const char *cp,
                               6943                 :                  NumericVar *dest, const char **endptr,
                               6944                 :                  Node *escontext)
                               6945                 : {
 2062 peter_e                  6946 GIC       57675 :     bool        have_dp = false;
                               6947                 :     int         i;
                               6948                 :     unsigned char *decdigits;
 7324 tgl                      6949           57675 :     int         sign = NUMERIC_POS;
                               6950           57675 :     int         dweight = -1;
                               6951                 :     int         ddigits;
                               6952           57675 :     int         dscale = 0;
                               6953                 :     int         weight;
                               6954                 :     int         ndigits;
                               6955                 :     int         offset;
                               6956                 :     NumericDigit *digits;
                               6957                 : 
                               6958                 :     /*
                               6959                 :      * We first parse the string to extract decimal digits and determine the
                               6960                 :      * correct decimal weight.  Then convert to NBASE representation.
                               6961                 :      */
 8866 JanWieck                 6962           57675 :     switch (*cp)
                               6963                 :     {
 8720 bruce                    6964 UIC           0 :         case '+':
 7324 tgl                      6965               0 :             sign = NUMERIC_POS;
 8720 bruce                    6966               0 :             cp++;
                               6967               0 :             break;
                               6968                 : 
 8720 bruce                    6969 GIC         150 :         case '-':
 7324 tgl                      6970             150 :             sign = NUMERIC_NEG;
 8720 bruce                    6971             150 :             cp++;
                               6972             150 :             break;
                               6973                 :     }
                               6974                 : 
 8866 JanWieck                 6975           57675 :     if (*cp == '.')
                               6976                 :     {
 2062 peter_e                  6977             188 :         have_dp = true;
 8866 JanWieck                 6978             188 :         cp++;
                               6979                 :     }
                               6980                 : 
 8162 tgl                      6981           57675 :     if (!isdigit((unsigned char) *cp))
   64 dean.a.rasheed           6982 UNC           0 :         goto invalid_syntax;
                               6983                 : 
 7188 bruce                    6984 CBC       57675 :     decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
 7324 tgl                      6985 ECB             : 
                               6986                 :     /* leading padding for digit alignment later */
 7324 tgl                      6987 CBC       57675 :     memset(decdigits, 0, DEC_DIGITS);
                               6988           57675 :     i = DEC_DIGITS;
 7324 tgl                      6989 ECB             : 
 8866 JanWieck                 6990 GIC      233925 :     while (*cp)
                               6991                 :     {
 8162 tgl                      6992          176781 :         if (isdigit((unsigned char) *cp))
                               6993                 :         {
 7324                          6994          168613 :             decdigits[i++] = *cp++ - '0';
 8482                          6995          168613 :             if (!have_dp)
 7324                          6996          137325 :                 dweight++;
                               6997                 :             else
 7324 tgl                      6998 CBC       31288 :                 dscale++;
                               6999                 :         }
 8482                          7000            8168 :         else if (*cp == '.')
 8482 tgl                      7001 ECB             :         {
 8482 tgl                      7002 CBC        7556 :             if (have_dp)
   64 dean.a.rasheed           7003 UNC           0 :                 goto invalid_syntax;
 2062 peter_e                  7004 GIC        7556 :             have_dp = true;
 8482 tgl                      7005            7556 :             cp++;
                               7006                 :             /* decimal point must not be followed by underscore */
   64 dean.a.rasheed           7007 GNC        7556 :             if (*cp == '_')
                               7008               3 :                 goto invalid_syntax;
                               7009                 :         }
                               7010             612 :         else if (*cp == '_')
                               7011                 :         {
                               7012                 :             /* underscore must be followed by more digits */
                               7013              93 :             cp++;
                               7014              93 :             if (!isdigit((unsigned char) *cp))
                               7015               9 :                 goto invalid_syntax;
                               7016                 :         }
                               7017                 :         else
 8482 tgl                      7018 GIC         519 :             break;
                               7019                 :     }
                               7020                 : 
 7324 tgl                      7021 CBC       57663 :     ddigits = i - DEC_DIGITS;
                               7022                 :     /* trailing padding for digit alignment later */
 7188 bruce                    7023           57663 :     memset(decdigits + i, 0, DEC_DIGITS - 1);
 8866 JanWieck                 7024 ECB             : 
 8482 tgl                      7025                 :     /* Handle exponent, if any */
 8866 JanWieck                 7026 CBC       57663 :     if (*cp == 'e' || *cp == 'E')
 8866 JanWieck                 7027 ECB             :     {
   64 dean.a.rasheed           7028 GNC         501 :         int64       exponent = 0;
                               7029             501 :         bool        neg = false;
                               7030                 : 
                               7031                 :         /*
                               7032                 :          * At this point, dweight and dscale can't be more than about
                               7033                 :          * INT_MAX/2 due to the MaxAllocSize limit on string length, so
                               7034                 :          * constraining the exponent similarly should be enough to prevent
                               7035                 :          * integer overflow in this function.  If the value is too large to
                               7036                 :          * fit in storage format, make_result() will complain about it later;
                               7037                 :          * for consistency use the same ereport errcode/text as make_result().
                               7038                 :          */
                               7039                 : 
                               7040                 :         /* exponent sign */
                               7041             501 :         cp++;
                               7042             501 :         if (*cp == '+')
                               7043              77 :             cp++;
                               7044             424 :         else if (*cp == '-')
                               7045                 :         {
                               7046             190 :             neg = true;
                               7047             190 :             cp++;
                               7048                 :         }
                               7049                 : 
                               7050                 :         /* exponent digits */
                               7051             501 :         if (!isdigit((unsigned char) *cp))
                               7052               3 :             goto invalid_syntax;
                               7053                 : 
                               7054            1521 :         while (*cp)
                               7055                 :         {
                               7056            1032 :             if (isdigit((unsigned char) *cp))
                               7057                 :             {
                               7058            1011 :                 exponent = exponent * 10 + (*cp++ - '0');
                               7059            1011 :                 if (exponent > PG_INT32_MAX / 2)
                               7060               3 :                     goto out_of_range;
                               7061                 :             }
                               7062              21 :             else if (*cp == '_')
                               7063                 :             {
                               7064                 :                 /* underscore must be followed by more digits */
                               7065              21 :                 cp++;
                               7066              21 :                 if (!isdigit((unsigned char) *cp))
                               7067               6 :                     goto invalid_syntax;
                               7068                 :             }
                               7069                 :             else
   64 dean.a.rasheed           7070 UNC           0 :                 break;
                               7071                 :         }
                               7072                 : 
   64 dean.a.rasheed           7073 GNC         489 :         if (neg)
                               7074             190 :             exponent = -exponent;
                               7075                 : 
 7324 tgl                      7076 CBC         489 :         dweight += (int) exponent;
 7324 tgl                      7077 GIC         489 :         dscale -= (int) exponent;
                               7078             489 :         if (dscale < 0)
 7324 tgl                      7079 CBC         197 :             dscale = 0;
 8482 tgl                      7080 ECB             :     }
                               7081                 : 
 7324                          7082                 :     /*
                               7083                 :      * Okay, convert pure-decimal representation to base NBASE.  First we need
                               7084                 :      * to determine the converted weight and ndigits.  offset is the number of
                               7085                 :      * decimal zeroes to insert before the first given digit to have a
                               7086                 :      * correctly aligned first NBASE digit.
                               7087                 :      */
 7324 tgl                      7088 GIC       57651 :     if (dweight >= 0)
 7188 bruce                    7089           57324 :         weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
                               7090                 :     else
                               7091             327 :         weight = -((-dweight - 1) / DEC_DIGITS + 1);
 7324 tgl                      7092 CBC       57651 :     offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
 7188 bruce                    7093 GIC       57651 :     ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
 7324 tgl                      7094 EUB             : 
 7324 tgl                      7095 GBC       57651 :     alloc_var(dest, ndigits);
                               7096           57651 :     dest->sign = sign;
                               7097           57651 :     dest->weight = weight;
 7324 tgl                      7098 GIC       57651 :     dest->dscale = dscale;
 7324 tgl                      7099 ECB             : 
 7324 tgl                      7100 CBC       57651 :     i = DEC_DIGITS - offset;
                               7101           57651 :     digits = dest->digits;
 7324 tgl                      7102 ECB             : 
 7324 tgl                      7103 GIC      135687 :     while (ndigits-- > 0)
                               7104                 :     {
 7324 tgl                      7105 ECB             : #if DEC_DIGITS == 4
 7188 bruce                    7106 GIC       78036 :         *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
 7188 bruce                    7107 CBC       78036 :                      decdigits[i + 2]) * 10 + decdigits[i + 3];
 7324 tgl                      7108 ECB             : #elif DEC_DIGITS == 2
                               7109                 :         *digits++ = decdigits[i] * 10 + decdigits[i + 1];
                               7110                 : #elif DEC_DIGITS == 1
                               7111                 :         *digits++ = decdigits[i];
 7324 tgl                      7112 EUB             : #else
                               7113                 : #error unsupported NBASE
 7324 tgl                      7114 ECB             : #endif
 7324 tgl                      7115 GIC       78036 :         i += DEC_DIGITS;
                               7116                 :     }
 8866 JanWieck                 7117 ECB             : 
 7324 tgl                      7118 CBC       57651 :     pfree(decdigits);
                               7119                 : 
 7324 tgl                      7120 ECB             :     /* Strip any leading/trailing zeroes, and normalize weight if zero */
 7324 tgl                      7121 GIC       57651 :     strip_var(dest);
 5114 tgl                      7122 ECB             : 
                               7123                 :     /* Return end+1 position for caller */
  121 tgl                      7124 GNC       57651 :     *endptr = cp;
                               7125                 : 
                               7126           57651 :     return true;
                               7127                 : 
   64 dean.a.rasheed           7128               3 : out_of_range:
                               7129               3 :     ereturn(escontext, false,
                               7130                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               7131                 :              errmsg("value overflows numeric format")));
                               7132                 : 
                               7133              21 : invalid_syntax:
                               7134              21 :     ereturn(escontext, false,
                               7135                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                               7136                 :              errmsg("invalid input syntax for type %s: \"%s\"",
                               7137                 :                     "numeric", str)));
                               7138                 : }
                               7139                 : 
                               7140                 : 
                               7141                 : /*
                               7142                 :  * Return the numeric value of a single hex digit.
                               7143                 :  */
                               7144                 : static inline int
   76                          7145             354 : xdigit_value(char dig)
                               7146                 : {
                               7147             447 :     return dig >= '0' && dig <= '9' ? dig - '0' :
                               7148             147 :         dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
                               7149              54 :         dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
                               7150                 : }
                               7151                 : 
                               7152                 : /*
                               7153                 :  * set_var_from_non_decimal_integer_str()
                               7154                 :  *
                               7155                 :  *  Parse a string containing a non-decimal integer
                               7156                 :  *
                               7157                 :  * This function does not handle leading or trailing spaces.  It returns
                               7158                 :  * the end+1 position parsed into *endptr, so that caller can check for
                               7159                 :  * trailing spaces/garbage if deemed necessary.
                               7160                 :  *
                               7161                 :  * cp is the place to actually start parsing; str is what to use in error
                               7162                 :  * reports.  The number's sign and base prefix indicator (e.g., "0x") are
                               7163                 :  * assumed to have already been parsed, so cp should point to the number's
                               7164                 :  * first digit in the base specified.
                               7165                 :  *
                               7166                 :  * base is expected to be 2, 8 or 16.
                               7167                 :  *
                               7168                 :  * Returns true on success, false on failure (if escontext points to an
                               7169                 :  * ErrorSaveContext; otherwise errors are thrown).
                               7170                 :  */
                               7171                 : static bool
                               7172              78 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
                               7173                 :                                      int base, NumericVar *dest,
                               7174                 :                                      const char **endptr, Node *escontext)
                               7175                 : {
                               7176              78 :     const char *firstdigit = cp;
                               7177                 :     int64       tmp;
                               7178                 :     int64       mul;
                               7179                 :     NumericVar  tmp_var;
                               7180                 : 
                               7181              78 :     init_var(&tmp_var);
                               7182                 : 
                               7183              78 :     zero_var(dest);
                               7184                 : 
                               7185                 :     /*
                               7186                 :      * Process input digits in groups that fit in int64.  Here "tmp" is the
                               7187                 :      * value of the digits in the group, and "mul" is base^n, where n is the
                               7188                 :      * number of digits in the group.  Thus tmp < mul, and we must start a new
                               7189                 :      * group when mul * base threatens to overflow PG_INT64_MAX.
                               7190                 :      */
                               7191              78 :     tmp = 0;
                               7192              78 :     mul = 1;
                               7193                 : 
                               7194              78 :     if (base == 16)
                               7195                 :     {
                               7196             414 :         while (*cp)
                               7197                 :         {
                               7198             399 :             if (isxdigit((unsigned char) *cp))
                               7199                 :             {
                               7200             354 :                 if (mul > PG_INT64_MAX / 16)
                               7201                 :                 {
                               7202                 :                     /* Add the contribution from this group of digits */
                               7203              15 :                     int64_to_numericvar(mul, &tmp_var);
                               7204              15 :                     mul_var(dest, &tmp_var, dest, 0);
                               7205              15 :                     int64_to_numericvar(tmp, &tmp_var);
                               7206              15 :                     add_var(dest, &tmp_var, dest);
                               7207                 : 
                               7208                 :                     /* Result will overflow if weight overflows int16 */
                               7209              15 :                     if (dest->weight > SHRT_MAX)
   76 dean.a.rasheed           7210 UNC           0 :                         goto out_of_range;
                               7211                 : 
                               7212                 :                     /* Begin a new group */
   76 dean.a.rasheed           7213 GNC          15 :                     tmp = 0;
                               7214              15 :                     mul = 1;
                               7215                 :                 }
                               7216                 : 
                               7217             354 :                 tmp = tmp * 16 + xdigit_value(*cp++);
                               7218             354 :                 mul = mul * 16;
                               7219                 :             }
   64                          7220              45 :             else if (*cp == '_')
                               7221                 :             {
                               7222                 :                 /* Underscore must be followed by more digits */
                               7223              33 :                 cp++;
                               7224              33 :                 if (!isxdigit((unsigned char) *cp))
                               7225               9 :                     goto invalid_syntax;
                               7226                 :             }
                               7227                 :             else
   76                          7228              12 :                 break;
                               7229                 :         }
                               7230                 :     }
                               7231              42 :     else if (base == 8)
                               7232                 :     {
                               7233             318 :         while (*cp)
                               7234                 :         {
                               7235             303 :             if (*cp >= '0' && *cp <= '7')
                               7236                 :             {
                               7237             279 :                 if (mul > PG_INT64_MAX / 8)
                               7238                 :                 {
                               7239                 :                     /* Add the contribution from this group of digits */
                               7240               9 :                     int64_to_numericvar(mul, &tmp_var);
                               7241               9 :                     mul_var(dest, &tmp_var, dest, 0);
                               7242               9 :                     int64_to_numericvar(tmp, &tmp_var);
                               7243               9 :                     add_var(dest, &tmp_var, dest);
                               7244                 : 
                               7245                 :                     /* Result will overflow if weight overflows int16 */
                               7246               9 :                     if (dest->weight > SHRT_MAX)
   76 dean.a.rasheed           7247 UNC           0 :                         goto out_of_range;
                               7248                 : 
                               7249                 :                     /* Begin a new group */
   76 dean.a.rasheed           7250 GNC           9 :                     tmp = 0;
                               7251               9 :                     mul = 1;
                               7252                 :                 }
                               7253                 : 
                               7254             279 :                 tmp = tmp * 8 + (*cp++ - '0');
                               7255             279 :                 mul = mul * 8;
                               7256                 :             }
   64                          7257              24 :             else if (*cp == '_')
                               7258                 :             {
                               7259                 :                 /* Underscore must be followed by more digits */
                               7260              18 :                 cp++;
                               7261              18 :                 if (*cp < '0' || *cp > '7')
   64 dean.a.rasheed           7262 UNC           0 :                     goto invalid_syntax;
                               7263                 :             }
                               7264                 :             else
   76 dean.a.rasheed           7265 GNC           6 :                 break;
                               7266                 :         }
                               7267                 :     }
                               7268              21 :     else if (base == 2)
                               7269                 :     {
                               7270             780 :         while (*cp)
                               7271                 :         {
                               7272             765 :             if (*cp >= '0' && *cp <= '1')
                               7273                 :             {
                               7274             708 :                 if (mul > PG_INT64_MAX / 2)
                               7275                 :                 {
                               7276                 :                     /* Add the contribution from this group of digits */
                               7277               9 :                     int64_to_numericvar(mul, &tmp_var);
                               7278               9 :                     mul_var(dest, &tmp_var, dest, 0);
                               7279               9 :                     int64_to_numericvar(tmp, &tmp_var);
                               7280               9 :                     add_var(dest, &tmp_var, dest);
                               7281                 : 
                               7282                 :                     /* Result will overflow if weight overflows int16 */
                               7283               9 :                     if (dest->weight > SHRT_MAX)
   76 dean.a.rasheed           7284 UNC           0 :                         goto out_of_range;
                               7285                 : 
                               7286                 :                     /* Begin a new group */
   76 dean.a.rasheed           7287 GNC           9 :                     tmp = 0;
                               7288               9 :                     mul = 1;
                               7289                 :                 }
                               7290                 : 
                               7291             708 :                 tmp = tmp * 2 + (*cp++ - '0');
                               7292             708 :                 mul = mul * 2;
                               7293                 :             }
   64                          7294              57 :             else if (*cp == '_')
                               7295                 :             {
                               7296                 :                 /* Underscore must be followed by more digits */
                               7297              51 :                 cp++;
                               7298              51 :                 if (*cp < '0' || *cp > '1')
   64 dean.a.rasheed           7299 UNC           0 :                     goto invalid_syntax;
                               7300                 :             }
                               7301                 :             else
   76 dean.a.rasheed           7302 GNC           6 :                 break;
                               7303                 :         }
                               7304                 :     }
                               7305                 :     else
                               7306                 :         /* Should never happen; treat as invalid input */
   76 dean.a.rasheed           7307 UNC           0 :         goto invalid_syntax;
                               7308                 : 
                               7309                 :     /* Check that we got at least one digit */
   76 dean.a.rasheed           7310 GNC          69 :     if (unlikely(cp == firstdigit))
   76 dean.a.rasheed           7311 UNC           0 :         goto invalid_syntax;
                               7312                 : 
                               7313                 :     /* Add the contribution from the final group of digits */
   76 dean.a.rasheed           7314 GNC          69 :     int64_to_numericvar(mul, &tmp_var);
                               7315              69 :     mul_var(dest, &tmp_var, dest, 0);
                               7316              69 :     int64_to_numericvar(tmp, &tmp_var);
                               7317              69 :     add_var(dest, &tmp_var, dest);
                               7318                 : 
                               7319              69 :     if (dest->weight > SHRT_MAX)
   76 dean.a.rasheed           7320 UNC           0 :         goto out_of_range;
                               7321                 : 
   76 dean.a.rasheed           7322 GNC          69 :     dest->sign = sign;
                               7323                 : 
                               7324              69 :     free_var(&tmp_var);
                               7325                 : 
                               7326                 :     /* Return end+1 position for caller */
                               7327              69 :     *endptr = cp;
                               7328                 : 
                               7329              69 :     return true;
                               7330                 : 
   76 dean.a.rasheed           7331 UNC           0 : out_of_range:
                               7332               0 :     ereturn(escontext, false,
                               7333                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               7334                 :              errmsg("value overflows numeric format")));
                               7335                 : 
   76 dean.a.rasheed           7336 GNC           9 : invalid_syntax:
                               7337               9 :     ereturn(escontext, false,
                               7338                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                               7339                 :              errmsg("invalid input syntax for type %s: \"%s\"",
                               7340                 :                     "numeric", str)));
   76 dean.a.rasheed           7341 ECB             : }
                               7342                 : 
                               7343                 : 
 8866 JanWieck                 7344                 : /*
                               7345                 :  * set_var_from_num() -
                               7346                 :  *
                               7347                 :  *  Convert the packed db format into a variable
                               7348                 :  */
 8866 JanWieck                 7349 EUB             : static void
 8720 bruce                    7350 CBC        6184 : set_var_from_num(Numeric num, NumericVar *dest)
 8866 JanWieck                 7351 ECB             : {
                               7352                 :     int         ndigits;
                               7353                 : 
 6270 bruce                    7354 CBC        6184 :     ndigits = NUMERIC_NDIGITS(num);
                               7355                 : 
 7324 tgl                      7356            6184 :     alloc_var(dest, ndigits);
                               7357                 : 
 4632 rhaas                    7358 GIC        6184 :     dest->weight = NUMERIC_WEIGHT(num);
 8720 bruce                    7359 CBC        6184 :     dest->sign = NUMERIC_SIGN(num);
 7324 tgl                      7360            6184 :     dest->dscale = NUMERIC_DSCALE(num);
 8866 JanWieck                 7361 ECB             : 
 4632 rhaas                    7362 GIC        6184 :     memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
 8866 JanWieck                 7363            6184 : }
 8866 JanWieck                 7364 ECB             : 
                               7365                 : 
                               7366                 : /*
 3791 heikki.linnakangas       7367                 :  * init_var_from_num() -
                               7368                 :  *
                               7369                 :  *  Initialize a variable from packed db format. The digits array is not
                               7370                 :  *  copied, which saves some cycles when the resulting var is not modified.
                               7371                 :  *  Also, there's no need to call free_var(), as long as you don't assign any
                               7372                 :  *  other value to it (with set_var_* functions, or by using the var as the
                               7373                 :  *  destination of a function like add_var())
                               7374                 :  *
                               7375                 :  *  CAUTION: Do not modify the digits buffer of a var initialized with this
                               7376                 :  *  function, e.g by calling round_var() or trunc_var(), as the changes will
                               7377                 :  *  propagate to the original Numeric! It's OK to use it as the destination
                               7378                 :  *  argument of one of the calculational functions, though.
                               7379                 :  */
                               7380                 : static void
 3791 heikki.linnakangas       7381 GIC     2426534 : init_var_from_num(Numeric num, NumericVar *dest)
                               7382                 : {
                               7383         2426534 :     dest->ndigits = NUMERIC_NDIGITS(num);
                               7384         2426534 :     dest->weight = NUMERIC_WEIGHT(num);
                               7385         2426534 :     dest->sign = NUMERIC_SIGN(num);
                               7386         2426534 :     dest->dscale = NUMERIC_DSCALE(num);
 3791 heikki.linnakangas       7387 CBC     2426534 :     dest->digits = NUMERIC_DIGITS(num);
 3602 bruce                    7388         2426534 :     dest->buf = NULL;            /* digits array is not palloc'd */
 3791 heikki.linnakangas       7389         2426534 : }
 3791 heikki.linnakangas       7390 ECB             : 
                               7391                 : 
 7324 tgl                      7392                 : /*
 8866 JanWieck                 7393                 :  * set_var_from_var() -
                               7394                 :  *
                               7395                 :  *  Copy one variable into another
                               7396                 :  */
                               7397                 : static void
 2037 andres                   7398 CBC       16592 : set_var_from_var(const NumericVar *value, NumericVar *dest)
                               7399                 : {
 8482 tgl                      7400 ECB             :     NumericDigit *newbuf;
                               7401                 : 
 8482 tgl                      7402 CBC       16592 :     newbuf = digitbuf_alloc(value->ndigits + 1);
 8482 tgl                      7403 GIC       16592 :     newbuf[0] = 0;              /* spare digit for rounding */
 2807 tgl                      7404 CBC       16592 :     if (value->ndigits > 0)       /* else value->digits might be null */
                               7405           16185 :         memcpy(newbuf + 1, value->digits,
                               7406           16185 :                value->ndigits * sizeof(NumericDigit));
                               7407                 : 
 8866 JanWieck                 7408           16592 :     digitbuf_free(dest->buf);
                               7409                 : 
 7004 neilc                    7410 GIC       16592 :     memmove(dest, value, sizeof(NumericVar));
 8720 bruce                    7411 CBC       16592 :     dest->buf = newbuf;
 8482 tgl                      7412           16592 :     dest->digits = newbuf + 1;
                               7413           16592 : }
                               7414                 : 
                               7415                 : 
 7324 tgl                      7416 EUB             : /*
                               7417                 :  * get_str_from_var() -
                               7418                 :  *
 8482 tgl                      7419 ECB             :  *  Convert a var to text representation (guts of numeric_out).
 3791 heikki.linnakangas       7420                 :  *  The var is displayed to the number of digits indicated by its dscale.
                               7421                 :  *  Returns a palloc'd string.
 8482 tgl                      7422                 :  */
                               7423                 : static char *
 2037 andres                   7424 CBC      394256 : get_str_from_var(const NumericVar *var)
 8482 tgl                      7425 ECB             : {
                               7426                 :     int         dscale;
                               7427                 :     char       *str;
                               7428                 :     char       *cp;
                               7429                 :     char       *endcp;
                               7430                 :     int         i;
                               7431                 :     int         d;
                               7432                 :     NumericDigit dig;
                               7433                 : 
 7324                          7434                 : #if DEC_DIGITS > 1
 7188 bruce                    7435                 :     NumericDigit d1;
                               7436                 : #endif
 7324 tgl                      7437                 : 
 3791 heikki.linnakangas       7438 CBC      394256 :     dscale = var->dscale;
 8482 tgl                      7439 ECB             : 
                               7440                 :     /*
 7324                          7441                 :      * Allocate space for the result.
                               7442                 :      *
 3994 heikki.linnakangas       7443                 :      * i is set to the # of decimal digits before decimal point. dscale is the
 6347 bruce                    7444                 :      * # of decimal digits we will print after decimal point. We may generate
                               7445                 :      * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
                               7446                 :      * need room for sign, decimal point, null terminator.
 8482 tgl                      7447                 :      */
 7324 tgl                      7448 GIC      394256 :     i = (var->weight + 1) * DEC_DIGITS;
 7324 tgl                      7449 CBC      394256 :     if (i <= 0)
 7324 tgl                      7450 GIC       69223 :         i = 1;
                               7451                 : 
 7324 tgl                      7452 CBC      394256 :     str = palloc(i + dscale + DEC_DIGITS + 2);
 8482                          7453          394256 :     cp = str;
                               7454                 : 
                               7455                 :     /*
                               7456                 :      * Output a dash for negative values
                               7457                 :      */
 8482 tgl                      7458 GIC      394256 :     if (var->sign == NUMERIC_NEG)
                               7459            2395 :         *cp++ = '-';
                               7460                 : 
 8053 bruce                    7461 ECB             :     /*
                               7462                 :      * Output all digits before the decimal point
                               7463                 :      */
 7324 tgl                      7464 CBC      394256 :     if (var->weight < 0)
                               7465                 :     {
 7324 tgl                      7466 GIC       69223 :         d = var->weight + 1;
 7324 tgl                      7467 CBC       69223 :         *cp++ = '0';
                               7468                 :     }
                               7469                 :     else
 7324 tgl                      7470 ECB             :     {
 7324 tgl                      7471 GIC      697166 :         for (d = 0; d <= var->weight; d++)
 7324 tgl                      7472 ECB             :         {
 7324 tgl                      7473 GIC      372133 :             dig = (d < var->ndigits) ? var->digits[d] : 0;
 7324 tgl                      7474 ECB             :             /* In the first digit, suppress extra leading decimal zeroes */
                               7475                 : #if DEC_DIGITS == 4
                               7476                 :             {
 7188 bruce                    7477 GIC      372133 :                 bool        putit = (d > 0);
                               7478                 : 
 7324 tgl                      7479 CBC      372133 :                 d1 = dig / 1000;
                               7480          372133 :                 dig -= d1 * 1000;
 7324 tgl                      7481 GIC      372133 :                 putit |= (d1 > 0);
                               7482          372133 :                 if (putit)
                               7483           49883 :                     *cp++ = d1 + '0';
                               7484          372133 :                 d1 = dig / 100;
                               7485          372133 :                 dig -= d1 * 100;
                               7486          372133 :                 putit |= (d1 > 0);
                               7487          372133 :                 if (putit)
                               7488          252072 :                     *cp++ = d1 + '0';
                               7489          372133 :                 d1 = dig / 10;
                               7490          372133 :                 dig -= d1 * 10;
 7324 tgl                      7491 CBC      372133 :                 putit |= (d1 > 0);
 7324 tgl                      7492 GIC      372133 :                 if (putit)
 7324 tgl                      7493 CBC      315238 :                     *cp++ = d1 + '0';
                               7494          372133 :                 *cp++ = dig + '0';
 7324 tgl                      7495 ECB             :             }
                               7496                 : #elif DEC_DIGITS == 2
                               7497                 :             d1 = dig / 10;
                               7498                 :             dig -= d1 * 10;
                               7499                 :             if (d1 > 0 || d > 0)
                               7500                 :                 *cp++ = d1 + '0';
                               7501                 :             *cp++ = dig + '0';
                               7502                 : #elif DEC_DIGITS == 1
                               7503                 :             *cp++ = dig + '0';
                               7504                 : #else
                               7505                 : #error unsupported NBASE
                               7506                 : #endif
                               7507                 :         }
                               7508                 :     }
                               7509                 : 
                               7510                 :     /*
                               7511                 :      * If requested, output a decimal point and all the digits that follow it.
                               7512                 :      * We initially put out a multiple of DEC_DIGITS digits, then truncate if
                               7513                 :      * needed.
                               7514                 :      */
 8482 tgl                      7515 GIC      394256 :     if (dscale > 0)
                               7516                 :     {
                               7517          320706 :         *cp++ = '.';
 7324 tgl                      7518 CBC      320706 :         endcp = cp + dscale;
 7324 tgl                      7519 GIC      945684 :         for (i = 0; i < dscale; d++, i += DEC_DIGITS)
                               7520                 :         {
                               7521          624978 :             dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
 7324 tgl                      7522 ECB             : #if DEC_DIGITS == 4
 7324 tgl                      7523 GIC      624978 :             d1 = dig / 1000;
                               7524          624978 :             dig -= d1 * 1000;
                               7525          624978 :             *cp++ = d1 + '0';
                               7526          624978 :             d1 = dig / 100;
 7324 tgl                      7527 CBC      624978 :             dig -= d1 * 100;
 7324 tgl                      7528 GIC      624978 :             *cp++ = d1 + '0';
 7324 tgl                      7529 CBC      624978 :             d1 = dig / 10;
 7324 tgl                      7530 GIC      624978 :             dig -= d1 * 10;
                               7531          624978 :             *cp++ = d1 + '0';
                               7532          624978 :             *cp++ = dig + '0';
                               7533                 : #elif DEC_DIGITS == 2
                               7534                 :             d1 = dig / 10;
                               7535                 :             dig -= d1 * 10;
                               7536                 :             *cp++ = d1 + '0';
 7324 tgl                      7537 ECB             :             *cp++ = dig + '0';
                               7538                 : #elif DEC_DIGITS == 1
                               7539                 :             *cp++ = dig + '0';
                               7540                 : #else
                               7541                 : #error unsupported NBASE
                               7542                 : #endif
                               7543                 :         }
 7324 tgl                      7544 CBC      320706 :         cp = endcp;
                               7545                 :     }
 8482 tgl                      7546 ECB             : 
                               7547                 :     /*
                               7548                 :      * terminate the string and return it
                               7549                 :      */
 8482 tgl                      7550 CBC      394256 :     *cp = '\0';
                               7551          394256 :     return str;
 8866 JanWieck                 7552 ECB             : }
                               7553                 : 
                               7554                 : /*
 4990 tgl                      7555                 :  * get_str_from_var_sci() -
 4990 tgl                      7556 EUB             :  *
                               7557                 :  *  Convert a var to a normalised scientific notation text representation.
                               7558                 :  *  This function does the heavy lifting for numeric_out_sci().
 4990 tgl                      7559 ECB             :  *
                               7560                 :  *  This notation has the general form a * 10^b, where a is known as the
                               7561                 :  *  "significand" and b is known as the "exponent".
                               7562                 :  *
                               7563                 :  *  Because we can't do superscript in ASCII (and because we want to copy
                               7564                 :  *  printf's behaviour) we display the exponent using E notation, with a
                               7565                 :  *  minimum of two exponent digits.
                               7566                 :  *
                               7567                 :  *  For example, the value 1234 could be output as 1.2e+03.
                               7568                 :  *
                               7569                 :  *  We assume that the exponent can fit into an int32.
                               7570                 :  *
                               7571                 :  *  rscale is the number of decimal digits desired after the decimal point in
                               7572                 :  *  the output, negative values will be treated as meaning zero.
                               7573                 :  *
                               7574                 :  *  Returns a palloc'd string.
                               7575                 :  */
                               7576                 : static char *
 2037 andres                   7577 CBC         108 : get_str_from_var_sci(const NumericVar *var, int rscale)
                               7578                 : {
 4990 tgl                      7579 ECB             :     int32       exponent;
                               7580                 :     NumericVar  tmp_var;
                               7581                 :     size_t      len;
                               7582                 :     char       *str;
                               7583                 :     char       *sig_out;
                               7584                 : 
 4990 tgl                      7585 GIC         108 :     if (rscale < 0)
 4990 tgl                      7586 LBC           0 :         rscale = 0;
 4990 tgl                      7587 ECB             : 
                               7588                 :     /*
                               7589                 :      * Determine the exponent of this number in normalised form.
                               7590                 :      *
                               7591                 :      * This is the exponent required to represent the number with only one
                               7592                 :      * significant digit before the decimal place.
 4990 tgl                      7593 EUB             :      */
 4990 tgl                      7594 GIC         108 :     if (var->ndigits > 0)
                               7595                 :     {
 4990 tgl                      7596 CBC          99 :         exponent = (var->weight + 1) * DEC_DIGITS;
 4990 tgl                      7597 ECB             : 
                               7598                 :         /*
                               7599                 :          * Compensate for leading decimal zeroes in the first numeric digit by
                               7600                 :          * decrementing the exponent.
                               7601                 :          */
 4990 tgl                      7602 GIC          99 :         exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
 4990 tgl                      7603 ECB             :     }
                               7604                 :     else
                               7605                 :     {
                               7606                 :         /*
                               7607                 :          * If var has no digits, then it must be zero.
 4990 tgl                      7608 EUB             :          *
                               7609                 :          * Zero doesn't technically have a meaningful exponent in normalised
                               7610                 :          * notation, but we just display the exponent as zero for consistency
 4990 tgl                      7611 ECB             :          * of output.
                               7612                 :          */
 4990 tgl                      7613 GIC           9 :         exponent = 0;
 4990 tgl                      7614 ECB             :     }
                               7615                 : 
                               7616                 :     /*
                               7617                 :      * Divide var by 10^exponent to get the significand, rounding to rscale
  612 dean.a.rasheed           7618                 :      * decimal digits in the process.
                               7619                 :      */
  612 dean.a.rasheed           7620 CBC         108 :     init_var(&tmp_var);
                               7621                 : 
  612 dean.a.rasheed           7622 GIC         108 :     power_ten_int(exponent, &tmp_var);
  612 dean.a.rasheed           7623 CBC         108 :     div_var(var, &tmp_var, &tmp_var, rscale, true);
                               7624             108 :     sig_out = get_str_from_var(&tmp_var);
 4990 tgl                      7625 ECB             : 
  612 dean.a.rasheed           7626 CBC         108 :     free_var(&tmp_var);
                               7627                 : 
                               7628                 :     /*
 4990 tgl                      7629 ECB             :      * Allocate space for the result.
 4990 tgl                      7630 EUB             :      *
                               7631                 :      * In addition to the significand, we need room for the exponent
                               7632                 :      * decoration ("e"), the sign of the exponent, up to 10 digits for the
 4790 bruce                    7633 ECB             :      * exponent itself, and of course the null terminator.
 4990 tgl                      7634                 :      */
 4990 tgl                      7635 GIC         108 :     len = strlen(sig_out) + 13;
                               7636             108 :     str = palloc(len);
 4990 tgl                      7637 CBC         108 :     snprintf(str, len, "%se%+03d", sig_out, exponent);
 4990 tgl                      7638 ECB             : 
 4990 tgl                      7639 GIC         108 :     pfree(sig_out);
 4990 tgl                      7640 ECB             : 
 4990 tgl                      7641 GIC         108 :     return str;
                               7642                 : }
 4990 tgl                      7643 ECB             : 
 8866 JanWieck                 7644                 : 
  643 dean.a.rasheed           7645 EUB             : /*
                               7646                 :  * numericvar_serialize - serialize NumericVar to binary format
                               7647                 :  *
  643 dean.a.rasheed           7648 ECB             :  * At variable level, no checks are performed on the weight or dscale, allowing
                               7649                 :  * us to pass around intermediate values with higher precision than supported
                               7650                 :  * by the numeric type.  Note: this is incompatible with numeric_send/recv(),
                               7651                 :  * which use 16-bit integers for these fields.
                               7652                 :  */
  643 dean.a.rasheed           7653 EUB             : static void
  643 dean.a.rasheed           7654 GIC          72 : numericvar_serialize(StringInfo buf, const NumericVar *var)
                               7655                 : {
  643 dean.a.rasheed           7656 ECB             :     int         i;
  643 dean.a.rasheed           7657 EUB             : 
  643 dean.a.rasheed           7658 GIC          72 :     pq_sendint32(buf, var->ndigits);
                               7659              72 :     pq_sendint32(buf, var->weight);
  643 dean.a.rasheed           7660 CBC          72 :     pq_sendint32(buf, var->sign);
                               7661              72 :     pq_sendint32(buf, var->dscale);
                               7662          318965 :     for (i = 0; i < var->ndigits; i++)
                               7663          318893 :         pq_sendint16(buf, var->digits[i]);
  643 dean.a.rasheed           7664 GIC          72 : }
  643 dean.a.rasheed           7665 ECB             : 
  643 dean.a.rasheed           7666 EUB             : /*
                               7667                 :  * numericvar_deserialize - deserialize binary format to NumericVar
  643 dean.a.rasheed           7668 ECB             :  */
                               7669                 : static void
  643 dean.a.rasheed           7670 CBC          72 : numericvar_deserialize(StringInfo buf, NumericVar *var)
                               7671                 : {
                               7672                 :     int         len,
  643 dean.a.rasheed           7673 ECB             :                 i;
                               7674                 : 
  643 dean.a.rasheed           7675 CBC          72 :     len = pq_getmsgint(buf, sizeof(int32));
                               7676                 : 
  643 dean.a.rasheed           7677 GBC          72 :     alloc_var(var, len);        /* sets var->ndigits */
  643 dean.a.rasheed           7678 EUB             : 
  643 dean.a.rasheed           7679 GIC          72 :     var->weight = pq_getmsgint(buf, sizeof(int32));
                               7680              72 :     var->sign = pq_getmsgint(buf, sizeof(int32));
                               7681              72 :     var->dscale = pq_getmsgint(buf, sizeof(int32));
  643 dean.a.rasheed           7682 CBC      318965 :     for (i = 0; i < len; i++)
                               7683          318893 :         var->digits[i] = pq_getmsgint(buf, sizeof(int16));
  643 dean.a.rasheed           7684 GIC          72 : }
                               7685                 : 
                               7686                 : 
                               7687                 : /*
                               7688                 :  * duplicate_numeric() - copy a packed-format Numeric
                               7689                 :  *
                               7690                 :  * This will handle NaN and Infinity cases.
                               7691                 :  */
                               7692                 : static Numeric
  991 tgl                      7693            5102 : duplicate_numeric(Numeric num)
                               7694                 : {
                               7695                 :     Numeric     res;
  991 tgl                      7696 ECB             : 
  991 tgl                      7697 GIC        5102 :     res = (Numeric) palloc(VARSIZE(num));
                               7698            5102 :     memcpy(res, num, VARSIZE(num));
                               7699            5102 :     return res;
  991 tgl                      7700 ECB             : }
                               7701                 : 
 7324                          7702                 : /*
                               7703                 :  * make_result_opt_error() -
 8866 JanWieck                 7704                 :  *
                               7705                 :  *  Create the packed db numeric format in palloc()'d memory from
  991 tgl                      7706                 :  *  a variable.  This will handle NaN and Infinity cases.
                               7707                 :  *
                               7708                 :  *  If "have_error" isn't NULL, on overflow *have_error is set to true and
                               7709                 :  *  NULL is returned.  This is helpful when caller needs to handle errors.
                               7710                 :  */
                               7711                 : static Numeric
 1485 akorotkov                7712 GIC     1559439 : make_result_opt_error(const NumericVar *var, bool *have_error)
                               7713                 : {
                               7714                 :     Numeric     result;
 7324 tgl                      7715         1559439 :     NumericDigit *digits = var->digits;
 8720 bruce                    7716         1559439 :     int         weight = var->weight;
                               7717         1559439 :     int         sign = var->sign;
                               7718                 :     int         n;
                               7719                 :     Size        len;
                               7720                 : 
 1343 michael                  7721         1559439 :     if (have_error)
                               7722           46557 :         *have_error = false;
                               7723                 : 
  991 tgl                      7724         1559439 :     if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
                               7725                 :     {
                               7726                 :         /*
  991 tgl                      7727 ECB             :          * Verify valid special value.  This could be just an Assert, perhaps,
                               7728                 :          * but it seems worthwhile to expend a few cycles to ensure that we
                               7729                 :          * never write any nonzero reserved bits to disk.
                               7730                 :          */
  991 tgl                      7731 CBC        2595 :         if (!(sign == NUMERIC_NAN ||
  991 tgl                      7732 ECB             :               sign == NUMERIC_PINF ||
                               7733                 :               sign == NUMERIC_NINF))
  991 tgl                      7734 LBC           0 :             elog(ERROR, "invalid numeric sign value 0x%x", sign);
  991 tgl                      7735 ECB             : 
 4632 rhaas                    7736 GIC        2595 :         result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
                               7737                 : 
                               7738            2595 :         SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
  991 tgl                      7739            2595 :         result->choice.n_header = sign;
                               7740                 :         /* the header word is all we need */
                               7741                 : 
                               7742                 :         dump_numeric("make_result()", result);
 8866 JanWieck                 7743            2595 :         return result;
 8866 JanWieck                 7744 ECB             :     }
                               7745                 : 
 7324 tgl                      7746 GIC     1556844 :     n = var->ndigits;
                               7747                 : 
 8485 tgl                      7748 ECB             :     /* truncate leading zeroes */
 7324 tgl                      7749 CBC     1556856 :     while (n > 0 && *digits == 0)
 8866 JanWieck                 7750 ECB             :     {
 7324 tgl                      7751 CBC          12 :         digits++;
 8866 JanWieck                 7752              12 :         weight--;
 8866 JanWieck                 7753 GIC          12 :         n--;
 8866 JanWieck                 7754 ECB             :     }
                               7755                 :     /* truncate trailing zeroes */
 7324 tgl                      7756 CBC     1599425 :     while (n > 0 && digits[n - 1] == 0)
 8866 JanWieck                 7757           42581 :         n--;
 8866 JanWieck                 7758 ECB             : 
 8485 tgl                      7759                 :     /* If zero result, force to weight=0 and positive sign */
 8866 JanWieck                 7760 GIC     1556844 :     if (n == 0)
                               7761                 :     {
                               7762           46384 :         weight = 0;
 8720 bruce                    7763           46384 :         sign = NUMERIC_POS;
                               7764                 :     }
                               7765                 : 
                               7766                 :     /* Build the result */
 4632 rhaas                    7767         1556844 :     if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
                               7768                 :     {
                               7769         1555977 :         len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
 4632 rhaas                    7770 CBC     1555977 :         result = (Numeric) palloc(len);
 4632 rhaas                    7771 GIC     1555977 :         SET_VARSIZE(result, len);
 4520 peter_e                  7772         1555977 :         result->choice.n_short.n_header =
                               7773                 :             (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
                               7774                 :              : NUMERIC_SHORT)
 4632 rhaas                    7775         1555977 :             | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
                               7776         1555977 :             | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
                               7777         1555977 :             | (weight & NUMERIC_SHORT_WEIGHT_MASK);
                               7778                 :     }
                               7779                 :     else
                               7780                 :     {
                               7781             867 :         len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
                               7782             867 :         result = (Numeric) palloc(len);
                               7783             867 :         SET_VARSIZE(result, len);
 4632 rhaas                    7784 CBC         867 :         result->choice.n_long.n_sign_dscale =
 4632 rhaas                    7785 GIC         867 :             sign | (var->dscale & NUMERIC_DSCALE_MASK);
                               7786             867 :         result->choice.n_long.n_weight = weight;
                               7787                 :     }
                               7788                 : 
                               7789         1556844 :     Assert(NUMERIC_NDIGITS(result) == n);
 2807 tgl                      7790         1556844 :     if (n > 0)
                               7791         1510460 :         memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
                               7792                 : 
                               7793                 :     /* Check for overflow of int16 fields */
 4632 rhaas                    7794 CBC     1556844 :     if (NUMERIC_WEIGHT(result) != weight ||
 7324 tgl                      7795         1556832 :         NUMERIC_DSCALE(result) != var->dscale)
 1485 akorotkov                7796 ECB             :     {
 1485 akorotkov                7797 GIC          12 :         if (have_error)
 1485 akorotkov                7798 ECB             :         {
 1485 akorotkov                7799 CBC           9 :             *have_error = true;
 1485 akorotkov                7800 GIC           9 :             return NULL;
                               7801                 :         }
                               7802                 :         else
                               7803                 :         {
 1485 akorotkov                7804 CBC           3 :             ereport(ERROR,
 1485 akorotkov                7805 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               7806                 :                      errmsg("value overflows numeric format")));
                               7807                 :         }
                               7808                 :     }
                               7809                 : 
 8866 JanWieck                 7810                 :     dump_numeric("make_result()", result);
 8866 JanWieck                 7811 GIC     1556832 :     return result;
 8866 JanWieck                 7812 ECB             : }
                               7813                 : 
                               7814                 : 
                               7815                 : /*
                               7816                 :  * make_result() -
 1485 akorotkov                7817                 :  *
                               7818                 :  *  An interface to make_result_opt_error() without "have_error" argument.
                               7819                 :  */
                               7820                 : static Numeric
 1485 akorotkov                7821 GIC     1029101 : make_result(const NumericVar *var)
                               7822                 : {
 1485 akorotkov                7823 CBC     1029101 :     return make_result_opt_error(var, NULL);
                               7824                 : }
 1485 akorotkov                7825 ECB             : 
                               7826                 : 
 7324 tgl                      7827                 : /*
 8866 JanWieck                 7828                 :  * apply_typmod() -
                               7829                 :  *
  991 tgl                      7830                 :  *  Do bounds checking and rounding according to the specified typmod.
                               7831                 :  *  Note that this is only applied to normal finite values.
                               7832                 :  *
                               7833                 :  * Returns true on success, false on failure (if escontext points to an
                               7834                 :  * ErrorSaveContext; otherwise errors are thrown).
 8866 JanWieck                 7835                 :  */
                               7836                 : static bool
  121 tgl                      7837 GNC       48764 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
 8866 JanWieck                 7838 ECB             : {
                               7839                 :     int         precision;
                               7840                 :     int         scale;
 7324 tgl                      7841                 :     int         maxdigits;
                               7842                 :     int         ddigits;
 8866 JanWieck                 7843                 :     int         i;
                               7844                 : 
                               7845                 :     /* Do nothing if we have an invalid typmod */
  622 dean.a.rasheed           7846 GIC       48764 :     if (!is_valid_numeric_typmod(typmod))
  121 tgl                      7847 GNC       46461 :         return true;
                               7848                 : 
  622 dean.a.rasheed           7849 GIC        2303 :     precision = numeric_typmod_precision(typmod);
                               7850            2303 :     scale = numeric_typmod_scale(typmod);
 7324 tgl                      7851            2303 :     maxdigits = precision - scale;
                               7852                 : 
                               7853                 :     /* Round to target scale (and set var->dscale) */
                               7854            2303 :     round_var(var, scale);
                               7855                 : 
                               7856                 :     /* but don't allow var->dscale to be negative */
  622 dean.a.rasheed           7857            2303 :     if (var->dscale < 0)
                               7858              54 :         var->dscale = 0;
                               7859                 : 
                               7860                 :     /*
                               7861                 :      * Check for overflow - note we can't do this before rounding, because
                               7862                 :      * rounding could raise the weight.  Also note that the var's weight could
                               7863                 :      * be inflated by leading zeroes, which will be stripped before storage
 6385 bruce                    7864 ECB             :      * but perhaps might not have been yet. In any case, we must recognize a
                               7865                 :      * true zero, whose weight doesn't mean anything.
 8735 JanWieck                 7866                 :      */
 7324 tgl                      7867 CBC        2303 :     ddigits = (var->weight + 1) * DEC_DIGITS;
                               7868            2303 :     if (ddigits > maxdigits)
                               7869                 :     {
 8485 tgl                      7870 ECB             :         /* Determine true weight; and check for all-zero result */
 8485 tgl                      7871 GIC         175 :         for (i = 0; i < var->ndigits; i++)
 8485 tgl                      7872 ECB             :         {
 7324 tgl                      7873 CBC         168 :             NumericDigit dig = var->digits[i];
 7324 tgl                      7874 ECB             : 
 7324 tgl                      7875 CBC         168 :             if (dig)
 7324 tgl                      7876 ECB             :             {
                               7877                 :                 /* Adjust for any high-order decimal zero digits */
                               7878                 : #if DEC_DIGITS == 4
 7324 tgl                      7879 CBC         168 :                 if (dig < 10)
                               7880             108 :                     ddigits -= 3;
                               7881              60 :                 else if (dig < 100)
 7324 tgl                      7882 GIC          30 :                     ddigits -= 2;
                               7883              30 :                 else if (dig < 1000)
                               7884              21 :                     ddigits -= 1;
                               7885                 : #elif DEC_DIGITS == 2
                               7886                 :                 if (dig < 10)
                               7887                 :                     ddigits -= 1;
                               7888                 : #elif DEC_DIGITS == 1
                               7889                 :                 /* no adjustment */
                               7890                 : #else
                               7891                 : #error unsupported NBASE
                               7892                 : #endif
 7324 tgl                      7893 CBC         168 :                 if (ddigits > maxdigits)
  121 tgl                      7894 GNC          36 :                     ereturn(escontext, false,
                               7895                 :                             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               7896                 :                              errmsg("numeric field overflow"),
                               7897                 :                              errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
                               7898                 :                                        precision, scale,
 6031 bruce                    7899 ECB             :                     /* Display 10^0 as 1 */
 6283                          7900                 :                                        maxdigits ? "10^" : "",
                               7901                 :                                        maxdigits ? maxdigits : 1
                               7902                 :                                        )));
 8485 tgl                      7903 GIC         132 :                 break;
                               7904                 :             }
 7324 tgl                      7905 UIC           0 :             ddigits -= DEC_DIGITS;
                               7906                 :         }
                               7907                 :     }
                               7908                 : 
  121 tgl                      7909 GNC        2267 :     return true;
                               7910                 : }
                               7911                 : 
                               7912                 : /*
                               7913                 :  * apply_typmod_special() -
                               7914                 :  *
                               7915                 :  *  Do bounds checking according to the specified typmod, for an Inf or NaN.
                               7916                 :  *  For convenience of most callers, the value is presented in packed form.
                               7917                 :  *
                               7918                 :  * Returns true on success, false on failure (if escontext points to an
                               7919                 :  * ErrorSaveContext; otherwise errors are thrown).
                               7920                 :  */
                               7921                 : static bool
                               7922             796 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
                               7923                 : {
                               7924                 :     int         precision;
                               7925                 :     int         scale;
                               7926                 : 
  991 tgl                      7927 GIC         796 :     Assert(NUMERIC_IS_SPECIAL(num));    /* caller error if not */
                               7928                 : 
                               7929                 :     /*
                               7930                 :      * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
  991 tgl                      7931 ECB             :      * but it's a longstanding behavior.  Inf is rejected if we have any
                               7932                 :      * typmod restriction, since an infinity shouldn't be claimed to fit in
                               7933                 :      * any finite number of digits.
                               7934                 :      */
  991 tgl                      7935 GIC         796 :     if (NUMERIC_IS_NAN(num))
  121 tgl                      7936 GNC         367 :         return true;
                               7937                 : 
                               7938                 :     /* Do nothing if we have a default typmod (-1) */
  622 dean.a.rasheed           7939 CBC         429 :     if (!is_valid_numeric_typmod(typmod))
  121 tgl                      7940 GNC         420 :         return true;
                               7941                 : 
  622 dean.a.rasheed           7942 GIC           9 :     precision = numeric_typmod_precision(typmod);
                               7943               9 :     scale = numeric_typmod_scale(typmod);
                               7944                 : 
  121 tgl                      7945 GNC           9 :     ereturn(escontext, false,
                               7946                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                               7947                 :              errmsg("numeric field overflow"),
  991 tgl                      7948 ECB             :              errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
                               7949                 :                        precision, scale)));
                               7950                 : }
                               7951                 : 
                               7952                 : 
                               7953                 : /*
                               7954                 :  * Convert numeric to int8, rounding if needed.
                               7955                 :  *
 2062 peter_e                  7956                 :  * If overflow, return false (no error is raised).  Return true if okay.
                               7957                 :  */
                               7958                 : static bool
 2037 andres                   7959 GIC        3932 : numericvar_to_int64(const NumericVar *var, int64 *result)
                               7960                 : {
                               7961                 :     NumericDigit *digits;
                               7962                 :     int         ndigits;
                               7963                 :     int         weight;
                               7964                 :     int         i;
                               7965                 :     int64       val;
                               7966                 :     bool        neg;
 3791 heikki.linnakangas       7967 ECB             :     NumericVar  rounded;
                               7968                 : 
                               7969                 :     /* Round to nearest integer */
 3791 heikki.linnakangas       7970 GIC        3932 :     init_var(&rounded);
                               7971            3932 :     set_var_from_var(var, &rounded);
                               7972            3932 :     round_var(&rounded, 0);
                               7973                 : 
 7324 tgl                      7974 ECB             :     /* Check for zero input */
 3791 heikki.linnakangas       7975 GIC        3932 :     strip_var(&rounded);
 3791 heikki.linnakangas       7976 CBC        3932 :     ndigits = rounded.ndigits;
 7324 tgl                      7977            3932 :     if (ndigits == 0)
 7324 tgl                      7978 ECB             :     {
 7324 tgl                      7979 GIC         176 :         *result = 0;
 3791 heikki.linnakangas       7980 CBC         176 :         free_var(&rounded);
 7324 tgl                      7981 GIC         176 :         return true;
                               7982                 :     }
                               7983                 : 
                               7984                 :     /*
                               7985                 :      * For input like 10000000000, we must treat stripped digits as real. So
                               7986                 :      * the loop assumes there are weight+1 digits before the decimal point.
                               7987                 :      */
 3791 heikki.linnakangas       7988            3756 :     weight = rounded.weight;
 7188 bruce                    7989 CBC        3756 :     Assert(weight >= 0 && ndigits <= weight + 1);
 7220 tgl                      7990 ECB             : 
 1944 andres                   7991                 :     /*
                               7992                 :      * Construct the result. To avoid issues with converting a value
                               7993                 :      * corresponding to INT64_MIN (which can't be represented as a positive 64
                               7994                 :      * bit two's complement integer), accumulate value as a negative number.
                               7995                 :      */
 3791 heikki.linnakangas       7996 GIC        3756 :     digits = rounded.digits;
                               7997            3756 :     neg = (rounded.sign == NUMERIC_NEG);
 1944 andres                   7998            3756 :     val = -digits[0];
 7220 tgl                      7999            5336 :     for (i = 1; i <= weight; i++)
                               8000                 :     {
 1944 andres                   8001            1595 :         if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
                               8002                 :         {
                               8003               6 :             free_var(&rounded);
                               8004               6 :             return false;
                               8005                 :         }
                               8006                 : 
                               8007            1589 :         if (i < ndigits)
 7324 tgl                      8008 ECB             :         {
 1944 andres                   8009 GIC        1484 :             if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
                               8010                 :             {
 3791 heikki.linnakangas       8011               9 :                 free_var(&rounded);
 7324 tgl                      8012 CBC           9 :                 return false;
 3791 heikki.linnakangas       8013 ECB             :             }
 7324 tgl                      8014                 :         }
                               8015                 :     }
                               8016                 : 
 3791 heikki.linnakangas       8017 CBC        3741 :     free_var(&rounded);
 3791 heikki.linnakangas       8018 ECB             : 
 1944 andres                   8019 GIC        3741 :     if (!neg)
                               8020                 :     {
                               8021            3438 :         if (unlikely(val == PG_INT64_MIN))
                               8022              12 :             return false;
                               8023            3426 :         val = -val;
 1944 andres                   8024 ECB             :     }
 1944 andres                   8025 GIC        3729 :     *result = val;
                               8026                 : 
 7324 tgl                      8027            3729 :     return true;
                               8028                 : }
 8866 JanWieck                 8029 ECB             : 
                               8030                 : /*
 7324 tgl                      8031                 :  * Convert int8 value to numeric.
                               8032                 :  */
                               8033                 : static void
 2942 andres                   8034 CBC      922207 : int64_to_numericvar(int64 val, NumericVar *var)
 7324 tgl                      8035 ECB             : {
                               8036                 :     uint64      uval,
                               8037                 :                 newuval;
                               8038                 :     NumericDigit *ptr;
                               8039                 :     int         ndigits;
                               8040                 : 
                               8041                 :     /* int64 can require at most 19 decimal digits; add one for safety */
 7188 bruce                    8042 GIC      922207 :     alloc_var(var, 20 / DEC_DIGITS);
 7324 tgl                      8043          922207 :     if (val < 0)
                               8044                 :     {
                               8045             733 :         var->sign = NUMERIC_NEG;
                               8046             733 :         uval = -val;
 7324 tgl                      8047 ECB             :     }
                               8048                 :     else
                               8049                 :     {
 7324 tgl                      8050 GIC      921474 :         var->sign = NUMERIC_POS;
 7324 tgl                      8051 CBC      921474 :         uval = val;
 7324 tgl                      8052 ECB             :     }
 7324 tgl                      8053 CBC      922207 :     var->dscale = 0;
 7324 tgl                      8054 GIC      922207 :     if (val == 0)
                               8055                 :     {
                               8056           17041 :         var->ndigits = 0;
                               8057           17041 :         var->weight = 0;
                               8058           17041 :         return;
                               8059                 :     }
                               8060          905166 :     ptr = var->digits + var->ndigits;
                               8061          905166 :     ndigits = 0;
                               8062                 :     do
                               8063                 :     {
                               8064         1057117 :         ptr--;
                               8065         1057117 :         ndigits++;
 7324 tgl                      8066 CBC     1057117 :         newuval = uval / NBASE;
 7324 tgl                      8067 GIC     1057117 :         *ptr = uval - newuval * NBASE;
                               8068         1057117 :         uval = newuval;
 7324 tgl                      8069 CBC     1057117 :     } while (uval);
                               8070          905166 :     var->digits = ptr;
                               8071          905166 :     var->ndigits = ndigits;
 7324 tgl                      8072 GIC      905166 :     var->weight = ndigits - 1;
                               8073                 : }
                               8074                 : 
 1013 fujii                    8075 ECB             : /*
                               8076                 :  * Convert numeric to uint64, rounding if needed.
                               8077                 :  *
                               8078                 :  * If overflow, return false (no error is raised).  Return true if okay.
                               8079                 :  */
                               8080                 : static bool
 1013 fujii                    8081 GIC          42 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
                               8082                 : {
                               8083                 :     NumericDigit *digits;
                               8084                 :     int         ndigits;
 1013 fujii                    8085 ECB             :     int         weight;
                               8086                 :     int         i;
                               8087                 :     uint64      val;
 1013 fujii                    8088 EUB             :     NumericVar  rounded;
                               8089                 : 
 1013 fujii                    8090 ECB             :     /* Round to nearest integer */
 1013 fujii                    8091 GIC          42 :     init_var(&rounded);
 1013 fujii                    8092 CBC          42 :     set_var_from_var(var, &rounded);
                               8093              42 :     round_var(&rounded, 0);
                               8094                 : 
                               8095                 :     /* Check for zero input */
 1013 fujii                    8096 GIC          42 :     strip_var(&rounded);
 1013 fujii                    8097 CBC          42 :     ndigits = rounded.ndigits;
 1013 fujii                    8098 GIC          42 :     if (ndigits == 0)
                               8099                 :     {
 1013 fujii                    8100 CBC           9 :         *result = 0;
 1013 fujii                    8101 GIC           9 :         free_var(&rounded);
                               8102               9 :         return true;
 1013 fujii                    8103 ECB             :     }
                               8104                 : 
                               8105                 :     /* Check for negative input */
 1013 fujii                    8106 CBC          33 :     if (rounded.sign == NUMERIC_NEG)
 1013 fujii                    8107 ECB             :     {
 1013 fujii                    8108 GIC           6 :         free_var(&rounded);
                               8109               6 :         return false;
 1013 fujii                    8110 ECB             :     }
                               8111                 : 
                               8112                 :     /*
                               8113                 :      * For input like 10000000000, we must treat stripped digits as real. So
                               8114                 :      * the loop assumes there are weight+1 digits before the decimal point.
                               8115                 :      */
 1013 fujii                    8116 CBC          27 :     weight = rounded.weight;
                               8117              27 :     Assert(weight >= 0 && ndigits <= weight + 1);
                               8118                 : 
                               8119                 :     /* Construct the result */
 1013 fujii                    8120 GIC          27 :     digits = rounded.digits;
 1013 fujii                    8121 CBC          27 :     val = digits[0];
 1013 fujii                    8122 GIC          93 :     for (i = 1; i <= weight; i++)
 1013 fujii                    8123 ECB             :     {
 1013 fujii                    8124 CBC          72 :         if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
 1013 fujii                    8125 ECB             :         {
 1013 fujii                    8126 LBC           0 :             free_var(&rounded);
 1013 fujii                    8127 UIC           0 :             return false;
                               8128                 :         }
 1013 fujii                    8129 ECB             : 
 1013 fujii                    8130 CBC          72 :         if (i < ndigits)
 1013 fujii                    8131 ECB             :         {
 1013 fujii                    8132 GIC          72 :             if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
                               8133                 :             {
                               8134               6 :                 free_var(&rounded);
 1013 fujii                    8135 CBC           6 :                 return false;
 1013 fujii                    8136 ECB             :             }
                               8137                 :         }
                               8138                 :     }
                               8139                 : 
 1013 fujii                    8140 CBC          21 :     free_var(&rounded);
                               8141                 : 
 1013 fujii                    8142 GIC          21 :     *result = val;
 1013 fujii                    8143 ECB             : 
 1013 fujii                    8144 CBC          21 :     return true;
 1013 fujii                    8145 ECB             : }
                               8146                 : 
                               8147                 : #ifdef HAVE_INT128
 2560 rhaas                    8148                 : /*
                               8149                 :  * Convert numeric to int128, rounding if needed.
                               8150                 :  *
 2062 peter_e                  8151                 :  * If overflow, return false (no error is raised).  Return true if okay.
                               8152                 :  */
 2560 rhaas                    8153                 : static bool
 2037 andres                   8154 CBC          27 : numericvar_to_int128(const NumericVar *var, int128 *result)
                               8155                 : {
                               8156                 :     NumericDigit *digits;
                               8157                 :     int         ndigits;
 2560 rhaas                    8158 ECB             :     int         weight;
                               8159                 :     int         i;
                               8160                 :     int128      val,
                               8161                 :                 oldval;
                               8162                 :     bool        neg;
                               8163                 :     NumericVar  rounded;
                               8164                 : 
                               8165                 :     /* Round to nearest integer */
 2560 rhaas                    8166 GIC          27 :     init_var(&rounded);
                               8167              27 :     set_var_from_var(var, &rounded);
                               8168              27 :     round_var(&rounded, 0);
                               8169                 : 
                               8170                 :     /* Check for zero input */
                               8171              27 :     strip_var(&rounded);
                               8172              27 :     ndigits = rounded.ndigits;
                               8173              27 :     if (ndigits == 0)
                               8174                 :     {
 2560 rhaas                    8175 LBC           0 :         *result = 0;
 2560 rhaas                    8176 UIC           0 :         free_var(&rounded);
 2560 rhaas                    8177 LBC           0 :         return true;
                               8178                 :     }
                               8179                 : 
                               8180                 :     /*
                               8181                 :      * For input like 10000000000, we must treat stripped digits as real. So
                               8182                 :      * the loop assumes there are weight+1 digits before the decimal point.
                               8183                 :      */
 2560 rhaas                    8184 GIC          27 :     weight = rounded.weight;
                               8185              27 :     Assert(weight >= 0 && ndigits <= weight + 1);
                               8186                 : 
                               8187                 :     /* Construct the result */
                               8188              27 :     digits = rounded.digits;
                               8189              27 :     neg = (rounded.sign == NUMERIC_NEG);
                               8190              27 :     val = digits[0];
 2560 rhaas                    8191 CBC          65 :     for (i = 1; i <= weight; i++)
                               8192                 :     {
 2560 rhaas                    8193 GIC          38 :         oldval = val;
                               8194              38 :         val *= NBASE;
                               8195              38 :         if (i < ndigits)
                               8196              35 :             val += digits[i];
                               8197                 : 
                               8198                 :         /*
                               8199                 :          * The overflow check is a bit tricky because we want to accept
 2560 rhaas                    8200 ECB             :          * INT128_MIN, which will overflow the positive accumulator.  We can
                               8201                 :          * detect this case easily though because INT128_MIN is the only
                               8202                 :          * nonzero value for which -val == val (on a two's complement machine,
                               8203                 :          * anyway).
                               8204                 :          */
 2560 rhaas                    8205 CBC          38 :         if ((val / NBASE) != oldval)    /* possible overflow? */
                               8206                 :         {
 2560 rhaas                    8207 UIC           0 :             if (!neg || (-val) != val || val == 0 || oldval < 0)
 2560 rhaas                    8208 ECB             :             {
 2560 rhaas                    8209 UIC           0 :                 free_var(&rounded);
                               8210               0 :                 return false;
 2560 rhaas                    8211 ECB             :             }
                               8212                 :         }
                               8213                 :     }
                               8214                 : 
 2560 rhaas                    8215 GIC          27 :     free_var(&rounded);
                               8216                 : 
                               8217              27 :     *result = neg ? -val : val;
                               8218              27 :     return true;
                               8219                 : }
                               8220                 : 
 2942 andres                   8221 ECB             : /*
                               8222                 :  * Convert 128 bit integer to numeric.
                               8223                 :  */
                               8224                 : static void
 2942 andres                   8225 CBC        4270 : int128_to_numericvar(int128 val, NumericVar *var)
                               8226                 : {
 2878 bruce                    8227 ECB             :     uint128     uval,
                               8228                 :                 newuval;
                               8229                 :     NumericDigit *ptr;
                               8230                 :     int         ndigits;
                               8231                 : 
                               8232                 :     /* int128 can require at most 39 decimal digits; add one for safety */
 2942 andres                   8233 CBC        4270 :     alloc_var(var, 40 / DEC_DIGITS);
                               8234            4270 :     if (val < 0)
 2942 andres                   8235 ECB             :     {
 2942 andres                   8236 LBC           0 :         var->sign = NUMERIC_NEG;
                               8237               0 :         uval = -val;
 2942 andres                   8238 ECB             :     }
                               8239                 :     else
                               8240                 :     {
 2942 andres                   8241 GIC        4270 :         var->sign = NUMERIC_POS;
                               8242            4270 :         uval = val;
                               8243                 :     }
                               8244            4270 :     var->dscale = 0;
                               8245            4270 :     if (val == 0)
                               8246                 :     {
 2942 andres                   8247 CBC          55 :         var->ndigits = 0;
                               8248              55 :         var->weight = 0;
 2942 andres                   8249 GIC          55 :         return;
                               8250                 :     }
                               8251            4215 :     ptr = var->digits + var->ndigits;
                               8252            4215 :     ndigits = 0;
                               8253                 :     do
                               8254                 :     {
                               8255           22460 :         ptr--;
                               8256           22460 :         ndigits++;
 2942 andres                   8257 CBC       22460 :         newuval = uval / NBASE;
 2942 andres                   8258 GIC       22460 :         *ptr = uval - newuval * NBASE;
 2942 andres                   8259 GBC       22460 :         uval = newuval;
 2942 andres                   8260 GIC       22460 :     } while (uval);
                               8261            4215 :     var->digits = ptr;
                               8262            4215 :     var->ndigits = ndigits;
 2942 andres                   8263 CBC        4215 :     var->weight = ndigits - 1;
                               8264                 : }
                               8265                 : #endif
                               8266                 : 
                               8267                 : /*
                               8268                 :  * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
                               8269                 :  */
                               8270                 : static double
 2037 andres                   8271 GIC        1616 : numericvar_to_double_no_overflow(const NumericVar *var)
                               8272                 : {
                               8273                 :     char       *tmp;
                               8274                 :     double      val;
                               8275                 :     char       *endptr;
 7494 tgl                      8276 ECB             : 
 3791 heikki.linnakangas       8277 GIC        1616 :     tmp = get_str_from_var(var);
                               8278                 : 
                               8279                 :     /* unlike float8in, we ignore ERANGE from strtod */
 7494 tgl                      8280            1616 :     val = strtod(tmp, &endptr);
 7494 tgl                      8281 CBC        1616 :     if (*endptr != '\0')
                               8282                 :     {
                               8283                 :         /* shouldn't happen ... */
 7196 tgl                      8284 UIC           0 :         ereport(ERROR,
                               8285                 :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                               8286                 :                  errmsg("invalid input syntax for type %s: \"%s\"",
                               8287                 :                         "double precision", tmp)));
                               8288                 :     }
 7494 tgl                      8289 ECB             : 
 7494 tgl                      8290 CBC        1616 :     pfree(tmp);
                               8291                 : 
 7494 tgl                      8292 GIC        1616 :     return val;
 7494 tgl                      8293 ECB             : }
                               8294                 : 
                               8295                 : 
 7324                          8296                 : /*
 8866 JanWieck                 8297                 :  * cmp_var() -
                               8298                 :  *
 7324 tgl                      8299                 :  *  Compare two values on variable level.  We assume zeroes have been
                               8300                 :  *  truncated to no digits.
                               8301                 :  */
                               8302                 : static int
 2037 andres                   8303 GIC        8383 : cmp_var(const NumericVar *var1, const NumericVar *var2)
                               8304                 : {
 6270 bruce                    8305           16766 :     return cmp_var_common(var1->digits, var1->ndigits,
                               8306            8383 :                           var1->weight, var1->sign,
                               8307            8383 :                           var2->digits, var2->ndigits,
                               8308            8383 :                           var2->weight, var2->sign);
                               8309                 : }
                               8310                 : 
                               8311                 : /*
                               8312                 :  * cmp_var_common() -
 6270 bruce                    8313 ECB             :  *
                               8314                 :  *  Main routine of cmp_var(). This function can be used by both
                               8315                 :  *  NumericVar and Numeric.
                               8316                 :  */
                               8317                 : static int
 6270 bruce                    8318 GIC     3222052 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
                               8319                 :                int var1weight, int var1sign,
                               8320                 :                const NumericDigit *var2digits, int var2ndigits,
                               8321                 :                int var2weight, int var2sign)
                               8322                 : {
                               8323         3222052 :     if (var1ndigits == 0)
 8866 JanWieck                 8324 ECB             :     {
 6270 bruce                    8325 CBC       97023 :         if (var2ndigits == 0)
 8866 JanWieck                 8326           82991 :             return 0;
 6270 bruce                    8327 GIC       14032 :         if (var2sign == NUMERIC_NEG)
 8866 JanWieck                 8328            2131 :             return 1;
 8866 JanWieck                 8329 CBC       11901 :         return -1;
 8866 JanWieck                 8330 ECB             :     }
 6270 bruce                    8331 CBC     3125029 :     if (var2ndigits == 0)
                               8332                 :     {
                               8333           15929 :         if (var1sign == NUMERIC_POS)
 8866 JanWieck                 8334           12455 :             return 1;
                               8335            3474 :         return -1;
                               8336                 :     }
                               8337                 : 
 6270 bruce                    8338 GIC     3109100 :     if (var1sign == NUMERIC_POS)
                               8339                 :     {
                               8340         3082035 :         if (var2sign == NUMERIC_NEG)
 8866 JanWieck                 8341            5575 :             return 1;
 6270 bruce                    8342 CBC     3076460 :         return cmp_abs_common(var1digits, var1ndigits, var1weight,
 6270 bruce                    8343 ECB             :                               var2digits, var2ndigits, var2weight);
                               8344                 :     }
                               8345                 : 
 6270 bruce                    8346 GIC       27065 :     if (var2sign == NUMERIC_POS)
 8866 JanWieck                 8347            6281 :         return -1;
                               8348                 : 
 6270 bruce                    8349           20784 :     return cmp_abs_common(var2digits, var2ndigits, var2weight,
 6270 bruce                    8350 ECB             :                           var1digits, var1ndigits, var1weight);
 8866 JanWieck                 8351                 : }
                               8352                 : 
                               8353                 : 
                               8354                 : /*
                               8355                 :  * add_var() -
                               8356                 :  *
                               8357                 :  *  Full version of add functionality on variable level (handling signs).
                               8358                 :  *  result might point to one of the operands too without danger.
                               8359                 :  */
                               8360                 : static void
 2037 andres                   8361 CBC      231922 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
                               8362                 : {
 8053 bruce                    8363 ECB             :     /*
                               8364                 :      * Decide on the signs of the two variables what to do
 8866 JanWieck                 8365                 :      */
 8866 JanWieck                 8366 CBC      231922 :     if (var1->sign == NUMERIC_POS)
                               8367                 :     {
 8866 JanWieck                 8368 GIC      231139 :         if (var2->sign == NUMERIC_POS)
                               8369                 :         {
                               8370                 :             /*
 8053 bruce                    8371 ECB             :              * Both are positive result = +(ABS(var1) + ABS(var2))
                               8372                 :              */
 8866 JanWieck                 8373 CBC      144592 :             add_abs(var1, var2, result);
 8866 JanWieck                 8374 GIC      144592 :             result->sign = NUMERIC_POS;
 8866 JanWieck                 8375 ECB             :         }
                               8376                 :         else
                               8377                 :         {
                               8378                 :             /*
 6385 bruce                    8379                 :              * var1 is positive, var2 is negative Must compare absolute values
                               8380                 :              */
 8866 JanWieck                 8381 CBC       86547 :             switch (cmp_abs(var1, var2))
                               8382                 :             {
 8301 tgl                      8383 GIC          16 :                 case 0:
                               8384                 :                     /* ----------
                               8385                 :                      * ABS(var1) == ABS(var2)
                               8386                 :                      * result = ZERO
                               8387                 :                      * ----------
 8301 tgl                      8388 ECB             :                      */
 8482 tgl                      8389 GIC          16 :                     zero_var(result);
 7720 bruce                    8390              16 :                     result->dscale = Max(var1->dscale, var2->dscale);
 8720                          8391              16 :                     break;
                               8392                 : 
 8301 tgl                      8393           86387 :                 case 1:
                               8394                 :                     /* ----------
                               8395                 :                      * ABS(var1) > ABS(var2)
 8301 tgl                      8396 ECB             :                      * result = +(ABS(var1) - ABS(var2))
                               8397                 :                      * ----------
                               8398                 :                      */
 8720 bruce                    8399 CBC       86387 :                     sub_abs(var1, var2, result);
                               8400           86387 :                     result->sign = NUMERIC_POS;
 8720 bruce                    8401 GIC       86387 :                     break;
                               8402                 : 
 8301 tgl                      8403             144 :                 case -1:
 8301 tgl                      8404 ECB             :                     /* ----------
                               8405                 :                      * ABS(var1) < ABS(var2)
                               8406                 :                      * result = -(ABS(var2) - ABS(var1))
                               8407                 :                      * ----------
                               8408                 :                      */
 8720 bruce                    8409 GIC         144 :                     sub_abs(var2, var1, result);
 8720 bruce                    8410 CBC         144 :                     result->sign = NUMERIC_NEG;
                               8411             144 :                     break;
 8866 JanWieck                 8412 ECB             :             }
                               8413                 :         }
                               8414                 :     }
                               8415                 :     else
                               8416                 :     {
 8866 JanWieck                 8417 GIC         783 :         if (var2->sign == NUMERIC_POS)
 8866 JanWieck                 8418 ECB             :         {
                               8419                 :             /* ----------
                               8420                 :              * var1 is negative, var2 is positive
                               8421                 :              * Must compare absolute values
                               8422                 :              * ----------
                               8423                 :              */
 8866 JanWieck                 8424 CBC         234 :             switch (cmp_abs(var1, var2))
 8866 JanWieck                 8425 ECB             :             {
 8301 tgl                      8426 CBC          15 :                 case 0:
                               8427                 :                     /* ----------
                               8428                 :                      * ABS(var1) == ABS(var2)
                               8429                 :                      * result = ZERO
                               8430                 :                      * ----------
                               8431                 :                      */
 8482 tgl                      8432 GIC          15 :                     zero_var(result);
 7720 bruce                    8433              15 :                     result->dscale = Max(var1->dscale, var2->dscale);
 8720                          8434              15 :                     break;
 8720 bruce                    8435 ECB             : 
 8301 tgl                      8436 GIC         147 :                 case 1:
                               8437                 :                     /* ----------
                               8438                 :                      * ABS(var1) > ABS(var2)
                               8439                 :                      * result = -(ABS(var1) - ABS(var2))
                               8440                 :                      * ----------
                               8441                 :                      */
 8720 bruce                    8442             147 :                     sub_abs(var1, var2, result);
                               8443             147 :                     result->sign = NUMERIC_NEG;
                               8444             147 :                     break;
 8720 bruce                    8445 ECB             : 
 8301 tgl                      8446 CBC          72 :                 case -1:
 8301 tgl                      8447 ECB             :                     /* ----------
                               8448                 :                      * ABS(var1) < ABS(var2)
                               8449                 :                      * result = +(ABS(var2) - ABS(var1))
                               8450                 :                      * ----------
                               8451                 :                      */
 8720 bruce                    8452 CBC          72 :                     sub_abs(var2, var1, result);
 8720 bruce                    8453 GIC          72 :                     result->sign = NUMERIC_POS;
 8720 bruce                    8454 CBC          72 :                     break;
 8866 JanWieck                 8455 ECB             :             }
                               8456                 :         }
                               8457                 :         else
                               8458                 :         {
                               8459                 :             /* ----------
                               8460                 :              * Both are negative
                               8461                 :              * result = -(ABS(var1) + ABS(var2))
                               8462                 :              * ----------
                               8463                 :              */
 8866 JanWieck                 8464 GIC         549 :             add_abs(var1, var2, result);
                               8465             549 :             result->sign = NUMERIC_NEG;
                               8466                 :         }
                               8467                 :     }
                               8468          231922 : }
                               8469                 : 
 8866 JanWieck                 8470 ECB             : 
 7324 tgl                      8471                 : /*
                               8472                 :  * sub_var() -
                               8473                 :  *
 8866 JanWieck                 8474                 :  *  Full version of sub functionality on variable level (handling signs).
                               8475                 :  *  result might point to one of the operands too without danger.
                               8476                 :  */
                               8477                 : static void
 2037 andres                   8478 CBC       57346 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
                               8479                 : {
 8053 bruce                    8480 EUB             :     /*
 8866 JanWieck                 8481                 :      * Decide on the signs of the two variables what to do
                               8482                 :      */
 8866 JanWieck                 8483 GIC       57346 :     if (var1->sign == NUMERIC_POS)
 8866 JanWieck                 8484 ECB             :     {
 8866 JanWieck                 8485 GIC       55961 :         if (var2->sign == NUMERIC_NEG)
 8866 JanWieck                 8486 ECB             :         {
                               8487                 :             /* ----------
                               8488                 :              * var1 is positive, var2 is negative
                               8489                 :              * result = +(ABS(var1) + ABS(var2))
                               8490                 :              * ----------
                               8491                 :              */
 8866 JanWieck                 8492 GIC        3026 :             add_abs(var1, var2, result);
                               8493            3026 :             result->sign = NUMERIC_POS;
 8866 JanWieck                 8494 ECB             :         }
                               8495                 :         else
                               8496                 :         {
                               8497                 :             /* ----------
                               8498                 :              * Both are positive
                               8499                 :              * Must compare absolute values
                               8500                 :              * ----------
                               8501                 :              */
 8866 JanWieck                 8502 GIC       52935 :             switch (cmp_abs(var1, var2))
                               8503                 :             {
 8301 tgl                      8504           14959 :                 case 0:
                               8505                 :                     /* ----------
                               8506                 :                      * ABS(var1) == ABS(var2)
                               8507                 :                      * result = ZERO
 8301 tgl                      8508 ECB             :                      * ----------
                               8509                 :                      */
 8482 tgl                      8510 GIC       14959 :                     zero_var(result);
 7720 bruce                    8511           14959 :                     result->dscale = Max(var1->dscale, var2->dscale);
 8720                          8512           14959 :                     break;
                               8513                 : 
 8301 tgl                      8514           37713 :                 case 1:
                               8515                 :                     /* ----------
                               8516                 :                      * ABS(var1) > ABS(var2)
                               8517                 :                      * result = +(ABS(var1) - ABS(var2))
                               8518                 :                      * ----------
                               8519                 :                      */
 8720 bruce                    8520 CBC       37713 :                     sub_abs(var1, var2, result);
                               8521           37713 :                     result->sign = NUMERIC_POS;
                               8522           37713 :                     break;
                               8523                 : 
 8301 tgl                      8524 GIC         263 :                 case -1:
 8301 tgl                      8525 ECB             :                     /* ----------
                               8526                 :                      * ABS(var1) < ABS(var2)
                               8527                 :                      * result = -(ABS(var2) - ABS(var1))
                               8528                 :                      * ----------
 8301 tgl                      8529 EUB             :                      */
 8720 bruce                    8530 GBC         263 :                     sub_abs(var2, var1, result);
                               8531             263 :                     result->sign = NUMERIC_NEG;
 8720 bruce                    8532 GIC         263 :                     break;
                               8533                 :             }
                               8534                 :         }
                               8535                 :     }
                               8536                 :     else
                               8537                 :     {
 8866 JanWieck                 8538 CBC        1385 :         if (var2->sign == NUMERIC_NEG)
 8866 JanWieck                 8539 ECB             :         {
                               8540                 :             /* ----------
                               8541                 :              * Both are negative
                               8542                 :              * Must compare absolute values
                               8543                 :              * ----------
                               8544                 :              */
 8866 JanWieck                 8545 CBC        1160 :             switch (cmp_abs(var1, var2))
                               8546                 :             {
 8301 tgl                      8547              83 :                 case 0:
 8301 tgl                      8548 ECB             :                     /* ----------
                               8549                 :                      * ABS(var1) == ABS(var2)
                               8550                 :                      * result = ZERO
                               8551                 :                      * ----------
                               8552                 :                      */
 8482 tgl                      8553 GIC          83 :                     zero_var(result);
 7720 bruce                    8554              83 :                     result->dscale = Max(var1->dscale, var2->dscale);
 8720                          8555              83 :                     break;
                               8556                 : 
 8301 tgl                      8557             117 :                 case 1:
                               8558                 :                     /* ----------
 8301 tgl                      8559 ECB             :                      * ABS(var1) > ABS(var2)
                               8560                 :                      * result = -(ABS(var1) - ABS(var2))
 8301 tgl                      8561 EUB             :                      * ----------
                               8562                 :                      */
 8720 bruce                    8563 GBC         117 :                     sub_abs(var1, var2, result);
                               8564             117 :                     result->sign = NUMERIC_NEG;
 8720 bruce                    8565 GIC         117 :                     break;
                               8566                 : 
 8301 tgl                      8567             960 :                 case -1:
                               8568                 :                     /* ----------
 8301 tgl                      8569 ECB             :                      * ABS(var1) < ABS(var2)
                               8570                 :                      * result = +(ABS(var2) - ABS(var1))
                               8571                 :                      * ----------
                               8572                 :                      */
 8720 bruce                    8573 GIC         960 :                     sub_abs(var2, var1, result);
                               8574             960 :                     result->sign = NUMERIC_POS;
                               8575             960 :                     break;
                               8576                 :             }
                               8577                 :         }
                               8578                 :         else
 8866 JanWieck                 8579 ECB             :         {
                               8580                 :             /* ----------
                               8581                 :              * var1 is negative, var2 is positive
                               8582                 :              * result = -(ABS(var1) + ABS(var2))
                               8583                 :              * ----------
                               8584                 :              */
 8866 JanWieck                 8585 GIC         225 :             add_abs(var1, var2, result);
                               8586             225 :             result->sign = NUMERIC_NEG;
 8866 JanWieck                 8587 ECB             :         }
                               8588                 :     }
 8866 JanWieck                 8589 GIC       57346 : }
 8866 JanWieck                 8590 EUB             : 
                               8591                 : 
                               8592                 : /*
                               8593                 :  * mul_var() -
                               8594                 :  *
 8866 JanWieck                 8595 ECB             :  *  Multiplication on variable level. Product of var1 * var2 is stored
 3260 bruce                    8596                 :  *  in result.  Result is rounded to no more than rscale fractional digits.
                               8597                 :  */
 8866 JanWieck                 8598                 : static void
 2037 andres                   8599 CBC      413936 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
                               8600                 :         int rscale)
 8866 JanWieck                 8601 ECB             : {
 8720 bruce                    8602                 :     int         res_ndigits;
                               8603                 :     int         res_sign;
                               8604                 :     int         res_weight;
 7324 tgl                      8605                 :     int         maxdigits;
                               8606                 :     int        *dig;
                               8607                 :     int         carry;
                               8608                 :     int         maxdig;
                               8609                 :     int         newdig;
 2703                          8610                 :     int         var1ndigits;
                               8611                 :     int         var2ndigits;
                               8612                 :     NumericDigit *var1digits;
                               8613                 :     NumericDigit *var2digits;
 7324                          8614                 :     NumericDigit *res_digits;
 8720 bruce                    8615                 :     int         i,
                               8616                 :                 i1,
                               8617                 :                 i2;
                               8618                 : 
                               8619                 :     /*
                               8620                 :      * Arrange for var1 to be the shorter of the two numbers.  This improves
                               8621                 :      * performance because the inner multiplication loop is much simpler than
                               8622                 :      * the outer loop, so it's better to have a smaller number of iterations
                               8623                 :      * of the outer loop.  This also reduces the number of times that the
                               8624                 :      * accumulator array needs to be normalized.
 2703 tgl                      8625                 :      */
 2703 tgl                      8626 GIC      413936 :     if (var1->ndigits > var2->ndigits)
                               8627                 :     {
 2037 andres                   8628            6599 :         const NumericVar *tmp = var1;
                               8629                 : 
 2703 tgl                      8630            6599 :         var1 = var2;
 2703 tgl                      8631 CBC        6599 :         var2 = tmp;
                               8632                 :     }
                               8633                 : 
 7324 tgl                      8634 ECB             :     /* copy these values into local vars for speed in inner loop */
 2703 tgl                      8635 CBC      413936 :     var1ndigits = var1->ndigits;
 2703 tgl                      8636 GIC      413936 :     var2ndigits = var2->ndigits;
                               8637          413936 :     var1digits = var1->digits;
 2703 tgl                      8638 GBC      413936 :     var2digits = var2->digits;
                               8639                 : 
 7324 tgl                      8640 GIC      413936 :     if (var1ndigits == 0 || var2ndigits == 0)
                               8641                 :     {
                               8642                 :         /* one or both inputs is zero; so is result */
                               8643             856 :         zero_var(result);
 7324 tgl                      8644 CBC         856 :         result->dscale = rscale;
 7324 tgl                      8645 GIC         856 :         return;
 7324 tgl                      8646 ECB             :     }
                               8647                 : 
                               8648                 :     /* Determine result sign and (maximum possible) weight */
 8866 JanWieck                 8649 GIC      413080 :     if (var1->sign == var2->sign)
                               8650          411815 :         res_sign = NUMERIC_POS;
                               8651                 :     else
                               8652            1265 :         res_sign = NUMERIC_NEG;
 7324 tgl                      8653          413080 :     res_weight = var1->weight + var2->weight + 2;
                               8654                 : 
                               8655                 :     /*
                               8656                 :      * Determine the number of result digits to compute.  If the exact result
 6385 bruce                    8657 ECB             :      * would have more than rscale fractional digits, truncate the computation
                               8658                 :      * with MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that
 2703 tgl                      8659                 :      * would only contribute to the right of that.  (This will give the exact
                               8660                 :      * rounded-to-rscale answer unless carries out of the ignored positions
                               8661                 :      * would have propagated through more than MUL_GUARD_DIGITS digits.)
                               8662                 :      *
                               8663                 :      * Note: an exact computation could not produce more than var1ndigits +
                               8664                 :      * var2ndigits digits, but we allocate one extra output digit in case
                               8665                 :      * rscale-driven rounding produces a carry out of the highest exact digit.
                               8666                 :      */
 7324 tgl                      8667 GIC      413080 :     res_ndigits = var1ndigits + var2ndigits + 1;
 2703                          8668          413080 :     maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
                               8669                 :         MUL_GUARD_DIGITS;
                               8670          413080 :     res_ndigits = Min(res_ndigits, maxdigits);
                               8671                 : 
 2703 tgl                      8672 CBC      413080 :     if (res_ndigits < 3)
                               8673                 :     {
                               8674                 :         /* All input digits will be ignored; so result is zero */
 2703 tgl                      8675 GIC           6 :         zero_var(result);
                               8676               6 :         result->dscale = rscale;
 2703 tgl                      8677 CBC           6 :         return;
                               8678                 :     }
 8866 JanWieck                 8679 ECB             : 
 7324 tgl                      8680                 :     /*
                               8681                 :      * We do the arithmetic in an array "dig[]" of signed int's.  Since
 6385 bruce                    8682                 :      * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
                               8683                 :      * to avoid normalizing carries immediately.
                               8684                 :      *
 7188                          8685                 :      * maxdig tracks the maximum possible value of any dig[] entry; when this
                               8686                 :      * threatens to exceed INT_MAX, we take the time to propagate carries.
 2757 tgl                      8687                 :      * Furthermore, we need to ensure that overflow doesn't occur during the
                               8688                 :      * carry propagation passes either.  The carry values could be as much as
                               8689                 :      * INT_MAX/NBASE, so really we must normalize when digits threaten to
                               8690                 :      * exceed INT_MAX - INT_MAX/NBASE.
                               8691                 :      *
                               8692                 :      * To avoid overflow in maxdig itself, it actually represents the max
                               8693                 :      * possible value divided by NBASE-1, ie, at the top of the loop it is
                               8694                 :      * known that no dig[] entry exceeds maxdig * (NBASE-1).
 7324                          8695                 :      */
 7324 tgl                      8696 CBC      413074 :     dig = (int *) palloc0(res_ndigits * sizeof(int));
 7324 tgl                      8697 GIC      413074 :     maxdig = 0;
                               8698                 : 
                               8699                 :     /*
 2703 tgl                      8700 ECB             :      * The least significant digits of var1 should be ignored if they don't
                               8701                 :      * contribute directly to the first res_ndigits digits of the result that
                               8702                 :      * we are computing.
                               8703                 :      *
                               8704                 :      * Digit i1 of var1 and digit i2 of var2 are multiplied and added to digit
                               8705                 :      * i1+i2+2 of the accumulator array, so we need only consider digits of
                               8706                 :      * var1 for which i1 <= res_ndigits - 3.
                               8707                 :      */
 2703 tgl                      8708 GIC     2314082 :     for (i1 = Min(var1ndigits - 1, res_ndigits - 3); i1 >= 0; i1--)
                               8709                 :     {
  406 dean.a.rasheed           8710         1901008 :         NumericDigit var1digit = var1digits[i1];
                               8711                 : 
 7324 tgl                      8712         1901008 :         if (var1digit == 0)
                               8713         1179720 :             continue;
                               8714                 : 
 7324 tgl                      8715 ECB             :         /* Time to normalize? */
 7324 tgl                      8716 GIC      721288 :         maxdig += var1digit;
 2757                          8717          721288 :         if (maxdig > (INT_MAX - INT_MAX / NBASE) / (NBASE - 1))
                               8718                 :         {
                               8719                 :             /* Yes, do it */
 7324 tgl                      8720 CBC        4572 :             carry = 0;
 7188 bruce                    8721 GIC    22905348 :             for (i = res_ndigits - 1; i >= 0; i--)
 7324 tgl                      8722 ECB             :             {
 7324 tgl                      8723 GIC    22900776 :                 newdig = dig[i] + carry;
                               8724        22900776 :                 if (newdig >= NBASE)
                               8725                 :                 {
 7188 bruce                    8726        11532801 :                     carry = newdig / NBASE;
 7188 bruce                    8727 CBC    11532801 :                     newdig -= carry * NBASE;
 7324 tgl                      8728 ECB             :                 }
                               8729                 :                 else
 7324 tgl                      8730 GIC    11367975 :                     carry = 0;
                               8731        22900776 :                 dig[i] = newdig;
                               8732                 :             }
                               8733            4572 :             Assert(carry == 0);
                               8734                 :             /* Reset maxdig to indicate new worst-case */
 7324 tgl                      8735 CBC        4572 :             maxdig = 1 + var1digit;
                               8736                 :         }
 7324 tgl                      8737 ECB             : 
                               8738                 :         /*
                               8739                 :          * Add the appropriate multiple of var2 into the accumulator.
                               8740                 :          *
                               8741                 :          * As above, digits of var2 can be ignored if they don't contribute,
                               8742                 :          * so we only include digits for which i1+i2+2 < res_ndigits.
  945                          8743                 :          *
                               8744                 :          * This inner loop is the performance bottleneck for multiplication,
                               8745                 :          * so we want to keep it simple enough so that it can be
                               8746                 :          * auto-vectorized.  Accordingly, process the digits left-to-right
                               8747                 :          * even though schoolbook multiplication would suggest right-to-left.
                               8748                 :          * Since we aren't propagating carries in this loop, the order does
                               8749                 :          * not matter.
                               8750                 :          */
                               8751                 :         {
  944 tgl                      8752 GIC      721288 :             int         i2limit = Min(var2ndigits, res_ndigits - i1 - 2);
  944 tgl                      8753 CBC      721288 :             int        *dig_i1_2 = &dig[i1 + 2];
  944 tgl                      8754 ECB             : 
  944 tgl                      8755 CBC   249555590 :             for (i2 = 0; i2 < i2limit; i2++)
  944 tgl                      8756 GIC   248834302 :                 dig_i1_2[i2] += var1digit * var2digits[i2];
  944 tgl                      8757 ECB             :         }
                               8758                 :     }
                               8759                 : 
                               8760                 :     /*
                               8761                 :      * Now we do a final carry propagation pass to normalize the result, which
                               8762                 :      * we combine with storing the result digits into the output. Note that
 6385 bruce                    8763                 :      * this is still done at full precision w/guard digits.
 7324 tgl                      8764                 :      */
 7324 tgl                      8765 CBC      413074 :     alloc_var(result, res_ndigits);
 7324 tgl                      8766 GIC      413074 :     res_digits = result->digits;
                               8767          413074 :     carry = 0;
 7188 bruce                    8768         5114614 :     for (i = res_ndigits - 1; i >= 0; i--)
                               8769                 :     {
 7324 tgl                      8770         4701540 :         newdig = dig[i] + carry;
 7324 tgl                      8771 CBC     4701540 :         if (newdig >= NBASE)
                               8772                 :         {
 7188 bruce                    8773 GIC      991510 :             carry = newdig / NBASE;
                               8774          991510 :             newdig -= carry * NBASE;
                               8775                 :         }
                               8776                 :         else
 7324 tgl                      8777         3710030 :             carry = 0;
 7324 tgl                      8778 CBC     4701540 :         res_digits[i] = newdig;
                               8779                 :     }
                               8780          413074 :     Assert(carry == 0);
                               8781                 : 
 7324 tgl                      8782 GIC      413074 :     pfree(dig);
                               8783                 : 
                               8784                 :     /*
                               8785                 :      * Finally, round the result to the requested precision.
 7324 tgl                      8786 ECB             :      */
 8720 bruce                    8787 CBC      413074 :     result->weight = res_weight;
                               8788          413074 :     result->sign = res_sign;
                               8789                 : 
 7324 tgl                      8790 ECB             :     /* Round to target rscale (and set result->dscale) */
 7324 tgl                      8791 GIC      413074 :     round_var(result, rscale);
                               8792                 : 
                               8793                 :     /* Strip leading and trailing zeroes */
                               8794          413074 :     strip_var(result);
                               8795                 : }
 8866 JanWieck                 8796 ECB             : 
                               8797                 : 
 7324 tgl                      8798                 : /*
                               8799                 :  * div_var() -
 8866 JanWieck                 8800                 :  *
                               8801                 :  *  Division on variable level. Quotient of var1 / var2 is stored in result.
                               8802                 :  *  The quotient is figured to exactly rscale fractional digits.
                               8803                 :  *  If round is true, it is rounded at the rscale'th digit; if false, it
                               8804                 :  *  is truncated (towards zero) at that digit.
                               8805                 :  */
                               8806                 : static void
 2037 andres                   8807 CBC       88565 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
 6518 bruce                    8808 ECB             :         int rscale, bool round)
                               8809                 : {
                               8810                 :     int         div_ndigits;
                               8811                 :     int         res_ndigits;
                               8812                 :     int         res_sign;
                               8813                 :     int         res_weight;
                               8814                 :     int         carry;
                               8815                 :     int         borrow;
                               8816                 :     int         divisor1;
                               8817                 :     int         divisor2;
 5483 tgl                      8818                 :     NumericDigit *dividend;
                               8819                 :     NumericDigit *divisor;
                               8820                 :     NumericDigit *res_digits;
                               8821                 :     int         i;
                               8822                 :     int         j;
                               8823                 : 
                               8824                 :     /* copy these values into local vars for speed in inner loop */
 5483 tgl                      8825 GIC       88565 :     int         var1ndigits = var1->ndigits;
                               8826           88565 :     int         var2ndigits = var2->ndigits;
                               8827                 : 
                               8828                 :     /*
                               8829                 :      * First of all division by zero check; we must not be handed an
                               8830                 :      * unnormalized divisor.
                               8831                 :      */
 5483 tgl                      8832 CBC       88565 :     if (var2ndigits == 0 || var2->digits[0] == 0)
 5483 tgl                      8833 GIC          28 :         ereport(ERROR,
                               8834                 :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
                               8835                 :                  errmsg("division by zero")));
                               8836                 : 
 5483 tgl                      8837 ECB             :     /*
                               8838                 :      * If the divisor has just one or two digits, delegate to div_var_int(),
  406 dean.a.rasheed           8839                 :      * which uses fast short division.
                               8840                 :      *
                               8841                 :      * Similarly, on platforms with 128-bit integer support, delegate to
                               8842                 :      * div_var_int64() for divisors with three or four digits.
                               8843                 :      */
  406 dean.a.rasheed           8844 GIC       88537 :     if (var2ndigits <= 2)
                               8845                 :     {
                               8846                 :         int         idivisor;
                               8847                 :         int         idivisor_weight;
                               8848                 : 
  406 dean.a.rasheed           8849 CBC       86823 :         idivisor = var2->digits[0];
                               8850           86823 :         idivisor_weight = var2->weight;
  406 dean.a.rasheed           8851 GIC       86823 :         if (var2ndigits == 2)
                               8852                 :         {
                               8853            1545 :             idivisor = idivisor * NBASE + var2->digits[1];
                               8854            1545 :             idivisor_weight--;
                               8855                 :         }
                               8856           86823 :         if (var2->sign == NUMERIC_NEG)
                               8857             243 :             idivisor = -idivisor;
                               8858                 : 
  406 dean.a.rasheed           8859 CBC       86823 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
  406 dean.a.rasheed           8860 GIC       86823 :         return;
  406 dean.a.rasheed           8861 ECB             :     }
                               8862                 : #ifdef HAVE_INT128
   76 dean.a.rasheed           8863 GNC        1714 :     if (var2ndigits <= 4)
                               8864                 :     {
                               8865                 :         int64       idivisor;
                               8866                 :         int         idivisor_weight;
                               8867                 : 
                               8868             243 :         idivisor = var2->digits[0];
                               8869             243 :         idivisor_weight = var2->weight;
                               8870             912 :         for (i = 1; i < var2ndigits; i++)
                               8871                 :         {
                               8872             669 :             idivisor = idivisor * NBASE + var2->digits[i];
                               8873             669 :             idivisor_weight--;
                               8874                 :         }
                               8875             243 :         if (var2->sign == NUMERIC_NEG)
                               8876              60 :             idivisor = -idivisor;
                               8877                 : 
                               8878             243 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
                               8879             243 :         return;
                               8880                 :     }
                               8881                 : #endif
                               8882                 : 
                               8883                 :     /*
                               8884                 :      * Otherwise, perform full long division.
                               8885                 :      */
                               8886                 : 
  406 dean.a.rasheed           8887 ECB             :     /* Result zero check */
 5483 tgl                      8888 CBC        1471 :     if (var1ndigits == 0)
 5483 tgl                      8889 ECB             :     {
 5483 tgl                      8890 GIC          12 :         zero_var(result);
 5483 tgl                      8891 CBC          12 :         result->dscale = rscale;
 5483 tgl                      8892 GIC          12 :         return;
                               8893                 :     }
                               8894                 : 
                               8895                 :     /*
                               8896                 :      * Determine the result sign, weight and number of digits to calculate.
 5483 tgl                      8897 ECB             :      * The weight figured here is correct if the emitted quotient has no
                               8898                 :      * leading zero digits; otherwise strip_var() will fix things up.
                               8899                 :      */
 5483 tgl                      8900 GIC        1459 :     if (var1->sign == var2->sign)
 5483 tgl                      8901 CBC        1429 :         res_sign = NUMERIC_POS;
                               8902                 :     else
 5483 tgl                      8903 GIC          30 :         res_sign = NUMERIC_NEG;
                               8904            1459 :     res_weight = var1->weight - var2->weight;
                               8905                 :     /* The number of accurate result digits we need to produce: */
                               8906            1459 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
 5483 tgl                      8907 ECB             :     /* ... but always at least 1 */
 5483 tgl                      8908 CBC        1459 :     res_ndigits = Max(res_ndigits, 1);
 5483 tgl                      8909 ECB             :     /* If rounding needed, figure one more digit to ensure correct result */
 5483 tgl                      8910 GIC        1459 :     if (round)
                               8911            1459 :         res_ndigits++;
                               8912                 : 
                               8913                 :     /*
                               8914                 :      * The working dividend normally requires res_ndigits + var2ndigits
 5483 tgl                      8915 ECB             :      * digits, but make it at least var1ndigits so we can load all of var1
                               8916                 :      * into it.  (There will be an additional digit dividend[0] in the
                               8917                 :      * dividend space, but for consistency with Knuth's notation we don't
                               8918                 :      * count that in div_ndigits.)
                               8919                 :      */
 5483 tgl                      8920 GIC        1459 :     div_ndigits = res_ndigits + var2ndigits;
                               8921            1459 :     div_ndigits = Max(div_ndigits, var1ndigits);
 5483 tgl                      8922 ECB             : 
                               8923                 :     /*
                               8924                 :      * We need a workspace with room for the working dividend (div_ndigits+1
                               8925                 :      * digits) plus room for the possibly-normalized divisor (var2ndigits
                               8926                 :      * digits).  It is convenient also to have a zero at divisor[0] with the
                               8927                 :      * actual divisor data in divisor[1 .. var2ndigits].  Transferring the
                               8928                 :      * digits into the workspace also allows us to realloc the result (which
                               8929                 :      * might be the same as either input var) before we begin the main loop.
                               8930                 :      * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
                               8931                 :      * any additional dividend positions beyond var1ndigits, start out 0.
                               8932                 :      */
                               8933                 :     dividend = (NumericDigit *)
 5483 tgl                      8934 CBC        1459 :         palloc0((div_ndigits + var2ndigits + 2) * sizeof(NumericDigit));
 5483 tgl                      8935 GIC        1459 :     divisor = dividend + (div_ndigits + 1);
                               8936            1459 :     memcpy(dividend + 1, var1->digits, var1ndigits * sizeof(NumericDigit));
                               8937            1459 :     memcpy(divisor + 1, var2->digits, var2ndigits * sizeof(NumericDigit));
                               8938                 : 
                               8939                 :     /*
 5483 tgl                      8940 ECB             :      * Now we can realloc the result to hold the generated quotient digits.
                               8941                 :      */
 5483 tgl                      8942 CBC        1459 :     alloc_var(result, res_ndigits);
 5483 tgl                      8943 GIC        1459 :     res_digits = result->digits;
 5483 tgl                      8944 ECB             : 
                               8945                 :     /*
                               8946                 :      * The full multiple-place algorithm is taken from Knuth volume 2,
                               8947                 :      * Algorithm 4.3.1D.
                               8948                 :      *
                               8949                 :      * We need the first divisor digit to be >= NBASE/2.  If it isn't, make it
  332                          8950                 :      * so by scaling up both the divisor and dividend by the factor "d".  (The
                               8951                 :      * reason for allocating dividend[0] above is to leave room for possible
                               8952                 :      * carry here.)
                               8953                 :      */
  332 tgl                      8954 GIC        1459 :     if (divisor[1] < HALF_NBASE)
                               8955                 :     {
                               8956            1459 :         int         d = NBASE / (divisor[1] + 1);
                               8957                 : 
                               8958            1459 :         carry = 0;
                               8959           12548 :         for (i = var2ndigits; i > 0; i--)
                               8960                 :         {
                               8961           11089 :             carry += divisor[i] * d;
  332 tgl                      8962 CBC       11089 :             divisor[i] = carry % NBASE;
                               8963           11089 :             carry = carry / NBASE;
                               8964                 :         }
  332 tgl                      8965 GIC        1459 :         Assert(carry == 0);
  332 tgl                      8966 CBC        1459 :         carry = 0;
                               8967                 :         /* at this point only var1ndigits of dividend can be nonzero */
  332 tgl                      8968 GIC       12994 :         for (i = var1ndigits; i >= 0; i--)
                               8969                 :         {
                               8970           11535 :             carry += dividend[i] * d;
                               8971           11535 :             dividend[i] = carry % NBASE;
                               8972           11535 :             carry = carry / NBASE;
                               8973                 :         }
                               8974            1459 :         Assert(carry == 0);
                               8975            1459 :         Assert(divisor[1] >= HALF_NBASE);
  332 tgl                      8976 ECB             :     }
                               8977                 :     /* First 2 divisor digits are used repeatedly in main loop */
  332 tgl                      8978 GIC        1459 :     divisor1 = divisor[1];
                               8979            1459 :     divisor2 = divisor[2];
                               8980                 : 
                               8981                 :     /*
                               8982                 :      * Begin the main loop.  Each iteration of this loop produces the j'th
                               8983                 :      * quotient digit by dividing dividend[j .. j + var2ndigits] by the
                               8984                 :      * divisor; this is essentially the same as the common manual procedure
                               8985                 :      * for long division.
                               8986                 :      */
                               8987           11521 :     for (j = 0; j < res_ndigits; j++)
                               8988                 :     {
                               8989                 :         /* Estimate quotient digit from the first two dividend digits */
                               8990           10062 :         int         next2digits = dividend[j] * NBASE + dividend[j + 1];
                               8991                 :         int         qhat;
                               8992                 : 
                               8993                 :         /*
                               8994                 :          * If next2digits are 0, then quotient digit must be 0 and there's no
                               8995                 :          * need to adjust the working dividend.  It's worth testing here to
                               8996                 :          * fall out ASAP when processing trailing zeroes in a dividend.
                               8997                 :          */
                               8998           10062 :         if (next2digits == 0)
                               8999                 :         {
                               9000              36 :             res_digits[j] = 0;
                               9001              36 :             continue;
                               9002                 :         }
  332 tgl                      9003 ECB             : 
  332 tgl                      9004 GIC       10026 :         if (dividend[j] == divisor1)
  332 tgl                      9005 CBC          60 :             qhat = NBASE - 1;
                               9006                 :         else
                               9007            9966 :             qhat = next2digits / divisor1;
 5483 tgl                      9008 ECB             : 
                               9009                 :         /*
                               9010                 :          * Adjust quotient digit if it's too large.  Knuth proves that after
                               9011                 :          * this step, the quotient digit will be either correct or just one
  332                          9012                 :          * too large.  (Note: it's OK to use dividend[j+2] here because we
                               9013                 :          * know the divisor length is at least 2.)
 5483                          9014                 :          */
  332 tgl                      9015 CBC       10026 :         while (divisor2 * qhat >
  332 tgl                      9016 GIC       11672 :                (next2digits - qhat * divisor1) * NBASE + dividend[j + 2])
  332 tgl                      9017 CBC        1646 :             qhat--;
                               9018                 : 
                               9019                 :         /* As above, need do nothing more when quotient digit is 0 */
                               9020           10026 :         if (qhat > 0)
 5483 tgl                      9021 ECB             :         {
  332 tgl                      9022 CBC        8818 :             NumericDigit *dividend_j = &dividend[j];
                               9023                 : 
                               9024                 :             /*
                               9025                 :              * Multiply the divisor by qhat, and subtract that from the
  332 tgl                      9026 ECB             :              * working dividend.  The multiplication and subtraction are
                               9027                 :              * folded together here, noting that qhat <= NBASE (since it might
                               9028                 :              * be one too large), and so the intermediate result "tmp_result"
                               9029                 :              * is in the range [-NBASE^2, NBASE - 1], and "borrow" is in the
                               9030                 :              * range [0, NBASE].
                               9031                 :              */
  332 tgl                      9032 GIC        8818 :             borrow = 0;
                               9033           87086 :             for (i = var2ndigits; i >= 0; i--)
                               9034                 :             {
                               9035                 :                 int         tmp_result;
                               9036                 : 
                               9037           78268 :                 tmp_result = dividend_j[i] - borrow - divisor[i] * qhat;
                               9038           78268 :                 borrow = (NBASE - 1 - tmp_result) / NBASE;
                               9039           78268 :                 dividend_j[i] = tmp_result + borrow * NBASE;
                               9040                 :             }
                               9041                 : 
                               9042                 :             /*
                               9043                 :              * If we got a borrow out of the top dividend digit, then indeed
  332 tgl                      9044 ECB             :              * qhat was one too large.  Fix it, and add back the divisor to
                               9045                 :              * correct the working dividend.  (Knuth proves that this will
                               9046                 :              * occur only about 3/NBASE of the time; hence, it's a good idea
                               9047                 :              * to test this code with small NBASE to be sure this section gets
                               9048                 :              * exercised.)
 5483                          9049                 :              */
  332 tgl                      9050 GIC        8818 :             if (borrow)
                               9051                 :             {
  332 tgl                      9052 CBC          13 :                 qhat--;
                               9053              13 :                 carry = 0;
 5483                          9054            1154 :                 for (i = var2ndigits; i >= 0; i--)
                               9055                 :                 {
  332 tgl                      9056 GIC        1141 :                     carry += dividend_j[i] + divisor[i];
                               9057            1141 :                     if (carry >= NBASE)
                               9058                 :                     {
                               9059            1047 :                         dividend_j[i] = carry - NBASE;
                               9060            1047 :                         carry = 1;
                               9061                 :                     }
                               9062                 :                     else
                               9063                 :                     {
                               9064              94 :                         dividend_j[i] = carry;
                               9065              94 :                         carry = 0;
                               9066                 :                     }
                               9067                 :                 }
                               9068                 :                 /* A carry should occur here to cancel the borrow above */
                               9069              13 :                 Assert(carry == 1);
                               9070                 :             }
                               9071                 :         }
                               9072                 : 
  332 tgl                      9073 ECB             :         /* And we're done with this quotient digit */
  332 tgl                      9074 CBC       10026 :         res_digits[j] = qhat;
                               9075                 :     }
                               9076                 : 
 5483 tgl                      9077 GIC        1459 :     pfree(dividend);
                               9078                 : 
                               9079                 :     /*
                               9080                 :      * Finally, round or truncate the result to the requested precision.
                               9081                 :      */
                               9082            1459 :     result->weight = res_weight;
                               9083            1459 :     result->sign = res_sign;
                               9084                 : 
 5483 tgl                      9085 ECB             :     /* Round or truncate to target rscale (and set result->dscale) */
 5483 tgl                      9086 GIC        1459 :     if (round)
 5483 tgl                      9087 CBC        1459 :         round_var(result, rscale);
                               9088                 :     else
 5483 tgl                      9089 LBC           0 :         trunc_var(result, rscale);
 5483 tgl                      9090 ECB             : 
                               9091                 :     /* Strip leading and trailing zeroes */
 5483 tgl                      9092 GIC        1459 :     strip_var(result);
 5483 tgl                      9093 ECB             : }
                               9094                 : 
                               9095                 : 
                               9096                 : /*
                               9097                 :  * div_var_fast() -
                               9098                 :  *
                               9099                 :  *  This has the same API as div_var, but is implemented using the division
                               9100                 :  *  algorithm from the "FM" library, rather than Knuth's schoolbook-division
                               9101                 :  *  approach.  This is significantly faster but can produce inaccurate
                               9102                 :  *  results, because it sometimes has to propagate rounding to the left,
                               9103                 :  *  and so we can never be entirely sure that we know the requested digits
                               9104                 :  *  exactly.  We compute DIV_GUARD_DIGITS extra digits, but there is
                               9105                 :  *  no certainty that that's enough.  We use this only in the transcendental
                               9106                 :  *  function calculation routines, where everything is approximate anyway.
 2692                          9107                 :  *
                               9108                 :  *  Although we provide a "round" argument for consistency with div_var,
                               9109                 :  *  it is unwise to use this function with round=false.  In truncation mode
                               9110                 :  *  it is possible to get a result with no significant digits, for example
                               9111                 :  *  with rscale=0 we might compute 0.99999... and truncate that to 0 when
                               9112                 :  *  the correct answer is 1.
                               9113                 :  */
                               9114                 : static void
 2037 andres                   9115 GIC        2901 : div_var_fast(const NumericVar *var1, const NumericVar *var2,
                               9116                 :              NumericVar *result, int rscale, bool round)
                               9117                 : {
                               9118                 :     int         div_ndigits;
                               9119                 :     int         load_ndigits;
                               9120                 :     int         res_sign;
                               9121                 :     int         res_weight;
                               9122                 :     int        *div;
                               9123                 :     int         qdigit;
                               9124                 :     int         carry;
                               9125                 :     int         maxdiv;
                               9126                 :     int         newdig;
                               9127                 :     NumericDigit *res_digits;
                               9128                 :     double      fdividend,
 7324 tgl                      9129 ECB             :                 fdivisor,
                               9130                 :                 fdivisorinverse,
                               9131                 :                 fquotient;
                               9132                 :     int         qi;
 8720 bruce                    9133                 :     int         i;
                               9134                 : 
                               9135                 :     /* copy these values into local vars for speed in inner loop */
 7324 tgl                      9136 GIC        2901 :     int         var1ndigits = var1->ndigits;
                               9137            2901 :     int         var2ndigits = var2->ndigits;
                               9138            2901 :     NumericDigit *var1digits = var1->digits;
                               9139            2901 :     NumericDigit *var2digits = var2->digits;
                               9140                 : 
                               9141                 :     /*
 7324 tgl                      9142 ECB             :      * First of all division by zero check; we must not be handed an
                               9143                 :      * unnormalized divisor.
 8866 JanWieck                 9144                 :      */
 7324 tgl                      9145 CBC        2901 :     if (var2ndigits == 0 || var2digits[0] == 0)
 7196 tgl                      9146 GIC           3 :         ereport(ERROR,
 7196 tgl                      9147 ECB             :                 (errcode(ERRCODE_DIVISION_BY_ZERO),
                               9148                 :                  errmsg("division by zero")));
                               9149                 : 
 8053 bruce                    9150                 :     /*
  406 dean.a.rasheed           9151                 :      * If the divisor has just one or two digits, delegate to div_var_int(),
                               9152                 :      * which uses fast short division.
                               9153                 :      *
                               9154                 :      * Similarly, on platforms with 128-bit integer support, delegate to
                               9155                 :      * div_var_int64() for divisors with three or four digits.
                               9156                 :      */
  406 dean.a.rasheed           9157 CBC        2898 :     if (var2ndigits <= 2)
  406 dean.a.rasheed           9158 ECB             :     {
                               9159                 :         int         idivisor;
                               9160                 :         int         idivisor_weight;
                               9161                 : 
  406 dean.a.rasheed           9162 CBC         207 :         idivisor = var2->digits[0];
  406 dean.a.rasheed           9163 GIC         207 :         idivisor_weight = var2->weight;
                               9164             207 :         if (var2ndigits == 2)
                               9165                 :         {
  406 dean.a.rasheed           9166 UIC           0 :             idivisor = idivisor * NBASE + var2->digits[1];
  406 dean.a.rasheed           9167 LBC           0 :             idivisor_weight--;
  406 dean.a.rasheed           9168 ECB             :         }
  406 dean.a.rasheed           9169 GIC         207 :         if (var2->sign == NUMERIC_NEG)
  406 dean.a.rasheed           9170 UIC           0 :             idivisor = -idivisor;
  406 dean.a.rasheed           9171 ECB             : 
  406 dean.a.rasheed           9172 GIC         207 :         div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
                               9173             207 :         return;
  406 dean.a.rasheed           9174 ECB             :     }
                               9175                 : #ifdef HAVE_INT128
   76 dean.a.rasheed           9176 GNC        2691 :     if (var2ndigits <= 4)
                               9177                 :     {
                               9178                 :         int64       idivisor;
                               9179                 :         int         idivisor_weight;
                               9180                 : 
                               9181              21 :         idivisor = var2->digits[0];
                               9182              21 :         idivisor_weight = var2->weight;
                               9183              75 :         for (i = 1; i < var2ndigits; i++)
                               9184                 :         {
                               9185              54 :             idivisor = idivisor * NBASE + var2->digits[i];
                               9186              54 :             idivisor_weight--;
                               9187                 :         }
                               9188              21 :         if (var2->sign == NUMERIC_NEG)
   76 dean.a.rasheed           9189 UNC           0 :             idivisor = -idivisor;
                               9190                 : 
   76 dean.a.rasheed           9191 GNC          21 :         div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
                               9192              21 :         return;
                               9193                 :     }
                               9194                 : #endif
                               9195                 : 
                               9196                 :     /*
                               9197                 :      * Otherwise, perform full long division.
                               9198                 :      */
                               9199                 : 
                               9200                 :     /* Result zero check */
 7324 tgl                      9201 GIC        2670 :     if (var1ndigits == 0)
                               9202                 :     {
 8482                          9203               6 :         zero_var(result);
 7324                          9204               6 :         result->dscale = rscale;
 8866 JanWieck                 9205               6 :         return;
                               9206                 :     }
 8866 JanWieck                 9207 ECB             : 
                               9208                 :     /*
                               9209                 :      * Determine the result sign, weight and number of digits to calculate
                               9210                 :      */
 7324 tgl                      9211 GIC        2664 :     if (var1->sign == var2->sign)
                               9212            2628 :         res_sign = NUMERIC_POS;
                               9213                 :     else
                               9214              36 :         res_sign = NUMERIC_NEG;
                               9215            2664 :     res_weight = var1->weight - var2->weight + 1;
                               9216                 :     /* The number of accurate result digits we need to produce: */
 7188 bruce                    9217            2664 :     div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
                               9218                 :     /* Add guard digits for roundoff error */
 7324 tgl                      9219            2664 :     div_ndigits += DIV_GUARD_DIGITS;
                               9220            2664 :     if (div_ndigits < DIV_GUARD_DIGITS)
 7324 tgl                      9221 UIC           0 :         div_ndigits = DIV_GUARD_DIGITS;
                               9222                 : 
                               9223                 :     /*
                               9224                 :      * We do the arithmetic in an array "div[]" of signed int's.  Since
 6385 bruce                    9225 ECB             :      * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
                               9226                 :      * to avoid normalizing carries immediately.
                               9227                 :      *
                               9228                 :      * We start with div[] containing one zero digit followed by the
                               9229                 :      * dividend's digits (plus appended zeroes to reach the desired precision
                               9230                 :      * including guard digits).  Each step of the main loop computes an
                               9231                 :      * (approximate) quotient digit and stores it into div[], removing one
 3260                          9232                 :      * position of dividend space.  A final pass of carry propagation takes
 6347                          9233                 :      * care of any mistaken quotient digits.
                               9234                 :      *
                               9235                 :      * Note that div[] doesn't necessarily contain all of the digits from the
                               9236                 :      * dividend --- the desired precision plus guard digits might be less than
                               9237                 :      * the dividend's precision.  This happens, for example, in the square
                               9238                 :      * root algorithm, where we typically divide a 2N-digit number by an
                               9239                 :      * N-digit number, and only require a result with N digits of precision.
                               9240                 :      */
 7324 tgl                      9241 GIC        2664 :     div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
 1107 dean.a.rasheed           9242            2664 :     load_ndigits = Min(div_ndigits, var1ndigits);
                               9243           36354 :     for (i = 0; i < load_ndigits; i++)
 7188 bruce                    9244 CBC       33690 :         div[i + 1] = var1digits[i];
                               9245                 : 
                               9246                 :     /*
                               9247                 :      * We estimate each quotient digit using floating-point arithmetic, taking
                               9248                 :      * the first four digits of the (current) dividend and divisor.  This must
 2692 tgl                      9249 ECB             :      * be float to avoid overflow.  The quotient digits will generally be off
                               9250                 :      * by no more than one from the exact answer.
 8866 JanWieck                 9251                 :      */
 7324 tgl                      9252 GIC        2664 :     fdivisor = (double) var2digits[0];
 7324 tgl                      9253 CBC       10656 :     for (i = 1; i < 4; i++)
 7324 tgl                      9254 ECB             :     {
 7324 tgl                      9255 GIC        7992 :         fdivisor *= NBASE;
 7324 tgl                      9256 CBC        7992 :         if (i < var2ndigits)
                               9257            7992 :             fdivisor += (double) var2digits[i];
                               9258                 :     }
                               9259            2664 :     fdivisorinverse = 1.0 / fdivisor;
 8866 JanWieck                 9260 ECB             : 
                               9261                 :     /*
                               9262                 :      * maxdiv tracks the maximum possible absolute value of any div[] entry;
 6385 bruce                    9263                 :      * when this threatens to exceed INT_MAX, we take the time to propagate
                               9264                 :      * carries.  Furthermore, we need to ensure that overflow doesn't occur
                               9265                 :      * during the carry propagation passes either.  The carry values may have
                               9266                 :      * an absolute value as high as INT_MAX/NBASE + 1, so really we must
                               9267                 :      * normalize when digits threaten to exceed INT_MAX - INT_MAX/NBASE - 1.
 2700 tgl                      9268                 :      *
                               9269                 :      * To avoid overflow in maxdiv itself, it represents the max absolute
                               9270                 :      * value divided by NBASE-1, ie, at the top of the loop it is known that
                               9271                 :      * no div[] entry has an absolute value exceeding maxdiv * (NBASE-1).
 2692                          9272                 :      *
                               9273                 :      * Actually, though, that holds good only for div[] entries after div[qi];
                               9274                 :      * the adjustment done at the bottom of the loop may cause div[qi + 1] to
                               9275                 :      * exceed the maxdiv limit, so that div[qi] in the next iteration is
                               9276                 :      * beyond the limit.  This does not cause problems, as explained below.
                               9277                 :      */
 7324 tgl                      9278 CBC        2664 :     maxdiv = 1;
 8720 bruce                    9279 ECB             : 
                               9280                 :     /*
                               9281                 :      * Outer loop computes next quotient digit, which will go into div[qi]
                               9282                 :      */
 7324 tgl                      9283 GIC       45144 :     for (qi = 0; qi < div_ndigits; qi++)
                               9284                 :     {
                               9285                 :         /* Approximate the current dividend value */
                               9286           42480 :         fdividend = (double) div[qi];
                               9287          169920 :         for (i = 1; i < 4; i++)
 7324 tgl                      9288 ECB             :         {
 7324 tgl                      9289 GIC      127440 :             fdividend *= NBASE;
 7188 bruce                    9290 CBC      127440 :             if (qi + i <= div_ndigits)
                               9291          119448 :                 fdividend += (double) div[qi + i];
 7324 tgl                      9292 ECB             :         }
                               9293                 :         /* Compute the (approximate) quotient digit */
 7324 tgl                      9294 GIC       42480 :         fquotient = fdividend * fdivisorinverse;
                               9295           42480 :         qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
 7188 bruce                    9296               3 :             (((int) fquotient) - 1);    /* truncate towards -infinity */
                               9297                 : 
 7324 tgl                      9298           42480 :         if (qdigit != 0)
                               9299                 :         {
 7324 tgl                      9300 ECB             :             /* Do we need to normalize now? */
  184 peter                    9301 GNC       37983 :             maxdiv += abs(qdigit);
 2700 tgl                      9302 GIC       37983 :             if (maxdiv > (INT_MAX - INT_MAX / NBASE - 1) / (NBASE - 1))
 8866 JanWieck                 9303 ECB             :             {
 1107 dean.a.rasheed           9304                 :                 /*
                               9305                 :                  * Yes, do it.  Note that if var2ndigits is much smaller than
                               9306                 :                  * div_ndigits, we can save a significant amount of effort
                               9307                 :                  * here by noting that we only need to normalise those div[]
                               9308                 :                  * entries touched where prior iterations subtracted multiples
                               9309                 :                  * of the divisor.
                               9310                 :                  */
 7324 tgl                      9311 CBC          48 :                 carry = 0;
 1107 dean.a.rasheed           9312 GIC         948 :                 for (i = Min(qi + var2ndigits - 2, div_ndigits); i > qi; i--)
                               9313                 :                 {
 7324 tgl                      9314             900 :                     newdig = div[i] + carry;
                               9315             900 :                     if (newdig < 0)
                               9316                 :                     {
 7188 bruce                    9317             900 :                         carry = -((-newdig - 1) / NBASE) - 1;
                               9318             900 :                         newdig -= carry * NBASE;
                               9319                 :                     }
 7324 tgl                      9320 LBC           0 :                     else if (newdig >= NBASE)
 7324 tgl                      9321 ECB             :                     {
 7188 bruce                    9322 UIC           0 :                         carry = newdig / NBASE;
                               9323               0 :                         newdig -= carry * NBASE;
                               9324                 :                     }
                               9325                 :                     else
 7324 tgl                      9326               0 :                         carry = 0;
 7324 tgl                      9327 GIC         900 :                     div[i] = newdig;
                               9328                 :                 }
                               9329              48 :                 newdig = div[qi] + carry;
                               9330              48 :                 div[qi] = newdig;
                               9331                 : 
                               9332                 :                 /*
                               9333                 :                  * All the div[] digits except possibly div[qi] are now in the
 2692 tgl                      9334 ECB             :                  * range 0..NBASE-1.  We do not need to consider div[qi] in
                               9335                 :                  * the maxdiv value anymore, so we can reset maxdiv to 1.
 7324                          9336                 :                  */
 2692 tgl                      9337 CBC          48 :                 maxdiv = 1;
                               9338                 : 
                               9339                 :                 /*
                               9340                 :                  * Recompute the quotient digit since new info may have
                               9341                 :                  * propagated into the top four dividend digits
 7324 tgl                      9342 ECB             :                  */
 7324 tgl                      9343 CBC          48 :                 fdividend = (double) div[qi];
 7324 tgl                      9344 GIC         192 :                 for (i = 1; i < 4; i++)
                               9345                 :                 {
                               9346             144 :                     fdividend *= NBASE;
 7188 bruce                    9347             144 :                     if (qi + i <= div_ndigits)
                               9348             144 :                         fdividend += (double) div[qi + i];
                               9349                 :                 }
                               9350                 :                 /* Compute the (approximate) quotient digit */
 7324 tgl                      9351              48 :                 fquotient = fdividend * fdivisorinverse;
                               9352              48 :                 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
 6385 bruce                    9353 UIC           0 :                     (((int) fquotient) - 1);    /* truncate towards -infinity */
  184 peter                    9354 GNC          48 :                 maxdiv += abs(qdigit);
                               9355                 :             }
 8866 JanWieck                 9356 ECB             : 
                               9357                 :             /*
 2692 tgl                      9358                 :              * Subtract off the appropriate multiple of the divisor.
                               9359                 :              *
                               9360                 :              * The digits beyond div[qi] cannot overflow, because we know they
                               9361                 :              * will fall within the maxdiv limit.  As for div[qi] itself, note
                               9362                 :              * that qdigit is approximately trunc(div[qi] / vardigits[0]),
                               9363                 :              * which would make the new value simply div[qi] mod vardigits[0].
                               9364                 :              * The lower-order terms in qdigit can change this result by not
                               9365                 :              * more than about twice INT_MAX/NBASE, so overflow is impossible.
  406 dean.a.rasheed           9366                 :              *
                               9367                 :              * This inner loop is the performance bottleneck for division, so
                               9368                 :              * code it in the same way as the inner loop of mul_var() so that
                               9369                 :              * it can be auto-vectorized.  We cast qdigit to NumericDigit
                               9370                 :              * before multiplying to allow the compiler to generate more
                               9371                 :              * efficient code (using 16-bit multiplication), which is safe
                               9372                 :              * since we know that the quotient digit is off by at most one, so
                               9373                 :              * there is no overflow risk.
 2692 tgl                      9374                 :              */
 7324 tgl                      9375 CBC       37983 :             if (qdigit != 0)
                               9376                 :             {
 7188 bruce                    9377 GIC       37983 :                 int         istop = Min(var2ndigits, div_ndigits - qi + 1);
  406 dean.a.rasheed           9378 CBC       37983 :                 int        *div_qi = &div[qi];
 8866 JanWieck                 9379 ECB             : 
 7324 tgl                      9380 GIC      465018 :                 for (i = 0; i < istop; i++)
  406 dean.a.rasheed           9381          427035 :                     div_qi[i] -= ((NumericDigit) qdigit) * var2digits[i];
                               9382                 :             }
                               9383                 :         }
                               9384                 : 
                               9385                 :         /*
                               9386                 :          * The dividend digit we are about to replace might still be nonzero.
 2692 tgl                      9387 ECB             :          * Fold it into the next digit position.
                               9388                 :          *
                               9389                 :          * There is no risk of overflow here, although proving that requires
                               9390                 :          * some care.  Much as with the argument for div[qi] not overflowing,
                               9391                 :          * if we consider the first two terms in the numerator and denominator
                               9392                 :          * of qdigit, we can see that the final value of div[qi + 1] will be
                               9393                 :          * approximately a remainder mod (vardigits[0]*NBASE + vardigits[1]).
                               9394                 :          * Accounting for the lower-order terms is a bit complicated but ends
                               9395                 :          * up adding not much more than INT_MAX/NBASE to the possible range.
                               9396                 :          * Thus, div[qi + 1] cannot overflow here, and in its role as div[qi]
                               9397                 :          * in the next loop iteration, it can't be large enough to cause
                               9398                 :          * overflow in the carry propagation step (if any), either.
                               9399                 :          *
                               9400                 :          * But having said that: div[qi] can be more than INT_MAX/NBASE, as
                               9401                 :          * noted above, which means that the product div[qi] * NBASE *can*
                               9402                 :          * overflow.  When that happens, adding it to div[qi + 1] will always
                               9403                 :          * cause a canceling overflow so that the end result is correct.  We
                               9404                 :          * could avoid the intermediate overflow by doing the multiplication
                               9405                 :          * and addition in int64 arithmetic, but so far there appears no need.
                               9406                 :          */
 7188 bruce                    9407 CBC       42480 :         div[qi + 1] += div[qi] * NBASE;
                               9408                 : 
 7324 tgl                      9409 GIC       42480 :         div[qi] = qdigit;
                               9410                 :     }
                               9411                 : 
                               9412                 :     /*
                               9413                 :      * Approximate and store the last quotient digit (div[div_ndigits])
                               9414                 :      */
 7324 tgl                      9415 CBC        2664 :     fdividend = (double) div[qi];
                               9416           10656 :     for (i = 1; i < 4; i++)
                               9417            7992 :         fdividend *= NBASE;
 7324 tgl                      9418 GIC        2664 :     fquotient = fdividend * fdivisorinverse;
                               9419            2664 :     qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
 7188 bruce                    9420 LBC           0 :         (((int) fquotient) - 1);    /* truncate towards -infinity */
 7324 tgl                      9421 GIC        2664 :     div[qi] = qdigit;
 8866 JanWieck                 9422 ECB             : 
                               9423                 :     /*
                               9424                 :      * Because the quotient digits might be off by one, some of them might be
                               9425                 :      * -1 or NBASE at this point.  The represented value is correct in a
                               9426                 :      * mathematical sense, but it doesn't look right.  We do a final carry
                               9427                 :      * propagation pass to normalize the digits, which we combine with storing
                               9428                 :      * the result digits into the output.  Note that this is still done at
                               9429                 :      * full precision w/guard digits.
                               9430                 :      */
 7188 bruce                    9431 GIC        2664 :     alloc_var(result, div_ndigits + 1);
 7324 tgl                      9432 CBC        2664 :     res_digits = result->digits;
                               9433            2664 :     carry = 0;
 7324 tgl                      9434 GIC       47808 :     for (i = div_ndigits; i >= 0; i--)
                               9435                 :     {
                               9436           45144 :         newdig = div[i] + carry;
 7324 tgl                      9437 CBC       45144 :         if (newdig < 0)
 8866 JanWieck                 9438 ECB             :         {
 7188 bruce                    9439 CBC           6 :             carry = -((-newdig - 1) / NBASE) - 1;
 7188 bruce                    9440 GIC           6 :             newdig -= carry * NBASE;
                               9441                 :         }
 7324 tgl                      9442           45138 :         else if (newdig >= NBASE)
                               9443                 :         {
 7188 bruce                    9444             174 :             carry = newdig / NBASE;
                               9445             174 :             newdig -= carry * NBASE;
                               9446                 :         }
                               9447                 :         else
 7324 tgl                      9448           44964 :             carry = 0;
                               9449           45144 :         res_digits[i] = newdig;
 8866 JanWieck                 9450 ECB             :     }
 7324 tgl                      9451 GIC        2664 :     Assert(carry == 0);
 8866 JanWieck                 9452 ECB             : 
 7324 tgl                      9453 CBC        2664 :     pfree(div);
 8866 JanWieck                 9454 ECB             : 
                               9455                 :     /*
 7324 tgl                      9456                 :      * Finally, round the result to the requested precision.
 8866 JanWieck                 9457                 :      */
 7324 tgl                      9458 GIC        2664 :     result->weight = res_weight;
 7324 tgl                      9459 CBC        2664 :     result->sign = res_sign;
 7324 tgl                      9460 ECB             : 
                               9461                 :     /* Round to target rscale (and set result->dscale) */
 6518 bruce                    9462 GIC        2664 :     if (round)
                               9463             405 :         round_var(result, rscale);
 6518 bruce                    9464 ECB             :     else
 6518 bruce                    9465 CBC        2259 :         trunc_var(result, rscale);
                               9466                 : 
                               9467                 :     /* Strip leading and trailing zeroes */
 7324 tgl                      9468 GIC        2664 :     strip_var(result);
 8866 JanWieck                 9469 ECB             : }
                               9470                 : 
                               9471                 : 
                               9472                 : /*
                               9473                 :  * div_var_int() -
  406 dean.a.rasheed           9474                 :  *
                               9475                 :  *  Divide a numeric variable by a 32-bit integer with the specified weight.
                               9476                 :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
                               9477                 :  */
                               9478                 : static void
  406 dean.a.rasheed           9479 GIC       96609 : div_var_int(const NumericVar *var, int ival, int ival_weight,
                               9480                 :             NumericVar *result, int rscale, bool round)
                               9481                 : {
  406 dean.a.rasheed           9482 CBC       96609 :     NumericDigit *var_digits = var->digits;
                               9483           96609 :     int         var_ndigits = var->ndigits;
                               9484                 :     int         res_sign;
                               9485                 :     int         res_weight;
  406 dean.a.rasheed           9486 ECB             :     int         res_ndigits;
                               9487                 :     NumericDigit *res_buf;
                               9488                 :     NumericDigit *res_digits;
  406 dean.a.rasheed           9489 EUB             :     uint32      divisor;
                               9490                 :     int         i;
                               9491                 : 
  406 dean.a.rasheed           9492 ECB             :     /* Guard against division by zero */
  406 dean.a.rasheed           9493 GIC       96609 :     if (ival == 0)
  406 dean.a.rasheed           9494 UIC           0 :         ereport(ERROR,
                               9495                 :                 errcode(ERRCODE_DIVISION_BY_ZERO),
                               9496                 :                 errmsg("division by zero"));
                               9497                 : 
                               9498                 :     /* Result zero check */
  406 dean.a.rasheed           9499 GIC       96609 :     if (var_ndigits == 0)
                               9500                 :     {
                               9501            1141 :         zero_var(result);
                               9502            1141 :         result->dscale = rscale;
                               9503            1141 :         return;
                               9504                 :     }
                               9505                 : 
                               9506                 :     /*
                               9507                 :      * Determine the result sign, weight and number of digits to calculate.
                               9508                 :      * The weight figured here is correct if the emitted quotient has no
                               9509                 :      * leading zero digits; otherwise strip_var() will fix things up.
                               9510                 :      */
                               9511           95468 :     if (var->sign == NUMERIC_POS)
                               9512           94055 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
                               9513                 :     else
                               9514            1413 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
  406 dean.a.rasheed           9515 CBC       95468 :     res_weight = var->weight - ival_weight;
                               9516                 :     /* The number of accurate result digits we need to produce: */
  406 dean.a.rasheed           9517 GIC       95468 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
                               9518                 :     /* ... but always at least 1 */
                               9519           95468 :     res_ndigits = Max(res_ndigits, 1);
                               9520                 :     /* If rounding needed, figure one more digit to ensure correct result */
                               9521           95468 :     if (round)
                               9522           68459 :         res_ndigits++;
                               9523                 : 
                               9524           95468 :     res_buf = digitbuf_alloc(res_ndigits + 1);
                               9525           95468 :     res_buf[0] = 0;             /* spare digit for later rounding */
                               9526           95468 :     res_digits = res_buf + 1;
                               9527                 : 
                               9528                 :     /*
                               9529                 :      * Now compute the quotient digits.  This is the short division algorithm
                               9530                 :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
                               9531                 :      * allow the divisor to exceed the internal base.
                               9532                 :      *
                               9533                 :      * In this algorithm, the carry from one digit to the next is at most
                               9534                 :      * divisor - 1.  Therefore, while processing the next digit, carry may
                               9535                 :      * become as large as divisor * NBASE - 1, and so it requires a 64-bit
  406 dean.a.rasheed           9536 ECB             :      * integer if this exceeds UINT_MAX.
                               9537                 :      */
  184 peter                    9538 GNC       95468 :     divisor = abs(ival);
  406 dean.a.rasheed           9539 ECB             : 
  406 dean.a.rasheed           9540 GIC       95468 :     if (divisor <= UINT_MAX / NBASE)
                               9541                 :     {
                               9542                 :         /* carry cannot overflow 32 bits */
                               9543           94217 :         uint32      carry = 0;
                               9544                 : 
  406 dean.a.rasheed           9545 CBC      945778 :         for (i = 0; i < res_ndigits; i++)
  406 dean.a.rasheed           9546 ECB             :         {
  406 dean.a.rasheed           9547 GIC      851561 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
                               9548          851561 :             res_digits[i] = (NumericDigit) (carry / divisor);
                               9549          851561 :             carry = carry % divisor;
                               9550                 :         }
                               9551                 :     }
                               9552                 :     else
                               9553                 :     {
                               9554                 :         /* carry may exceed 32 bits */
                               9555            1251 :         uint64      carry = 0;
                               9556                 : 
  406 dean.a.rasheed           9557 CBC        4086 :         for (i = 0; i < res_ndigits; i++)
                               9558                 :         {
  406 dean.a.rasheed           9559 GIC        2835 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
                               9560            2835 :             res_digits[i] = (NumericDigit) (carry / divisor);
                               9561            2835 :             carry = carry % divisor;
  406 dean.a.rasheed           9562 ECB             :         }
                               9563                 :     }
                               9564                 : 
                               9565                 :     /* Store the quotient in result */
  406 dean.a.rasheed           9566 GBC       95468 :     digitbuf_free(result->buf);
                               9567           95468 :     result->ndigits = res_ndigits;
  406 dean.a.rasheed           9568 GIC       95468 :     result->buf = res_buf;
  406 dean.a.rasheed           9569 CBC       95468 :     result->digits = res_digits;
  406 dean.a.rasheed           9570 GBC       95468 :     result->weight = res_weight;
  406 dean.a.rasheed           9571 GIC       95468 :     result->sign = res_sign;
  406 dean.a.rasheed           9572 ECB             : 
                               9573                 :     /* Round or truncate to target rscale (and set result->dscale) */
  406 dean.a.rasheed           9574 GIC       95468 :     if (round)
                               9575           68459 :         round_var(result, rscale);
  406 dean.a.rasheed           9576 ECB             :     else
  406 dean.a.rasheed           9577 GIC       27009 :         trunc_var(result, rscale);
                               9578                 : 
                               9579                 :     /* Strip leading/trailing zeroes */
                               9580           95468 :     strip_var(result);
  406 dean.a.rasheed           9581 ECB             : }
                               9582                 : 
                               9583                 : 
                               9584                 : #ifdef HAVE_INT128
                               9585                 : /*
                               9586                 :  * div_var_int64() -
                               9587                 :  *
                               9588                 :  *  Divide a numeric variable by a 64-bit integer with the specified weight.
                               9589                 :  *  The quotient var / (ival * NBASE^ival_weight) is stored in result.
                               9590                 :  *
                               9591                 :  *  This duplicates the logic in div_var_int(), so any changes made there
                               9592                 :  *  should be made here too.
                               9593                 :  */
                               9594                 : static void
   76 dean.a.rasheed           9595 GNC         264 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
                               9596                 :               NumericVar *result, int rscale, bool round)
                               9597                 : {
                               9598             264 :     NumericDigit *var_digits = var->digits;
                               9599             264 :     int         var_ndigits = var->ndigits;
                               9600                 :     int         res_sign;
                               9601                 :     int         res_weight;
                               9602                 :     int         res_ndigits;
                               9603                 :     NumericDigit *res_buf;
                               9604                 :     NumericDigit *res_digits;
                               9605                 :     uint64      divisor;
                               9606                 :     int         i;
                               9607                 : 
                               9608                 :     /* Guard against division by zero */
                               9609             264 :     if (ival == 0)
   76 dean.a.rasheed           9610 UNC           0 :         ereport(ERROR,
                               9611                 :                 errcode(ERRCODE_DIVISION_BY_ZERO),
                               9612                 :                 errmsg("division by zero"));
                               9613                 : 
                               9614                 :     /* Result zero check */
   76 dean.a.rasheed           9615 GNC         264 :     if (var_ndigits == 0)
                               9616                 :     {
                               9617              48 :         zero_var(result);
                               9618              48 :         result->dscale = rscale;
                               9619              48 :         return;
                               9620                 :     }
                               9621                 : 
                               9622                 :     /*
                               9623                 :      * Determine the result sign, weight and number of digits to calculate.
                               9624                 :      * The weight figured here is correct if the emitted quotient has no
                               9625                 :      * leading zero digits; otherwise strip_var() will fix things up.
                               9626                 :      */
                               9627             216 :     if (var->sign == NUMERIC_POS)
                               9628             129 :         res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
                               9629                 :     else
                               9630              87 :         res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
                               9631             216 :     res_weight = var->weight - ival_weight;
                               9632                 :     /* The number of accurate result digits we need to produce: */
                               9633             216 :     res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
                               9634                 :     /* ... but always at least 1 */
                               9635             216 :     res_ndigits = Max(res_ndigits, 1);
                               9636                 :     /* If rounding needed, figure one more digit to ensure correct result */
                               9637             216 :     if (round)
                               9638             216 :         res_ndigits++;
                               9639                 : 
                               9640             216 :     res_buf = digitbuf_alloc(res_ndigits + 1);
                               9641             216 :     res_buf[0] = 0;             /* spare digit for later rounding */
                               9642             216 :     res_digits = res_buf + 1;
                               9643                 : 
                               9644                 :     /*
                               9645                 :      * Now compute the quotient digits.  This is the short division algorithm
                               9646                 :      * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
                               9647                 :      * allow the divisor to exceed the internal base.
                               9648                 :      *
                               9649                 :      * In this algorithm, the carry from one digit to the next is at most
                               9650                 :      * divisor - 1.  Therefore, while processing the next digit, carry may
                               9651                 :      * become as large as divisor * NBASE - 1, and so it requires a 128-bit
                               9652                 :      * integer if this exceeds PG_UINT64_MAX.
                               9653                 :      */
                               9654             216 :     divisor = i64abs(ival);
                               9655                 : 
                               9656             216 :     if (divisor <= PG_UINT64_MAX / NBASE)
                               9657                 :     {
                               9658                 :         /* carry cannot overflow 64 bits */
                               9659             168 :         uint64      carry = 0;
                               9660                 : 
                               9661            1721 :         for (i = 0; i < res_ndigits; i++)
                               9662                 :         {
                               9663            1553 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
                               9664            1553 :             res_digits[i] = (NumericDigit) (carry / divisor);
                               9665            1553 :             carry = carry % divisor;
                               9666                 :         }
                               9667                 :     }
                               9668                 :     else
                               9669                 :     {
                               9670                 :         /* carry may exceed 64 bits */
                               9671              48 :         uint128     carry = 0;
                               9672                 : 
                               9673             516 :         for (i = 0; i < res_ndigits; i++)
                               9674                 :         {
                               9675             468 :             carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
                               9676             468 :             res_digits[i] = (NumericDigit) (carry / divisor);
                               9677             468 :             carry = carry % divisor;
                               9678                 :         }
                               9679                 :     }
                               9680                 : 
                               9681                 :     /* Store the quotient in result */
                               9682             216 :     digitbuf_free(result->buf);
                               9683             216 :     result->ndigits = res_ndigits;
                               9684             216 :     result->buf = res_buf;
                               9685             216 :     result->digits = res_digits;
                               9686             216 :     result->weight = res_weight;
                               9687             216 :     result->sign = res_sign;
                               9688                 : 
                               9689                 :     /* Round or truncate to target rscale (and set result->dscale) */
                               9690             216 :     if (round)
                               9691             216 :         round_var(result, rscale);
                               9692                 :     else
   76 dean.a.rasheed           9693 UNC           0 :         trunc_var(result, rscale);
                               9694                 : 
                               9695                 :     /* Strip leading/trailing zeroes */
   76 dean.a.rasheed           9696 GNC         216 :     strip_var(result);
                               9697                 : }
                               9698                 : #endif
                               9699                 : 
                               9700                 : 
                               9701                 : /*
 7789 tgl                      9702 ECB             :  * Default scale selection for division
                               9703                 :  *
                               9704                 :  * Returns the appropriate result scale for the division result.
                               9705                 :  */
 7789 tgl                      9706 EUB             : static int
 2037 andres                   9707 GIC       61415 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
 7789 tgl                      9708 ECB             : {
 7494                          9709                 :     int         weight1,
                               9710                 :                 weight2,
                               9711                 :                 qweight,
                               9712                 :                 i;
                               9713                 :     NumericDigit firstdigit1,
                               9714                 :                 firstdigit2;
                               9715                 :     int         rscale;
                               9716                 : 
                               9717                 :     /*
 6385 bruce                    9718                 :      * The result scale of a division isn't specified in any SQL standard. For
                               9719                 :      * PostgreSQL we select a result scale that will give at least
 7494 tgl                      9720                 :      * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
                               9721                 :      * result no less accurate than float8; but use a scale not less than
                               9722                 :      * either input's display scale.
                               9723                 :      */
                               9724                 : 
                               9725                 :     /* Get the actual (normalized) weight and first digit of each input */
                               9726                 : 
 7494 tgl                      9727 GIC       61415 :     weight1 = 0;                /* values to use if var1 is zero */
 7494 tgl                      9728 CBC       61415 :     firstdigit1 = 0;
                               9729           61415 :     for (i = 0; i < var1->ndigits; i++)
                               9730                 :     {
                               9731           60559 :         firstdigit1 = var1->digits[i];
                               9732           60559 :         if (firstdigit1 != 0)
                               9733                 :         {
                               9734           60559 :             weight1 = var1->weight - i;
 7494 tgl                      9735 GIC       60559 :             break;
 7494 tgl                      9736 ECB             :         }
                               9737                 :     }
 7494 tgl                      9738 EUB             : 
 7494 tgl                      9739 GIC       61415 :     weight2 = 0;                /* values to use if var2 is zero */
                               9740           61415 :     firstdigit2 = 0;
                               9741           61415 :     for (i = 0; i < var2->ndigits; i++)
                               9742                 :     {
                               9743           61390 :         firstdigit2 = var2->digits[i];
                               9744           61390 :         if (firstdigit2 != 0)
                               9745                 :         {
                               9746           61390 :             weight2 = var2->weight - i;
                               9747           61390 :             break;
                               9748                 :         }
                               9749                 :     }
                               9750                 : 
                               9751                 :     /*
                               9752                 :      * Estimate weight of quotient.  If the two first digits are equal, we
                               9753                 :      * can't be sure, but assume that var1 is less than var2.
                               9754                 :      */
                               9755           61415 :     qweight = weight1 - weight2;
                               9756           61415 :     if (firstdigit1 <= firstdigit2)
                               9757           55625 :         qweight--;
 7494 tgl                      9758 ECB             : 
                               9759                 :     /* Select result scale */
 7324 tgl                      9760 CBC       61415 :     rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
                               9761           61415 :     rscale = Max(rscale, var1->dscale);
 7324 tgl                      9762 GIC       61415 :     rscale = Max(rscale, var2->dscale);
                               9763           61415 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
                               9764           61415 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                               9765                 : 
                               9766           61415 :     return rscale;
                               9767                 : }
                               9768                 : 
 7789 tgl                      9769 ECB             : 
 7324                          9770                 : /*
                               9771                 :  * mod_var() -
 8866 JanWieck                 9772                 :  *
                               9773                 :  *  Calculate the modulo of two numerics at variable level
                               9774                 :  */
                               9775                 : static void
 2037 andres                   9776 CBC       26484 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
                               9777                 : {
                               9778                 :     NumericVar  tmp;
                               9779                 : 
 8866 JanWieck                 9780 GIC       26484 :     init_var(&tmp);
                               9781                 : 
                               9782                 :     /* ---------
                               9783                 :      * We do this using the equation
                               9784                 :      *      mod(x,y) = x - trunc(x/y)*y
                               9785                 :      * div_var can be persuaded to give us trunc(x/y) directly.
                               9786                 :      * ----------
                               9787                 :      */
 5483 tgl                      9788           26484 :     div_var(var1, var2, &tmp, 0, false);
                               9789                 : 
                               9790           26478 :     mul_var(var2, &tmp, &tmp, var2->dscale);
                               9791                 : 
 8866 JanWieck                 9792           26478 :     sub_var(var1, &tmp, result);
                               9793                 : 
                               9794           26478 :     free_var(&tmp);
 8866 JanWieck                 9795 CBC       26478 : }
                               9796                 : 
                               9797                 : 
                               9798                 : /*
                               9799                 :  * div_mod_var() -
 1107 dean.a.rasheed           9800 ECB             :  *
                               9801                 :  *  Calculate the truncated integer quotient and numeric remainder of two
                               9802                 :  *  numeric variables.  The remainder is precise to var2's dscale.
                               9803                 :  */
                               9804                 : static void
 1107 dean.a.rasheed           9805 GIC        2259 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
 1107 dean.a.rasheed           9806 ECB             :             NumericVar *quot, NumericVar *rem)
                               9807                 : {
                               9808                 :     NumericVar  q;
                               9809                 :     NumericVar  r;
                               9810                 : 
 1107 dean.a.rasheed           9811 CBC        2259 :     init_var(&q);
                               9812            2259 :     init_var(&r);
 1107 dean.a.rasheed           9813 ECB             : 
                               9814                 :     /*
                               9815                 :      * Use div_var_fast() to get an initial estimate for the integer quotient.
                               9816                 :      * This might be inaccurate (per the warning in div_var_fast's comments),
                               9817                 :      * but we can correct it below.
                               9818                 :      */
 1107 dean.a.rasheed           9819 CBC        2259 :     div_var_fast(var1, var2, &q, 0, false);
                               9820                 : 
                               9821                 :     /* Compute initial estimate of remainder using the quotient estimate. */
 1107 dean.a.rasheed           9822 GIC        2259 :     mul_var(var2, &q, &r, var2->dscale);
                               9823            2259 :     sub_var(var1, &r, &r);
                               9824                 : 
                               9825                 :     /*
                               9826                 :      * Adjust the results if necessary --- the remainder should have the same
                               9827                 :      * sign as var1, and its absolute value should be less than the absolute
 1107 dean.a.rasheed           9828 ECB             :      * value of var2.
                               9829                 :      */
 1107 dean.a.rasheed           9830 GIC        2259 :     while (r.ndigits != 0 && r.sign != var1->sign)
 1107 dean.a.rasheed           9831 ECB             :     {
                               9832                 :         /* The absolute value of the quotient is too large */
 1107 dean.a.rasheed           9833 UIC           0 :         if (var1->sign == var2->sign)
 1107 dean.a.rasheed           9834 ECB             :         {
 1107 dean.a.rasheed           9835 LBC           0 :             sub_var(&q, &const_one, &q);
 1107 dean.a.rasheed           9836 UIC           0 :             add_var(&r, var2, &r);
 1107 dean.a.rasheed           9837 EUB             :         }
                               9838                 :         else
                               9839                 :         {
 1107 dean.a.rasheed           9840 UBC           0 :             add_var(&q, &const_one, &q);
 1107 dean.a.rasheed           9841 UIC           0 :             sub_var(&r, var2, &r);
                               9842                 :         }
 1107 dean.a.rasheed           9843 EUB             :     }
 1107 dean.a.rasheed           9844 ECB             : 
 1107 dean.a.rasheed           9845 GIC        2259 :     while (cmp_abs(&r, var2) >= 0)
 1107 dean.a.rasheed           9846 ECB             :     {
                               9847                 :         /* The absolute value of the quotient is too small */
 1107 dean.a.rasheed           9848 UIC           0 :         if (var1->sign == var2->sign)
                               9849                 :         {
                               9850               0 :             add_var(&q, &const_one, &q);
                               9851               0 :             sub_var(&r, var2, &r);
                               9852                 :         }
                               9853                 :         else
 1107 dean.a.rasheed           9854 ECB             :         {
 1107 dean.a.rasheed           9855 UIC           0 :             sub_var(&q, &const_one, &q);
                               9856               0 :             add_var(&r, var2, &r);
                               9857                 :         }
                               9858                 :     }
                               9859                 : 
 1107 dean.a.rasheed           9860 CBC        2259 :     set_var_from_var(&q, quot);
                               9861            2259 :     set_var_from_var(&r, rem);
                               9862                 : 
                               9863            2259 :     free_var(&q);
                               9864            2259 :     free_var(&r);
                               9865            2259 : }
                               9866                 : 
                               9867                 : 
 7324 tgl                      9868 ECB             : /*
 8866 JanWieck                 9869                 :  * ceil_var() -
 8866 JanWieck                 9870 EUB             :  *
 8866 JanWieck                 9871 ECB             :  *  Return the smallest integer greater than or equal to the argument
                               9872                 :  *  on variable level
                               9873                 :  */
                               9874                 : static void
 2037 andres                   9875 GIC         102 : ceil_var(const NumericVar *var, NumericVar *result)
                               9876                 : {
                               9877                 :     NumericVar  tmp;
                               9878                 : 
 8866 JanWieck                 9879             102 :     init_var(&tmp);
                               9880             102 :     set_var_from_var(var, &tmp);
                               9881                 : 
 7324 tgl                      9882             102 :     trunc_var(&tmp, 0);
                               9883                 : 
                               9884             102 :     if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
 8866 JanWieck                 9885              30 :         add_var(&tmp, &const_one, &tmp);
                               9886                 : 
                               9887             102 :     set_var_from_var(&tmp, result);
                               9888             102 :     free_var(&tmp);
                               9889             102 : }
                               9890                 : 
                               9891                 : 
 7324 tgl                      9892 ECB             : /*
                               9893                 :  * floor_var() -
 8866 JanWieck                 9894                 :  *
                               9895                 :  *  Return the largest integer equal to or less than the argument
                               9896                 :  *  on variable level
                               9897                 :  */
                               9898                 : static void
 2037 andres                   9899 GIC         288 : floor_var(const NumericVar *var, NumericVar *result)
                               9900                 : {
                               9901                 :     NumericVar  tmp;
                               9902                 : 
 8866 JanWieck                 9903             288 :     init_var(&tmp);
                               9904             288 :     set_var_from_var(var, &tmp);
                               9905                 : 
 7324 tgl                      9906             288 :     trunc_var(&tmp, 0);
                               9907                 : 
                               9908             288 :     if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
 8866 JanWieck                 9909              15 :         sub_var(&tmp, &const_one, &tmp);
                               9910                 : 
                               9911             288 :     set_var_from_var(&tmp, result);
                               9912             288 :     free_var(&tmp);
                               9913             288 : }
                               9914                 : 
                               9915                 : 
                               9916                 : /*
                               9917                 :  * gcd_var() -
                               9918                 :  *
                               9919                 :  *  Calculate the greatest common divisor of two numerics at variable level
                               9920                 :  */
                               9921                 : static void
 1170 dean.a.rasheed           9922             111 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
                               9923                 : {
 1170 dean.a.rasheed           9924 ECB             :     int         res_dscale;
                               9925                 :     int         cmp;
                               9926                 :     NumericVar  tmp_arg;
                               9927                 :     NumericVar  mod;
                               9928                 : 
 1170 dean.a.rasheed           9929 GIC         111 :     res_dscale = Max(var1->dscale, var2->dscale);
                               9930                 : 
                               9931                 :     /*
 1170 dean.a.rasheed           9932 ECB             :      * Arrange for var1 to be the number with the greater absolute value.
                               9933                 :      *
                               9934                 :      * This would happen automatically in the loop below, but avoids an
                               9935                 :      * expensive modulo operation.
                               9936                 :      */
 1170 dean.a.rasheed           9937 GBC         111 :     cmp = cmp_abs(var1, var2);
 1170 dean.a.rasheed           9938 CBC         111 :     if (cmp < 0)
                               9939                 :     {
 1170 dean.a.rasheed           9940 GIC          42 :         const NumericVar *tmp = var1;
                               9941                 : 
                               9942              42 :         var1 = var2;
                               9943              42 :         var2 = tmp;
                               9944                 :     }
                               9945                 : 
                               9946                 :     /*
                               9947                 :      * Also avoid the taking the modulo if the inputs have the same absolute
 1170 dean.a.rasheed           9948 ECB             :      * value, or if the smaller input is zero.
                               9949                 :      */
 1170 dean.a.rasheed           9950 CBC         111 :     if (cmp == 0 || var2->ndigits == 0)
 1170 dean.a.rasheed           9951 ECB             :     {
 1170 dean.a.rasheed           9952 GIC          36 :         set_var_from_var(var1, result);
 1170 dean.a.rasheed           9953 CBC          36 :         result->sign = NUMERIC_POS;
                               9954              36 :         result->dscale = res_dscale;
 1170 dean.a.rasheed           9955 GIC          36 :         return;
 1170 dean.a.rasheed           9956 ECB             :     }
                               9957                 : 
 1170 dean.a.rasheed           9958 GIC          75 :     init_var(&tmp_arg);
 1170 dean.a.rasheed           9959 CBC          75 :     init_var(&mod);
                               9960                 : 
 1170 dean.a.rasheed           9961 ECB             :     /* Use the Euclidean algorithm to find the GCD */
 1170 dean.a.rasheed           9962 CBC          75 :     set_var_from_var(var1, &tmp_arg);
 1170 dean.a.rasheed           9963 GIC          75 :     set_var_from_var(var2, result);
                               9964                 : 
 1170 dean.a.rasheed           9965 ECB             :     for (;;)
                               9966                 :     {
                               9967                 :         /* this loop can take a while, so allow it to be interrupted */
 1170 dean.a.rasheed           9968 CBC         294 :         CHECK_FOR_INTERRUPTS();
                               9969                 : 
                               9970             294 :         mod_var(&tmp_arg, result, &mod);
 1170 dean.a.rasheed           9971 GIC         294 :         if (mod.ndigits == 0)
                               9972              75 :             break;
                               9973             219 :         set_var_from_var(result, &tmp_arg);
                               9974             219 :         set_var_from_var(&mod, result);
 1170 dean.a.rasheed           9975 ECB             :     }
 1170 dean.a.rasheed           9976 CBC          75 :     result->sign = NUMERIC_POS;
 1170 dean.a.rasheed           9977 GIC          75 :     result->dscale = res_dscale;
                               9978                 : 
 1170 dean.a.rasheed           9979 CBC          75 :     free_var(&tmp_arg);
                               9980              75 :     free_var(&mod);
                               9981                 : }
 1170 dean.a.rasheed           9982 ECB             : 
                               9983                 : 
                               9984                 : /*
 8866 JanWieck                 9985                 :  * sqrt_var() -
                               9986                 :  *
                               9987                 :  *  Compute the square root of x using the Karatsuba Square Root algorithm.
                               9988                 :  *  NOTE: we allow rscale < 0 here, implying rounding before the decimal
                               9989                 :  *  point.
                               9990                 :  */
                               9991                 : static void
 2037 andres                   9992 GIC        2097 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
                               9993                 : {
                               9994                 :     int         stat;
                               9995                 :     int         res_weight;
 1107 dean.a.rasheed           9996 ECB             :     int         res_ndigits;
                               9997                 :     int         src_ndigits;
                               9998                 :     int         step;
                               9999                 :     int         ndigits[32];
                              10000                 :     int         blen;
                              10001                 :     int64       arg_int64;
                              10002                 :     int         src_idx;
                              10003                 :     int64       s_int64;
                              10004                 :     int64       r_int64;
                              10005                 :     NumericVar  s_var;
                              10006                 :     NumericVar  r_var;
                              10007                 :     NumericVar  a0_var;
                              10008                 :     NumericVar  a1_var;
                              10009                 :     NumericVar  q_var;
                              10010                 :     NumericVar  u_var;
 8866 JanWieck                10011 EUB             : 
 8866 JanWieck                10012 GIC        2097 :     stat = cmp_var(arg, &const_zero);
                              10013            2097 :     if (stat == 0)
                              10014                 :     {
 7324 tgl                     10015               9 :         zero_var(result);
 7324 tgl                     10016 CBC           9 :         result->dscale = rscale;
 8866 JanWieck                10017 GIC           9 :         return;
 8866 JanWieck                10018 ECB             :     }
                              10019                 : 
 6899 neilc                   10020                 :     /*
                              10021                 :      * SQL2003 defines sqrt() in terms of power, so we need to emit the right
                              10022                 :      * SQLSTATE error code if the operand is negative.
                              10023                 :      */
 8866 JanWieck                10024 GIC        2088 :     if (stat < 0)
 7196 tgl                     10025               3 :         ereport(ERROR,
                              10026                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
                              10027                 :                  errmsg("cannot take square root of a negative number")));
 8866 JanWieck                10028 ECB             : 
 1107 dean.a.rasheed          10029 CBC        2085 :     init_var(&s_var);
 1107 dean.a.rasheed          10030 GIC        2085 :     init_var(&r_var);
 1107 dean.a.rasheed          10031 CBC        2085 :     init_var(&a0_var);
                              10032            2085 :     init_var(&a1_var);
 1107 dean.a.rasheed          10033 GIC        2085 :     init_var(&q_var);
 1107 dean.a.rasheed          10034 CBC        2085 :     init_var(&u_var);
                              10035                 : 
 1107 dean.a.rasheed          10036 ECB             :     /*
                              10037                 :      * The result weight is half the input weight, rounded towards minus
                              10038                 :      * infinity --- res_weight = floor(arg->weight / 2).
                              10039                 :      */
 1107 dean.a.rasheed          10040 GIC        2085 :     if (arg->weight >= 0)
 1107 dean.a.rasheed          10041 CBC        1929 :         res_weight = arg->weight / 2;
 1107 dean.a.rasheed          10042 ECB             :     else
 1107 dean.a.rasheed          10043 CBC         156 :         res_weight = -((-arg->weight - 1) / 2 + 1);
                              10044                 : 
                              10045                 :     /*
                              10046                 :      * Number of NBASE digits to compute.  To ensure correct rounding, compute
                              10047                 :      * at least 1 extra decimal digit.  We explicitly allow rscale to be
                              10048                 :      * negative here, but must always compute at least 1 NBASE digit.  Thus
                              10049                 :      * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
                              10050                 :      */
 1107 dean.a.rasheed          10051 GIC        2085 :     if (rscale + 1 >= 0)
                              10052            2085 :         res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
                              10053                 :     else
 1107 dean.a.rasheed          10054 UIC           0 :         res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
 1107 dean.a.rasheed          10055 CBC        2085 :     res_ndigits = Max(res_ndigits, 1);
                              10056                 : 
 1107 dean.a.rasheed          10057 ECB             :     /*
                              10058                 :      * Number of source NBASE digits logically required to produce a result
                              10059                 :      * with this precision --- every digit before the decimal point, plus 2
                              10060                 :      * for each result digit after the decimal point (or minus 2 for each
                              10061                 :      * result digit we round before the decimal point).
                              10062                 :      */
 1107 dean.a.rasheed          10063 GIC        2085 :     src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
 1107 dean.a.rasheed          10064 CBC        2085 :     src_ndigits = Max(src_ndigits, 1);
 7494 tgl                     10065 ECB             : 
 1107 dean.a.rasheed          10066                 :     /* ----------
                              10067                 :      * From this point on, we treat the input and the result as integers and
                              10068                 :      * compute the integer square root and remainder using the Karatsuba
                              10069                 :      * Square Root algorithm, which may be written recursively as follows:
                              10070                 :      *
                              10071                 :      *  SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
                              10072                 :      *      [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
                              10073                 :      *        0 <= a0,a1,a2 < b and a3 >= b/4 ]
                              10074                 :      *      Let (s,r) = SqrtRem(a3*b + a2)
                              10075                 :      *      Let (q,u) = DivRem(r*b + a1, 2*s)
                              10076                 :      *      Let s = s*b + q
                              10077                 :      *      Let r = u*b + a0 - q^2
                              10078                 :      *      If r < 0 Then
                              10079                 :      *          Let r = r + s
                              10080                 :      *          Let s = s - 1
                              10081                 :      *          Let r = r + s
                              10082                 :      *      Return (s,r)
                              10083                 :      *
                              10084                 :      * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
                              10085                 :      * RR-3805, November 1999.  At the time of writing this was available
                              10086                 :      * on the net at <https://hal.inria.fr/inria-00072854>.
                              10087                 :      *
                              10088                 :      * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
                              10089                 :      * "choose a base b such that n requires at least four base-b digits to
                              10090                 :      * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
                              10091                 :      * than b".  For optimal performance, b should have approximately a
                              10092                 :      * quarter the number of digits in the input, so that the outer square
                              10093                 :      * root computes roughly twice as many digits as the inner one.  For
                              10094                 :      * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
                              10095                 :      *
                              10096                 :      * We implement the algorithm iteratively rather than recursively, to
                              10097                 :      * allow the working variables to be reused.  With this approach, each
                              10098                 :      * digit of the input is read precisely once --- src_idx tracks the number
                              10099                 :      * of input digits used so far.
                              10100                 :      *
                              10101                 :      * The array ndigits[] holds the number of NBASE digits of the input that
                              10102                 :      * will have been used at the end of each iteration, which roughly doubles
                              10103                 :      * each time.  Note that the array elements are stored in reverse order,
                              10104                 :      * so if the final iteration requires src_ndigits = 37 input digits, the
                              10105                 :      * array will contain [37,19,11,7,5,3], and we would start by computing
                              10106                 :      * the square root of the 3 most significant NBASE digits.
                              10107                 :      *
                              10108                 :      * In each iteration, we choose blen to be the largest integer for which
                              10109                 :      * the input number has a3 >= b/4, when written in the form above.  In
                              10110                 :      * general, this means blen = src_ndigits / 4 (truncated), but if
                              10111                 :      * src_ndigits is a multiple of 4, that might lead to the coefficient a3
                              10112                 :      * being less than b/4 (if the first input digit is less than NBASE/4), in
                              10113                 :      * which case we choose blen = src_ndigits / 4 - 1.  The number of digits
                              10114                 :      * in the inner square root is then src_ndigits - 2*blen.  So, for
                              10115                 :      * example, if we have src_ndigits = 26 initially, the array ndigits[]
                              10116                 :      * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
                              10117                 :      * the first input digit.
                              10118                 :      *
                              10119                 :      * Additionally, we can put an upper bound on the number of steps required
                              10120                 :      * as follows --- suppose that the number of source digits is an n-bit
                              10121                 :      * number in the range [2^(n-1), 2^n-1], then blen will be in the range
                              10122                 :      * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
                              10123                 :      * root will be in the range [2^(n-2), 2^(n-1)+1].  In the next step, blen
                              10124                 :      * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
                              10125                 :      * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
                              10126                 :      * This pattern repeats, and in the worst case the array ndigits[] will
 1107 dean.a.rasheed          10127 EUB             :      * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
                              10128                 :      * will require n steps.  Therefore, since all digit array sizes are
                              10129                 :      * signed 32-bit integers, the number of steps required is guaranteed to
                              10130                 :      * be less than 32.
                              10131                 :      * ----------
 1107 dean.a.rasheed          10132 ECB             :      */
 1107 dean.a.rasheed          10133 GIC        2085 :     step = 0;
 1107 dean.a.rasheed          10134 CBC        9981 :     while ((ndigits[step] = src_ndigits) > 4)
 8866 JanWieck                10135 ECB             :     {
 1107 dean.a.rasheed          10136                 :         /* Choose b so that a3 >= b/4, as described above */
 1107 dean.a.rasheed          10137 GIC        7896 :         blen = src_ndigits / 4;
                              10138            7896 :         if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
                              10139             162 :             blen--;
                              10140                 : 
                              10141                 :         /* Number of digits in the next step (inner square root) */
                              10142            7896 :         src_ndigits -= 2 * blen;
                              10143            7896 :         step++;
 1107 dean.a.rasheed          10144 ECB             :     }
 8866 JanWieck                10145                 : 
                              10146                 :     /*
 1107 dean.a.rasheed          10147                 :      * First iteration (innermost square root and remainder):
                              10148                 :      *
                              10149                 :      * Here src_ndigits <= 4, and the input fits in an int64.  Its square root
                              10150                 :      * has at most 9 decimal digits, so estimate it using double precision
                              10151                 :      * arithmetic, which will in fact almost certainly return the correct
                              10152                 :      * result with no further correction required.
                              10153                 :      */
 1107 dean.a.rasheed          10154 CBC        2085 :     arg_int64 = arg->digits[0];
                              10155            6657 :     for (src_idx = 1; src_idx < src_ndigits; src_idx++)
                              10156                 :     {
                              10157            4572 :         arg_int64 *= NBASE;
                              10158            4572 :         if (src_idx < arg->ndigits)
                              10159            3843 :             arg_int64 += arg->digits[src_idx];
                              10160                 :     }
                              10161                 : 
 1107 dean.a.rasheed          10162 GIC        2085 :     s_int64 = (int64) sqrt((double) arg_int64);
                              10163            2085 :     r_int64 = arg_int64 - s_int64 * s_int64;
                              10164                 : 
                              10165                 :     /*
                              10166                 :      * Use Newton's method to correct the result, if necessary.
                              10167                 :      *
                              10168                 :      * This uses integer division with truncation to compute the truncated
                              10169                 :      * integer square root by iterating using the formula x -> (x + n/x) / 2.
                              10170                 :      * This is known to converge to isqrt(n), unless n+1 is a perfect square.
 1107 dean.a.rasheed          10171 ECB             :      * If n+1 is a perfect square, the sequence will oscillate between the two
                              10172                 :      * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
                              10173                 :      * checking the remainder.
                              10174                 :      */
 1107 dean.a.rasheed          10175 GIC        2085 :     while (r_int64 < 0 || r_int64 > 2 * s_int64)
 1107 dean.a.rasheed          10176 ECB             :     {
 1107 dean.a.rasheed          10177 UIC           0 :         s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
 1107 dean.a.rasheed          10178 LBC           0 :         r_int64 = arg_int64 - s_int64 * s_int64;
                              10179                 :     }
 1107 dean.a.rasheed          10180 ECB             : 
                              10181                 :     /*
                              10182                 :      * Iterations with src_ndigits <= 8:
                              10183                 :      *
                              10184                 :      * The next 1 or 2 iterations compute larger (outer) square roots with
                              10185                 :      * src_ndigits <= 8, so the result still fits in an int64 (even though the
                              10186                 :      * input no longer does) and we can continue to compute using int64
                              10187                 :      * variables to avoid more expensive numeric computations.
                              10188                 :      *
                              10189                 :      * It is fairly easy to see that there is no risk of the intermediate
                              10190                 :      * values below overflowing 64-bit integers.  In the worst case, the
                              10191                 :      * previous iteration will have computed a 3-digit square root (of a
                              10192                 :      * 6-digit input less than NBASE^6 / 4), so at the start of this
                              10193                 :      * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
                              10194                 :      * less than 10^12.  In this case, blen will be 1, so numer will be less
                              10195                 :      * than 10^17, and denom will be less than 10^12 (and hence u will also be
                              10196                 :      * less than 10^12).  Finally, since q^2 = u*b + a0 - r, we can also be
                              10197                 :      * sure that q^2 < 10^17.  Therefore all these quantities fit comfortably
                              10198                 :      * in 64-bit integers.
                              10199                 :      */
 1107 dean.a.rasheed          10200 CBC        2085 :     step--;
                              10201            5283 :     while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
 1107 dean.a.rasheed          10202 ECB             :     {
                              10203                 :         int         b;
                              10204                 :         int         a0;
                              10205                 :         int         a1;
                              10206                 :         int         i;
                              10207                 :         int64       numer;
                              10208                 :         int64       denom;
                              10209                 :         int64       q;
 1107 dean.a.rasheed          10210 EUB             :         int64       u;
                              10211                 : 
 1107 dean.a.rasheed          10212 GIC        3198 :         blen = (src_ndigits - src_idx) / 2;
 1107 dean.a.rasheed          10213 ECB             : 
                              10214                 :         /* Extract a1 and a0, and compute b */
 1107 dean.a.rasheed          10215 GIC        3198 :         a0 = 0;
                              10216            3198 :         a1 = 0;
                              10217            3198 :         b = 1;
                              10218                 : 
                              10219            6468 :         for (i = 0; i < blen; i++, src_idx++)
                              10220                 :         {
                              10221            3270 :             b *= NBASE;
                              10222            3270 :             a1 *= NBASE;
                              10223            3270 :             if (src_idx < arg->ndigits)
 1107 dean.a.rasheed          10224 CBC        2400 :                 a1 += arg->digits[src_idx];
                              10225                 :         }
                              10226                 : 
 1107 dean.a.rasheed          10227 GIC        6468 :         for (i = 0; i < blen; i++, src_idx++)
                              10228                 :         {
                              10229            3270 :             a0 *= NBASE;
                              10230            3270 :             if (src_idx < arg->ndigits)
                              10231            2322 :                 a0 += arg->digits[src_idx];
                              10232                 :         }
                              10233                 : 
                              10234                 :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
                              10235            3198 :         numer = r_int64 * b + a1;
                              10236            3198 :         denom = 2 * s_int64;
                              10237            3198 :         q = numer / denom;
                              10238            3198 :         u = numer - q * denom;
                              10239                 : 
                              10240                 :         /* Compute s = s*b + q and r = u*b + a0 - q^2 */
                              10241            3198 :         s_int64 = s_int64 * b + q;
                              10242            3198 :         r_int64 = u * b + a0 - q * q;
                              10243                 : 
 1107 dean.a.rasheed          10244 CBC        3198 :         if (r_int64 < 0)
 1107 dean.a.rasheed          10245 ECB             :         {
                              10246                 :             /* s is too large by 1; set r += s, s--, r += s */
 1107 dean.a.rasheed          10247 GIC         105 :             r_int64 += s_int64;
 1107 dean.a.rasheed          10248 CBC         105 :             s_int64--;
                              10249             105 :             r_int64 += s_int64;
                              10250                 :         }
 1107 dean.a.rasheed          10251 ECB             : 
 1107 dean.a.rasheed          10252 CBC        3198 :         Assert(src_idx == src_ndigits); /* All input digits consumed */
 1107 dean.a.rasheed          10253 GIC        3198 :         step--;
                              10254                 :     }
                              10255                 : 
 1107 dean.a.rasheed          10256 ECB             :     /*
                              10257                 :      * On platforms with 128-bit integer support, we can further delay the
                              10258                 :      * need to use numeric variables.
                              10259                 :      */
                              10260                 : #ifdef HAVE_INT128
 1107 dean.a.rasheed          10261 CBC        2085 :     if (step >= 0)
                              10262                 :     {
 1107 dean.a.rasheed          10263 ECB             :         int128      s_int128;
                              10264                 :         int128      r_int128;
                              10265                 : 
 1107 dean.a.rasheed          10266 GIC        2085 :         s_int128 = s_int64;
                              10267            2085 :         r_int128 = r_int64;
                              10268                 : 
                              10269                 :         /*
                              10270                 :          * Iterations with src_ndigits <= 16:
                              10271                 :          *
 1107 dean.a.rasheed          10272 ECB             :          * The result fits in an int128 (even though the input doesn't) so we
                              10273                 :          * use int128 variables to avoid more expensive numeric computations.
                              10274                 :          */
 1107 dean.a.rasheed          10275 GIC        4524 :         while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
                              10276                 :         {
 1107 dean.a.rasheed          10277 ECB             :             int64       b;
                              10278                 :             int64       a0;
                              10279                 :             int64       a1;
                              10280                 :             int64       i;
                              10281                 :             int128      numer;
                              10282                 :             int128      denom;
                              10283                 :             int128      q;
                              10284                 :             int128      u;
                              10285                 : 
 1107 dean.a.rasheed          10286 GIC        2439 :             blen = (src_ndigits - src_idx) / 2;
                              10287                 : 
                              10288                 :             /* Extract a1 and a0, and compute b */
                              10289            2439 :             a0 = 0;
                              10290            2439 :             a1 = 0;
                              10291            2439 :             b = 1;
                              10292                 : 
 1107 dean.a.rasheed          10293 CBC        8040 :             for (i = 0; i < blen; i++, src_idx++)
                              10294                 :             {
 1107 dean.a.rasheed          10295 GIC        5601 :                 b *= NBASE;
                              10296            5601 :                 a1 *= NBASE;
 1107 dean.a.rasheed          10297 CBC        5601 :                 if (src_idx < arg->ndigits)
 1107 dean.a.rasheed          10298 GIC        3303 :                     a1 += arg->digits[src_idx];
                              10299                 :             }
                              10300                 : 
                              10301            8040 :             for (i = 0; i < blen; i++, src_idx++)
                              10302                 :             {
                              10303            5601 :                 a0 *= NBASE;
                              10304            5601 :                 if (src_idx < arg->ndigits)
 1107 dean.a.rasheed          10305 CBC        2235 :                     a0 += arg->digits[src_idx];
                              10306                 :             }
 1107 dean.a.rasheed          10307 ECB             : 
                              10308                 :             /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
 1107 dean.a.rasheed          10309 CBC        2439 :             numer = r_int128 * b + a1;
 1107 dean.a.rasheed          10310 GIC        2439 :             denom = 2 * s_int128;
 1107 dean.a.rasheed          10311 CBC        2439 :             q = numer / denom;
                              10312            2439 :             u = numer - q * denom;
                              10313                 : 
                              10314                 :             /* Compute s = s*b + q and r = u*b + a0 - q^2 */
 1107 dean.a.rasheed          10315 GIC        2439 :             s_int128 = s_int128 * b + q;
                              10316            2439 :             r_int128 = u * b + a0 - q * q;
                              10317                 : 
                              10318            2439 :             if (r_int128 < 0)
                              10319                 :             {
                              10320                 :                 /* s is too large by 1; set r += s, s--, r += s */
                              10321              96 :                 r_int128 += s_int128;
 1107 dean.a.rasheed          10322 CBC          96 :                 s_int128--;
 1107 dean.a.rasheed          10323 GIC          96 :                 r_int128 += s_int128;
                              10324                 :             }
                              10325                 : 
                              10326            2439 :             Assert(src_idx == src_ndigits); /* All input digits consumed */
                              10327            2439 :             step--;
 1107 dean.a.rasheed          10328 ECB             :         }
                              10329                 : 
                              10330                 :         /*
                              10331                 :          * All remaining iterations require numeric variables.  Convert the
                              10332                 :          * integer values to NumericVar and continue.  Note that in the final
                              10333                 :          * iteration we don't need the remainder, so we can save a few cycles
                              10334                 :          * there by not fully computing it.
                              10335                 :          */
 1107 dean.a.rasheed          10336 CBC        2085 :         int128_to_numericvar(s_int128, &s_var);
 1107 dean.a.rasheed          10337 GIC        2085 :         if (step >= 0)
                              10338            1362 :             int128_to_numericvar(r_int128, &r_var);
 1107 dean.a.rasheed          10339 ECB             :     }
                              10340                 :     else
                              10341                 :     {
 1107 dean.a.rasheed          10342 UIC           0 :         int64_to_numericvar(s_int64, &s_var);
                              10343                 :         /* step < 0, so we certainly don't need r */
                              10344                 :     }
                              10345                 : #else                           /* !HAVE_INT128 */
                              10346                 :     int64_to_numericvar(s_int64, &s_var);
 1107 dean.a.rasheed          10347 ECB             :     if (step >= 0)
                              10348                 :         int64_to_numericvar(r_int64, &r_var);
                              10349                 : #endif                          /* HAVE_INT128 */
 1107 dean.a.rasheed          10350 EUB             : 
                              10351                 :     /*
                              10352                 :      * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
                              10353                 :      * use numeric variables.
                              10354                 :      */
 1107 dean.a.rasheed          10355 GIC        4344 :     while (step >= 0)
                              10356                 :     {
 1107 dean.a.rasheed          10357 EUB             :         int         tmp_len;
 8866 JanWieck                10358                 : 
 1107 dean.a.rasheed          10359 GIC        2259 :         src_ndigits = ndigits[step];
                              10360            2259 :         blen = (src_ndigits - src_idx) / 2;
                              10361                 : 
 1107 dean.a.rasheed          10362 ECB             :         /* Extract a1 and a0 */
 1107 dean.a.rasheed          10363 GIC        2259 :         if (src_idx < arg->ndigits)
                              10364                 :         {
 1107 dean.a.rasheed          10365 GBC         756 :             tmp_len = Min(blen, arg->ndigits - src_idx);
 1107 dean.a.rasheed          10366 GIC         756 :             alloc_var(&a1_var, tmp_len);
 1107 dean.a.rasheed          10367 GBC         756 :             memcpy(a1_var.digits, arg->digits + src_idx,
 1107 dean.a.rasheed          10368 EUB             :                    tmp_len * sizeof(NumericDigit));
 1107 dean.a.rasheed          10369 GIC         756 :             a1_var.weight = blen - 1;
                              10370             756 :             a1_var.sign = NUMERIC_POS;
                              10371             756 :             a1_var.dscale = 0;
 1107 dean.a.rasheed          10372 GBC         756 :             strip_var(&a1_var);
 1107 dean.a.rasheed          10373 EUB             :         }
                              10374                 :         else
                              10375                 :         {
 1107 dean.a.rasheed          10376 GIC        1503 :             zero_var(&a1_var);
 1107 dean.a.rasheed          10377 CBC        1503 :             a1_var.dscale = 0;
 1107 dean.a.rasheed          10378 ECB             :         }
 1107 dean.a.rasheed          10379 GIC        2259 :         src_idx += blen;
 1107 dean.a.rasheed          10380 ECB             : 
 1107 dean.a.rasheed          10381 CBC        2259 :         if (src_idx < arg->ndigits)
 1107 dean.a.rasheed          10382 ECB             :         {
 1107 dean.a.rasheed          10383 GIC         756 :             tmp_len = Min(blen, arg->ndigits - src_idx);
                              10384             756 :             alloc_var(&a0_var, tmp_len);
                              10385             756 :             memcpy(a0_var.digits, arg->digits + src_idx,
                              10386                 :                    tmp_len * sizeof(NumericDigit));
                              10387             756 :             a0_var.weight = blen - 1;
                              10388             756 :             a0_var.sign = NUMERIC_POS;
                              10389             756 :             a0_var.dscale = 0;
                              10390             756 :             strip_var(&a0_var);
                              10391                 :         }
 1107 dean.a.rasheed          10392 ECB             :         else
                              10393                 :         {
 1107 dean.a.rasheed          10394 GIC        1503 :             zero_var(&a0_var);
                              10395            1503 :             a0_var.dscale = 0;
 1107 dean.a.rasheed          10396 ECB             :         }
 1107 dean.a.rasheed          10397 CBC        2259 :         src_idx += blen;
                              10398                 : 
 1107 dean.a.rasheed          10399 ECB             :         /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
 1107 dean.a.rasheed          10400 GIC        2259 :         set_var_from_var(&r_var, &q_var);
 1107 dean.a.rasheed          10401 CBC        2259 :         q_var.weight += blen;
                              10402            2259 :         add_var(&q_var, &a1_var, &q_var);
 1107 dean.a.rasheed          10403 GIC        2259 :         add_var(&s_var, &s_var, &u_var);
 1107 dean.a.rasheed          10404 CBC        2259 :         div_mod_var(&q_var, &u_var, &q_var, &u_var);
 1107 dean.a.rasheed          10405 ECB             : 
                              10406                 :         /* Compute s = s*b + q */
 1107 dean.a.rasheed          10407 GIC        2259 :         s_var.weight += blen;
                              10408            2259 :         add_var(&s_var, &q_var, &s_var);
                              10409                 : 
                              10410                 :         /*
                              10411                 :          * Compute r = u*b + a0 - q^2.
                              10412                 :          *
                              10413                 :          * In the final iteration, we don't actually need r; we just need to
                              10414                 :          * know whether it is negative, so that we know whether to adjust s.
                              10415                 :          * So instead of the final subtraction we can just compare.
 1107 dean.a.rasheed          10416 ECB             :          */
 1107 dean.a.rasheed          10417 GIC        2259 :         u_var.weight += blen;
                              10418            2259 :         add_var(&u_var, &a0_var, &u_var);
                              10419            2259 :         mul_var(&q_var, &q_var, &q_var, 0);
 1107 dean.a.rasheed          10420 ECB             : 
 1107 dean.a.rasheed          10421 CBC        2259 :         if (step > 0)
                              10422                 :         {
 1107 dean.a.rasheed          10423 ECB             :             /* Need r for later iterations */
 1107 dean.a.rasheed          10424 GIC         897 :             sub_var(&u_var, &q_var, &r_var);
 1107 dean.a.rasheed          10425 CBC         897 :             if (r_var.sign == NUMERIC_NEG)
 1107 dean.a.rasheed          10426 ECB             :             {
                              10427                 :                 /* s is too large by 1; set r += s, s--, r += s */
 1107 dean.a.rasheed          10428 CBC          60 :                 add_var(&r_var, &s_var, &r_var);
                              10429              60 :                 sub_var(&s_var, &const_one, &s_var);
                              10430              60 :                 add_var(&r_var, &s_var, &r_var);
                              10431                 :             }
                              10432                 :         }
                              10433                 :         else
                              10434                 :         {
                              10435                 :             /* Don't need r anymore, except to test if s is too large by 1 */
 1107 dean.a.rasheed          10436 GIC        1362 :             if (cmp_var(&u_var, &q_var) < 0)
                              10437              18 :                 sub_var(&s_var, &const_one, &s_var);
                              10438                 :         }
 1107 dean.a.rasheed          10439 ECB             : 
 1107 dean.a.rasheed          10440 GIC        2259 :         Assert(src_idx == src_ndigits); /* All input digits consumed */
                              10441            2259 :         step--;
                              10442                 :     }
                              10443                 : 
                              10444                 :     /*
                              10445                 :      * Construct the final result, rounding it to the requested precision.
 1107 dean.a.rasheed          10446 ECB             :      */
 1107 dean.a.rasheed          10447 GIC        2085 :     set_var_from_var(&s_var, result);
                              10448            2085 :     result->weight = res_weight;
                              10449            2085 :     result->sign = NUMERIC_POS;
                              10450                 : 
                              10451                 :     /* Round to target rscale (and set result->dscale) */
 7324 tgl                     10452            2085 :     round_var(result, rscale);
                              10453                 : 
 1107 dean.a.rasheed          10454 ECB             :     /* Strip leading and trailing zeroes */
 1107 dean.a.rasheed          10455 CBC        2085 :     strip_var(result);
                              10456                 : 
                              10457            2085 :     free_var(&s_var);
 1107 dean.a.rasheed          10458 GIC        2085 :     free_var(&r_var);
 1107 dean.a.rasheed          10459 CBC        2085 :     free_var(&a0_var);
                              10460            2085 :     free_var(&a1_var);
 1107 dean.a.rasheed          10461 GIC        2085 :     free_var(&q_var);
                              10462            2085 :     free_var(&u_var);
                              10463                 : }
                              10464                 : 
                              10465                 : 
                              10466                 : /*
 8866 JanWieck                10467 ECB             :  * exp_var() -
                              10468                 :  *
 2703 tgl                     10469                 :  *  Raise e to the power of x, computed to rscale fractional digits
 8866 JanWieck                10470                 :  */
                              10471                 : static void
 2037 andres                  10472 CBC          90 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
                              10473                 : {
                              10474                 :     NumericVar  x;
 2703 tgl                     10475 ECB             :     NumericVar  elem;
  406 dean.a.rasheed          10476                 :     int         ni;
                              10477                 :     double      val;
                              10478                 :     int         dweight;
 2703 tgl                     10479                 :     int         ndiv2;
                              10480                 :     int         sig_digits;
                              10481                 :     int         local_rscale;
                              10482                 : 
 8866 JanWieck                10483 GIC          90 :     init_var(&x);
 2703 tgl                     10484              90 :     init_var(&elem);
 8866 JanWieck                10485 ECB             : 
 8866 JanWieck                10486 GIC          90 :     set_var_from_var(arg, &x);
 8866 JanWieck                10487 ECB             : 
 2703 tgl                     10488                 :     /*
                              10489                 :      * Estimate the dweight of the result using floating point arithmetic, so
                              10490                 :      * that we can choose an appropriate local rscale for the calculation.
                              10491                 :      */
 2703 tgl                     10492 GIC          90 :     val = numericvar_to_double_no_overflow(&x);
 8866 JanWieck                10493 ECB             : 
  617 dean.a.rasheed          10494                 :     /* Guard against overflow/underflow */
                              10495                 :     /* If you change this limit, see also power_var()'s limit */
  184 peter                   10496 GNC          90 :     if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
  617 dean.a.rasheed          10497 ECB             :     {
  617 dean.a.rasheed          10498 GIC           3 :         if (val > 0)
  617 dean.a.rasheed          10499 UIC           0 :             ereport(ERROR,
                              10500                 :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                              10501                 :                      errmsg("value overflows numeric format")));
  617 dean.a.rasheed          10502 GIC           3 :         zero_var(result);
                              10503               3 :         result->dscale = rscale;
                              10504               3 :         return;
                              10505                 :     }
                              10506                 : 
                              10507                 :     /* decimal weight = log10(e^x) = x * log10(e) */
 2703 tgl                     10508              87 :     dweight = (int) (val * 0.434294481903252);
 8866 JanWieck                10509 ECB             : 
                              10510                 :     /*
                              10511                 :      * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
                              10512                 :      * 2^ndiv2, to improve the convergence rate of the Taylor series.
                              10513                 :      *
                              10514                 :      * Note that the overflow check above ensures that fabs(x) < 6000, which
                              10515                 :      * means that ndiv2 <= 20 here.
                              10516                 :      */
  184 peter                   10517 GNC          87 :     if (fabs(val) > 0.01)
                              10518                 :     {
 2703 tgl                     10519 GIC          72 :         ndiv2 = 1;
                              10520              72 :         val /= 2;
                              10521                 : 
  184 peter                   10522 GNC         909 :         while (fabs(val) > 0.01)
                              10523                 :         {
 2703 tgl                     10524 GIC         837 :             ndiv2++;
                              10525             837 :             val /= 2;
                              10526                 :         }
                              10527                 : 
                              10528              72 :         local_rscale = x.dscale + ndiv2;
  406 dean.a.rasheed          10529 CBC          72 :         div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
 2703 tgl                     10530 ECB             :     }
                              10531                 :     else
 2703 tgl                     10532 CBC          15 :         ndiv2 = 0;
 7324 tgl                     10533 ECB             : 
 2703                         10534                 :     /*
                              10535                 :      * Set the scale for the Taylor series expansion.  The final result has
                              10536                 :      * (dweight + rscale + 1) significant digits.  In addition, we have to
                              10537                 :      * raise the Taylor series result to the power 2^ndiv2, which introduces
                              10538                 :      * an error of up to around log10(2^ndiv2) digits, so work with this many
                              10539                 :      * extra digits of precision (plus a few more for good measure).
                              10540                 :      */
 2703 tgl                     10541 CBC          87 :     sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
                              10542              87 :     sig_digits = Max(sig_digits, 0) + 8;
                              10543                 : 
 2703 tgl                     10544 GIC          87 :     local_rscale = sig_digits - 1;
                              10545                 : 
 7494 tgl                     10546 ECB             :     /*
                              10547                 :      * Use the Taylor series
                              10548                 :      *
 7188 bruce                   10549                 :      * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
 7494 tgl                     10550                 :      *
 6347 bruce                   10551                 :      * Given the limited range of x, this should converge reasonably quickly.
                              10552                 :      * We run the series until the terms fall below the local_rscale limit.
                              10553                 :      */
 8866 JanWieck                10554 GIC          87 :     add_var(&const_one, &x, result);
                              10555                 : 
 2703 tgl                     10556              87 :     mul_var(&x, &x, &elem, local_rscale);
  406 dean.a.rasheed          10557 CBC          87 :     ni = 2;
                              10558              87 :     div_var_int(&elem, ni, 0, &elem, local_rscale, true);
                              10559                 : 
 2703 tgl                     10560            2496 :     while (elem.ndigits != 0)
                              10561                 :     {
 8866 JanWieck                10562 GIC        2409 :         add_var(result, &elem, result);
                              10563                 : 
 2703 tgl                     10564            2409 :         mul_var(&elem, &x, &elem, local_rscale);
  406 dean.a.rasheed          10565            2409 :         ni++;
                              10566            2409 :         div_var_int(&elem, ni, 0, &elem, local_rscale, true);
                              10567                 :     }
 8866 JanWieck                10568 ECB             : 
 2703 tgl                     10569                 :     /*
                              10570                 :      * Compensate for the argument range reduction.  Since the weight of the
 2703 tgl                     10571 EUB             :      * result doubles with each multiplication, we can reduce the local rscale
 2703 tgl                     10572 ECB             :      * as we proceed.
                              10573                 :      */
 8866 JanWieck                10574 GIC         996 :     while (ndiv2-- > 0)
                              10575                 :     {
 2703 tgl                     10576             909 :         local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
                              10577             909 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
 7324                         10578             909 :         mul_var(result, result, result, local_rscale);
                              10579                 :     }
 2703 tgl                     10580 ECB             : 
                              10581                 :     /* Round to requested rscale */
 2703 tgl                     10582 GIC          87 :     round_var(result, rscale);
                              10583                 : 
 8866 JanWieck                10584              87 :     free_var(&x);
                              10585              87 :     free_var(&elem);
                              10586                 : }
                              10587                 : 
                              10588                 : 
                              10589                 : /*
                              10590                 :  * Estimate the dweight of the most significant decimal digit of the natural
                              10591                 :  * logarithm of a number.
                              10592                 :  *
                              10593                 :  * Essentially, we're approximating log10(abs(ln(var))).  This is used to
                              10594                 :  * determine the appropriate rscale when computing natural logarithms.
                              10595                 :  *
                              10596                 :  * Note: many callers call this before range-checking the input.  Therefore,
                              10597                 :  * we must be robust against values that are invalid to apply ln() to.
                              10598                 :  * We don't wish to throw an error here, so just return zero in such cases.
                              10599                 :  */
                              10600                 : static int
 2037 andres                  10601             369 : estimate_ln_dweight(const NumericVar *var)
                              10602                 : {
                              10603                 :     int         ln_dweight;
                              10604                 : 
                              10605                 :     /* Caller should fail on ln(negative), but for the moment return zero */
  402 tgl                     10606             369 :     if (var->sign != NUMERIC_POS)
                              10607              21 :         return 0;
                              10608                 : 
 2703                         10609             657 :     if (cmp_var(var, &const_zero_point_nine) >= 0 &&
                              10610             309 :         cmp_var(var, &const_one_point_one) <= 0)
                              10611              45 :     {
                              10612                 :         /*
                              10613                 :          * 0.9 <= var <= 1.1
                              10614                 :          *
                              10615                 :          * ln(var) has a negative weight (possibly very large).  To get a
                              10616                 :          * reasonably accurate result, estimate it using ln(1+x) ~= x.
                              10617                 :          */
                              10618                 :         NumericVar  x;
                              10619                 : 
                              10620              45 :         init_var(&x);
                              10621              45 :         sub_var(var, &const_one, &x);
                              10622                 : 
                              10623              45 :         if (x.ndigits > 0)
                              10624                 :         {
                              10625                 :             /* Use weight of most significant decimal digit of x */
                              10626              21 :             ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
                              10627                 :         }
                              10628                 :         else
                              10629                 :         {
                              10630                 :             /* x = 0.  Since ln(1) = 0 exactly, we don't need extra digits */
                              10631              24 :             ln_dweight = 0;
                              10632                 :         }
                              10633                 : 
                              10634              45 :         free_var(&x);
                              10635                 :     }
                              10636                 :     else
                              10637                 :     {
                              10638                 :         /*
                              10639                 :          * Estimate the logarithm using the first couple of digits from the
                              10640                 :          * input number.  This will give an accurate result whenever the input
                              10641                 :          * is not too close to 1.
                              10642                 :          */
                              10643             303 :         if (var->ndigits > 0)
                              10644                 :         {
                              10645                 :             int         digits;
                              10646                 :             int         dweight;
                              10647                 :             double      ln_var;
                              10648                 : 
                              10649             282 :             digits = var->digits[0];
 2703 tgl                     10650 CBC         282 :             dweight = var->weight * DEC_DIGITS;
 2703 tgl                     10651 ECB             : 
 2703 tgl                     10652 GIC         282 :             if (var->ndigits > 1)
                              10653                 :             {
 2703 tgl                     10654 CBC         171 :                 digits = digits * NBASE + var->digits[1];
                              10655             171 :                 dweight -= DEC_DIGITS;
 2703 tgl                     10656 ECB             :             }
                              10657                 : 
                              10658                 :             /*----------
                              10659                 :              * We have var ~= digits * 10^dweight
                              10660                 :              * so ln(var) ~= ln(digits) + dweight * ln(10)
                              10661                 :              *----------
                              10662                 :              */
 2703 tgl                     10663 GIC         282 :             ln_var = log((double) digits) + dweight * 2.302585092994046;
  184 peter                   10664 GNC         282 :             ln_dweight = (int) log10(fabs(ln_var));
                              10665                 :         }
                              10666                 :         else
                              10667                 :         {
                              10668                 :             /* Caller should fail on ln(0), but for the moment return zero */
 2703 tgl                     10669 GIC          21 :             ln_dweight = 0;
                              10670                 :         }
 2703 tgl                     10671 ECB             :     }
                              10672                 : 
 2703 tgl                     10673 GIC         348 :     return ln_dweight;
 2703 tgl                     10674 ECB             : }
                              10675                 : 
                              10676                 : 
                              10677                 : /*
                              10678                 :  * ln_var() -
 8866 JanWieck                10679                 :  *
                              10680                 :  *  Compute the natural log of x
                              10681                 :  */
                              10682                 : static void
 2037 andres                  10683 GIC         417 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
                              10684                 : {
                              10685                 :     NumericVar  x;
                              10686                 :     NumericVar  xx;
                              10687                 :     int         ni;
                              10688                 :     NumericVar  elem;
                              10689                 :     NumericVar  fact;
                              10690                 :     int         nsqrt;
                              10691                 :     int         local_rscale;
 6902 neilc                   10692 ECB             :     int         cmp;
                              10693                 : 
 6902 neilc                   10694 GBC         417 :     cmp = cmp_var(arg, &const_zero);
                              10695             417 :     if (cmp == 0)
 7196 tgl                     10696 GIC          21 :         ereport(ERROR,
                              10697                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
                              10698                 :                  errmsg("cannot take logarithm of zero")));
 6902 neilc                   10699             396 :     else if (cmp < 0)
                              10700              18 :         ereport(ERROR,
                              10701                 :                 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
                              10702                 :                  errmsg("cannot take logarithm of a negative number")));
                              10703                 : 
 8866 JanWieck                10704             378 :     init_var(&x);
                              10705             378 :     init_var(&xx);
                              10706             378 :     init_var(&elem);
                              10707             378 :     init_var(&fact);
                              10708                 : 
                              10709             378 :     set_var_from_var(arg, &x);
 7324 tgl                     10710             378 :     set_var_from_var(&const_two, &fact);
                              10711                 : 
                              10712                 :     /*
                              10713                 :      * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
                              10714                 :      *
                              10715                 :      * The final logarithm will have up to around rscale+6 significant digits.
                              10716                 :      * Each sqrt() will roughly halve the weight of x, so adjust the local
 2703 tgl                     10717 ECB             :      * rscale as we work so that we keep this many significant digits at each
                              10718                 :      * step (plus a few more for good measure).
                              10719                 :      *
                              10720                 :      * Note that we allow local_rscale < 0 during this input reduction
                              10721                 :      * process, which implies rounding before the decimal point.  sqrt_var()
                              10722                 :      * explicitly supports this, and it significantly reduces the work
                              10723                 :      * required to reduce very large inputs to the required range.  Once the
                              10724                 :      * input reduction is complete, x.weight will be 0 and its display scale
                              10725                 :      * will be non-negative again.
                              10726                 :      */
 1134 dean.a.rasheed          10727 GIC         378 :     nsqrt = 0;
 7494 tgl                     10728             534 :     while (cmp_var(&x, &const_zero_point_nine) <= 0)
 8866 JanWieck                10729 ECB             :     {
 2703 tgl                     10730 GIC         156 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
 7324                         10731             156 :         sqrt_var(&x, &x, local_rscale);
 7324 tgl                     10732 CBC         156 :         mul_var(&fact, &const_two, &fact, 0);
 1134 dean.a.rasheed          10733             156 :         nsqrt++;
 8866 JanWieck                10734 ECB             :     }
 7494 tgl                     10735 GIC        2064 :     while (cmp_var(&x, &const_one_point_one) >= 0)
 8866 JanWieck                10736 ECB             :     {
 2703 tgl                     10737 GIC        1686 :         local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
 7324 tgl                     10738 CBC        1686 :         sqrt_var(&x, &x, local_rscale);
                              10739            1686 :         mul_var(&fact, &const_two, &fact, 0);
 1134 dean.a.rasheed          10740            1686 :         nsqrt++;
 8866 JanWieck                10741 ECB             :     }
                              10742                 : 
                              10743                 :     /*
 7494 tgl                     10744                 :      * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
                              10745                 :      *
 7188 bruce                   10746                 :      * z + z^3/3 + z^5/5 + ...
 7494 tgl                     10747                 :      *
 6347 bruce                   10748                 :      * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
                              10749                 :      * due to the above range-reduction of x.
                              10750                 :      *
                              10751                 :      * The convergence of this is not as fast as one would like, but is
                              10752                 :      * tolerable given that z is small.
 1134 dean.a.rasheed          10753                 :      *
                              10754                 :      * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
                              10755                 :      * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
                              10756                 :      * digits of precision (plus a few more for good measure).
                              10757                 :      */
 1134 dean.a.rasheed          10758 CBC         378 :     local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
 2703 tgl                     10759 ECB             : 
 8866 JanWieck                10760 GIC         378 :     sub_var(&x, &const_one, result);
 8866 JanWieck                10761 CBC         378 :     add_var(&x, &const_one, &elem);
 5483 tgl                     10762 GIC         378 :     div_var_fast(result, &elem, result, local_rscale, true);
 8866 JanWieck                10763             378 :     set_var_from_var(result, &xx);
 7324 tgl                     10764 CBC         378 :     mul_var(result, result, &x, local_rscale);
 8866 JanWieck                10765 ECB             : 
  406 dean.a.rasheed          10766 CBC         378 :     ni = 1;
                              10767                 : 
                              10768                 :     for (;;)
 8866 JanWieck                10769 ECB             :     {
  406 dean.a.rasheed          10770 CBC        7011 :         ni += 2;
 7324 tgl                     10771 GIC        7011 :         mul_var(&xx, &x, &xx, local_rscale);
  406 dean.a.rasheed          10772            7011 :         div_var_int(&xx, ni, 0, &elem, local_rscale, true);
                              10773                 : 
 7494 tgl                     10774            7011 :         if (elem.ndigits == 0)
 8866 JanWieck                10775             378 :             break;
                              10776                 : 
                              10777            6633 :         add_var(result, &elem, result);
 7331 tgl                     10778 ECB             : 
 7188 bruce                   10779 GIC        6633 :         if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
 7331 tgl                     10780 UIC           0 :             break;
                              10781                 :     }
                              10782                 : 
 7324 tgl                     10783 ECB             :     /* Compensate for argument range reduction, round to requested rscale */
 7324 tgl                     10784 CBC         378 :     mul_var(result, &fact, result, rscale);
                              10785                 : 
 8866 JanWieck                10786 GIC         378 :     free_var(&x);
                              10787             378 :     free_var(&xx);
                              10788             378 :     free_var(&elem);
                              10789             378 :     free_var(&fact);
                              10790             378 : }
                              10791                 : 
 8866 JanWieck                10792 ECB             : 
                              10793                 : /*
                              10794                 :  * log_var() -
                              10795                 :  *
                              10796                 :  *  Compute the logarithm of num in a given base.
                              10797                 :  *
                              10798                 :  *  Note: this routine chooses dscale of the result.
                              10799                 :  */
                              10800                 : static void
 2037 andres                  10801 GIC         108 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
                              10802                 : {
 8866 JanWieck                10803 ECB             :     NumericVar  ln_base;
                              10804                 :     NumericVar  ln_num;
                              10805                 :     int         ln_base_dweight;
 2703 tgl                     10806                 :     int         ln_num_dweight;
                              10807                 :     int         result_dweight;
 7324                         10808                 :     int         rscale;
                              10809                 :     int         ln_base_rscale;
 2703                         10810                 :     int         ln_num_rscale;
                              10811                 : 
 8866 JanWieck                10812 CBC         108 :     init_var(&ln_base);
                              10813             108 :     init_var(&ln_num);
 8866 JanWieck                10814 ECB             : 
 2703 tgl                     10815                 :     /* Estimated dweights of ln(base), ln(num) and the final result */
 2703 tgl                     10816 GIC         108 :     ln_base_dweight = estimate_ln_dweight(base);
                              10817             108 :     ln_num_dweight = estimate_ln_dweight(num);
 2703 tgl                     10818 CBC         108 :     result_dweight = ln_num_dweight - ln_base_dweight;
                              10819                 : 
 2703 tgl                     10820 ECB             :     /*
                              10821                 :      * Select the scale of the result so that it will have at least
                              10822                 :      * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
                              10823                 :      * input's display scale.
                              10824                 :      */
 2703 tgl                     10825 GIC         108 :     rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
 7324 tgl                     10826 CBC         108 :     rscale = Max(rscale, base->dscale);
                              10827             108 :     rscale = Max(rscale, num->dscale);
                              10828             108 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              10829             108 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                              10830                 : 
                              10831                 :     /*
 2703 tgl                     10832 ECB             :      * Set the scales for ln(base) and ln(num) so that they each have more
                              10833                 :      * significant digits than the final result.
                              10834                 :      */
 2703 tgl                     10835 CBC         108 :     ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
 2703 tgl                     10836 GIC         108 :     ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              10837                 : 
 2703 tgl                     10838 CBC         108 :     ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
                              10839             108 :     ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
 7494 tgl                     10840 ECB             : 
                              10841                 :     /* Form natural logarithms */
 2703 tgl                     10842 GIC         108 :     ln_var(base, &ln_base, ln_base_rscale);
 2703 tgl                     10843 CBC          96 :     ln_var(num, &ln_num, ln_num_rscale);
 8720 bruce                   10844 ECB             : 
                              10845                 :     /* Divide and round to the required scale */
 5483 tgl                     10846 GIC          81 :     div_var_fast(&ln_num, &ln_base, result, rscale, true);
                              10847                 : 
 8866 JanWieck                10848              78 :     free_var(&ln_num);
                              10849              78 :     free_var(&ln_base);
                              10850              78 : }
                              10851                 : 
                              10852                 : 
 7324 tgl                     10853 ECB             : /*
 8866 JanWieck                10854                 :  * power_var() -
                              10855                 :  *
                              10856                 :  *  Raise base to the power of exp
                              10857                 :  *
                              10858                 :  *  Note: this routine chooses dscale of the result.
 8866 JanWieck                10859 EUB             :  */
                              10860                 : static void
 2037 andres                  10861 GIC         570 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
                              10862                 : {
                              10863                 :     int         res_sign;
                              10864                 :     NumericVar  abs_base;
                              10865                 :     NumericVar  ln_base;
                              10866                 :     NumericVar  ln_num;
                              10867                 :     int         ln_dweight;
                              10868                 :     int         rscale;
                              10869                 :     int         sig_digits;
                              10870                 :     int         local_rscale;
                              10871                 :     double      val;
 8866 JanWieck                10872 ECB             : 
                              10873                 :     /* If exp can be represented as an integer, use power_var_int */
 7324 tgl                     10874 GIC         570 :     if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
                              10875                 :     {
 7324 tgl                     10876 ECB             :         /* exact integer, but does it fit in int? */
                              10877                 :         int64       expval64;
                              10878                 : 
 2942 andres                  10879 GIC         507 :         if (numericvar_to_int64(exp, &expval64))
 7324 tgl                     10880 ECB             :         {
  611 dean.a.rasheed          10881 GIC         504 :             if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
 7324 tgl                     10882 ECB             :             {
                              10883                 :                 /* Okay, use power_var_int */
  171 dean.a.rasheed          10884 GNC         489 :                 power_var_int(base, (int) expval64, exp->dscale, result);
 7324 tgl                     10885 GIC         483 :                 return;
                              10886                 :             }
                              10887                 :         }
 7324 tgl                     10888 ECB             :     }
                              10889                 : 
                              10890                 :     /*
 2703                         10891                 :      * This avoids log(0) for cases of 0 raised to a non-integer.  0 ^ 0 is
                              10892                 :      * handled by power_var_int().
 5449 bruce                   10893                 :      */
 5449 bruce                   10894 GIC          81 :     if (cmp_var(base, &const_zero) == 0)
 5449 bruce                   10895 ECB             :     {
 5449 bruce                   10896 CBC           9 :         set_var_from_var(&const_zero, result);
 2118 tgl                     10897               9 :         result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
 5449 bruce                   10898 GIC           9 :         return;
 5449 bruce                   10899 ECB             :     }
 5050                         10900                 : 
  617 dean.a.rasheed          10901 CBC          72 :     init_var(&abs_base);
 8866 JanWieck                10902              72 :     init_var(&ln_base);
 8866 JanWieck                10903 GIC          72 :     init_var(&ln_num);
                              10904                 : 
                              10905                 :     /*
  617 dean.a.rasheed          10906 ECB             :      * If base is negative, insist that exp be an integer.  The result is then
                              10907                 :      * positive if exp is even and negative if exp is odd.
                              10908                 :      */
  617 dean.a.rasheed          10909 CBC          72 :     if (base->sign == NUMERIC_NEG)
                              10910                 :     {
                              10911                 :         /*
  617 dean.a.rasheed          10912 ECB             :          * Check that exp is an integer.  This error code is defined by the
                              10913                 :          * SQL standard, and matches other errors in numeric_power().
                              10914                 :          */
  617 dean.a.rasheed          10915 CBC          18 :         if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
                              10916               9 :             ereport(ERROR,
                              10917                 :                     (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
                              10918                 :                      errmsg("a negative number raised to a non-integer power yields a complex result")));
  617 dean.a.rasheed          10919 ECB             : 
                              10920                 :         /* Test if exp is odd or even */
  617 dean.a.rasheed          10921 GIC           9 :         if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
                              10922               6 :             (exp->digits[exp->ndigits - 1] & 1))
                              10923               3 :             res_sign = NUMERIC_NEG;
                              10924                 :         else
                              10925               6 :             res_sign = NUMERIC_POS;
                              10926                 : 
                              10927                 :         /* Then work with abs(base) below */
                              10928               9 :         set_var_from_var(base, &abs_base);
  617 dean.a.rasheed          10929 CBC           9 :         abs_base.sign = NUMERIC_POS;
                              10930               9 :         base = &abs_base;
  617 dean.a.rasheed          10931 ECB             :     }
                              10932                 :     else
  617 dean.a.rasheed          10933 CBC          54 :         res_sign = NUMERIC_POS;
                              10934                 : 
                              10935                 :     /*----------
 2703 tgl                     10936 ECB             :      * Decide on the scale for the ln() calculation.  For this we need an
                              10937                 :      * estimate of the weight of the result, which we obtain by doing an
                              10938                 :      * initial low-precision calculation of exp * ln(base).
                              10939                 :      *
                              10940                 :      * We want result = e ^ (exp * ln(base))
                              10941                 :      * so result dweight = log10(result) = exp * ln(base) * log10(e)
 2530 dean.a.rasheed          10942                 :      *
                              10943                 :      * We also perform a crude overflow test here so that we can exit early if
                              10944                 :      * the full-precision result is sure to overflow, and to guard against
                              10945                 :      * integer overflow when determining the scale for the real calculation.
                              10946                 :      * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
                              10947                 :      * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
                              10948                 :      * Since the values here are only approximations, we apply a small fuzz
                              10949                 :      * factor to this overflow test and let exp_var() determine the exact
                              10950                 :      * overflow threshold so that it is consistent for all inputs.
                              10951                 :      *----------
 2703 tgl                     10952                 :      */
 2703 tgl                     10953 CBC          63 :     ln_dweight = estimate_ln_dweight(base);
                              10954                 : 
                              10955                 :     /*
                              10956                 :      * Set the scale for the low-precision calculation, computing ln(base) to
                              10957                 :      * around 8 significant digits.  Note that ln_dweight may be as small as
                              10958                 :      * -SHRT_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE here.
  550 dean.a.rasheed          10959 ECB             :      */
 2703 tgl                     10960 CBC          63 :     local_rscale = 8 - ln_dweight;
                              10961              63 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              10962                 : 
 7324 tgl                     10963 GIC          63 :     ln_var(base, &ln_base, local_rscale);
 8866 JanWieck                10964 ECB             : 
 7324 tgl                     10965 GIC          63 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
                              10966                 : 
 7494 tgl                     10967 CBC          63 :     val = numericvar_to_double_no_overflow(&ln_num);
                              10968                 : 
  617 dean.a.rasheed          10969 ECB             :     /* initial overflow/underflow test with fuzz factor */
  184 peter                   10970 GNC          63 :     if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
  617 dean.a.rasheed          10971 ECB             :     {
  617 dean.a.rasheed          10972 CBC           3 :         if (val > 0)
  617 dean.a.rasheed          10973 LBC           0 :             ereport(ERROR,
  617 dean.a.rasheed          10974 ECB             :                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                              10975                 :                      errmsg("value overflows numeric format")));
  617 dean.a.rasheed          10976 GIC           3 :         zero_var(result);
                              10977               3 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
                              10978               3 :         return;
                              10979                 :     }
                              10980                 : 
 2530                         10981              60 :     val *= 0.434294481903252;   /* approximate decimal result weight */
                              10982                 : 
                              10983                 :     /* choose the result scale */
 7324 tgl                     10984 CBC          60 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
 7324 tgl                     10985 GIC          60 :     rscale = Max(rscale, base->dscale);
                              10986              60 :     rscale = Max(rscale, exp->dscale);
                              10987              60 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              10988              60 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                              10989                 : 
                              10990                 :     /* significant digits required in the result */
  617 dean.a.rasheed          10991              60 :     sig_digits = rscale + (int) val;
                              10992              60 :     sig_digits = Max(sig_digits, 0);
                              10993                 : 
                              10994                 :     /* set the scale for the real exp * ln(base) calculation */
  617 dean.a.rasheed          10995 CBC          60 :     local_rscale = sig_digits - ln_dweight + 8;
 2703 tgl                     10996              60 :     local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              10997                 : 
 2703 tgl                     10998 ECB             :     /* and do the real calculation */
                              10999                 : 
 2703 tgl                     11000 GIC          60 :     ln_var(base, &ln_base, local_rscale);
                              11001                 : 
                              11002              60 :     mul_var(&ln_base, exp, &ln_num, local_rscale);
                              11003                 : 
 7324 tgl                     11004 CBC          60 :     exp_var(&ln_num, result, rscale);
                              11005                 : 
  617 dean.a.rasheed          11006 GIC          60 :     if (res_sign == NUMERIC_NEG && result->ndigits > 0)
                              11007               3 :         result->sign = NUMERIC_NEG;
  617 dean.a.rasheed          11008 ECB             : 
 7324 tgl                     11009 GIC          60 :     free_var(&ln_num);
 7324 tgl                     11010 CBC          60 :     free_var(&ln_base);
  617 dean.a.rasheed          11011 GBC          60 :     free_var(&abs_base);
                              11012                 : }
                              11013                 : 
 7324 tgl                     11014 ECB             : /*
                              11015                 :  * power_var_int() -
                              11016                 :  *
                              11017                 :  *  Raise base to the power of exp, where exp is an integer.
                              11018                 :  *
                              11019                 :  *  Note: this routine chooses dscale of the result.
                              11020                 :  */
                              11021                 : static void
  171 dean.a.rasheed          11022 GNC         489 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
                              11023                 :               NumericVar *result)
                              11024                 : {
                              11025                 :     double      f;
                              11026                 :     int         p;
                              11027                 :     int         i;
                              11028                 :     int         rscale;
                              11029                 :     int         sig_digits;
                              11030                 :     unsigned int mask;
                              11031                 :     bool        neg;
                              11032                 :     NumericVar  base_prod;
 7324 tgl                     11033 ECB             :     int         local_rscale;
                              11034                 : 
                              11035                 :     /*
                              11036                 :      * Choose the result scale.  For this we need an estimate of the decimal
                              11037                 :      * weight of the result, which we obtain by approximating using double
                              11038                 :      * precision arithmetic.
                              11039                 :      *
                              11040                 :      * We also perform crude overflow/underflow tests here so that we can exit
                              11041                 :      * early if the result is sure to overflow/underflow, and to guard against
                              11042                 :      * integer overflow when choosing the result scale.
                              11043                 :      */
  171 dean.a.rasheed          11044 GNC         489 :     if (base->ndigits != 0)
                              11045                 :     {
                              11046                 :         /*----------
                              11047                 :          * Choose f (double) and p (int) such that base ~= f * 10^p.
                              11048                 :          * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
                              11049                 :          *----------
                              11050                 :          */
                              11051             474 :         f = base->digits[0];
                              11052             474 :         p = base->weight * DEC_DIGITS;
                              11053                 : 
                              11054             516 :         for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
                              11055                 :         {
                              11056              42 :             f = f * NBASE + base->digits[i];
                              11057              42 :             p -= DEC_DIGITS;
                              11058                 :         }
                              11059                 : 
                              11060             474 :         f = exp * (log10(f) + p);   /* approximate decimal result weight */
                              11061                 :     }
                              11062                 :     else
                              11063              15 :         f = 0;                  /* result is 0 or 1 (weight 0), or error */
                              11064                 : 
                              11065                 :     /* overflow/underflow tests with fuzz factors */
                              11066             489 :     if (f > (SHRT_MAX + 1) * DEC_DIGITS)
                              11067               6 :         ereport(ERROR,
                              11068                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                              11069                 :                  errmsg("value overflows numeric format")));
                              11070             483 :     if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
                              11071                 :     {
                              11072               6 :         zero_var(result);
                              11073               6 :         result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
                              11074              93 :         return;
                              11075                 :     }
                              11076                 : 
                              11077                 :     /*
                              11078                 :      * Choose the result scale in the same way as power_var(), so it has at
                              11079                 :      * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
                              11080                 :      * either input's display scale.
                              11081                 :      */
                              11082             477 :     rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
                              11083             477 :     rscale = Max(rscale, base->dscale);
                              11084             477 :     rscale = Max(rscale, exp_dscale);
                              11085             477 :     rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              11086             477 :     rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
                              11087                 : 
 3132 tgl                     11088 ECB             :     /* Handle some common special cases, as well as corner cases */
 7324 tgl                     11089 CBC         477 :     switch (exp)
                              11090                 :     {
                              11091              33 :         case 0:
                              11092                 : 
 5449 bruce                   11093 ECB             :             /*
 5050                         11094                 :              * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
                              11095                 :              * it as 1 because most programming languages do this. SQL:2003
                              11096                 :              * also requires a return value of 1.
 1728 peter_e                 11097                 :              * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
 5449 bruce                   11098                 :              */
 7324 tgl                     11099 GIC          33 :             set_var_from_var(&const_one, result);
 7188 bruce                   11100              33 :             result->dscale = rscale; /* no need to round */
 7324 tgl                     11101 CBC          33 :             return;
 7324 tgl                     11102 GIC          21 :         case 1:
                              11103              21 :             set_var_from_var(base, result);
                              11104              21 :             round_var(result, rscale);
                              11105              21 :             return;
                              11106              12 :         case -1:
 6518 bruce                   11107              12 :             div_var(&const_one, base, result, rscale, true);
 7324 tgl                     11108              12 :             return;
                              11109              21 :         case 2:
 7324 tgl                     11110 CBC          21 :             mul_var(base, base, result, rscale);
                              11111              21 :             return;
 7324 tgl                     11112 GIC         390 :         default:
 7324 tgl                     11113 CBC         390 :             break;
                              11114                 :     }
                              11115                 : 
                              11116                 :     /* Handle the special case where the base is zero */
 2703 tgl                     11117 GIC         390 :     if (base->ndigits == 0)
                              11118                 :     {
 2703 tgl                     11119 UIC           0 :         if (exp < 0)
                              11120               0 :             ereport(ERROR,
                              11121                 :                     (errcode(ERRCODE_DIVISION_BY_ZERO),
                              11122                 :                      errmsg("division by zero")));
 2703 tgl                     11123 LBC           0 :         zero_var(result);
 2703 tgl                     11124 UIC           0 :         result->dscale = rscale;
 2703 tgl                     11125 LBC           0 :         return;
 2703 tgl                     11126 ECB             :     }
                              11127                 : 
                              11128                 :     /*
 7188 bruce                   11129                 :      * The general case repeatedly multiplies base according to the bit
                              11130                 :      * pattern of exp.
 2703 tgl                     11131                 :      *
                              11132                 :      * The local rscale used for each multiplication is varied to keep a fixed
                              11133                 :      * number of significant digits, sufficient to give the required result
                              11134                 :      * scale.
                              11135                 :      */
                              11136                 : 
                              11137                 :     /*
                              11138                 :      * Approximate number of significant digits in the result.  Note that the
                              11139                 :      * underflow test above, together with the choice of rscale, ensures that
                              11140                 :      * this approximation is necessarily > 0.
                              11141                 :      */
 2703 tgl                     11142 CBC         390 :     sig_digits = 1 + rscale + (int) f;
                              11143                 : 
                              11144                 :     /*
                              11145                 :      * The multiplications to produce the result may introduce an error of up
                              11146                 :      * to around log10(abs(exp)) digits, so work with this many extra digits
 2703 tgl                     11147 ECB             :      * of precision (plus a few more for good measure).
                              11148                 :      */
  824 dean.a.rasheed          11149 GIC         390 :     sig_digits += (int) log(fabs((double) exp)) + 8;
 2703 tgl                     11150 ECB             : 
                              11151                 :     /*
                              11152                 :      * Now we can proceed with the multiplications.
                              11153                 :      */
 7324 tgl                     11154 GIC         390 :     neg = (exp < 0);
  184 peter                   11155 GNC         390 :     mask = abs(exp);
                              11156                 : 
 7324 tgl                     11157 GIC         390 :     init_var(&base_prod);
                              11158             390 :     set_var_from_var(base, &base_prod);
                              11159                 : 
 3132                         11160             390 :     if (mask & 1)
 7324 tgl                     11161 CBC         195 :         set_var_from_var(base, result);
 7324 tgl                     11162 ECB             :     else
 7324 tgl                     11163 GIC         195 :         set_var_from_var(&const_one, result);
 7324 tgl                     11164 ECB             : 
 3132 tgl                     11165 GIC        2100 :     while ((mask >>= 1) > 0)
                              11166                 :     {
 2703 tgl                     11167 ECB             :         /*
                              11168                 :          * Do the multiplications using rscales large enough to hold the
                              11169                 :          * results to the required number of significant digits, but don't
                              11170                 :          * waste time by exceeding the scales of the numbers themselves.
                              11171                 :          */
 2703 tgl                     11172 CBC        1710 :         local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
 2703 tgl                     11173 GIC        1710 :         local_rscale = Min(local_rscale, 2 * base_prod.dscale);
                              11174            1710 :         local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
 2703 tgl                     11175 ECB             : 
 7324 tgl                     11176 GIC        1710 :         mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
                              11177                 : 
 3132                         11178            1710 :         if (mask & 1)
                              11179                 :         {
 2703                         11180            1137 :             local_rscale = sig_digits -
                              11181            1137 :                 (base_prod.weight + result->weight) * DEC_DIGITS;
                              11182            1137 :             local_rscale = Min(local_rscale,
                              11183                 :                                base_prod.dscale + result->dscale);
 2703 tgl                     11184 CBC        1137 :             local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
                              11185                 : 
 7324 tgl                     11186 GIC        1137 :             mul_var(&base_prod, result, result, local_rscale);
                              11187                 :         }
                              11188                 : 
                              11189                 :         /*
 3132 tgl                     11190 ECB             :          * When abs(base) > 1, the number of digits to the left of the decimal
                              11191                 :          * point in base_prod doubles at each iteration, so if exp is large we
                              11192                 :          * could easily spend large amounts of time and memory space doing the
                              11193                 :          * multiplications.  But once the weight exceeds what will fit in
                              11194                 :          * int16, the final result is guaranteed to overflow (or underflow, if
                              11195                 :          * exp < 0), so we can give up before wasting too many cycles.
                              11196                 :          */
 3132 tgl                     11197 GIC        1710 :         if (base_prod.weight > SHRT_MAX || result->weight > SHRT_MAX)
                              11198                 :         {
                              11199                 :             /* overflow, unless neg, in which case result should be 0 */
 3132 tgl                     11200 UIC           0 :             if (!neg)
                              11201               0 :                 ereport(ERROR,
                              11202                 :                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                              11203                 :                          errmsg("value overflows numeric format")));
 3132 tgl                     11204 LBC           0 :             zero_var(result);
                              11205               0 :             neg = false;
 3132 tgl                     11206 UIC           0 :             break;
                              11207                 :         }
                              11208                 :     }
                              11209                 : 
 7324 tgl                     11210 CBC         390 :     free_var(&base_prod);
                              11211                 : 
                              11212                 :     /* Compensate for input sign, and round to requested rscale */
 7324 tgl                     11213 GIC         390 :     if (neg)
 5483 tgl                     11214 CBC         183 :         div_var_fast(&const_one, result, result, rscale, true);
                              11215                 :     else
 7324 tgl                     11216 GIC         207 :         round_var(result, rscale);
                              11217                 : }
                              11218                 : 
                              11219                 : /*
                              11220                 :  * power_ten_int() -
                              11221                 :  *
                              11222                 :  *  Raise ten to the power of exp, where exp is an integer.  Note that unlike
                              11223                 :  *  power_var_int(), this does no overflow/underflow checking or rounding.
  612 dean.a.rasheed          11224 ECB             :  */
                              11225                 : static void
  612 dean.a.rasheed          11226 GIC         108 : power_ten_int(int exp, NumericVar *result)
                              11227                 : {
                              11228                 :     /* Construct the result directly, starting from 10^0 = 1 */
                              11229             108 :     set_var_from_var(&const_one, result);
                              11230                 : 
                              11231                 :     /* Scale needed to represent the result exactly */
                              11232             108 :     result->dscale = exp < 0 ? -exp : 0;
                              11233                 : 
                              11234                 :     /* Base-NBASE weight of result and remaining exponent */
  612 dean.a.rasheed          11235 CBC         108 :     if (exp >= 0)
                              11236              75 :         result->weight = exp / DEC_DIGITS;
  612 dean.a.rasheed          11237 ECB             :     else
  612 dean.a.rasheed          11238 GIC          33 :         result->weight = (exp + 1) / DEC_DIGITS - 1;
                              11239                 : 
  612 dean.a.rasheed          11240 CBC         108 :     exp -= result->weight * DEC_DIGITS;
  612 dean.a.rasheed          11241 ECB             : 
                              11242                 :     /* Final adjustment of the result's single NBASE digit */
  612 dean.a.rasheed          11243 GIC         273 :     while (exp-- > 0)
                              11244             165 :         result->digits[0] *= 10;
  612 dean.a.rasheed          11245 CBC         108 : }
  612 dean.a.rasheed          11246 ECB             : 
 8866 JanWieck                11247                 : 
                              11248                 : /* ----------------------------------------------------------------------
                              11249                 :  *
                              11250                 :  * Following are the lowest level functions that operate unsigned
                              11251                 :  * on the variable level
                              11252                 :  *
                              11253                 :  * ----------------------------------------------------------------------
                              11254                 :  */
                              11255                 : 
                              11256                 : 
                              11257                 : /* ----------
                              11258                 :  * cmp_abs() -
                              11259                 :  *
                              11260                 :  *  Compare the absolute values of var1 and var2
                              11261                 :  *  Returns:    -1 for ABS(var1) < ABS(var2)
                              11262                 :  *              0  for ABS(var1) == ABS(var2)
                              11263                 :  *              1  for ABS(var1) > ABS(var2)
                              11264                 :  * ----------
                              11265                 :  */
                              11266                 : static int
 2037 andres                  11267 GIC      143246 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
 8866 JanWieck                11268 ECB             : {
 6270 bruce                   11269 CBC      286492 :     return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
 6270 bruce                   11270 GIC      143246 :                           var2->digits, var2->ndigits, var2->weight);
 6270 bruce                   11271 ECB             : }
                              11272                 : 
                              11273                 : /* ----------
                              11274                 :  * cmp_abs_common() -
                              11275                 :  *
 6031                         11276                 :  *  Main routine of cmp_abs(). This function can be used by both
                              11277                 :  *  NumericVar and Numeric.
 6270                         11278                 :  * ----------
                              11279                 :  */
                              11280                 : static int
 6270 bruce                   11281 CBC     3240490 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
                              11282                 :                const NumericDigit *var2digits, int var2ndigits, int var2weight)
                              11283                 : {
 8720 bruce                   11284 GIC     3240490 :     int         i1 = 0;
                              11285         3240490 :     int         i2 = 0;
                              11286                 : 
                              11287                 :     /* Check any digits before the first common digit */
                              11288                 : 
 6270                         11289         3240490 :     while (var1weight > var2weight && i1 < var1ndigits)
                              11290                 :     {
 7324 tgl                     11291           10088 :         if (var1digits[i1++] != 0)
 8720 bruce                   11292           10088 :             return 1;
 6270 bruce                   11293 UIC           0 :         var1weight--;
                              11294                 :     }
 6270 bruce                   11295 GIC     3230402 :     while (var2weight > var1weight && i2 < var2ndigits)
                              11296                 :     {
 7324 tgl                     11297            9038 :         if (var2digits[i2++] != 0)
 8720 bruce                   11298            9038 :             return -1;
 6270 bruce                   11299 LBC           0 :         var2weight--;
                              11300                 :     }
 8866 JanWieck                11301 ECB             : 
 7324 tgl                     11302                 :     /* At this point, either w1 == w2 or we've run out of digits */
                              11303                 : 
 6270 bruce                   11304 CBC     3221364 :     if (var1weight == var2weight)
 8866 JanWieck                11305 ECB             :     {
 6270 bruce                   11306 GIC     6029656 :         while (i1 < var1ndigits && i2 < var2ndigits)
 8866 JanWieck                11307 ECB             :         {
 7324 tgl                     11308 GIC     4011418 :             int         stat = var1digits[i1++] - var2digits[i2++];
                              11309                 : 
 8861 JanWieck                11310         4011418 :             if (stat)
 8861 JanWieck                11311 ECB             :             {
 8861 JanWieck                11312 CBC     1203117 :                 if (stat > 0)
                              11313          784631 :                     return 1;
 8861 JanWieck                11314 GIC      418486 :                 return -1;
 8861 JanWieck                11315 ECB             :             }
 8866                         11316                 :         }
                              11317                 :     }
                              11318                 : 
                              11319                 :     /*
 6385 bruce                   11320                 :      * At this point, we've run out of digits on one side or the other; so any
 6385 bruce                   11321 EUB             :      * remaining nonzero digits imply that side is larger
                              11322                 :      */
 6270 bruce                   11323 GIC     2018415 :     while (i1 < var1ndigits)
                              11324                 :     {
 7324 tgl                     11325 CBC        1110 :         if (var1digits[i1++] != 0)
 8866 JanWieck                11326 GIC         942 :             return 1;
 8866 JanWieck                11327 ECB             :     }
 6270 bruce                   11328 CBC     2017431 :     while (i2 < var2ndigits)
 8866 JanWieck                11329 ECB             :     {
 7324 tgl                     11330 CBC         402 :         if (var2digits[i2++] != 0)
 8866 JanWieck                11331             276 :             return -1;
                              11332                 :     }
                              11333                 : 
 8866 JanWieck                11334 GIC     2017029 :     return 0;
                              11335                 : }
                              11336                 : 
                              11337                 : 
                              11338                 : /*
                              11339                 :  * add_abs() -
                              11340                 :  *
                              11341                 :  *  Add the absolute values of two variables into result.
 8866 JanWieck                11342 ECB             :  *  result might point to one of the operands without danger.
                              11343                 :  */
                              11344                 : static void
 2037 andres                  11345 GIC      148392 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
                              11346                 : {
                              11347                 :     NumericDigit *res_buf;
                              11348                 :     NumericDigit *res_digits;
                              11349                 :     int         res_ndigits;
                              11350                 :     int         res_weight;
                              11351                 :     int         res_rscale,
                              11352                 :                 rscale1,
 7324 tgl                     11353 ECB             :                 rscale2;
 8720 bruce                   11354                 :     int         res_dscale;
                              11355                 :     int         i,
                              11356                 :                 i1,
                              11357                 :                 i2;
 8720 bruce                   11358 CBC      148392 :     int         carry = 0;
 8053 bruce                   11359 ECB             : 
                              11360                 :     /* copy these values into local vars for speed in inner loop */
 8301 tgl                     11361 GIC      148392 :     int         var1ndigits = var1->ndigits;
                              11362          148392 :     int         var2ndigits = var2->ndigits;
                              11363          148392 :     NumericDigit *var1digits = var1->digits;
                              11364          148392 :     NumericDigit *var2digits = var2->digits;
                              11365                 : 
 7720 bruce                   11366 CBC      148392 :     res_weight = Max(var1->weight, var2->weight) + 1;
 7324 tgl                     11367 ECB             : 
 7720 bruce                   11368 CBC      148392 :     res_dscale = Max(var1->dscale, var2->dscale);
 7324 tgl                     11369 ECB             : 
                              11370                 :     /* Note: here we are figuring rscale in base-NBASE digits */
 7324 tgl                     11371 GIC      148392 :     rscale1 = var1->ndigits - var1->weight - 1;
                              11372          148392 :     rscale2 = var2->ndigits - var2->weight - 1;
                              11373          148392 :     res_rscale = Max(rscale1, rscale2);
                              11374                 : 
 8866 JanWieck                11375          148392 :     res_ndigits = res_rscale + res_weight + 1;
 8482 tgl                     11376 CBC      148392 :     if (res_ndigits <= 0)
 8482 tgl                     11377 LBC           0 :         res_ndigits = 1;
                              11378                 : 
 7324 tgl                     11379 CBC      148392 :     res_buf = digitbuf_alloc(res_ndigits + 1);
                              11380          148392 :     res_buf[0] = 0;             /* spare digit for later rounding */
 7324 tgl                     11381 GIC      148392 :     res_digits = res_buf + 1;
                              11382                 : 
 8866 JanWieck                11383 CBC      148392 :     i1 = res_rscale + var1->weight + 1;
                              11384          148392 :     i2 = res_rscale + var2->weight + 1;
 8866 JanWieck                11385 GIC     1594356 :     for (i = res_ndigits - 1; i >= 0; i--)
                              11386                 :     {
 8866 JanWieck                11387 CBC     1445964 :         i1--;
 8866 JanWieck                11388 GIC     1445964 :         i2--;
 8301 tgl                     11389 CBC     1445964 :         if (i1 >= 0 && i1 < var1ndigits)
                              11390          632497 :             carry += var1digits[i1];
                              11391         1445964 :         if (i2 >= 0 && i2 < var2ndigits)
 8301 tgl                     11392 GIC      498901 :             carry += var2digits[i2];
                              11393                 : 
 7324                         11394         1445964 :         if (carry >= NBASE)
                              11395                 :         {
                              11396          110947 :             res_digits[i] = carry - NBASE;
 8301                         11397          110947 :             carry = 1;
                              11398                 :         }
                              11399                 :         else
                              11400                 :         {
                              11401         1335017 :             res_digits[i] = carry;
 8301 tgl                     11402 CBC     1335017 :             carry = 0;
                              11403                 :         }
                              11404                 :     }
                              11405                 : 
 8301 tgl                     11406 GIC      148392 :     Assert(carry == 0);         /* else we failed to allow for carry out */
                              11407                 : 
 8866 JanWieck                11408          148392 :     digitbuf_free(result->buf);
                              11409          148392 :     result->ndigits = res_ndigits;
 8720 bruce                   11410          148392 :     result->buf = res_buf;
                              11411          148392 :     result->digits = res_digits;
                              11412          148392 :     result->weight = res_weight;
                              11413          148392 :     result->dscale = res_dscale;
                              11414                 : 
 7324 tgl                     11415 ECB             :     /* Remove leading/trailing zeroes */
 7324 tgl                     11416 GIC      148392 :     strip_var(result);
 8866 JanWieck                11417          148392 : }
                              11418                 : 
                              11419                 : 
 7324 tgl                     11420 ECB             : /*
                              11421                 :  * sub_abs()
 8866 JanWieck                11422                 :  *
                              11423                 :  *  Subtract the absolute value of var2 from the absolute value of var1
                              11424                 :  *  and store in result. result might point to one of the operands
                              11425                 :  *  without danger.
                              11426                 :  *
                              11427                 :  *  ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
                              11428                 :  */
                              11429                 : static void
 2037 andres                  11430 GIC      125803 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
                              11431                 : {
                              11432                 :     NumericDigit *res_buf;
                              11433                 :     NumericDigit *res_digits;
                              11434                 :     int         res_ndigits;
 8720 bruce                   11435 ECB             :     int         res_weight;
                              11436                 :     int         res_rscale,
 7324 tgl                     11437                 :                 rscale1,
                              11438                 :                 rscale2;
 8720 bruce                   11439                 :     int         res_dscale;
                              11440                 :     int         i,
                              11441                 :                 i1,
                              11442                 :                 i2;
 8720 bruce                   11443 CBC      125803 :     int         borrow = 0;
 8053 bruce                   11444 ECB             : 
                              11445                 :     /* copy these values into local vars for speed in inner loop */
 8301 tgl                     11446 GIC      125803 :     int         var1ndigits = var1->ndigits;
                              11447          125803 :     int         var2ndigits = var2->ndigits;
                              11448          125803 :     NumericDigit *var1digits = var1->digits;
                              11449          125803 :     NumericDigit *var2digits = var2->digits;
 8866 JanWieck                11450 ECB             : 
 8866 JanWieck                11451 GIC      125803 :     res_weight = var1->weight;
                              11452                 : 
 7720 bruce                   11453          125803 :     res_dscale = Max(var1->dscale, var2->dscale);
                              11454                 : 
                              11455                 :     /* Note: here we are figuring rscale in base-NBASE digits */
 7324 tgl                     11456 CBC      125803 :     rscale1 = var1->ndigits - var1->weight - 1;
                              11457          125803 :     rscale2 = var2->ndigits - var2->weight - 1;
 7324 tgl                     11458 GIC      125803 :     res_rscale = Max(rscale1, rscale2);
                              11459                 : 
 8866 JanWieck                11460          125803 :     res_ndigits = res_rscale + res_weight + 1;
 8482 tgl                     11461          125803 :     if (res_ndigits <= 0)
 8482 tgl                     11462 LBC           0 :         res_ndigits = 1;
 8866 JanWieck                11463 ECB             : 
 7324 tgl                     11464 CBC      125803 :     res_buf = digitbuf_alloc(res_ndigits + 1);
 7324 tgl                     11465 GIC      125803 :     res_buf[0] = 0;             /* spare digit for later rounding */
 7324 tgl                     11466 CBC      125803 :     res_digits = res_buf + 1;
                              11467                 : 
 8866 JanWieck                11468 GIC      125803 :     i1 = res_rscale + var1->weight + 1;
 8866 JanWieck                11469 CBC      125803 :     i2 = res_rscale + var2->weight + 1;
                              11470         2143353 :     for (i = res_ndigits - 1; i >= 0; i--)
 8866 JanWieck                11471 ECB             :     {
 8866 JanWieck                11472 GIC     2017550 :         i1--;
                              11473         2017550 :         i2--;
 8301 tgl                     11474 CBC     2017550 :         if (i1 >= 0 && i1 < var1ndigits)
 8301 tgl                     11475 GIC     1847994 :             borrow += var1digits[i1];
                              11476         2017550 :         if (i2 >= 0 && i2 < var2ndigits)
                              11477         1805219 :             borrow -= var2digits[i2];
                              11478                 : 
 8866 JanWieck                11479         2017550 :         if (borrow < 0)
                              11480                 :         {
 7324 tgl                     11481          190584 :             res_digits[i] = borrow + NBASE;
 8866 JanWieck                11482          190584 :             borrow = -1;
                              11483                 :         }
                              11484                 :         else
                              11485                 :         {
                              11486         1826966 :             res_digits[i] = borrow;
                              11487         1826966 :             borrow = 0;
                              11488                 :         }
                              11489                 :     }
                              11490                 : 
 8301 tgl                     11491          125803 :     Assert(borrow == 0);        /* else caller gave us var1 < var2 */
                              11492                 : 
 8866 JanWieck                11493          125803 :     digitbuf_free(result->buf);
 8866 JanWieck                11494 CBC      125803 :     result->ndigits = res_ndigits;
 8720 bruce                   11495 GIC      125803 :     result->buf = res_buf;
                              11496          125803 :     result->digits = res_digits;
                              11497          125803 :     result->weight = res_weight;
                              11498          125803 :     result->dscale = res_dscale;
                              11499                 : 
                              11500                 :     /* Remove leading/trailing zeroes */
 7324 tgl                     11501 CBC      125803 :     strip_var(result);
                              11502          125803 : }
                              11503                 : 
 7324 tgl                     11504 ECB             : /*
                              11505                 :  * round_var
                              11506                 :  *
                              11507                 :  * Round the value of a variable to no more than rscale decimal digits
                              11508                 :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
                              11509                 :  * rounding before the decimal point.
                              11510                 :  */
                              11511                 : static void
 7324 tgl                     11512 GIC      496023 : round_var(NumericVar *var, int rscale)
 7324 tgl                     11513 ECB             : {
 7188 bruce                   11514 GBC      496023 :     NumericDigit *digits = var->digits;
                              11515                 :     int         di;
                              11516                 :     int         ndigits;
 7324 tgl                     11517 ECB             :     int         carry;
                              11518                 : 
 7324 tgl                     11519 CBC      496023 :     var->dscale = rscale;
                              11520                 : 
                              11521                 :     /* decimal digits wanted */
                              11522          496023 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
                              11523                 : 
                              11524                 :     /*
 6385 bruce                   11525 ECB             :      * If di = 0, the value loses all digits, but could round up to 1 if its
                              11526                 :      * first extra digit is >= 5.  If di < 0 the result must be 0.
 7324 tgl                     11527                 :      */
 7324 tgl                     11528 CBC      496023 :     if (di < 0)
 7324 tgl                     11529 ECB             :     {
 7324 tgl                     11530 GIC          34 :         var->ndigits = 0;
                              11531              34 :         var->weight = 0;
 7324 tgl                     11532 CBC          34 :         var->sign = NUMERIC_POS;
 7324 tgl                     11533 ECB             :     }
                              11534                 :     else
                              11535                 :     {
                              11536                 :         /* NBASE digits wanted */
 7188 bruce                   11537 CBC      495989 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
                              11538                 : 
                              11539                 :         /* 0, or number of decimal digits to keep in last NBASE digit */
 7324 tgl                     11540 GIC      495989 :         di %= DEC_DIGITS;
 7324 tgl                     11541 ECB             : 
 7324 tgl                     11542 GIC      495989 :         if (ndigits < var->ndigits ||
 7324 tgl                     11543 CBC      409732 :             (ndigits == var->ndigits && di > 0))
                              11544                 :         {
                              11545          329635 :             var->ndigits = ndigits;
                              11546                 : 
 7324 tgl                     11547 ECB             : #if DEC_DIGITS == 1
                              11548                 :             /* di must be zero */
                              11549                 :             carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
                              11550                 : #else
 7324 tgl                     11551 CBC      329635 :             if (di == 0)
                              11552           67146 :                 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
                              11553                 :             else
                              11554                 :             {
                              11555                 :                 /* Must round within last NBASE digit */
                              11556                 :                 int         extra,
                              11557                 :                             pow10;
                              11558                 : 
                              11559                 : #if DEC_DIGITS == 4
 7324 tgl                     11560 GIC      262489 :                 pow10 = round_powers[di];
                              11561                 : #elif DEC_DIGITS == 2
                              11562                 :                 pow10 = 10;
 7324 tgl                     11563 ECB             : #else
                              11564                 : #error unsupported NBASE
                              11565                 : #endif
 7324 tgl                     11566 GIC      262489 :                 extra = digits[--ndigits] % pow10;
                              11567          262489 :                 digits[ndigits] -= extra;
                              11568          262489 :                 carry = 0;
 7188 bruce                   11569          262489 :                 if (extra >= pow10 / 2)
                              11570                 :                 {
 7324 tgl                     11571            9665 :                     pow10 += digits[ndigits];
                              11572            9665 :                     if (pow10 >= NBASE)
                              11573                 :                     {
                              11574             406 :                         pow10 -= NBASE;
                              11575             406 :                         carry = 1;
                              11576                 :                     }
                              11577            9665 :                     digits[ndigits] = pow10;
                              11578                 :                 }
                              11579                 :             }
                              11580                 : #endif
                              11581                 : 
                              11582                 :             /* Propagate carry if needed */
                              11583          347212 :             while (carry)
                              11584                 :             {
 7324 tgl                     11585 CBC       17577 :                 carry += digits[--ndigits];
 7324 tgl                     11586 GIC       17577 :                 if (carry >= NBASE)
                              11587                 :                 {
                              11588           12387 :                     digits[ndigits] = carry - NBASE;
                              11589           12387 :                     carry = 1;
                              11590                 :                 }
                              11591                 :                 else
 7324 tgl                     11592 ECB             :                 {
 7324 tgl                     11593 CBC        5190 :                     digits[ndigits] = carry;
 7324 tgl                     11594 GIC        5190 :                     carry = 0;
 7324 tgl                     11595 ECB             :                 }
                              11596                 :             }
                              11597                 : 
 7324 tgl                     11598 CBC      329635 :             if (ndigits < 0)
                              11599                 :             {
 7324 tgl                     11600 GIC          45 :                 Assert(ndigits == -1);  /* better not have added > 1 digit */
 7324 tgl                     11601 CBC          45 :                 Assert(var->digits > var->buf);
 7324 tgl                     11602 GIC          45 :                 var->digits--;
                              11603              45 :                 var->ndigits++;
 7324 tgl                     11604 CBC          45 :                 var->weight++;
                              11605                 :             }
                              11606                 :         }
 7324 tgl                     11607 ECB             :     }
 7324 tgl                     11608 CBC      496023 : }
                              11609                 : 
                              11610                 : /*
 7324 tgl                     11611 ECB             :  * trunc_var
                              11612                 :  *
 5483                         11613                 :  * Truncate (towards zero) the value of a variable at rscale decimal digits
                              11614                 :  * after the decimal point.  NOTE: we allow rscale < 0 here, implying
 7324                         11615                 :  * truncation before the decimal point.
                              11616                 :  */
                              11617                 : static void
 7324 tgl                     11618 GIC       29884 : trunc_var(NumericVar *var, int rscale)
                              11619                 : {
                              11620                 :     int         di;
                              11621                 :     int         ndigits;
                              11622                 : 
 7324 tgl                     11623 CBC       29884 :     var->dscale = rscale;
 7324 tgl                     11624 ECB             : 
                              11625                 :     /* decimal digits wanted */
 7324 tgl                     11626 CBC       29884 :     di = (var->weight + 1) * DEC_DIGITS + rscale;
 7324 tgl                     11627 ECB             : 
                              11628                 :     /*
                              11629                 :      * If di <= 0, the value loses all digits.
                              11630                 :      */
 7324 tgl                     11631 GIC       29884 :     if (di <= 0)
 7324 tgl                     11632 ECB             :     {
 7324 tgl                     11633 GIC          27 :         var->ndigits = 0;
                              11634              27 :         var->weight = 0;
                              11635              27 :         var->sign = NUMERIC_POS;
                              11636                 :     }
                              11637                 :     else
                              11638                 :     {
                              11639                 :         /* NBASE digits wanted */
 7188 bruce                   11640 CBC       29857 :         ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
 7324 tgl                     11641 ECB             : 
 7324 tgl                     11642 CBC       29857 :         if (ndigits <= var->ndigits)
 7324 tgl                     11643 ECB             :         {
 7324 tgl                     11644 CBC       29761 :             var->ndigits = ndigits;
 7324 tgl                     11645 ECB             : 
                              11646                 : #if DEC_DIGITS == 1
                              11647                 :             /* no within-digit stuff to worry about */
                              11648                 : #else
                              11649                 :             /* 0, or number of decimal digits to keep in last NBASE digit */
 7324 tgl                     11650 CBC       29761 :             di %= DEC_DIGITS;
 7324 tgl                     11651 ECB             : 
 7324 tgl                     11652 CBC       29761 :             if (di > 0)
 7324 tgl                     11653 ECB             :             {
                              11654                 :                 /* Must truncate within last NBASE digit */
 7188 bruce                   11655 GIC          41 :                 NumericDigit *digits = var->digits;
                              11656                 :                 int         extra,
                              11657                 :                             pow10;
 7324 tgl                     11658 ECB             : 
                              11659                 : #if DEC_DIGITS == 4
 7324 tgl                     11660 GBC          41 :                 pow10 = round_powers[di];
 7324 tgl                     11661 EUB             : #elif DEC_DIGITS == 2
                              11662                 :                 pow10 = 10;
                              11663                 : #else
                              11664                 : #error unsupported NBASE
                              11665                 : #endif
 7324 tgl                     11666 GBC          41 :                 extra = digits[--ndigits] % pow10;
 7324 tgl                     11667 GIC          41 :                 digits[ndigits] -= extra;
                              11668                 :             }
                              11669                 : #endif
                              11670                 :         }
                              11671                 :     }
                              11672           29884 : }
                              11673                 : 
                              11674                 : /*
                              11675                 :  * strip_var
                              11676                 :  *
                              11677                 :  * Strip any leading and trailing zeroes from a numeric variable
                              11678                 :  */
                              11679                 : static void
                              11680          938626 : strip_var(NumericVar *var)
                              11681                 : {
 7188 bruce                   11682          938626 :     NumericDigit *digits = var->digits;
 7324 tgl                     11683 CBC      938626 :     int         ndigits = var->ndigits;
                              11684                 : 
                              11685                 :     /* Strip leading zeroes */
 7324 tgl                     11686 GIC     2226262 :     while (ndigits > 0 && *digits == 0)
                              11687                 :     {
                              11688         1287636 :         digits++;
                              11689         1287636 :         var->weight--;
 7324 tgl                     11690 CBC     1287636 :         ndigits--;
                              11691                 :     }
                              11692                 : 
                              11693                 :     /* Strip trailing zeroes */
 7324 tgl                     11694 GIC     1216040 :     while (ndigits > 0 && digits[ndigits - 1] == 0)
 7324 tgl                     11695 CBC      277414 :         ndigits--;
 7324 tgl                     11696 ECB             : 
                              11697                 :     /* If it's zero, normalize the sign and weight */
 7324 tgl                     11698 CBC      938626 :     if (ndigits == 0)
 7324 tgl                     11699 ECB             :     {
 7324 tgl                     11700 GIC       12984 :         var->sign = NUMERIC_POS;
 7324 tgl                     11701 CBC       12984 :         var->weight = 0;
 7324 tgl                     11702 ECB             :     }
                              11703                 : 
 7324 tgl                     11704 CBC      938626 :     var->digits = digits;
 7324 tgl                     11705 GIC      938626 :     var->ndigits = ndigits;
 8866 JanWieck                11706 CBC      938626 : }
                              11707                 : 
                              11708                 : 
                              11709                 : /* ----------------------------------------------------------------------
                              11710                 :  *
                              11711                 :  * Fast sum accumulator functions
                              11712                 :  *
 2410 heikki.linnakangas      11713 ECB             :  * ----------------------------------------------------------------------
                              11714                 :  */
                              11715                 : 
                              11716                 : /*
                              11717                 :  * Reset the accumulator's value to zero.  The buffers to hold the digits
                              11718                 :  * are not free'd.
                              11719                 :  */
                              11720                 : static void
 2410 heikki.linnakangas      11721 CBC           9 : accum_sum_reset(NumericSumAccum *accum)
 2410 heikki.linnakangas      11722 ECB             : {
                              11723                 :     int         i;
                              11724                 : 
 2410 heikki.linnakangas      11725 CBC           9 :     accum->dscale = 0;
 2410 heikki.linnakangas      11726 GIC          33 :     for (i = 0; i < accum->ndigits; i++)
 2410 heikki.linnakangas      11727 ECB             :     {
 2410 heikki.linnakangas      11728 GIC          24 :         accum->pos_digits[i] = 0;
                              11729              24 :         accum->neg_digits[i] = 0;
                              11730                 :     }
                              11731               9 : }
                              11732                 : 
                              11733                 : /*
                              11734                 :  * Accumulate a new value.
                              11735                 :  */
                              11736                 : static void
 2037 andres                  11737         1177852 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
 2410 heikki.linnakangas      11738 ECB             : {
                              11739                 :     int32      *accum_digits;
                              11740                 :     int         i,
 2410 heikki.linnakangas      11741 EUB             :                 val_i;
                              11742                 :     int         val_ndigits;
                              11743                 :     NumericDigit *val_digits;
                              11744                 : 
                              11745                 :     /*
                              11746                 :      * If we have accumulated too many values since the last carry
                              11747                 :      * propagation, do it now, to avoid overflowing.  (We could allow more
                              11748                 :      * than NBASE - 1, if we reserved two extra digits, rather than one, for
                              11749                 :      * carry propagation.  But even with NBASE - 1, this needs to be done so
                              11750                 :      * seldom, that the performance difference is negligible.)
 2410 heikki.linnakangas      11751 ECB             :      */
 2410 heikki.linnakangas      11752 GIC     1177852 :     if (accum->num_uncarried == NBASE - 1)
                              11753              81 :         accum_sum_carry(accum);
 2410 heikki.linnakangas      11754 ECB             : 
                              11755                 :     /*
                              11756                 :      * Adjust the weight or scale of the old value, so that it can accommodate
                              11757                 :      * the new value.
                              11758                 :      */
 2410 heikki.linnakangas      11759 GIC     1177852 :     accum_sum_rescale(accum, val);
                              11760                 : 
                              11761                 :     /* */
                              11762         1177852 :     if (val->sign == NUMERIC_POS)
                              11763          877513 :         accum_digits = accum->pos_digits;
                              11764                 :     else
                              11765          300339 :         accum_digits = accum->neg_digits;
                              11766                 : 
 2410 heikki.linnakangas      11767 ECB             :     /* copy these values into local vars for speed in loop */
 2410 heikki.linnakangas      11768 GIC     1177852 :     val_ndigits = val->ndigits;
                              11769         1177852 :     val_digits = val->digits;
 2410 heikki.linnakangas      11770 ECB             : 
 2410 heikki.linnakangas      11771 GIC     1177852 :     i = accum->weight - val->weight;
                              11772         5944973 :     for (val_i = 0; val_i < val_ndigits; val_i++)
 2410 heikki.linnakangas      11773 ECB             :     {
 2410 heikki.linnakangas      11774 GIC     4767121 :         accum_digits[i] += (int32) val_digits[val_i];
                              11775         4767121 :         i++;
 2410 heikki.linnakangas      11776 ECB             :     }
                              11777                 : 
 2410 heikki.linnakangas      11778 GIC     1177852 :     accum->num_uncarried++;
 2410 heikki.linnakangas      11779 CBC     1177852 : }
                              11780                 : 
 2410 heikki.linnakangas      11781 ECB             : /*
                              11782                 :  * Propagate carries.
                              11783                 :  */
                              11784                 : static void
 2410 heikki.linnakangas      11785 CBC       86382 : accum_sum_carry(NumericSumAccum *accum)
 2410 heikki.linnakangas      11786 ECB             : {
                              11787                 :     int         i;
                              11788                 :     int         ndigits;
                              11789                 :     int32      *dig;
                              11790                 :     int32       carry;
 2410 heikki.linnakangas      11791 GIC       86382 :     int32       newdig = 0;
                              11792                 : 
                              11793                 :     /*
                              11794                 :      * If no new values have been added since last carry propagation, nothing
                              11795                 :      * to do.
                              11796                 :      */
                              11797           86382 :     if (accum->num_uncarried == 0)
                              11798              36 :         return;
                              11799                 : 
                              11800                 :     /*
                              11801                 :      * We maintain that the weight of the accumulator is always one larger
                              11802                 :      * than needed to hold the current value, before carrying, to make sure
                              11803                 :      * there is enough space for the possible extra digit when carry is
                              11804                 :      * propagated.  We cannot expand the buffer here, unless we require
                              11805                 :      * callers of accum_sum_final() to switch to the right memory context.
                              11806                 :      */
                              11807           86346 :     Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
 2410 heikki.linnakangas      11808 ECB             : 
 2410 heikki.linnakangas      11809 GIC       86346 :     ndigits = accum->ndigits;
 2410 heikki.linnakangas      11810 ECB             : 
                              11811                 :     /* Propagate carry in the positive sum */
 2410 heikki.linnakangas      11812 GIC       86346 :     dig = accum->pos_digits;
                              11813           86346 :     carry = 0;
                              11814         1302779 :     for (i = ndigits - 1; i >= 0; i--)
                              11815                 :     {
                              11816         1216433 :         newdig = dig[i] + carry;
                              11817         1216433 :         if (newdig >= NBASE)
                              11818                 :         {
                              11819           55407 :             carry = newdig / NBASE;
                              11820           55407 :             newdig -= carry * NBASE;
                              11821                 :         }
 2410 heikki.linnakangas      11822 ECB             :         else
 2410 heikki.linnakangas      11823 GIC     1161026 :             carry = 0;
                              11824         1216433 :         dig[i] = newdig;
 2410 heikki.linnakangas      11825 ECB             :     }
                              11826                 :     /* Did we use up the digit reserved for carry propagation? */
 2410 heikki.linnakangas      11827 GIC       86346 :     if (newdig > 0)
                              11828            1321 :         accum->have_carry_space = false;
                              11829                 : 
 2410 heikki.linnakangas      11830 ECB             :     /* And the same for the negative sum */
 2410 heikki.linnakangas      11831 GIC       86346 :     dig = accum->neg_digits;
 2410 heikki.linnakangas      11832 CBC       86346 :     carry = 0;
                              11833         1302779 :     for (i = ndigits - 1; i >= 0; i--)
 2410 heikki.linnakangas      11834 EUB             :     {
 2410 heikki.linnakangas      11835 GIC     1216433 :         newdig = dig[i] + carry;
 2410 heikki.linnakangas      11836 CBC     1216433 :         if (newdig >= NBASE)
                              11837                 :         {
                              11838              99 :             carry = newdig / NBASE;
                              11839              99 :             newdig -= carry * NBASE;
 2410 heikki.linnakangas      11840 EUB             :         }
                              11841                 :         else
 2410 heikki.linnakangas      11842 GIC     1216334 :             carry = 0;
                              11843         1216433 :         dig[i] = newdig;
                              11844                 :     }
 2410 heikki.linnakangas      11845 CBC       86346 :     if (newdig > 0)
 2410 heikki.linnakangas      11846 GIC          15 :         accum->have_carry_space = false;
 2410 heikki.linnakangas      11847 ECB             : 
 2410 heikki.linnakangas      11848 GIC       86346 :     accum->num_uncarried = 0;
 2410 heikki.linnakangas      11849 ECB             : }
                              11850                 : 
                              11851                 : /*
                              11852                 :  * Re-scale accumulator to accommodate new value.
                              11853                 :  *
                              11854                 :  * If the new value has more digits than the current digit buffers in the
                              11855                 :  * accumulator, enlarge the buffers.
                              11856                 :  */
                              11857                 : static void
 2037 andres                  11858 GIC     1177852 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
                              11859                 : {
 2410 heikki.linnakangas      11860         1177852 :     int         old_weight = accum->weight;
                              11861         1177852 :     int         old_ndigits = accum->ndigits;
                              11862                 :     int         accum_ndigits;
                              11863                 :     int         accum_weight;
 2410 heikki.linnakangas      11864 ECB             :     int         accum_rscale;
                              11865                 :     int         val_rscale;
                              11866                 : 
 2410 heikki.linnakangas      11867 CBC     1177852 :     accum_weight = old_weight;
 2410 heikki.linnakangas      11868 GIC     1177852 :     accum_ndigits = old_ndigits;
 2410 heikki.linnakangas      11869 ECB             : 
                              11870                 :     /*
                              11871                 :      * Does the new value have a larger weight? If so, enlarge the buffers,
                              11872                 :      * and shift the existing value to the new weight, by adding leading
                              11873                 :      * zeros.
                              11874                 :      *
                              11875                 :      * We enforce that the accumulator always has a weight one larger than
                              11876                 :      * needed for the inputs, so that we have space for an extra digit at the
                              11877                 :      * final carry-propagation phase, if necessary.
                              11878                 :      */
 2410 heikki.linnakangas      11879 GIC     1177852 :     if (val->weight >= accum_weight)
                              11880                 :     {
                              11881          131114 :         accum_weight = val->weight + 1;
                              11882          131114 :         accum_ndigits = accum_ndigits + (accum_weight - old_weight);
                              11883                 :     }
                              11884                 : 
                              11885                 :     /*
 2410 heikki.linnakangas      11886 ECB             :      * Even though the new value is small, we might've used up the space
                              11887                 :      * reserved for the carry digit in the last call to accum_sum_carry().  If
                              11888                 :      * so, enlarge to make room for another one.
                              11889                 :      */
 2410 heikki.linnakangas      11890 GIC     1046738 :     else if (!accum->have_carry_space)
                              11891                 :     {
                              11892              37 :         accum_weight++;
                              11893              37 :         accum_ndigits++;
                              11894                 :     }
                              11895                 : 
                              11896                 :     /* Is the new value wider on the right side? */
                              11897         1177852 :     accum_rscale = accum_ndigits - accum_weight - 1;
                              11898         1177852 :     val_rscale = val->ndigits - val->weight - 1;
 2410 heikki.linnakangas      11899 CBC     1177852 :     if (val_rscale > accum_rscale)
 2410 heikki.linnakangas      11900 GIC       86123 :         accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
                              11901                 : 
 2410 heikki.linnakangas      11902 CBC     1177852 :     if (accum_ndigits != old_ndigits ||
 2410 heikki.linnakangas      11903 ECB             :         accum_weight != old_weight)
                              11904                 :     {
                              11905                 :         int32      *new_pos_digits;
                              11906                 :         int32      *new_neg_digits;
                              11907                 :         int         weightdiff;
                              11908                 : 
 2410 heikki.linnakangas      11909 CBC      131298 :         weightdiff = accum_weight - old_weight;
                              11910                 : 
 2410 heikki.linnakangas      11911 GIC      131298 :         new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
 2410 heikki.linnakangas      11912 CBC      131298 :         new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
 2410 heikki.linnakangas      11913 ECB             : 
 2410 heikki.linnakangas      11914 CBC      131298 :         if (accum->pos_digits)
                              11915                 :         {
                              11916           45210 :             memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
 2410 heikki.linnakangas      11917 ECB             :                    old_ndigits * sizeof(int32));
 2410 heikki.linnakangas      11918 GBC       45210 :             pfree(accum->pos_digits);
                              11919                 : 
 2410 heikki.linnakangas      11920 CBC       45210 :             memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
 2410 heikki.linnakangas      11921 ECB             :                    old_ndigits * sizeof(int32));
 2410 heikki.linnakangas      11922 CBC       45210 :             pfree(accum->neg_digits);
                              11923                 :         }
 2410 heikki.linnakangas      11924 ECB             : 
 2410 heikki.linnakangas      11925 CBC      131298 :         accum->pos_digits = new_pos_digits;
                              11926          131298 :         accum->neg_digits = new_neg_digits;
                              11927                 : 
                              11928          131298 :         accum->weight = accum_weight;
                              11929          131298 :         accum->ndigits = accum_ndigits;
 2410 heikki.linnakangas      11930 ECB             : 
 2410 heikki.linnakangas      11931 CBC      131298 :         Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
                              11932          131298 :         accum->have_carry_space = true;
 2410 heikki.linnakangas      11933 ECB             :     }
                              11934                 : 
 2410 heikki.linnakangas      11935 CBC     1177852 :     if (val->dscale > accum->dscale)
 2410 heikki.linnakangas      11936 GIC         150 :         accum->dscale = val->dscale;
 2410 heikki.linnakangas      11937 CBC     1177852 : }
 2410 heikki.linnakangas      11938 ECB             : 
                              11939                 : /*
                              11940                 :  * Return the current value of the accumulator.  This perform final carry
                              11941                 :  * propagation, and adds together the positive and negative sums.
                              11942                 :  *
                              11943                 :  * Unlike all the other routines, the caller is not required to switch to
                              11944                 :  * the memory context that holds the accumulator.
                              11945                 :  */
                              11946                 : static void
 2410 heikki.linnakangas      11947 CBC       86301 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
                              11948                 : {
 2410 heikki.linnakangas      11949 ECB             :     int         i;
                              11950                 :     NumericVar  pos_var;
                              11951                 :     NumericVar  neg_var;
                              11952                 : 
 2410 heikki.linnakangas      11953 CBC       86301 :     if (accum->ndigits == 0)
 2410 heikki.linnakangas      11954 ECB             :     {
 2410 heikki.linnakangas      11955 UIC           0 :         set_var_from_var(&const_zero, result);
                              11956               0 :         return;
 2410 heikki.linnakangas      11957 ECB             :     }
                              11958                 : 
                              11959                 :     /* Perform final carry */
 2410 heikki.linnakangas      11960 GIC       86301 :     accum_sum_carry(accum);
                              11961                 : 
                              11962                 :     /* Create NumericVars representing the positive and negative sums */
                              11963           86301 :     init_var(&pos_var);
                              11964           86301 :     init_var(&neg_var);
                              11965                 : 
                              11966           86301 :     pos_var.ndigits = neg_var.ndigits = accum->ndigits;
                              11967           86301 :     pos_var.weight = neg_var.weight = accum->weight;
                              11968           86301 :     pos_var.dscale = neg_var.dscale = accum->dscale;
                              11969           86301 :     pos_var.sign = NUMERIC_POS;
                              11970           86301 :     neg_var.sign = NUMERIC_NEG;
 2410 heikki.linnakangas      11971 ECB             : 
 2410 heikki.linnakangas      11972 GIC       86301 :     pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
                              11973           86301 :     neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
                              11974                 : 
                              11975         1302547 :     for (i = 0; i < accum->ndigits; i++)
                              11976                 :     {
                              11977         1216246 :         Assert(accum->pos_digits[i] < NBASE);
                              11978         1216246 :         pos_var.digits[i] = (int16) accum->pos_digits[i];
                              11979                 : 
                              11980         1216246 :         Assert(accum->neg_digits[i] < NBASE);
                              11981         1216246 :         neg_var.digits[i] = (int16) accum->neg_digits[i];
                              11982                 :     }
                              11983                 : 
 2410 heikki.linnakangas      11984 ECB             :     /* And add them together */
 2410 heikki.linnakangas      11985 GIC       86301 :     add_var(&pos_var, &neg_var, result);
                              11986                 : 
 2410 heikki.linnakangas      11987 ECB             :     /* Remove leading/trailing zeroes */
 2410 heikki.linnakangas      11988 CBC       86301 :     strip_var(result);
 2410 heikki.linnakangas      11989 ECB             : }
                              11990                 : 
                              11991                 : /*
                              11992                 :  * Copy an accumulator's state.
                              11993                 :  *
                              11994                 :  * 'dst' is assumed to be uninitialized beforehand.  No attempt is made at
                              11995                 :  * freeing old values.
                              11996                 :  */
                              11997                 : static void
 2410 heikki.linnakangas      11998 CBC          21 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
 2410 heikki.linnakangas      11999 ECB             : {
 2410 heikki.linnakangas      12000 GIC          21 :     dst->pos_digits = palloc(src->ndigits * sizeof(int32));
 2410 heikki.linnakangas      12001 CBC          21 :     dst->neg_digits = palloc(src->ndigits * sizeof(int32));
 2410 heikki.linnakangas      12002 ECB             : 
 2410 heikki.linnakangas      12003 GBC          21 :     memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
 2410 heikki.linnakangas      12004 GIC          21 :     memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
 2410 heikki.linnakangas      12005 CBC          21 :     dst->num_uncarried = src->num_uncarried;
                              12006              21 :     dst->ndigits = src->ndigits;
                              12007              21 :     dst->weight = src->weight;
 2410 heikki.linnakangas      12008 GIC          21 :     dst->dscale = src->dscale;
 2410 heikki.linnakangas      12009 CBC          21 : }
 2410 heikki.linnakangas      12010 ECB             : 
                              12011                 : /*
                              12012                 :  * Add the current value of 'accum2' into 'accum'.
                              12013                 :  */
                              12014                 : static void
 2410 heikki.linnakangas      12015 CBC          24 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
 2410 heikki.linnakangas      12016 ECB             : {
                              12017                 :     NumericVar  tmp_var;
                              12018                 : 
 2410 heikki.linnakangas      12019 GIC          24 :     init_var(&tmp_var);
 2410 heikki.linnakangas      12020 ECB             : 
 2410 heikki.linnakangas      12021 GIC          24 :     accum_sum_final(accum2, &tmp_var);
 2410 heikki.linnakangas      12022 CBC          24 :     accum_sum_add(accum, &tmp_var);
 2410 heikki.linnakangas      12023 ECB             : 
 2410 heikki.linnakangas      12024 GIC          24 :     free_var(&tmp_var);
                              12025              24 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a