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