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