Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * numeric.c
4 : * An exact numeric data type for the Postgres database system
5 : *
6 : * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane.
7 : *
8 : * Many of the algorithmic ideas are borrowed from David M. Smith's "FM"
9 : * multiple-precision math library, most recently published as Algorithm
10 : * 786: Multiple-Precision Complex Arithmetic and Functions, ACM
11 : * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998,
12 : * pages 359-367.
13 : *
14 : * Copyright (c) 1998-2026, 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 "common/hashfn.h"
30 : #include "common/int.h"
31 : #include "common/int128.h"
32 : #include "funcapi.h"
33 : #include "lib/hyperloglog.h"
34 : #include "libpq/pqformat.h"
35 : #include "miscadmin.h"
36 : #include "nodes/nodeFuncs.h"
37 : #include "nodes/supportnodes.h"
38 : #include "optimizer/optimizer.h"
39 : #include "utils/array.h"
40 : #include "utils/builtins.h"
41 : #include "utils/float.h"
42 : #include "utils/guc.h"
43 : #include "utils/numeric.h"
44 : #include "utils/pg_lsn.h"
45 : #include "utils/sortsupport.h"
46 :
47 : /* ----------
48 : * Uncomment the following to enable compilation of dump_numeric()
49 : * and dump_var() and to get a dump of any result produced by make_result().
50 : * ----------
51 : */
52 : /* #define NUMERIC_DEBUG */
53 :
54 :
55 : /* ----------
56 : * Local data types
57 : *
58 : * Numeric values are represented in a base-NBASE floating point format.
59 : * Each "digit" ranges from 0 to NBASE-1. The type NumericDigit is signed
60 : * and wide enough to store a digit. We assume that NBASE*NBASE can fit in
61 : * an int. Although the purely calculational routines could handle any even
62 : * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
63 : * in NBASE a power of ten, so that I/O conversions and decimal rounding
64 : * are easy. Also, it's actually more efficient if NBASE is rather less than
65 : * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var to
66 : * postpone processing carries.
67 : *
68 : * Values of NBASE other than 10000 are considered of historical interest only
69 : * and are no longer supported in any sense; no mechanism exists for the client
70 : * to discover the base, so every client supporting binary mode expects the
71 : * base-10000 format. If you plan to change this, also note the numeric
72 : * abbreviation code, which assumes NBASE=10000.
73 : * ----------
74 : */
75 :
76 : #if 0
77 : #define NBASE 10
78 : #define HALF_NBASE 5
79 : #define DEC_DIGITS 1 /* decimal digits per NBASE digit */
80 : #define MUL_GUARD_DIGITS 4 /* these are measured in NBASE digits */
81 : #define DIV_GUARD_DIGITS 8
82 :
83 : typedef signed char NumericDigit;
84 : #endif
85 :
86 : #if 0
87 : #define NBASE 100
88 : #define HALF_NBASE 50
89 : #define DEC_DIGITS 2 /* decimal digits per NBASE digit */
90 : #define MUL_GUARD_DIGITS 3 /* these are measured in NBASE digits */
91 : #define DIV_GUARD_DIGITS 6
92 :
93 : typedef signed char NumericDigit;
94 : #endif
95 :
96 : #if 1
97 : #define NBASE 10000
98 : #define HALF_NBASE 5000
99 : #define DEC_DIGITS 4 /* decimal digits per NBASE digit */
100 : #define MUL_GUARD_DIGITS 2 /* these are measured in NBASE digits */
101 : #define DIV_GUARD_DIGITS 4
102 :
103 : typedef int16 NumericDigit;
104 : #endif
105 :
106 : #define NBASE_SQR (NBASE * NBASE)
107 :
108 : /*
109 : * The Numeric type as stored on disk.
110 : *
111 : * If the high bits of the first word of a NumericChoice (n_header, or
112 : * n_short.n_header, or n_long.n_sign_dscale) are NUMERIC_SHORT, then the
113 : * numeric follows the NumericShort format; if they are NUMERIC_POS or
114 : * NUMERIC_NEG, it follows the NumericLong format. If they are NUMERIC_SPECIAL,
115 : * the value is a NaN or Infinity. We currently always store SPECIAL values
116 : * using just two bytes (i.e. only n_header), but previous releases used only
117 : * the NumericLong format, so we might find 4-byte NaNs (though not infinities)
118 : * on disk if a database has been migrated using pg_upgrade. In either case,
119 : * the low-order bits of a special value's header are reserved and currently
120 : * should always be set to zero.
121 : *
122 : * In the NumericShort format, the remaining 14 bits of the header word
123 : * (n_short.n_header) are allocated as follows: 1 for sign (positive or
124 : * negative), 6 for dynamic scale, and 7 for weight. In practice, most
125 : * commonly-encountered values can be represented this way.
126 : *
127 : * In the NumericLong format, the remaining 14 bits of the header word
128 : * (n_long.n_sign_dscale) represent the display scale; and the weight is
129 : * stored separately in n_weight.
130 : *
131 : * NOTE: by convention, values in the packed form have been stripped of
132 : * all leading and trailing zero digits (where a "digit" is of base NBASE).
133 : * In particular, if the value is zero, there will be no digits at all!
134 : * The weight is arbitrary in that case, but we normally set it to zero.
135 : */
136 :
137 : struct NumericShort
138 : {
139 : uint16 n_header; /* Sign + display scale + weight */
140 : NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
141 : };
142 :
143 : struct NumericLong
144 : {
145 : uint16 n_sign_dscale; /* Sign + display scale */
146 : int16 n_weight; /* Weight of 1st digit */
147 : NumericDigit n_data[FLEXIBLE_ARRAY_MEMBER]; /* Digits */
148 : };
149 :
150 : union NumericChoice
151 : {
152 : uint16 n_header; /* Header word */
153 : struct NumericLong n_long; /* Long form (4-byte header) */
154 : struct NumericShort n_short; /* Short form (2-byte header) */
155 : };
156 :
157 : struct NumericData
158 : {
159 : int32 vl_len_; /* varlena header (do not touch directly!) */
160 : union NumericChoice choice; /* choice of format */
161 : };
162 :
163 :
164 : /*
165 : * Interpretation of high bits.
166 : */
167 :
168 : #define NUMERIC_SIGN_MASK 0xC000
169 : #define NUMERIC_POS 0x0000
170 : #define NUMERIC_NEG 0x4000
171 : #define NUMERIC_SHORT 0x8000
172 : #define NUMERIC_SPECIAL 0xC000
173 :
174 : #define NUMERIC_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_SIGN_MASK)
175 : #define NUMERIC_IS_SHORT(n) (NUMERIC_FLAGBITS(n) == NUMERIC_SHORT)
176 : #define NUMERIC_IS_SPECIAL(n) (NUMERIC_FLAGBITS(n) == NUMERIC_SPECIAL)
177 :
178 : #define NUMERIC_HDRSZ (VARHDRSZ + sizeof(uint16) + sizeof(int16))
179 : #define NUMERIC_HDRSZ_SHORT (VARHDRSZ + sizeof(uint16))
180 :
181 : /*
182 : * If the flag bits are NUMERIC_SHORT or NUMERIC_SPECIAL, we want the short
183 : * header; otherwise, we want the long one. Instead of testing against each
184 : * value, we can just look at the high bit, for a slight efficiency gain.
185 : */
186 : #define NUMERIC_HEADER_IS_SHORT(n) (((n)->choice.n_header & 0x8000) != 0)
187 : #define NUMERIC_HEADER_SIZE(n) \
188 : (VARHDRSZ + sizeof(uint16) + \
189 : (NUMERIC_HEADER_IS_SHORT(n) ? 0 : sizeof(int16)))
190 :
191 : /*
192 : * Definitions for special values (NaN, positive infinity, negative infinity).
193 : *
194 : * The two bits after the NUMERIC_SPECIAL bits are 00 for NaN, 01 for positive
195 : * infinity, 11 for negative infinity. (This makes the sign bit match where
196 : * it is in a short-format value, though we make no use of that at present.)
197 : * We could mask off the remaining bits before testing the active bits, but
198 : * currently those bits must be zeroes, so masking would just add cycles.
199 : */
200 : #define NUMERIC_EXT_SIGN_MASK 0xF000 /* high bits plus NaN/Inf flag bits */
201 : #define NUMERIC_NAN 0xC000
202 : #define NUMERIC_PINF 0xD000
203 : #define NUMERIC_NINF 0xF000
204 : #define NUMERIC_INF_SIGN_MASK 0x2000
205 :
206 : #define NUMERIC_EXT_FLAGBITS(n) ((n)->choice.n_header & NUMERIC_EXT_SIGN_MASK)
207 : #define NUMERIC_IS_NAN(n) ((n)->choice.n_header == NUMERIC_NAN)
208 : #define NUMERIC_IS_PINF(n) ((n)->choice.n_header == NUMERIC_PINF)
209 : #define NUMERIC_IS_NINF(n) ((n)->choice.n_header == NUMERIC_NINF)
210 : #define NUMERIC_IS_INF(n) \
211 : (((n)->choice.n_header & ~NUMERIC_INF_SIGN_MASK) == NUMERIC_PINF)
212 :
213 : /*
214 : * Short format definitions.
215 : */
216 :
217 : #define NUMERIC_SHORT_SIGN_MASK 0x2000
218 : #define NUMERIC_SHORT_DSCALE_MASK 0x1F80
219 : #define NUMERIC_SHORT_DSCALE_SHIFT 7
220 : #define NUMERIC_SHORT_DSCALE_MAX \
221 : (NUMERIC_SHORT_DSCALE_MASK >> NUMERIC_SHORT_DSCALE_SHIFT)
222 : #define NUMERIC_SHORT_WEIGHT_SIGN_MASK 0x0040
223 : #define NUMERIC_SHORT_WEIGHT_MASK 0x003F
224 : #define NUMERIC_SHORT_WEIGHT_MAX NUMERIC_SHORT_WEIGHT_MASK
225 : #define NUMERIC_SHORT_WEIGHT_MIN (-(NUMERIC_SHORT_WEIGHT_MASK+1))
226 :
227 : /*
228 : * Extract sign, display scale, weight. These macros extract field values
229 : * suitable for the NumericVar format from the Numeric (on-disk) format.
230 : *
231 : * Note that we don't trouble to ensure that dscale and weight read as zero
232 : * for an infinity; however, that doesn't matter since we never convert
233 : * "special" numerics to NumericVar form. Only the constants defined below
234 : * (const_nan, etc) ever represent a non-finite value as a NumericVar.
235 : */
236 :
237 : #define NUMERIC_DSCALE_MASK 0x3FFF
238 : #define NUMERIC_DSCALE_MAX NUMERIC_DSCALE_MASK
239 :
240 : #define NUMERIC_SIGN(n) \
241 : (NUMERIC_IS_SHORT(n) ? \
242 : (((n)->choice.n_short.n_header & NUMERIC_SHORT_SIGN_MASK) ? \
243 : NUMERIC_NEG : NUMERIC_POS) : \
244 : (NUMERIC_IS_SPECIAL(n) ? \
245 : NUMERIC_EXT_FLAGBITS(n) : NUMERIC_FLAGBITS(n)))
246 : #define NUMERIC_DSCALE(n) (NUMERIC_HEADER_IS_SHORT((n)) ? \
247 : ((n)->choice.n_short.n_header & NUMERIC_SHORT_DSCALE_MASK) \
248 : >> NUMERIC_SHORT_DSCALE_SHIFT \
249 : : ((n)->choice.n_long.n_sign_dscale & NUMERIC_DSCALE_MASK))
250 : #define NUMERIC_WEIGHT(n) (NUMERIC_HEADER_IS_SHORT((n)) ? \
251 : (((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_SIGN_MASK ? \
252 : ~NUMERIC_SHORT_WEIGHT_MASK : 0) \
253 : | ((n)->choice.n_short.n_header & NUMERIC_SHORT_WEIGHT_MASK)) \
254 : : ((n)->choice.n_long.n_weight))
255 :
256 : /*
257 : * Maximum weight of a stored Numeric value (based on the use of int16 for the
258 : * weight in NumericLong). Note that intermediate values held in NumericVar
259 : * and NumericSumAccum variables may have much larger weights.
260 : */
261 : #define NUMERIC_WEIGHT_MAX PG_INT16_MAX
262 :
263 : /* ----------
264 : * NumericVar is the format we use for arithmetic. The digit-array part
265 : * is the same as the NumericData storage format, but the header is more
266 : * complex.
267 : *
268 : * The value represented by a NumericVar is determined by the sign, weight,
269 : * ndigits, and digits[] array. If it is a "special" value (NaN or Inf)
270 : * then only the sign field matters; ndigits should be zero, and the weight
271 : * and dscale fields are ignored.
272 : *
273 : * Note: the first digit of a NumericVar's value is assumed to be multiplied
274 : * by NBASE ** weight. Another way to say it is that there are weight+1
275 : * digits before the decimal point. It is possible to have weight < 0.
276 : *
277 : * buf points at the physical start of the palloc'd digit buffer for the
278 : * NumericVar. digits points at the first digit in actual use (the one
279 : * with the specified weight). We normally leave an unused digit or two
280 : * (preset to zeroes) between buf and digits, so that there is room to store
281 : * a carry out of the top digit without reallocating space. We just need to
282 : * decrement digits (and increment weight) to make room for the carry digit.
283 : * (There is no such extra space in a numeric value stored in the database,
284 : * only in a NumericVar in memory.)
285 : *
286 : * If buf is NULL then the digit buffer isn't actually palloc'd and should
287 : * not be freed --- see the constants below for an example.
288 : *
289 : * dscale, or display scale, is the nominal precision expressed as number
290 : * of digits after the decimal point (it must always be >= 0 at present).
291 : * dscale may be more than the number of physically stored fractional digits,
292 : * implying that we have suppressed storage of significant trailing zeroes.
293 : * It should never be less than the number of stored digits, since that would
294 : * imply hiding digits that are present. NOTE that dscale is always expressed
295 : * in *decimal* digits, and so it may correspond to a fractional number of
296 : * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
297 : *
298 : * rscale, or result scale, is the target precision for a computation.
299 : * Like dscale it is expressed as number of *decimal* digits after the decimal
300 : * point, and is always >= 0 at present.
301 : * Note that rscale is not stored in variables --- it's figured on-the-fly
302 : * from the dscales of the inputs.
303 : *
304 : * While we consistently use "weight" to refer to the base-NBASE weight of
305 : * a numeric value, it is convenient in some scale-related calculations to
306 : * make use of the base-10 weight (ie, the approximate log10 of the value).
307 : * To avoid confusion, such a decimal-units weight is called a "dweight".
308 : *
309 : * NB: All the variable-level functions are written in a style that makes it
310 : * possible to give one and the same variable as argument and destination.
311 : * This is feasible because the digit buffer is separate from the variable.
312 : * ----------
313 : */
314 : typedef struct NumericVar
315 : {
316 : int ndigits; /* # of digits in digits[] - can be 0! */
317 : int weight; /* weight of first digit */
318 : int sign; /* NUMERIC_POS, _NEG, _NAN, _PINF, or _NINF */
319 : int dscale; /* display scale */
320 : NumericDigit *buf; /* start of palloc'd space for digits[] */
321 : NumericDigit *digits; /* base-NBASE digits */
322 : } NumericVar;
323 :
324 :
325 : /* ----------
326 : * Data for generate_series
327 : * ----------
328 : */
329 : typedef struct
330 : {
331 : NumericVar current;
332 : NumericVar stop;
333 : NumericVar step;
334 : } generate_series_numeric_fctx;
335 :
336 :
337 : /* ----------
338 : * Sort support.
339 : * ----------
340 : */
341 : typedef struct
342 : {
343 : void *buf; /* buffer for short varlenas */
344 : int64 input_count; /* number of non-null values seen */
345 : bool estimating; /* true if estimating cardinality */
346 :
347 : hyperLogLogState abbr_card; /* cardinality estimator */
348 : } NumericSortSupport;
349 :
350 :
351 : /* ----------
352 : * Fast sum accumulator.
353 : *
354 : * NumericSumAccum is used to implement SUM(), and other standard aggregates
355 : * that track the sum of input values. It uses 32-bit integers to store the
356 : * digits, instead of the normal 16-bit integers (with NBASE=10000). This
357 : * way, we can safely accumulate up to NBASE - 1 values without propagating
358 : * carry, before risking overflow of any of the digits. 'num_uncarried'
359 : * tracks how many values have been accumulated without propagating carry.
360 : *
361 : * Positive and negative values are accumulated separately, in 'pos_digits'
362 : * and 'neg_digits'. This is simpler and faster than deciding whether to add
363 : * or subtract from the current value, for each new value (see sub_var() for
364 : * the logic we avoid by doing this). Both buffers are of same size, and
365 : * have the same weight and scale. In accum_sum_final(), the positive and
366 : * negative sums are added together to produce the final result.
367 : *
368 : * When a new value has a larger ndigits or weight than the accumulator
369 : * currently does, the accumulator is enlarged to accommodate the new value.
370 : * We normally have one zero digit reserved for carry propagation, and that
371 : * is indicated by the 'have_carry_space' flag. When accum_sum_carry() uses
372 : * up the reserved digit, it clears the 'have_carry_space' flag. The next
373 : * call to accum_sum_add() will enlarge the buffer, to make room for the
374 : * extra digit, and set the flag again.
375 : *
376 : * To initialize a new accumulator, simply reset all fields to zeros.
377 : *
378 : * The accumulator does not handle NaNs.
379 : * ----------
380 : */
381 : typedef struct NumericSumAccum
382 : {
383 : int ndigits;
384 : int weight;
385 : int dscale;
386 : int num_uncarried;
387 : bool have_carry_space;
388 : int32 *pos_digits;
389 : int32 *neg_digits;
390 : } NumericSumAccum;
391 :
392 :
393 : /*
394 : * We define our own macros for packing and unpacking abbreviated-key
395 : * representations, just to have a notational indication that that's
396 : * what we're doing. Now that sizeof(Datum) is always 8, we can rely
397 : * on fitting an int64 into Datum.
398 : *
399 : * The range of abbreviations for finite values is from +PG_INT64_MAX
400 : * to -PG_INT64_MAX. NaN has the abbreviation PG_INT64_MIN, and we
401 : * define the sort ordering to make that work out properly (see further
402 : * comments below). PINF and NINF share the abbreviations of the largest
403 : * and smallest finite abbreviation classes.
404 : */
405 : #define NumericAbbrevGetDatum(X) Int64GetDatum(X)
406 : #define DatumGetNumericAbbrev(X) DatumGetInt64(X)
407 : #define NUMERIC_ABBREV_NAN NumericAbbrevGetDatum(PG_INT64_MIN)
408 : #define NUMERIC_ABBREV_PINF NumericAbbrevGetDatum(-PG_INT64_MAX)
409 : #define NUMERIC_ABBREV_NINF NumericAbbrevGetDatum(PG_INT64_MAX)
410 :
411 :
412 : /* ----------
413 : * Some preinitialized constants
414 : * ----------
415 : */
416 : static const NumericDigit const_zero_data[1] = {0};
417 : static const NumericVar const_zero =
418 : {0, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_zero_data};
419 :
420 : static const NumericDigit const_one_data[1] = {1};
421 : static const NumericVar const_one =
422 : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_one_data};
423 :
424 : static const NumericVar const_minus_one =
425 : {1, 0, NUMERIC_NEG, 0, NULL, (NumericDigit *) const_one_data};
426 :
427 : static const NumericDigit const_two_data[1] = {2};
428 : static const NumericVar const_two =
429 : {1, 0, NUMERIC_POS, 0, NULL, (NumericDigit *) const_two_data};
430 :
431 : #if DEC_DIGITS == 4
432 : static const NumericDigit const_zero_point_nine_data[1] = {9000};
433 : #elif DEC_DIGITS == 2
434 : static const NumericDigit const_zero_point_nine_data[1] = {90};
435 : #elif DEC_DIGITS == 1
436 : static const NumericDigit const_zero_point_nine_data[1] = {9};
437 : #endif
438 : static const NumericVar const_zero_point_nine =
439 : {1, -1, NUMERIC_POS, 1, NULL, (NumericDigit *) const_zero_point_nine_data};
440 :
441 : #if DEC_DIGITS == 4
442 : static const NumericDigit const_one_point_one_data[2] = {1, 1000};
443 : #elif DEC_DIGITS == 2
444 : static const NumericDigit const_one_point_one_data[2] = {1, 10};
445 : #elif DEC_DIGITS == 1
446 : static const NumericDigit const_one_point_one_data[2] = {1, 1};
447 : #endif
448 : static const NumericVar const_one_point_one =
449 : {2, 0, NUMERIC_POS, 1, NULL, (NumericDigit *) const_one_point_one_data};
450 :
451 : static const NumericVar const_nan =
452 : {0, 0, NUMERIC_NAN, 0, NULL, NULL};
453 :
454 : static const NumericVar const_pinf =
455 : {0, 0, NUMERIC_PINF, 0, NULL, NULL};
456 :
457 : static const NumericVar const_ninf =
458 : {0, 0, NUMERIC_NINF, 0, NULL, NULL};
459 :
460 : #if DEC_DIGITS == 4
461 : static const int round_powers[4] = {0, 1000, 100, 10};
462 : #endif
463 :
464 :
465 : /* ----------
466 : * Local functions
467 : * ----------
468 : */
469 :
470 : #ifdef NUMERIC_DEBUG
471 : static void dump_numeric(const char *str, Numeric num);
472 : static void dump_var(const char *str, NumericVar *var);
473 : #else
474 : #define dump_numeric(s,n)
475 : #define dump_var(s,v)
476 : #endif
477 :
478 : #define digitbuf_alloc(ndigits) \
479 : ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
480 : #define digitbuf_free(buf) \
481 : do { \
482 : if ((buf) != NULL) \
483 : pfree(buf); \
484 : } while (0)
485 :
486 : #define init_var(v) memset(v, 0, sizeof(NumericVar))
487 :
488 : #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \
489 : (num)->choice.n_short.n_data : (num)->choice.n_long.n_data)
490 : #define NUMERIC_NDIGITS(num) \
491 : ((VARSIZE(num) - NUMERIC_HEADER_SIZE(num)) / sizeof(NumericDigit))
492 : #define NUMERIC_CAN_BE_SHORT(scale,weight) \
493 : ((scale) <= NUMERIC_SHORT_DSCALE_MAX && \
494 : (weight) <= NUMERIC_SHORT_WEIGHT_MAX && \
495 : (weight) >= NUMERIC_SHORT_WEIGHT_MIN)
496 :
497 : static void alloc_var(NumericVar *var, int ndigits);
498 : static void free_var(NumericVar *var);
499 : static void zero_var(NumericVar *var);
500 :
501 : static bool set_var_from_str(const char *str, const char *cp,
502 : NumericVar *dest, const char **endptr,
503 : Node *escontext);
504 : static bool set_var_from_non_decimal_integer_str(const char *str,
505 : const char *cp, int sign,
506 : int base, NumericVar *dest,
507 : const char **endptr,
508 : Node *escontext);
509 : static void set_var_from_num(Numeric num, NumericVar *dest);
510 : static void init_var_from_num(Numeric num, NumericVar *dest);
511 : static void set_var_from_var(const NumericVar *value, NumericVar *dest);
512 : static char *get_str_from_var(const NumericVar *var);
513 : static char *get_str_from_var_sci(const NumericVar *var, int rscale);
514 :
515 : static void numericvar_serialize(StringInfo buf, const NumericVar *var);
516 : static void numericvar_deserialize(StringInfo buf, NumericVar *var);
517 :
518 : static Numeric duplicate_numeric(Numeric num);
519 : static Numeric make_result(const NumericVar *var);
520 : static Numeric make_result_safe(const NumericVar *var, Node *escontext);
521 :
522 : static bool apply_typmod(NumericVar *var, int32 typmod, Node *escontext);
523 : static bool apply_typmod_special(Numeric num, int32 typmod, Node *escontext);
524 :
525 : static bool numericvar_to_int32(const NumericVar *var, int32 *result);
526 : static bool numericvar_to_int64(const NumericVar *var, int64 *result);
527 : static void int64_to_numericvar(int64 val, NumericVar *var);
528 : static bool numericvar_to_uint64(const NumericVar *var, uint64 *result);
529 : static void int128_to_numericvar(INT128 val, NumericVar *var);
530 : static double numericvar_to_double_no_overflow(const NumericVar *var);
531 :
532 : static Datum numeric_abbrev_convert(Datum original_datum, SortSupport ssup);
533 : static bool numeric_abbrev_abort(int memtupcount, SortSupport ssup);
534 : static int numeric_fast_cmp(Datum x, Datum y, SortSupport ssup);
535 : static int numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup);
536 :
537 : static Datum numeric_abbrev_convert_var(const NumericVar *var,
538 : NumericSortSupport *nss);
539 :
540 : static int cmp_numerics(Numeric num1, Numeric num2);
541 : static int cmp_var(const NumericVar *var1, const NumericVar *var2);
542 : static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
543 : int var1weight, int var1sign,
544 : const NumericDigit *var2digits, int var2ndigits,
545 : int var2weight, int var2sign);
546 : static void add_var(const NumericVar *var1, const NumericVar *var2,
547 : NumericVar *result);
548 : static void sub_var(const NumericVar *var1, const NumericVar *var2,
549 : NumericVar *result);
550 : static void mul_var(const NumericVar *var1, const NumericVar *var2,
551 : NumericVar *result,
552 : int rscale);
553 : static void mul_var_short(const NumericVar *var1, const NumericVar *var2,
554 : NumericVar *result);
555 : static void div_var(const NumericVar *var1, const NumericVar *var2,
556 : NumericVar *result, int rscale, bool round, bool exact);
557 : static void div_var_int(const NumericVar *var, int ival, int ival_weight,
558 : NumericVar *result, int rscale, bool round);
559 : #ifdef HAVE_INT128
560 : static void div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
561 : NumericVar *result, int rscale, bool round);
562 : #endif
563 : static int select_div_scale(const NumericVar *var1, const NumericVar *var2);
564 : static void mod_var(const NumericVar *var1, const NumericVar *var2,
565 : NumericVar *result);
566 : static void div_mod_var(const NumericVar *var1, const NumericVar *var2,
567 : NumericVar *quot, NumericVar *rem);
568 : static void ceil_var(const NumericVar *var, NumericVar *result);
569 : static void floor_var(const NumericVar *var, NumericVar *result);
570 :
571 : static void gcd_var(const NumericVar *var1, const NumericVar *var2,
572 : NumericVar *result);
573 : static void sqrt_var(const NumericVar *arg, NumericVar *result, int rscale);
574 : static void exp_var(const NumericVar *arg, NumericVar *result, int rscale);
575 : static int estimate_ln_dweight(const NumericVar *var);
576 : static void ln_var(const NumericVar *arg, NumericVar *result, int rscale);
577 : static void log_var(const NumericVar *base, const NumericVar *num,
578 : NumericVar *result);
579 : static void power_var(const NumericVar *base, const NumericVar *exp,
580 : NumericVar *result);
581 : static void power_var_int(const NumericVar *base, int exp, int exp_dscale,
582 : NumericVar *result);
583 : static void power_ten_int(int exp, NumericVar *result);
584 : static void random_var(pg_prng_state *state, const NumericVar *rmin,
585 : const NumericVar *rmax, NumericVar *result);
586 :
587 : static int cmp_abs(const NumericVar *var1, const NumericVar *var2);
588 : static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
589 : int var1weight,
590 : const NumericDigit *var2digits, int var2ndigits,
591 : int var2weight);
592 : static void add_abs(const NumericVar *var1, const NumericVar *var2,
593 : NumericVar *result);
594 : static void sub_abs(const NumericVar *var1, const NumericVar *var2,
595 : NumericVar *result);
596 : static void round_var(NumericVar *var, int rscale);
597 : static void trunc_var(NumericVar *var, int rscale);
598 : static void strip_var(NumericVar *var);
599 : static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
600 : const NumericVar *count_var,
601 : NumericVar *result_var);
602 :
603 : static void accum_sum_add(NumericSumAccum *accum, const NumericVar *val);
604 : static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val);
605 : static void accum_sum_carry(NumericSumAccum *accum);
606 : static void accum_sum_reset(NumericSumAccum *accum);
607 : static void accum_sum_final(NumericSumAccum *accum, NumericVar *result);
608 : static void accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src);
609 : static void accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2);
610 :
611 :
612 : /* ----------------------------------------------------------------------
613 : *
614 : * Input-, output- and rounding-functions
615 : *
616 : * ----------------------------------------------------------------------
617 : */
618 :
619 :
620 : /*
621 : * numeric_in() -
622 : *
623 : * Input function for numeric data type
624 : */
625 : Datum
626 103741 : numeric_in(PG_FUNCTION_ARGS)
627 : {
628 103741 : char *str = PG_GETARG_CSTRING(0);
629 : #ifdef NOT_USED
630 : Oid typelem = PG_GETARG_OID(1);
631 : #endif
632 103741 : int32 typmod = PG_GETARG_INT32(2);
633 103741 : Node *escontext = fcinfo->context;
634 : Numeric res;
635 : const char *cp;
636 : const char *numstart;
637 : int sign;
638 :
639 : /* Skip leading spaces */
640 103741 : cp = str;
641 120021 : while (*cp)
642 : {
643 120009 : if (!isspace((unsigned char) *cp))
644 103729 : break;
645 16280 : cp++;
646 : }
647 :
648 : /*
649 : * Process the number's sign. This duplicates logic in set_var_from_str(),
650 : * but it's worth doing here, since it simplifies the handling of
651 : * infinities and non-decimal integers.
652 : */
653 103741 : numstart = cp;
654 103741 : sign = NUMERIC_POS;
655 :
656 103741 : if (*cp == '+')
657 32 : cp++;
658 103709 : else if (*cp == '-')
659 : {
660 2496 : sign = NUMERIC_NEG;
661 2496 : cp++;
662 : }
663 :
664 : /*
665 : * Check for NaN and infinities. We recognize the same strings allowed by
666 : * float8in().
667 : *
668 : * Since all other legal inputs have a digit or a decimal point after the
669 : * sign, we need only check for NaN/infinity if that's not the case.
670 : */
671 103741 : if (!isdigit((unsigned char) *cp) && *cp != '.')
672 : {
673 : /*
674 : * The number must be NaN or infinity; anything else can only be a
675 : * syntax error. Note that NaN mustn't have a sign.
676 : */
677 1198 : if (pg_strncasecmp(numstart, "NaN", 3) == 0)
678 : {
679 396 : res = make_result(&const_nan);
680 396 : cp = numstart + 3;
681 : }
682 802 : else if (pg_strncasecmp(cp, "Infinity", 8) == 0)
683 : {
684 337 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
685 337 : cp += 8;
686 : }
687 465 : else if (pg_strncasecmp(cp, "inf", 3) == 0)
688 : {
689 392 : res = make_result(sign == NUMERIC_POS ? &const_pinf : &const_ninf);
690 392 : cp += 3;
691 : }
692 : else
693 73 : goto invalid_syntax;
694 :
695 : /*
696 : * Check for trailing junk; there should be nothing left but spaces.
697 : *
698 : * We intentionally do this check before applying the typmod because
699 : * we would like to throw any trailing-junk syntax error before any
700 : * semantic error resulting from apply_typmod_special().
701 : */
702 1153 : while (*cp)
703 : {
704 28 : if (!isspace((unsigned char) *cp))
705 0 : goto invalid_syntax;
706 28 : cp++;
707 : }
708 :
709 1125 : if (!apply_typmod_special(res, typmod, escontext))
710 0 : PG_RETURN_NULL();
711 : }
712 : else
713 : {
714 : /*
715 : * We have a normal numeric value, which may be a non-decimal integer
716 : * or a regular decimal number.
717 : */
718 : NumericVar value;
719 : int base;
720 :
721 102543 : init_var(&value);
722 :
723 : /*
724 : * Determine the number's base by looking for a non-decimal prefix
725 : * indicator ("0x", "0o", or "0b").
726 : */
727 102543 : if (cp[0] == '0')
728 : {
729 33400 : switch (cp[1])
730 : {
731 48 : case 'x':
732 : case 'X':
733 48 : base = 16;
734 48 : break;
735 28 : case 'o':
736 : case 'O':
737 28 : base = 8;
738 28 : break;
739 28 : case 'b':
740 : case 'B':
741 28 : base = 2;
742 28 : break;
743 33296 : default:
744 33296 : base = 10;
745 : }
746 : }
747 : else
748 69143 : base = 10;
749 :
750 : /* Parse the rest of the number and apply the sign */
751 102543 : if (base == 10)
752 : {
753 102439 : if (!set_var_from_str(str, cp, &value, &cp, escontext))
754 16 : PG_RETURN_NULL();
755 102407 : value.sign = sign;
756 : }
757 : else
758 : {
759 104 : if (!set_var_from_non_decimal_integer_str(str, cp + 2, sign, base,
760 : &value, &cp, escontext))
761 0 : PG_RETURN_NULL();
762 : }
763 :
764 : /*
765 : * Should be nothing left but spaces. As above, throw any typmod error
766 : * after finishing syntax check.
767 : */
768 102551 : while (*cp)
769 : {
770 100 : if (!isspace((unsigned char) *cp))
771 48 : goto invalid_syntax;
772 52 : cp++;
773 : }
774 :
775 102451 : if (!apply_typmod(&value, typmod, escontext))
776 16 : PG_RETURN_NULL();
777 :
778 102435 : res = make_result_safe(&value, escontext);
779 :
780 102435 : free_var(&value);
781 : }
782 :
783 103560 : PG_RETURN_NUMERIC(res);
784 :
785 121 : invalid_syntax:
786 121 : ereturn(escontext, (Datum) 0,
787 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
788 : errmsg("invalid input syntax for type %s: \"%s\"",
789 : "numeric", str)));
790 : }
791 :
792 :
793 : /*
794 : * numeric_out() -
795 : *
796 : * Output function for numeric data type
797 : */
798 : Datum
799 535502 : numeric_out(PG_FUNCTION_ARGS)
800 : {
801 535502 : Numeric num = PG_GETARG_NUMERIC(0);
802 : NumericVar x;
803 : char *str;
804 :
805 : /*
806 : * Handle NaN and infinities
807 : */
808 535502 : if (NUMERIC_IS_SPECIAL(num))
809 : {
810 2344 : if (NUMERIC_IS_PINF(num))
811 688 : PG_RETURN_CSTRING(pstrdup("Infinity"));
812 1656 : else if (NUMERIC_IS_NINF(num))
813 436 : PG_RETURN_CSTRING(pstrdup("-Infinity"));
814 : else
815 1220 : PG_RETURN_CSTRING(pstrdup("NaN"));
816 : }
817 :
818 : /*
819 : * Get the number in the variable format.
820 : */
821 533158 : init_var_from_num(num, &x);
822 :
823 533158 : str = get_str_from_var(&x);
824 :
825 533158 : PG_RETURN_CSTRING(str);
826 : }
827 :
828 : /*
829 : * numeric_is_nan() -
830 : *
831 : * Is Numeric value a NaN?
832 : */
833 : bool
834 4339 : numeric_is_nan(Numeric num)
835 : {
836 4339 : return NUMERIC_IS_NAN(num);
837 : }
838 :
839 : /*
840 : * numeric_is_inf() -
841 : *
842 : * Is Numeric value an infinity?
843 : */
844 : bool
845 801 : numeric_is_inf(Numeric num)
846 : {
847 801 : return NUMERIC_IS_INF(num);
848 : }
849 :
850 : /*
851 : * numeric_is_integral() -
852 : *
853 : * Is Numeric value integral?
854 : */
855 : static bool
856 54 : numeric_is_integral(Numeric num)
857 : {
858 : NumericVar arg;
859 :
860 : /* Reject NaN, but infinities are considered integral */
861 54 : if (NUMERIC_IS_SPECIAL(num))
862 : {
863 25 : if (NUMERIC_IS_NAN(num))
864 0 : return false;
865 25 : return true;
866 : }
867 :
868 : /* Integral if there are no digits to the right of the decimal point */
869 29 : init_var_from_num(num, &arg);
870 :
871 29 : return (arg.ndigits == 0 || arg.ndigits <= arg.weight + 1);
872 : }
873 :
874 : /*
875 : * make_numeric_typmod() -
876 : *
877 : * Pack numeric precision and scale values into a typmod. The upper 16 bits
878 : * are used for the precision (though actually not all these bits are needed,
879 : * since the maximum allowed precision is 1000). The lower 16 bits are for
880 : * the scale, but since the scale is constrained to the range [-1000, 1000],
881 : * we use just the lower 11 of those 16 bits, and leave the remaining 5 bits
882 : * unset, for possible future use.
883 : *
884 : * For purely historical reasons VARHDRSZ is then added to the result, thus
885 : * the unused space in the upper 16 bits is not all as freely available as it
886 : * might seem. (We can't let the result overflow to a negative int32, as
887 : * other parts of the system would interpret that as not-a-valid-typmod.)
888 : */
889 : static inline int32
890 1059 : make_numeric_typmod(int precision, int scale)
891 : {
892 1059 : return ((precision << 16) | (scale & 0x7ff)) + VARHDRSZ;
893 : }
894 :
895 : /*
896 : * Because of the offset, valid numeric typmods are at least VARHDRSZ
897 : */
898 : static inline bool
899 119710 : is_valid_numeric_typmod(int32 typmod)
900 : {
901 119710 : return typmod >= (int32) VARHDRSZ;
902 : }
903 :
904 : /*
905 : * numeric_typmod_precision() -
906 : *
907 : * Extract the precision from a numeric typmod --- see make_numeric_typmod().
908 : */
909 : static inline int
910 32907 : numeric_typmod_precision(int32 typmod)
911 : {
912 32907 : return ((typmod - VARHDRSZ) >> 16) & 0xffff;
913 : }
914 :
915 : /*
916 : * numeric_typmod_scale() -
917 : *
918 : * Extract the scale from a numeric typmod --- see make_numeric_typmod().
919 : *
920 : * Note that the scale may be negative, so we must do sign extension when
921 : * unpacking it. We do this using the bit hack (x^1024)-1024, which sign
922 : * extends an 11-bit two's complement number x.
923 : */
924 : static inline int
925 28007 : numeric_typmod_scale(int32 typmod)
926 : {
927 28007 : return (((typmod - VARHDRSZ) & 0x7ff) ^ 1024) - 1024;
928 : }
929 :
930 : /*
931 : * numeric_maximum_size() -
932 : *
933 : * Maximum size of a numeric with given typmod, or -1 if unlimited/unknown.
934 : */
935 : int32
936 4900 : numeric_maximum_size(int32 typmod)
937 : {
938 : int precision;
939 : int numeric_digits;
940 :
941 4900 : if (!is_valid_numeric_typmod(typmod))
942 0 : return -1;
943 :
944 : /* precision (ie, max # of digits) is in upper bits of typmod */
945 4900 : precision = numeric_typmod_precision(typmod);
946 :
947 : /*
948 : * This formula computes the maximum number of NumericDigits we could need
949 : * in order to store the specified number of decimal digits. Because the
950 : * weight is stored as a number of NumericDigits rather than a number of
951 : * decimal digits, it's possible that the first NumericDigit will contain
952 : * only a single decimal digit. Thus, the first two decimal digits can
953 : * require two NumericDigits to store, but it isn't until we reach
954 : * DEC_DIGITS + 2 decimal digits that we potentially need a third
955 : * NumericDigit.
956 : */
957 4900 : numeric_digits = (precision + 2 * (DEC_DIGITS - 1)) / DEC_DIGITS;
958 :
959 : /*
960 : * In most cases, the size of a numeric will be smaller than the value
961 : * computed below, because the varlena header will typically get toasted
962 : * down to a single byte before being stored on disk, and it may also be
963 : * possible to use a short numeric header. But our job here is to compute
964 : * the worst case.
965 : */
966 4900 : return NUMERIC_HDRSZ + (numeric_digits * sizeof(NumericDigit));
967 : }
968 :
969 : /*
970 : * numeric_out_sci() -
971 : *
972 : * Output function for numeric data type in scientific notation.
973 : */
974 : char *
975 164 : numeric_out_sci(Numeric num, int scale)
976 : {
977 : NumericVar x;
978 : char *str;
979 :
980 : /*
981 : * Handle NaN and infinities
982 : */
983 164 : if (NUMERIC_IS_SPECIAL(num))
984 : {
985 12 : if (NUMERIC_IS_PINF(num))
986 4 : return pstrdup("Infinity");
987 8 : else if (NUMERIC_IS_NINF(num))
988 4 : return pstrdup("-Infinity");
989 : else
990 4 : return pstrdup("NaN");
991 : }
992 :
993 152 : init_var_from_num(num, &x);
994 :
995 152 : str = get_str_from_var_sci(&x, scale);
996 :
997 152 : return str;
998 : }
999 :
1000 : /*
1001 : * numeric_normalize() -
1002 : *
1003 : * Output function for numeric data type, suppressing insignificant trailing
1004 : * zeroes and then any trailing decimal point. The intent of this is to
1005 : * produce strings that are equal if and only if the input numeric values
1006 : * compare equal.
1007 : */
1008 : char *
1009 22529 : numeric_normalize(Numeric num)
1010 : {
1011 : NumericVar x;
1012 : char *str;
1013 : int last;
1014 :
1015 : /*
1016 : * Handle NaN and infinities
1017 : */
1018 22529 : if (NUMERIC_IS_SPECIAL(num))
1019 : {
1020 0 : if (NUMERIC_IS_PINF(num))
1021 0 : return pstrdup("Infinity");
1022 0 : else if (NUMERIC_IS_NINF(num))
1023 0 : return pstrdup("-Infinity");
1024 : else
1025 0 : return pstrdup("NaN");
1026 : }
1027 :
1028 22529 : init_var_from_num(num, &x);
1029 :
1030 22529 : str = get_str_from_var(&x);
1031 :
1032 : /* If there's no decimal point, there's certainly nothing to remove. */
1033 22529 : if (strchr(str, '.') != NULL)
1034 : {
1035 : /*
1036 : * Back up over trailing fractional zeroes. Since there is a decimal
1037 : * point, this loop will terminate safely.
1038 : */
1039 31 : last = strlen(str) - 1;
1040 62 : while (str[last] == '0')
1041 31 : last--;
1042 :
1043 : /* We want to get rid of the decimal point too, if it's now last. */
1044 31 : if (str[last] == '.')
1045 31 : last--;
1046 :
1047 : /* Delete whatever we backed up over. */
1048 31 : str[last + 1] = '\0';
1049 : }
1050 :
1051 22529 : return str;
1052 : }
1053 :
1054 : /*
1055 : * numeric_recv - converts external binary format to numeric
1056 : *
1057 : * External format is a sequence of int16's:
1058 : * ndigits, weight, sign, dscale, NumericDigits.
1059 : */
1060 : Datum
1061 51 : numeric_recv(PG_FUNCTION_ARGS)
1062 : {
1063 51 : StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
1064 :
1065 : #ifdef NOT_USED
1066 : Oid typelem = PG_GETARG_OID(1);
1067 : #endif
1068 51 : int32 typmod = PG_GETARG_INT32(2);
1069 : NumericVar value;
1070 : Numeric res;
1071 : int len,
1072 : i;
1073 :
1074 51 : init_var(&value);
1075 :
1076 51 : len = (uint16) pq_getmsgint(buf, sizeof(uint16));
1077 :
1078 51 : alloc_var(&value, len);
1079 :
1080 51 : value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
1081 : /* we allow any int16 for weight --- OK? */
1082 :
1083 51 : value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
1084 51 : if (!(value.sign == NUMERIC_POS ||
1085 0 : value.sign == NUMERIC_NEG ||
1086 0 : value.sign == NUMERIC_NAN ||
1087 0 : value.sign == NUMERIC_PINF ||
1088 0 : value.sign == NUMERIC_NINF))
1089 0 : ereport(ERROR,
1090 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1091 : errmsg("invalid sign in external \"numeric\" value")));
1092 :
1093 51 : value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
1094 51 : if ((value.dscale & NUMERIC_DSCALE_MASK) != value.dscale)
1095 0 : ereport(ERROR,
1096 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1097 : errmsg("invalid scale in external \"numeric\" value")));
1098 :
1099 137 : for (i = 0; i < len; i++)
1100 : {
1101 86 : NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
1102 :
1103 86 : if (d < 0 || d >= NBASE)
1104 0 : ereport(ERROR,
1105 : (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1106 : errmsg("invalid digit in external \"numeric\" value")));
1107 86 : value.digits[i] = d;
1108 : }
1109 :
1110 : /*
1111 : * If the given dscale would hide any digits, truncate those digits away.
1112 : * We could alternatively throw an error, but that would take a bunch of
1113 : * extra code (about as much as trunc_var involves), and it might cause
1114 : * client compatibility issues. Be careful not to apply trunc_var to
1115 : * special values, as it could do the wrong thing; we don't need it
1116 : * anyway, since make_result will ignore all but the sign field.
1117 : *
1118 : * After doing that, be sure to check the typmod restriction.
1119 : */
1120 51 : if (value.sign == NUMERIC_POS ||
1121 0 : value.sign == NUMERIC_NEG)
1122 : {
1123 51 : trunc_var(&value, value.dscale);
1124 :
1125 51 : (void) apply_typmod(&value, typmod, NULL);
1126 :
1127 51 : res = make_result(&value);
1128 : }
1129 : else
1130 : {
1131 : /* apply_typmod_special wants us to make the Numeric first */
1132 0 : res = make_result(&value);
1133 :
1134 0 : (void) apply_typmod_special(res, typmod, NULL);
1135 : }
1136 :
1137 51 : free_var(&value);
1138 :
1139 51 : PG_RETURN_NUMERIC(res);
1140 : }
1141 :
1142 : /*
1143 : * numeric_send - converts numeric to binary format
1144 : */
1145 : Datum
1146 35 : numeric_send(PG_FUNCTION_ARGS)
1147 : {
1148 35 : Numeric num = PG_GETARG_NUMERIC(0);
1149 : NumericVar x;
1150 : StringInfoData buf;
1151 : int i;
1152 :
1153 35 : init_var_from_num(num, &x);
1154 :
1155 35 : pq_begintypsend(&buf);
1156 :
1157 35 : pq_sendint16(&buf, x.ndigits);
1158 35 : pq_sendint16(&buf, x.weight);
1159 35 : pq_sendint16(&buf, x.sign);
1160 35 : pq_sendint16(&buf, x.dscale);
1161 97 : for (i = 0; i < x.ndigits; i++)
1162 62 : pq_sendint16(&buf, x.digits[i]);
1163 :
1164 35 : PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
1165 : }
1166 :
1167 :
1168 : /*
1169 : * numeric_support()
1170 : *
1171 : * Planner support function for the numeric() length coercion function.
1172 : *
1173 : * Flatten calls that solely represent increases in allowable precision.
1174 : * Scale changes mutate every datum, so they are unoptimizable. Some values,
1175 : * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from
1176 : * an unconstrained numeric to any constrained numeric is also unoptimizable.
1177 : */
1178 : Datum
1179 427 : numeric_support(PG_FUNCTION_ARGS)
1180 : {
1181 427 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
1182 427 : Node *ret = NULL;
1183 :
1184 427 : if (IsA(rawreq, SupportRequestSimplify))
1185 : {
1186 187 : SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq;
1187 187 : FuncExpr *expr = req->fcall;
1188 : Node *typmod;
1189 :
1190 : Assert(list_length(expr->args) >= 2);
1191 :
1192 187 : typmod = (Node *) lsecond(expr->args);
1193 :
1194 187 : if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1195 : {
1196 187 : Node *source = (Node *) linitial(expr->args);
1197 187 : int32 old_typmod = exprTypmod(source);
1198 187 : int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
1199 187 : int32 old_scale = numeric_typmod_scale(old_typmod);
1200 187 : int32 new_scale = numeric_typmod_scale(new_typmod);
1201 187 : int32 old_precision = numeric_typmod_precision(old_typmod);
1202 187 : int32 new_precision = numeric_typmod_precision(new_typmod);
1203 :
1204 : /*
1205 : * If new_typmod is invalid, the destination is unconstrained;
1206 : * that's always OK. If old_typmod is valid, the source is
1207 : * constrained, and we're OK if the scale is unchanged and the
1208 : * precision is not decreasing. See further notes in function
1209 : * header comment.
1210 : */
1211 374 : if (!is_valid_numeric_typmod(new_typmod) ||
1212 196 : (is_valid_numeric_typmod(old_typmod) &&
1213 4 : new_scale == old_scale && new_precision >= old_precision))
1214 4 : ret = relabel_to_typmod(source, new_typmod);
1215 : }
1216 : }
1217 :
1218 427 : PG_RETURN_POINTER(ret);
1219 : }
1220 :
1221 : /*
1222 : * numeric() -
1223 : *
1224 : * This is a special function called by the Postgres database system
1225 : * before a value is stored in a tuple's attribute. The precision and
1226 : * scale of the attribute have to be applied on the value.
1227 : */
1228 : Datum
1229 8083 : numeric (PG_FUNCTION_ARGS)
1230 : {
1231 8083 : Numeric num = PG_GETARG_NUMERIC(0);
1232 8083 : int32 typmod = PG_GETARG_INT32(1);
1233 : Numeric new;
1234 : int precision;
1235 : int scale;
1236 : int ddigits;
1237 : int maxdigits;
1238 : int dscale;
1239 : NumericVar var;
1240 :
1241 : /*
1242 : * Handle NaN and infinities: if apply_typmod_special doesn't complain,
1243 : * just return a copy of the input.
1244 : */
1245 8083 : if (NUMERIC_IS_SPECIAL(num))
1246 : {
1247 172 : if (!apply_typmod_special(num, typmod, fcinfo->context))
1248 0 : PG_RETURN_NULL();
1249 160 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1250 : }
1251 :
1252 : /*
1253 : * If the value isn't a valid type modifier, simply return a copy of the
1254 : * input value
1255 : */
1256 7911 : if (!is_valid_numeric_typmod(typmod))
1257 0 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1258 :
1259 : /*
1260 : * Get the precision and scale out of the typmod value
1261 : */
1262 7911 : precision = numeric_typmod_precision(typmod);
1263 7911 : scale = numeric_typmod_scale(typmod);
1264 7911 : maxdigits = precision - scale;
1265 :
1266 : /* The target display scale is non-negative */
1267 7911 : dscale = Max(scale, 0);
1268 :
1269 : /*
1270 : * If the number is certainly in bounds and due to the target scale no
1271 : * rounding could be necessary, just make a copy of the input and modify
1272 : * its scale fields, unless the larger scale forces us to abandon the
1273 : * short representation. (Note we assume the existing dscale is
1274 : * honest...)
1275 : */
1276 7911 : ddigits = (NUMERIC_WEIGHT(num) + 1) * DEC_DIGITS;
1277 7911 : if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num)
1278 4838 : && (NUMERIC_CAN_BE_SHORT(dscale, NUMERIC_WEIGHT(num))
1279 0 : || !NUMERIC_IS_SHORT(num)))
1280 : {
1281 4838 : new = duplicate_numeric(num);
1282 4838 : if (NUMERIC_IS_SHORT(num))
1283 4838 : new->choice.n_short.n_header =
1284 4838 : (num->choice.n_short.n_header & ~NUMERIC_SHORT_DSCALE_MASK)
1285 4838 : | (dscale << NUMERIC_SHORT_DSCALE_SHIFT);
1286 : else
1287 0 : new->choice.n_long.n_sign_dscale = NUMERIC_SIGN(new) |
1288 0 : ((uint16) dscale & NUMERIC_DSCALE_MASK);
1289 4838 : PG_RETURN_NUMERIC(new);
1290 : }
1291 :
1292 : /*
1293 : * We really need to fiddle with things - unpack the number into a
1294 : * variable and let apply_typmod() do it.
1295 : */
1296 3073 : init_var(&var);
1297 :
1298 3073 : set_var_from_num(num, &var);
1299 3073 : if (!apply_typmod(&var, typmod, fcinfo->context))
1300 0 : PG_RETURN_NULL();
1301 3033 : new = make_result_safe(&var, fcinfo->context);
1302 :
1303 3033 : free_var(&var);
1304 :
1305 3033 : PG_RETURN_NUMERIC(new);
1306 : }
1307 :
1308 : Datum
1309 1087 : numerictypmodin(PG_FUNCTION_ARGS)
1310 : {
1311 1087 : ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
1312 : int32 *tl;
1313 : int n;
1314 : int32 typmod;
1315 :
1316 1087 : tl = ArrayGetIntegerTypmods(ta, &n);
1317 :
1318 1087 : if (n == 2)
1319 : {
1320 1075 : if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
1321 12 : ereport(ERROR,
1322 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1323 : errmsg("NUMERIC precision %d must be between 1 and %d",
1324 : tl[0], NUMERIC_MAX_PRECISION)));
1325 1063 : if (tl[1] < NUMERIC_MIN_SCALE || tl[1] > NUMERIC_MAX_SCALE)
1326 8 : ereport(ERROR,
1327 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1328 : errmsg("NUMERIC scale %d must be between %d and %d",
1329 : tl[1], NUMERIC_MIN_SCALE, NUMERIC_MAX_SCALE)));
1330 1055 : typmod = make_numeric_typmod(tl[0], tl[1]);
1331 : }
1332 12 : else if (n == 1)
1333 : {
1334 4 : if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
1335 0 : ereport(ERROR,
1336 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1337 : errmsg("NUMERIC precision %d must be between 1 and %d",
1338 : tl[0], NUMERIC_MAX_PRECISION)));
1339 : /* scale defaults to zero */
1340 4 : typmod = make_numeric_typmod(tl[0], 0);
1341 : }
1342 : else
1343 : {
1344 8 : ereport(ERROR,
1345 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1346 : errmsg("invalid NUMERIC type modifier")));
1347 : typmod = 0; /* keep compiler quiet */
1348 : }
1349 :
1350 1059 : PG_RETURN_INT32(typmod);
1351 : }
1352 :
1353 : Datum
1354 209 : numerictypmodout(PG_FUNCTION_ARGS)
1355 : {
1356 209 : int32 typmod = PG_GETARG_INT32(0);
1357 209 : char *res = (char *) palloc(64);
1358 :
1359 209 : if (is_valid_numeric_typmod(typmod))
1360 209 : snprintf(res, 64, "(%d,%d)",
1361 : numeric_typmod_precision(typmod),
1362 : numeric_typmod_scale(typmod));
1363 : else
1364 0 : *res = '\0';
1365 :
1366 209 : PG_RETURN_CSTRING(res);
1367 : }
1368 :
1369 :
1370 : /* ----------------------------------------------------------------------
1371 : *
1372 : * Sign manipulation, rounding and the like
1373 : *
1374 : * ----------------------------------------------------------------------
1375 : */
1376 :
1377 : Datum
1378 13004 : numeric_abs(PG_FUNCTION_ARGS)
1379 : {
1380 13004 : Numeric num = PG_GETARG_NUMERIC(0);
1381 : Numeric res;
1382 :
1383 : /*
1384 : * Do it the easy way directly on the packed format
1385 : */
1386 13004 : res = duplicate_numeric(num);
1387 :
1388 13004 : if (NUMERIC_IS_SHORT(num))
1389 12960 : res->choice.n_short.n_header =
1390 12960 : num->choice.n_short.n_header & ~NUMERIC_SHORT_SIGN_MASK;
1391 44 : else if (NUMERIC_IS_SPECIAL(num))
1392 : {
1393 : /* This changes -Inf to Inf, and doesn't affect NaN */
1394 12 : res->choice.n_short.n_header =
1395 12 : num->choice.n_short.n_header & ~NUMERIC_INF_SIGN_MASK;
1396 : }
1397 : else
1398 32 : res->choice.n_long.n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
1399 :
1400 13004 : PG_RETURN_NUMERIC(res);
1401 : }
1402 :
1403 :
1404 : Datum
1405 623 : numeric_uminus(PG_FUNCTION_ARGS)
1406 : {
1407 623 : Numeric num = PG_GETARG_NUMERIC(0);
1408 : Numeric res;
1409 :
1410 : /*
1411 : * Do it the easy way directly on the packed format
1412 : */
1413 623 : res = duplicate_numeric(num);
1414 :
1415 623 : if (NUMERIC_IS_SPECIAL(num))
1416 : {
1417 : /* Flip the sign, if it's Inf or -Inf */
1418 84 : if (!NUMERIC_IS_NAN(num))
1419 56 : res->choice.n_short.n_header =
1420 56 : num->choice.n_short.n_header ^ NUMERIC_INF_SIGN_MASK;
1421 : }
1422 :
1423 : /*
1424 : * The packed format is known to be totally zero digit trimmed always. So
1425 : * once we've eliminated specials, we can identify a zero by the fact that
1426 : * there are no digits at all. Do nothing to a zero.
1427 : */
1428 539 : else if (NUMERIC_NDIGITS(num) != 0)
1429 : {
1430 : /* Else, flip the sign */
1431 463 : if (NUMERIC_IS_SHORT(num))
1432 463 : res->choice.n_short.n_header =
1433 463 : num->choice.n_short.n_header ^ NUMERIC_SHORT_SIGN_MASK;
1434 0 : else if (NUMERIC_SIGN(num) == NUMERIC_POS)
1435 0 : res->choice.n_long.n_sign_dscale =
1436 0 : NUMERIC_NEG | NUMERIC_DSCALE(num);
1437 : else
1438 0 : res->choice.n_long.n_sign_dscale =
1439 0 : NUMERIC_POS | NUMERIC_DSCALE(num);
1440 : }
1441 :
1442 623 : PG_RETURN_NUMERIC(res);
1443 : }
1444 :
1445 :
1446 : Datum
1447 0 : numeric_uplus(PG_FUNCTION_ARGS)
1448 : {
1449 0 : Numeric num = PG_GETARG_NUMERIC(0);
1450 :
1451 0 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1452 : }
1453 :
1454 :
1455 : /*
1456 : * numeric_sign_internal() -
1457 : *
1458 : * Returns -1 if the argument is less than 0, 0 if the argument is equal
1459 : * to 0, and 1 if the argument is greater than zero. Caller must have
1460 : * taken care of the NaN case, but we can handle infinities here.
1461 : */
1462 : static int
1463 2476 : numeric_sign_internal(Numeric num)
1464 : {
1465 2476 : if (NUMERIC_IS_SPECIAL(num))
1466 : {
1467 : Assert(!NUMERIC_IS_NAN(num));
1468 : /* Must be Inf or -Inf */
1469 223 : if (NUMERIC_IS_PINF(num))
1470 129 : return 1;
1471 : else
1472 94 : return -1;
1473 : }
1474 :
1475 : /*
1476 : * The packed format is known to be totally zero digit trimmed always. So
1477 : * once we've eliminated specials, we can identify a zero by the fact that
1478 : * there are no digits at all.
1479 : */
1480 2253 : else if (NUMERIC_NDIGITS(num) == 0)
1481 161 : return 0;
1482 2092 : else if (NUMERIC_SIGN(num) == NUMERIC_NEG)
1483 511 : return -1;
1484 : else
1485 1581 : return 1;
1486 : }
1487 :
1488 : /*
1489 : * numeric_sign() -
1490 : *
1491 : * returns -1 if the argument is less than 0, 0 if the argument is equal
1492 : * to 0, and 1 if the argument is greater than zero.
1493 : */
1494 : Datum
1495 32 : numeric_sign(PG_FUNCTION_ARGS)
1496 : {
1497 32 : Numeric num = PG_GETARG_NUMERIC(0);
1498 :
1499 : /*
1500 : * Handle NaN (infinities can be handled normally)
1501 : */
1502 32 : if (NUMERIC_IS_NAN(num))
1503 4 : PG_RETURN_NUMERIC(make_result(&const_nan));
1504 :
1505 28 : switch (numeric_sign_internal(num))
1506 : {
1507 4 : case 0:
1508 4 : PG_RETURN_NUMERIC(make_result(&const_zero));
1509 12 : case 1:
1510 12 : PG_RETURN_NUMERIC(make_result(&const_one));
1511 12 : case -1:
1512 12 : PG_RETURN_NUMERIC(make_result(&const_minus_one));
1513 : }
1514 :
1515 : Assert(false);
1516 0 : return (Datum) 0;
1517 : }
1518 :
1519 :
1520 : /*
1521 : * numeric_round() -
1522 : *
1523 : * Round a value to have 'scale' digits after the decimal point.
1524 : * We allow negative 'scale', implying rounding before the decimal
1525 : * point --- Oracle interprets rounding that way.
1526 : */
1527 : Datum
1528 5217 : numeric_round(PG_FUNCTION_ARGS)
1529 : {
1530 5217 : Numeric num = PG_GETARG_NUMERIC(0);
1531 5217 : int32 scale = PG_GETARG_INT32(1);
1532 : Numeric res;
1533 : NumericVar arg;
1534 :
1535 : /*
1536 : * Handle NaN and infinities
1537 : */
1538 5217 : if (NUMERIC_IS_SPECIAL(num))
1539 64 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1540 :
1541 : /*
1542 : * Limit the scale value to avoid possible overflow in calculations.
1543 : *
1544 : * These limits are based on the maximum number of digits a Numeric value
1545 : * can have before and after the decimal point, but we must allow for one
1546 : * extra digit before the decimal point, in case the most significant
1547 : * digit rounds up; we must check if that causes Numeric overflow.
1548 : */
1549 5153 : scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS - 1);
1550 5153 : scale = Min(scale, NUMERIC_DSCALE_MAX);
1551 :
1552 : /*
1553 : * Unpack the argument and round it at the proper digit position
1554 : */
1555 5153 : init_var(&arg);
1556 5153 : set_var_from_num(num, &arg);
1557 :
1558 5153 : round_var(&arg, scale);
1559 :
1560 : /* We don't allow negative output dscale */
1561 5153 : if (scale < 0)
1562 149 : arg.dscale = 0;
1563 :
1564 : /*
1565 : * Return the rounded result
1566 : */
1567 5153 : res = make_result(&arg);
1568 :
1569 5149 : free_var(&arg);
1570 5149 : PG_RETURN_NUMERIC(res);
1571 : }
1572 :
1573 :
1574 : /*
1575 : * numeric_trunc() -
1576 : *
1577 : * Truncate a value to have 'scale' digits after the decimal point.
1578 : * We allow negative 'scale', implying a truncation before the decimal
1579 : * point --- Oracle interprets truncation that way.
1580 : */
1581 : Datum
1582 442 : numeric_trunc(PG_FUNCTION_ARGS)
1583 : {
1584 442 : Numeric num = PG_GETARG_NUMERIC(0);
1585 442 : int32 scale = PG_GETARG_INT32(1);
1586 : Numeric res;
1587 : NumericVar arg;
1588 :
1589 : /*
1590 : * Handle NaN and infinities
1591 : */
1592 442 : if (NUMERIC_IS_SPECIAL(num))
1593 24 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1594 :
1595 : /*
1596 : * Limit the scale value to avoid possible overflow in calculations.
1597 : *
1598 : * These limits are based on the maximum number of digits a Numeric value
1599 : * can have before and after the decimal point.
1600 : */
1601 418 : scale = Max(scale, -(NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS);
1602 418 : scale = Min(scale, NUMERIC_DSCALE_MAX);
1603 :
1604 : /*
1605 : * Unpack the argument and truncate it at the proper digit position
1606 : */
1607 418 : init_var(&arg);
1608 418 : set_var_from_num(num, &arg);
1609 :
1610 418 : trunc_var(&arg, scale);
1611 :
1612 : /* We don't allow negative output dscale */
1613 418 : if (scale < 0)
1614 20 : arg.dscale = 0;
1615 :
1616 : /*
1617 : * Return the truncated result
1618 : */
1619 418 : res = make_result(&arg);
1620 :
1621 418 : free_var(&arg);
1622 418 : PG_RETURN_NUMERIC(res);
1623 : }
1624 :
1625 :
1626 : /*
1627 : * numeric_ceil() -
1628 : *
1629 : * Return the smallest integer greater than or equal to the argument
1630 : */
1631 : Datum
1632 148 : numeric_ceil(PG_FUNCTION_ARGS)
1633 : {
1634 148 : Numeric num = PG_GETARG_NUMERIC(0);
1635 : Numeric res;
1636 : NumericVar result;
1637 :
1638 : /*
1639 : * Handle NaN and infinities
1640 : */
1641 148 : if (NUMERIC_IS_SPECIAL(num))
1642 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1643 :
1644 136 : init_var_from_num(num, &result);
1645 136 : ceil_var(&result, &result);
1646 :
1647 136 : res = make_result(&result);
1648 136 : free_var(&result);
1649 :
1650 136 : PG_RETURN_NUMERIC(res);
1651 : }
1652 :
1653 :
1654 : /*
1655 : * numeric_floor() -
1656 : *
1657 : * Return the largest integer equal to or less than the argument
1658 : */
1659 : Datum
1660 84 : numeric_floor(PG_FUNCTION_ARGS)
1661 : {
1662 84 : Numeric num = PG_GETARG_NUMERIC(0);
1663 : Numeric res;
1664 : NumericVar result;
1665 :
1666 : /*
1667 : * Handle NaN and infinities
1668 : */
1669 84 : if (NUMERIC_IS_SPECIAL(num))
1670 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
1671 :
1672 72 : init_var_from_num(num, &result);
1673 72 : floor_var(&result, &result);
1674 :
1675 72 : res = make_result(&result);
1676 72 : free_var(&result);
1677 :
1678 72 : PG_RETURN_NUMERIC(res);
1679 : }
1680 :
1681 :
1682 : /*
1683 : * generate_series_numeric() -
1684 : *
1685 : * Generate series of numeric.
1686 : */
1687 : Datum
1688 80256 : generate_series_numeric(PG_FUNCTION_ARGS)
1689 : {
1690 80256 : return generate_series_step_numeric(fcinfo);
1691 : }
1692 :
1693 : Datum
1694 80556 : generate_series_step_numeric(PG_FUNCTION_ARGS)
1695 : {
1696 : generate_series_numeric_fctx *fctx;
1697 : FuncCallContext *funcctx;
1698 : MemoryContext oldcontext;
1699 :
1700 80556 : if (SRF_IS_FIRSTCALL())
1701 : {
1702 116 : Numeric start_num = PG_GETARG_NUMERIC(0);
1703 116 : Numeric stop_num = PG_GETARG_NUMERIC(1);
1704 116 : NumericVar steploc = const_one;
1705 :
1706 : /* Reject NaN and infinities in start and stop values */
1707 116 : if (NUMERIC_IS_SPECIAL(start_num))
1708 : {
1709 8 : if (NUMERIC_IS_NAN(start_num))
1710 4 : ereport(ERROR,
1711 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1712 : errmsg("start value cannot be NaN")));
1713 : else
1714 4 : ereport(ERROR,
1715 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1716 : errmsg("start value cannot be infinity")));
1717 : }
1718 108 : if (NUMERIC_IS_SPECIAL(stop_num))
1719 : {
1720 8 : if (NUMERIC_IS_NAN(stop_num))
1721 4 : ereport(ERROR,
1722 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1723 : errmsg("stop value cannot be NaN")));
1724 : else
1725 4 : ereport(ERROR,
1726 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1727 : errmsg("stop value cannot be infinity")));
1728 : }
1729 :
1730 : /* see if we were given an explicit step size */
1731 100 : if (PG_NARGS() == 3)
1732 : {
1733 48 : Numeric step_num = PG_GETARG_NUMERIC(2);
1734 :
1735 48 : if (NUMERIC_IS_SPECIAL(step_num))
1736 : {
1737 8 : if (NUMERIC_IS_NAN(step_num))
1738 4 : ereport(ERROR,
1739 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1740 : errmsg("step size cannot be NaN")));
1741 : else
1742 4 : ereport(ERROR,
1743 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1744 : errmsg("step size cannot be infinity")));
1745 : }
1746 :
1747 40 : init_var_from_num(step_num, &steploc);
1748 :
1749 40 : if (cmp_var(&steploc, &const_zero) == 0)
1750 4 : ereport(ERROR,
1751 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1752 : errmsg("step size cannot equal zero")));
1753 : }
1754 :
1755 : /* create a function context for cross-call persistence */
1756 88 : funcctx = SRF_FIRSTCALL_INIT();
1757 :
1758 : /*
1759 : * Switch to memory context appropriate for multiple function calls.
1760 : */
1761 88 : oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1762 :
1763 : /* allocate memory for user context */
1764 88 : fctx = palloc_object(generate_series_numeric_fctx);
1765 :
1766 : /*
1767 : * Use fctx to keep state from call to call. Seed current with the
1768 : * original start value. We must copy the start_num and stop_num
1769 : * values rather than pointing to them, since we may have detoasted
1770 : * them in the per-call context.
1771 : */
1772 88 : init_var(&fctx->current);
1773 88 : init_var(&fctx->stop);
1774 88 : init_var(&fctx->step);
1775 :
1776 88 : set_var_from_num(start_num, &fctx->current);
1777 88 : set_var_from_num(stop_num, &fctx->stop);
1778 88 : set_var_from_var(&steploc, &fctx->step);
1779 :
1780 88 : funcctx->user_fctx = fctx;
1781 88 : MemoryContextSwitchTo(oldcontext);
1782 : }
1783 :
1784 : /* stuff done on every call of the function */
1785 80528 : funcctx = SRF_PERCALL_SETUP();
1786 :
1787 : /*
1788 : * Get the saved state and use current state as the result of this
1789 : * iteration.
1790 : */
1791 80528 : fctx = funcctx->user_fctx;
1792 :
1793 160936 : if ((fctx->step.sign == NUMERIC_POS &&
1794 80408 : cmp_var(&fctx->current, &fctx->stop) <= 0) ||
1795 320 : (fctx->step.sign == NUMERIC_NEG &&
1796 120 : cmp_var(&fctx->current, &fctx->stop) >= 0))
1797 : {
1798 80440 : Numeric result = make_result(&fctx->current);
1799 :
1800 : /* switch to memory context appropriate for iteration calculation */
1801 80440 : oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1802 :
1803 : /* increment current in preparation for next iteration */
1804 80440 : add_var(&fctx->current, &fctx->step, &fctx->current);
1805 80440 : MemoryContextSwitchTo(oldcontext);
1806 :
1807 : /* do when there is more left to send */
1808 80440 : SRF_RETURN_NEXT(funcctx, NumericGetDatum(result));
1809 : }
1810 : else
1811 : /* do when there is no more left */
1812 88 : SRF_RETURN_DONE(funcctx);
1813 : }
1814 :
1815 : /*
1816 : * Planner support function for generate_series(numeric, numeric [, numeric])
1817 : */
1818 : Datum
1819 535 : generate_series_numeric_support(PG_FUNCTION_ARGS)
1820 : {
1821 535 : Node *rawreq = (Node *) PG_GETARG_POINTER(0);
1822 535 : Node *ret = NULL;
1823 :
1824 535 : if (IsA(rawreq, SupportRequestRows))
1825 : {
1826 : /* Try to estimate the number of rows returned */
1827 130 : SupportRequestRows *req = (SupportRequestRows *) rawreq;
1828 :
1829 130 : if (is_funcclause(req->node)) /* be paranoid */
1830 : {
1831 130 : List *args = ((FuncExpr *) req->node)->args;
1832 : Node *arg1,
1833 : *arg2,
1834 : *arg3;
1835 :
1836 : /* We can use estimated argument values here */
1837 130 : arg1 = estimate_expression_value(req->root, linitial(args));
1838 130 : arg2 = estimate_expression_value(req->root, lsecond(args));
1839 130 : if (list_length(args) >= 3)
1840 85 : arg3 = estimate_expression_value(req->root, lthird(args));
1841 : else
1842 45 : arg3 = NULL;
1843 :
1844 : /*
1845 : * If any argument is constant NULL, we can safely assume that
1846 : * zero rows are returned. Otherwise, if they're all non-NULL
1847 : * constants, we can calculate the number of rows that will be
1848 : * returned.
1849 : */
1850 130 : if ((IsA(arg1, Const) &&
1851 125 : ((Const *) arg1)->constisnull) ||
1852 130 : (IsA(arg2, Const) &&
1853 130 : ((Const *) arg2)->constisnull) ||
1854 85 : (arg3 != NULL && IsA(arg3, Const) &&
1855 80 : ((Const *) arg3)->constisnull))
1856 : {
1857 0 : req->rows = 0;
1858 0 : ret = (Node *) req;
1859 : }
1860 130 : else if (IsA(arg1, Const) &&
1861 125 : IsA(arg2, Const) &&
1862 85 : (arg3 == NULL || IsA(arg3, Const)))
1863 : {
1864 : Numeric start_num;
1865 : Numeric stop_num;
1866 115 : NumericVar step = const_one;
1867 :
1868 : /*
1869 : * If any argument is NaN or infinity, generate_series() will
1870 : * error out, so we needn't produce an estimate.
1871 : */
1872 115 : start_num = DatumGetNumeric(((Const *) arg1)->constvalue);
1873 115 : stop_num = DatumGetNumeric(((Const *) arg2)->constvalue);
1874 :
1875 115 : if (NUMERIC_IS_SPECIAL(start_num) ||
1876 100 : NUMERIC_IS_SPECIAL(stop_num))
1877 40 : PG_RETURN_POINTER(NULL);
1878 :
1879 90 : if (arg3)
1880 : {
1881 : Numeric step_num;
1882 :
1883 55 : step_num = DatumGetNumeric(((Const *) arg3)->constvalue);
1884 :
1885 55 : if (NUMERIC_IS_SPECIAL(step_num))
1886 15 : PG_RETURN_POINTER(NULL);
1887 :
1888 40 : init_var_from_num(step_num, &step);
1889 : }
1890 :
1891 : /*
1892 : * The number of rows that will be returned is given by
1893 : * floor((stop - start) / step) + 1, if the sign of step
1894 : * matches the sign of stop - start. Otherwise, no rows will
1895 : * be returned.
1896 : */
1897 75 : if (cmp_var(&step, &const_zero) != 0)
1898 : {
1899 : NumericVar start;
1900 : NumericVar stop;
1901 : NumericVar res;
1902 :
1903 65 : init_var_from_num(start_num, &start);
1904 65 : init_var_from_num(stop_num, &stop);
1905 :
1906 65 : init_var(&res);
1907 65 : sub_var(&stop, &start, &res);
1908 :
1909 65 : if (step.sign != res.sign)
1910 : {
1911 : /* no rows will be returned */
1912 5 : req->rows = 0;
1913 5 : ret = (Node *) req;
1914 : }
1915 : else
1916 : {
1917 60 : if (arg3)
1918 25 : div_var(&res, &step, &res, 0, false, false);
1919 : else
1920 35 : trunc_var(&res, 0); /* step = 1 */
1921 :
1922 60 : req->rows = numericvar_to_double_no_overflow(&res) + 1;
1923 60 : ret = (Node *) req;
1924 : }
1925 :
1926 65 : free_var(&res);
1927 : }
1928 : }
1929 : }
1930 : }
1931 :
1932 495 : PG_RETURN_POINTER(ret);
1933 : }
1934 :
1935 :
1936 : /*
1937 : * Implements the numeric version of the width_bucket() function
1938 : * defined by SQL2003. See also width_bucket_float8().
1939 : *
1940 : * 'bound1' and 'bound2' are the lower and upper bounds of the
1941 : * histogram's range, respectively. 'count' is the number of buckets
1942 : * in the histogram. width_bucket() returns an integer indicating the
1943 : * bucket number that 'operand' belongs to in an equiwidth histogram
1944 : * with the specified characteristics. An operand smaller than the
1945 : * lower bound is assigned to bucket 0. An operand greater than or equal
1946 : * to the upper bound is assigned to an additional bucket (with number
1947 : * count+1). We don't allow the histogram bounds to be NaN or +/- infinity,
1948 : * but we do allow those values for the operand (taking NaN to be larger
1949 : * than any other value, as we do in comparisons).
1950 : */
1951 : Datum
1952 529 : width_bucket_numeric(PG_FUNCTION_ARGS)
1953 : {
1954 529 : Numeric operand = PG_GETARG_NUMERIC(0);
1955 529 : Numeric bound1 = PG_GETARG_NUMERIC(1);
1956 529 : Numeric bound2 = PG_GETARG_NUMERIC(2);
1957 529 : int32 count = PG_GETARG_INT32(3);
1958 : NumericVar count_var;
1959 : NumericVar result_var;
1960 : int32 result;
1961 :
1962 529 : if (count <= 0)
1963 8 : ereport(ERROR,
1964 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1965 : errmsg("count must be greater than zero")));
1966 :
1967 521 : if (NUMERIC_IS_SPECIAL(bound1) || NUMERIC_IS_SPECIAL(bound2))
1968 : {
1969 16 : if (NUMERIC_IS_NAN(bound1) || NUMERIC_IS_NAN(bound2))
1970 4 : ereport(ERROR,
1971 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1972 : errmsg("lower and upper bounds cannot be NaN")));
1973 :
1974 12 : if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2))
1975 12 : ereport(ERROR,
1976 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1977 : errmsg("lower and upper bounds must be finite")));
1978 : }
1979 :
1980 505 : init_var(&result_var);
1981 505 : init_var(&count_var);
1982 :
1983 : /* Convert 'count' to a numeric, for ease of use later */
1984 505 : int64_to_numericvar((int64) count, &count_var);
1985 :
1986 505 : switch (cmp_numerics(bound1, bound2))
1987 : {
1988 4 : case 0:
1989 4 : ereport(ERROR,
1990 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
1991 : errmsg("lower bound cannot equal upper bound")));
1992 : break;
1993 :
1994 : /* bound1 < bound2 */
1995 372 : case -1:
1996 372 : if (cmp_numerics(operand, bound1) < 0)
1997 77 : set_var_from_var(&const_zero, &result_var);
1998 295 : else if (cmp_numerics(operand, bound2) >= 0)
1999 78 : add_var(&count_var, &const_one, &result_var);
2000 : else
2001 217 : compute_bucket(operand, bound1, bound2, &count_var,
2002 : &result_var);
2003 372 : break;
2004 :
2005 : /* bound1 > bound2 */
2006 129 : case 1:
2007 129 : if (cmp_numerics(operand, bound1) > 0)
2008 8 : set_var_from_var(&const_zero, &result_var);
2009 121 : else if (cmp_numerics(operand, bound2) <= 0)
2010 16 : add_var(&count_var, &const_one, &result_var);
2011 : else
2012 105 : compute_bucket(operand, bound1, bound2, &count_var,
2013 : &result_var);
2014 129 : break;
2015 : }
2016 :
2017 : /* if result exceeds the range of a legal int4, we ereport here */
2018 501 : if (!numericvar_to_int32(&result_var, &result))
2019 0 : ereport(ERROR,
2020 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2021 : errmsg("integer out of range")));
2022 :
2023 501 : free_var(&count_var);
2024 501 : free_var(&result_var);
2025 :
2026 501 : PG_RETURN_INT32(result);
2027 : }
2028 :
2029 : /*
2030 : * 'operand' is inside the bucket range, so determine the correct
2031 : * bucket for it to go in. The calculations performed by this function
2032 : * are derived directly from the SQL2003 spec. Note however that we
2033 : * multiply by count before dividing, to avoid unnecessary roundoff error.
2034 : */
2035 : static void
2036 322 : compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
2037 : const NumericVar *count_var, NumericVar *result_var)
2038 : {
2039 : NumericVar bound1_var;
2040 : NumericVar bound2_var;
2041 : NumericVar operand_var;
2042 :
2043 322 : init_var_from_num(bound1, &bound1_var);
2044 322 : init_var_from_num(bound2, &bound2_var);
2045 322 : init_var_from_num(operand, &operand_var);
2046 :
2047 : /*
2048 : * Per spec, bound1 is inclusive and bound2 is exclusive, and so we have
2049 : * bound1 <= operand < bound2 or bound1 >= operand > bound2. Either way,
2050 : * the result is ((operand - bound1) * count) / (bound2 - bound1) + 1,
2051 : * where the quotient is computed using floor division (i.e., division to
2052 : * zero decimal places with truncation), which guarantees that the result
2053 : * is in the range [1, count]. Reversing the bounds doesn't affect the
2054 : * computation, because the signs cancel out when dividing.
2055 : */
2056 322 : sub_var(&operand_var, &bound1_var, &operand_var);
2057 322 : sub_var(&bound2_var, &bound1_var, &bound2_var);
2058 :
2059 322 : mul_var(&operand_var, count_var, &operand_var,
2060 322 : operand_var.dscale + count_var->dscale);
2061 322 : div_var(&operand_var, &bound2_var, result_var, 0, false, true);
2062 322 : add_var(result_var, &const_one, result_var);
2063 :
2064 322 : free_var(&bound1_var);
2065 322 : free_var(&bound2_var);
2066 322 : free_var(&operand_var);
2067 322 : }
2068 :
2069 : /* ----------------------------------------------------------------------
2070 : *
2071 : * Comparison functions
2072 : *
2073 : * Note: btree indexes need these routines not to leak memory; therefore,
2074 : * be careful to free working copies of toasted datums. Most places don't
2075 : * need to be so careful.
2076 : *
2077 : * Sort support:
2078 : *
2079 : * We implement the sortsupport strategy routine in order to get the benefit of
2080 : * abbreviation. The ordinary numeric comparison can be quite slow as a result
2081 : * of palloc/pfree cycles (due to detoasting packed values for alignment);
2082 : * while this could be worked on itself, the abbreviation strategy gives more
2083 : * speedup in many common cases.
2084 : *
2085 : * The abbreviated format is an int64. The representation is negated relative
2086 : * to the original value, because we use the largest negative value for NaN,
2087 : * which sorts higher than other values. We convert the absolute value of the
2088 : * numeric to a 63-bit positive value, and then negate it if the original
2089 : * number was positive.
2090 : *
2091 : * We abort the abbreviation process if the abbreviation cardinality is below
2092 : * 0.01% of the row count (1 per 10k non-null rows). The actual break-even
2093 : * point is somewhat below that, perhaps 1 per 30k (at 1 per 100k there's a
2094 : * very small penalty), but we don't want to build up too many abbreviated
2095 : * values before first testing for abort, so we take the slightly pessimistic
2096 : * number. We make no attempt to estimate the cardinality of the real values,
2097 : * since it plays no part in the cost model here (if the abbreviation is equal,
2098 : * the cost of comparing equal and unequal underlying values is comparable).
2099 : * We discontinue even checking for abort (saving us the hashing overhead) if
2100 : * the estimated cardinality gets to 100k; that would be enough to support many
2101 : * billions of rows while doing no worse than breaking even.
2102 : *
2103 : * ----------------------------------------------------------------------
2104 : */
2105 :
2106 : /*
2107 : * Sort support strategy routine.
2108 : */
2109 : Datum
2110 791 : numeric_sortsupport(PG_FUNCTION_ARGS)
2111 : {
2112 791 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
2113 :
2114 791 : ssup->comparator = numeric_fast_cmp;
2115 :
2116 791 : if (ssup->abbreviate)
2117 : {
2118 : NumericSortSupport *nss;
2119 171 : MemoryContext oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2120 :
2121 171 : nss = palloc_object(NumericSortSupport);
2122 :
2123 : /*
2124 : * palloc a buffer for handling unaligned packed values in addition to
2125 : * the support struct
2126 : */
2127 171 : nss->buf = palloc(VARATT_SHORT_MAX + VARHDRSZ + 1);
2128 :
2129 171 : nss->input_count = 0;
2130 171 : nss->estimating = true;
2131 171 : initHyperLogLog(&nss->abbr_card, 10);
2132 :
2133 171 : ssup->ssup_extra = nss;
2134 :
2135 171 : ssup->abbrev_full_comparator = ssup->comparator;
2136 171 : ssup->comparator = numeric_cmp_abbrev;
2137 171 : ssup->abbrev_converter = numeric_abbrev_convert;
2138 171 : ssup->abbrev_abort = numeric_abbrev_abort;
2139 :
2140 171 : MemoryContextSwitchTo(oldcontext);
2141 : }
2142 :
2143 791 : PG_RETURN_VOID();
2144 : }
2145 :
2146 : /*
2147 : * Abbreviate a numeric datum, handling NaNs and detoasting
2148 : * (must not leak memory!)
2149 : */
2150 : static Datum
2151 12779 : numeric_abbrev_convert(Datum original_datum, SortSupport ssup)
2152 : {
2153 12779 : NumericSortSupport *nss = ssup->ssup_extra;
2154 12779 : void *original_varatt = PG_DETOAST_DATUM_PACKED(original_datum);
2155 : Numeric value;
2156 : Datum result;
2157 :
2158 12779 : nss->input_count += 1;
2159 :
2160 : /*
2161 : * This is to handle packed datums without needing a palloc/pfree cycle;
2162 : * we keep and reuse a buffer large enough to handle any short datum.
2163 : */
2164 12779 : if (VARATT_IS_SHORT(original_varatt))
2165 : {
2166 679 : void *buf = nss->buf;
2167 679 : Size sz = VARSIZE_SHORT(original_varatt) - VARHDRSZ_SHORT;
2168 :
2169 : Assert(sz <= VARATT_SHORT_MAX - VARHDRSZ_SHORT);
2170 :
2171 679 : SET_VARSIZE(buf, VARHDRSZ + sz);
2172 679 : memcpy(VARDATA(buf), VARDATA_SHORT(original_varatt), sz);
2173 :
2174 679 : value = (Numeric) buf;
2175 : }
2176 : else
2177 12100 : value = (Numeric) original_varatt;
2178 :
2179 12779 : if (NUMERIC_IS_SPECIAL(value))
2180 : {
2181 100 : if (NUMERIC_IS_PINF(value))
2182 32 : result = NUMERIC_ABBREV_PINF;
2183 68 : else if (NUMERIC_IS_NINF(value))
2184 32 : result = NUMERIC_ABBREV_NINF;
2185 : else
2186 36 : result = NUMERIC_ABBREV_NAN;
2187 : }
2188 : else
2189 : {
2190 : NumericVar var;
2191 :
2192 12679 : init_var_from_num(value, &var);
2193 :
2194 12679 : result = numeric_abbrev_convert_var(&var, nss);
2195 : }
2196 :
2197 : /* should happen only for external/compressed toasts */
2198 12779 : if (original_varatt != DatumGetPointer(original_datum))
2199 0 : pfree(original_varatt);
2200 :
2201 12779 : return result;
2202 : }
2203 :
2204 : /*
2205 : * Consider whether to abort abbreviation.
2206 : *
2207 : * We pay no attention to the cardinality of the non-abbreviated data. There is
2208 : * no reason to do so: unlike text, we have no fast check for equal values, so
2209 : * we pay the full overhead whenever the abbreviations are equal regardless of
2210 : * whether the underlying values are also equal.
2211 : */
2212 : static bool
2213 96 : numeric_abbrev_abort(int memtupcount, SortSupport ssup)
2214 : {
2215 96 : NumericSortSupport *nss = ssup->ssup_extra;
2216 : double abbr_card;
2217 :
2218 96 : if (memtupcount < 10000 || nss->input_count < 10000 || !nss->estimating)
2219 96 : return false;
2220 :
2221 0 : abbr_card = estimateHyperLogLog(&nss->abbr_card);
2222 :
2223 : /*
2224 : * If we have >100k distinct values, then even if we were sorting many
2225 : * billion rows we'd likely still break even, and the penalty of undoing
2226 : * that many rows of abbrevs would probably not be worth it. Stop even
2227 : * counting at that point.
2228 : */
2229 0 : if (abbr_card > 100000.0)
2230 : {
2231 0 : if (trace_sort)
2232 0 : elog(LOG,
2233 : "numeric_abbrev: estimation ends at cardinality %f"
2234 : " after " INT64_FORMAT " values (%d rows)",
2235 : abbr_card, nss->input_count, memtupcount);
2236 0 : nss->estimating = false;
2237 0 : return false;
2238 : }
2239 :
2240 : /*
2241 : * Target minimum cardinality is 1 per ~10k of non-null inputs. (The
2242 : * break even point is somewhere between one per 100k rows, where
2243 : * abbreviation has a very slight penalty, and 1 per 10k where it wins by
2244 : * a measurable percentage.) We use the relatively pessimistic 10k
2245 : * threshold, and add a 0.5 row fudge factor, because it allows us to
2246 : * abort earlier on genuinely pathological data where we've had exactly
2247 : * one abbreviated value in the first 10k (non-null) rows.
2248 : */
2249 0 : if (abbr_card < nss->input_count / 10000.0 + 0.5)
2250 : {
2251 0 : if (trace_sort)
2252 0 : elog(LOG,
2253 : "numeric_abbrev: aborting abbreviation at cardinality %f"
2254 : " below threshold %f after " INT64_FORMAT " values (%d rows)",
2255 : abbr_card, nss->input_count / 10000.0 + 0.5,
2256 : nss->input_count, memtupcount);
2257 0 : return true;
2258 : }
2259 :
2260 0 : if (trace_sort)
2261 0 : elog(LOG,
2262 : "numeric_abbrev: cardinality %f"
2263 : " after " INT64_FORMAT " values (%d rows)",
2264 : abbr_card, nss->input_count, memtupcount);
2265 :
2266 0 : return false;
2267 : }
2268 :
2269 : /*
2270 : * Non-fmgr interface to the comparison routine to allow sortsupport to elide
2271 : * the fmgr call. The saving here is small given how slow numeric comparisons
2272 : * are, but it is a required part of the sort support API when abbreviations
2273 : * are performed.
2274 : *
2275 : * Two palloc/pfree cycles could be saved here by using persistent buffers for
2276 : * aligning short-varlena inputs, but this has not so far been considered to
2277 : * be worth the effort.
2278 : */
2279 : static int
2280 17208108 : numeric_fast_cmp(Datum x, Datum y, SortSupport ssup)
2281 : {
2282 17208108 : Numeric nx = DatumGetNumeric(x);
2283 17208108 : Numeric ny = DatumGetNumeric(y);
2284 : int result;
2285 :
2286 17208108 : result = cmp_numerics(nx, ny);
2287 :
2288 17208108 : if (nx != DatumGetPointer(x))
2289 7409856 : pfree(nx);
2290 17208108 : if (ny != DatumGetPointer(y))
2291 7409852 : pfree(ny);
2292 :
2293 17208108 : return result;
2294 : }
2295 :
2296 : /*
2297 : * Compare abbreviations of values. (Abbreviations may be equal where the true
2298 : * values differ, but if the abbreviations differ, they must reflect the
2299 : * ordering of the true values.)
2300 : */
2301 : static int
2302 126967 : numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup)
2303 : {
2304 : /*
2305 : * NOTE WELL: this is intentionally backwards, because the abbreviation is
2306 : * negated relative to the original value, to handle NaN/infinity cases.
2307 : */
2308 126967 : if (DatumGetNumericAbbrev(x) < DatumGetNumericAbbrev(y))
2309 66757 : return 1;
2310 60210 : if (DatumGetNumericAbbrev(x) > DatumGetNumericAbbrev(y))
2311 60061 : return -1;
2312 149 : return 0;
2313 : }
2314 :
2315 : /*
2316 : * Abbreviate a NumericVar into the 64-bit sortsupport size.
2317 : *
2318 : * The 31-bit value is constructed as:
2319 : *
2320 : * 0 + 7bits digit weight + 24 bits digit value
2321 : *
2322 : * where the digit weight is in single decimal digits, not digit words, and
2323 : * stored in excess-44 representation[1]. The 24-bit digit value is the 7 most
2324 : * significant decimal digits of the value converted to binary. Values whose
2325 : * weights would fall outside the representable range are rounded off to zero
2326 : * (which is also used to represent actual zeros) or to 0x7FFFFFFF (which
2327 : * otherwise cannot occur). Abbreviation therefore fails to gain any advantage
2328 : * where values are outside the range 10^-44 to 10^83, which is not considered
2329 : * to be a serious limitation, or when values are of the same magnitude and
2330 : * equal in the first 7 decimal digits, which is considered to be an
2331 : * unavoidable limitation given the available bits. (Stealing three more bits
2332 : * to compare another digit would narrow the range of representable weights by
2333 : * a factor of 8, which starts to look like a real limiting factor.)
2334 : *
2335 : * (The value 44 for the excess is essentially arbitrary)
2336 : *
2337 : * The 63-bit value is constructed as:
2338 : *
2339 : * 0 + 7bits weight + 4 x 14-bit packed digit words
2340 : *
2341 : * The weight in this case is again stored in excess-44, but this time it is
2342 : * the original weight in digit words (i.e. powers of 10000). The first four
2343 : * digit words of the value (if present; trailing zeros are assumed as needed)
2344 : * are packed into 14 bits each to form the rest of the value. Again,
2345 : * out-of-range values are rounded off to 0 or 0x7FFFFFFFFFFFFFFF. The
2346 : * representable range in this case is 10^-176 to 10^332, which is considered
2347 : * to be good enough for all practical purposes, and comparison of 4 words
2348 : * means that at least 13 decimal digits are compared, which is considered to
2349 : * be a reasonable compromise between effectiveness and efficiency in computing
2350 : * the abbreviation.
2351 : *
2352 : * (The value 44 for the excess is even more arbitrary here, it was chosen just
2353 : * to match the value used in the 31-bit case)
2354 : *
2355 : * [1] - Excess-k representation means that the value is offset by adding 'k'
2356 : * and then treated as unsigned, so the smallest representable value is stored
2357 : * with all bits zero. This allows simple comparisons to work on the composite
2358 : * value.
2359 : */
2360 : static Datum
2361 12679 : numeric_abbrev_convert_var(const NumericVar *var, NumericSortSupport *nss)
2362 : {
2363 12679 : int ndigits = var->ndigits;
2364 12679 : int weight = var->weight;
2365 : int64 result;
2366 :
2367 12679 : if (ndigits == 0 || weight < -44)
2368 : {
2369 34 : result = 0;
2370 : }
2371 12645 : else if (weight > 83)
2372 : {
2373 8 : result = PG_INT64_MAX;
2374 : }
2375 : else
2376 : {
2377 12637 : result = ((int64) (weight + 44) << 56);
2378 :
2379 12637 : switch (ndigits)
2380 : {
2381 0 : default:
2382 0 : result |= ((int64) var->digits[3]);
2383 : pg_fallthrough;
2384 4138 : case 3:
2385 4138 : result |= ((int64) var->digits[2]) << 14;
2386 : pg_fallthrough;
2387 12198 : case 2:
2388 12198 : result |= ((int64) var->digits[1]) << 28;
2389 : pg_fallthrough;
2390 12637 : case 1:
2391 12637 : result |= ((int64) var->digits[0]) << 42;
2392 12637 : break;
2393 : }
2394 : }
2395 :
2396 : /* the abbrev is negated relative to the original */
2397 12679 : if (var->sign == NUMERIC_POS)
2398 12615 : result = -result;
2399 :
2400 12679 : if (nss->estimating)
2401 : {
2402 12679 : uint32 tmp = ((uint32) result
2403 12679 : ^ (uint32) ((uint64) result >> 32));
2404 :
2405 12679 : addHyperLogLog(&nss->abbr_card, DatumGetUInt32(hash_uint32(tmp)));
2406 : }
2407 :
2408 12679 : return NumericAbbrevGetDatum(result);
2409 : }
2410 :
2411 :
2412 : /*
2413 : * Ordinary (non-sortsupport) comparisons follow.
2414 : */
2415 :
2416 : Datum
2417 485645 : numeric_cmp(PG_FUNCTION_ARGS)
2418 : {
2419 485645 : Numeric num1 = PG_GETARG_NUMERIC(0);
2420 485645 : Numeric num2 = PG_GETARG_NUMERIC(1);
2421 : int result;
2422 :
2423 485645 : result = cmp_numerics(num1, num2);
2424 :
2425 485645 : PG_FREE_IF_COPY(num1, 0);
2426 485645 : PG_FREE_IF_COPY(num2, 1);
2427 :
2428 485645 : PG_RETURN_INT32(result);
2429 : }
2430 :
2431 :
2432 : Datum
2433 428457 : numeric_eq(PG_FUNCTION_ARGS)
2434 : {
2435 428457 : Numeric num1 = PG_GETARG_NUMERIC(0);
2436 428457 : Numeric num2 = PG_GETARG_NUMERIC(1);
2437 : bool result;
2438 :
2439 428457 : result = cmp_numerics(num1, num2) == 0;
2440 :
2441 428457 : PG_FREE_IF_COPY(num1, 0);
2442 428457 : PG_FREE_IF_COPY(num2, 1);
2443 :
2444 428457 : PG_RETURN_BOOL(result);
2445 : }
2446 :
2447 : Datum
2448 3584 : numeric_ne(PG_FUNCTION_ARGS)
2449 : {
2450 3584 : Numeric num1 = PG_GETARG_NUMERIC(0);
2451 3584 : Numeric num2 = PG_GETARG_NUMERIC(1);
2452 : bool result;
2453 :
2454 3584 : result = cmp_numerics(num1, num2) != 0;
2455 :
2456 3584 : PG_FREE_IF_COPY(num1, 0);
2457 3584 : PG_FREE_IF_COPY(num2, 1);
2458 :
2459 3584 : PG_RETURN_BOOL(result);
2460 : }
2461 :
2462 : Datum
2463 34063 : numeric_gt(PG_FUNCTION_ARGS)
2464 : {
2465 34063 : Numeric num1 = PG_GETARG_NUMERIC(0);
2466 34063 : Numeric num2 = PG_GETARG_NUMERIC(1);
2467 : bool result;
2468 :
2469 34063 : result = cmp_numerics(num1, num2) > 0;
2470 :
2471 34063 : PG_FREE_IF_COPY(num1, 0);
2472 34063 : PG_FREE_IF_COPY(num2, 1);
2473 :
2474 34063 : PG_RETURN_BOOL(result);
2475 : }
2476 :
2477 : Datum
2478 8164 : numeric_ge(PG_FUNCTION_ARGS)
2479 : {
2480 8164 : Numeric num1 = PG_GETARG_NUMERIC(0);
2481 8164 : Numeric num2 = PG_GETARG_NUMERIC(1);
2482 : bool result;
2483 :
2484 8164 : result = cmp_numerics(num1, num2) >= 0;
2485 :
2486 8164 : PG_FREE_IF_COPY(num1, 0);
2487 8164 : PG_FREE_IF_COPY(num2, 1);
2488 :
2489 8164 : PG_RETURN_BOOL(result);
2490 : }
2491 :
2492 : Datum
2493 198390 : numeric_lt(PG_FUNCTION_ARGS)
2494 : {
2495 198390 : Numeric num1 = PG_GETARG_NUMERIC(0);
2496 198390 : Numeric num2 = PG_GETARG_NUMERIC(1);
2497 : bool result;
2498 :
2499 198390 : result = cmp_numerics(num1, num2) < 0;
2500 :
2501 198390 : PG_FREE_IF_COPY(num1, 0);
2502 198390 : PG_FREE_IF_COPY(num2, 1);
2503 :
2504 198390 : PG_RETURN_BOOL(result);
2505 : }
2506 :
2507 : Datum
2508 9690 : numeric_le(PG_FUNCTION_ARGS)
2509 : {
2510 9690 : Numeric num1 = PG_GETARG_NUMERIC(0);
2511 9690 : Numeric num2 = PG_GETARG_NUMERIC(1);
2512 : bool result;
2513 :
2514 9690 : result = cmp_numerics(num1, num2) <= 0;
2515 :
2516 9690 : PG_FREE_IF_COPY(num1, 0);
2517 9690 : PG_FREE_IF_COPY(num2, 1);
2518 :
2519 9690 : PG_RETURN_BOOL(result);
2520 : }
2521 :
2522 : static int
2523 18390486 : cmp_numerics(Numeric num1, Numeric num2)
2524 : {
2525 : int result;
2526 :
2527 : /*
2528 : * We consider all NANs to be equal and larger than any non-NAN (including
2529 : * Infinity). This is somewhat arbitrary; the important thing is to have
2530 : * a consistent sort order.
2531 : */
2532 18390486 : if (NUMERIC_IS_SPECIAL(num1))
2533 : {
2534 3327 : if (NUMERIC_IS_NAN(num1))
2535 : {
2536 3264 : if (NUMERIC_IS_NAN(num2))
2537 463 : result = 0; /* NAN = NAN */
2538 : else
2539 2801 : result = 1; /* NAN > non-NAN */
2540 : }
2541 63 : else if (NUMERIC_IS_PINF(num1))
2542 : {
2543 50 : if (NUMERIC_IS_NAN(num2))
2544 0 : result = -1; /* PINF < NAN */
2545 50 : else if (NUMERIC_IS_PINF(num2))
2546 4 : result = 0; /* PINF = PINF */
2547 : else
2548 46 : result = 1; /* PINF > anything else */
2549 : }
2550 : else /* num1 must be NINF */
2551 : {
2552 13 : if (NUMERIC_IS_NINF(num2))
2553 4 : result = 0; /* NINF = NINF */
2554 : else
2555 9 : result = -1; /* NINF < anything else */
2556 : }
2557 : }
2558 18387159 : else if (NUMERIC_IS_SPECIAL(num2))
2559 : {
2560 5594 : if (NUMERIC_IS_NINF(num2))
2561 8 : result = 1; /* normal > NINF */
2562 : else
2563 5586 : result = -1; /* normal < NAN or PINF */
2564 : }
2565 : else
2566 : {
2567 36763774 : result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
2568 18381745 : NUMERIC_WEIGHT(num1), NUMERIC_SIGN(num1),
2569 18381565 : NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
2570 18382029 : NUMERIC_WEIGHT(num2), NUMERIC_SIGN(num2));
2571 : }
2572 :
2573 18390486 : return result;
2574 : }
2575 :
2576 : /*
2577 : * in_range support function for numeric.
2578 : */
2579 : Datum
2580 768 : in_range_numeric_numeric(PG_FUNCTION_ARGS)
2581 : {
2582 768 : Numeric val = PG_GETARG_NUMERIC(0);
2583 768 : Numeric base = PG_GETARG_NUMERIC(1);
2584 768 : Numeric offset = PG_GETARG_NUMERIC(2);
2585 768 : bool sub = PG_GETARG_BOOL(3);
2586 768 : bool less = PG_GETARG_BOOL(4);
2587 : bool result;
2588 :
2589 : /*
2590 : * Reject negative (including -Inf) or NaN offset. Negative is per spec,
2591 : * and NaN is because appropriate semantics for that seem non-obvious.
2592 : */
2593 768 : if (NUMERIC_IS_NAN(offset) ||
2594 764 : NUMERIC_IS_NINF(offset) ||
2595 764 : NUMERIC_SIGN(offset) == NUMERIC_NEG)
2596 4 : ereport(ERROR,
2597 : (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
2598 : errmsg("invalid preceding or following size in window function")));
2599 :
2600 : /*
2601 : * Deal with cases where val and/or base is NaN, following the rule that
2602 : * NaN sorts after non-NaN (cf cmp_numerics). The offset cannot affect
2603 : * the conclusion.
2604 : */
2605 764 : if (NUMERIC_IS_NAN(val))
2606 : {
2607 124 : if (NUMERIC_IS_NAN(base))
2608 40 : result = true; /* NAN = NAN */
2609 : else
2610 84 : result = !less; /* NAN > non-NAN */
2611 : }
2612 640 : else if (NUMERIC_IS_NAN(base))
2613 : {
2614 84 : result = less; /* non-NAN < NAN */
2615 : }
2616 :
2617 : /*
2618 : * Deal with infinite offset (necessarily +Inf, at this point).
2619 : */
2620 556 : else if (NUMERIC_IS_SPECIAL(offset))
2621 : {
2622 : Assert(NUMERIC_IS_PINF(offset));
2623 280 : if (sub ? NUMERIC_IS_PINF(base) : NUMERIC_IS_NINF(base))
2624 : {
2625 : /*
2626 : * base +/- offset would produce NaN, so return true for any val
2627 : * (see in_range_float8_float8() for reasoning).
2628 : */
2629 116 : result = true;
2630 : }
2631 164 : else if (sub)
2632 : {
2633 : /* base - offset must be -inf */
2634 100 : if (less)
2635 36 : result = NUMERIC_IS_NINF(val); /* only -inf is <= sum */
2636 : else
2637 64 : result = true; /* any val is >= sum */
2638 : }
2639 : else
2640 : {
2641 : /* base + offset must be +inf */
2642 64 : if (less)
2643 0 : result = true; /* any val is <= sum */
2644 : else
2645 64 : result = NUMERIC_IS_PINF(val); /* only +inf is >= sum */
2646 : }
2647 : }
2648 :
2649 : /*
2650 : * Deal with cases where val and/or base is infinite. The offset, being
2651 : * now known finite, cannot affect the conclusion.
2652 : */
2653 276 : else if (NUMERIC_IS_SPECIAL(val))
2654 : {
2655 52 : if (NUMERIC_IS_PINF(val))
2656 : {
2657 24 : if (NUMERIC_IS_PINF(base))
2658 16 : result = true; /* PINF = PINF */
2659 : else
2660 8 : result = !less; /* PINF > any other non-NAN */
2661 : }
2662 : else /* val must be NINF */
2663 : {
2664 28 : if (NUMERIC_IS_NINF(base))
2665 20 : result = true; /* NINF = NINF */
2666 : else
2667 8 : result = less; /* NINF < anything else */
2668 : }
2669 : }
2670 224 : else if (NUMERIC_IS_SPECIAL(base))
2671 : {
2672 16 : if (NUMERIC_IS_NINF(base))
2673 8 : result = !less; /* normal > NINF */
2674 : else
2675 8 : result = less; /* normal < PINF */
2676 : }
2677 : else
2678 : {
2679 : /*
2680 : * Otherwise go ahead and compute base +/- offset. While it's
2681 : * possible for this to overflow the numeric format, it's unlikely
2682 : * enough that we don't take measures to prevent it.
2683 : */
2684 : NumericVar valv;
2685 : NumericVar basev;
2686 : NumericVar offsetv;
2687 : NumericVar sum;
2688 :
2689 208 : init_var_from_num(val, &valv);
2690 208 : init_var_from_num(base, &basev);
2691 208 : init_var_from_num(offset, &offsetv);
2692 208 : init_var(&sum);
2693 :
2694 208 : if (sub)
2695 104 : sub_var(&basev, &offsetv, &sum);
2696 : else
2697 104 : add_var(&basev, &offsetv, &sum);
2698 :
2699 208 : if (less)
2700 104 : result = (cmp_var(&valv, &sum) <= 0);
2701 : else
2702 104 : result = (cmp_var(&valv, &sum) >= 0);
2703 :
2704 208 : free_var(&sum);
2705 : }
2706 :
2707 764 : PG_FREE_IF_COPY(val, 0);
2708 764 : PG_FREE_IF_COPY(base, 1);
2709 764 : PG_FREE_IF_COPY(offset, 2);
2710 :
2711 764 : PG_RETURN_BOOL(result);
2712 : }
2713 :
2714 : Datum
2715 405032 : hash_numeric(PG_FUNCTION_ARGS)
2716 : {
2717 405032 : Numeric key = PG_GETARG_NUMERIC(0);
2718 : Datum digit_hash;
2719 : Datum result;
2720 : int weight;
2721 : int start_offset;
2722 : int end_offset;
2723 : int i;
2724 : int hash_len;
2725 : NumericDigit *digits;
2726 :
2727 : /* If it's NaN or infinity, don't try to hash the rest of the fields */
2728 405032 : if (NUMERIC_IS_SPECIAL(key))
2729 0 : PG_RETURN_UINT32(0);
2730 :
2731 405032 : weight = NUMERIC_WEIGHT(key);
2732 405032 : start_offset = 0;
2733 405032 : end_offset = 0;
2734 :
2735 : /*
2736 : * Omit any leading or trailing zeros from the input to the hash. The
2737 : * numeric implementation *should* guarantee that leading and trailing
2738 : * zeros are suppressed, but we're paranoid. Note that we measure the
2739 : * starting and ending offsets in units of NumericDigits, not bytes.
2740 : */
2741 405032 : digits = NUMERIC_DIGITS(key);
2742 405032 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2743 : {
2744 403945 : if (digits[i] != (NumericDigit) 0)
2745 403945 : break;
2746 :
2747 0 : start_offset++;
2748 :
2749 : /*
2750 : * The weight is effectively the # of digits before the decimal point,
2751 : * so decrement it for each leading zero we skip.
2752 : */
2753 0 : weight--;
2754 : }
2755 :
2756 : /*
2757 : * If there are no non-zero digits, then the value of the number is zero,
2758 : * regardless of any other fields.
2759 : */
2760 405032 : if (NUMERIC_NDIGITS(key) == start_offset)
2761 1087 : PG_RETURN_UINT32(-1);
2762 :
2763 403945 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2764 : {
2765 403945 : if (digits[i] != (NumericDigit) 0)
2766 403945 : break;
2767 :
2768 0 : end_offset++;
2769 : }
2770 :
2771 : /* If we get here, there should be at least one non-zero digit */
2772 : Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2773 :
2774 : /*
2775 : * Note that we don't hash on the Numeric's scale, since two numerics can
2776 : * compare equal but have different scales. We also don't hash on the
2777 : * sign, although we could: since a sign difference implies inequality,
2778 : * this shouldn't affect correctness.
2779 : */
2780 403945 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2781 403945 : digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
2782 : hash_len * sizeof(NumericDigit));
2783 :
2784 : /* Mix in the weight, via XOR */
2785 403945 : result = digit_hash ^ weight;
2786 :
2787 403945 : PG_RETURN_DATUM(result);
2788 : }
2789 :
2790 : /*
2791 : * Returns 64-bit value by hashing a value to a 64-bit value, with a seed.
2792 : * Otherwise, similar to hash_numeric.
2793 : */
2794 : Datum
2795 56 : hash_numeric_extended(PG_FUNCTION_ARGS)
2796 : {
2797 56 : Numeric key = PG_GETARG_NUMERIC(0);
2798 56 : uint64 seed = PG_GETARG_INT64(1);
2799 : Datum digit_hash;
2800 : Datum result;
2801 : int weight;
2802 : int start_offset;
2803 : int end_offset;
2804 : int i;
2805 : int hash_len;
2806 : NumericDigit *digits;
2807 :
2808 : /* If it's NaN or infinity, don't try to hash the rest of the fields */
2809 56 : if (NUMERIC_IS_SPECIAL(key))
2810 0 : PG_RETURN_UINT64(seed);
2811 :
2812 56 : weight = NUMERIC_WEIGHT(key);
2813 56 : start_offset = 0;
2814 56 : end_offset = 0;
2815 :
2816 56 : digits = NUMERIC_DIGITS(key);
2817 56 : for (i = 0; i < NUMERIC_NDIGITS(key); i++)
2818 : {
2819 48 : if (digits[i] != (NumericDigit) 0)
2820 48 : break;
2821 :
2822 0 : start_offset++;
2823 :
2824 0 : weight--;
2825 : }
2826 :
2827 56 : if (NUMERIC_NDIGITS(key) == start_offset)
2828 8 : PG_RETURN_UINT64(seed - 1);
2829 :
2830 48 : for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
2831 : {
2832 48 : if (digits[i] != (NumericDigit) 0)
2833 48 : break;
2834 :
2835 0 : end_offset++;
2836 : }
2837 :
2838 : Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
2839 :
2840 48 : hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
2841 48 : digit_hash = hash_any_extended((unsigned char *) (NUMERIC_DIGITS(key)
2842 48 : + start_offset),
2843 : hash_len * sizeof(NumericDigit),
2844 : seed);
2845 :
2846 48 : result = UInt64GetDatum(DatumGetUInt64(digit_hash) ^ weight);
2847 :
2848 48 : PG_RETURN_DATUM(result);
2849 : }
2850 :
2851 :
2852 : /* ----------------------------------------------------------------------
2853 : *
2854 : * Basic arithmetic functions
2855 : *
2856 : * ----------------------------------------------------------------------
2857 : */
2858 :
2859 :
2860 : /*
2861 : * numeric_add() -
2862 : *
2863 : * Add two numerics
2864 : */
2865 : Datum
2866 168428 : numeric_add(PG_FUNCTION_ARGS)
2867 : {
2868 168428 : Numeric num1 = PG_GETARG_NUMERIC(0);
2869 168428 : Numeric num2 = PG_GETARG_NUMERIC(1);
2870 : Numeric res;
2871 :
2872 168428 : res = numeric_add_safe(num1, num2, NULL);
2873 :
2874 168428 : PG_RETURN_NUMERIC(res);
2875 : }
2876 :
2877 : /*
2878 : * numeric_add_safe() -
2879 : *
2880 : * Internal version of numeric_add() with support for soft error reporting.
2881 : */
2882 : Numeric
2883 169122 : numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)
2884 : {
2885 : NumericVar arg1;
2886 : NumericVar arg2;
2887 : NumericVar result;
2888 : Numeric res;
2889 :
2890 : /*
2891 : * Handle NaN and infinities
2892 : */
2893 169122 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2894 : {
2895 132 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2896 52 : return make_result(&const_nan);
2897 80 : if (NUMERIC_IS_PINF(num1))
2898 : {
2899 24 : if (NUMERIC_IS_NINF(num2))
2900 4 : return make_result(&const_nan); /* Inf + -Inf */
2901 : else
2902 20 : return make_result(&const_pinf);
2903 : }
2904 56 : if (NUMERIC_IS_NINF(num1))
2905 : {
2906 24 : if (NUMERIC_IS_PINF(num2))
2907 4 : return make_result(&const_nan); /* -Inf + Inf */
2908 : else
2909 20 : return make_result(&const_ninf);
2910 : }
2911 : /* by here, num1 must be finite, so num2 is not */
2912 32 : if (NUMERIC_IS_PINF(num2))
2913 16 : return make_result(&const_pinf);
2914 : Assert(NUMERIC_IS_NINF(num2));
2915 16 : return make_result(&const_ninf);
2916 : }
2917 :
2918 : /*
2919 : * Unpack the values, let add_var() compute the result and return it.
2920 : */
2921 168990 : init_var_from_num(num1, &arg1);
2922 168990 : init_var_from_num(num2, &arg2);
2923 :
2924 168990 : init_var(&result);
2925 168990 : add_var(&arg1, &arg2, &result);
2926 :
2927 168990 : res = make_result_safe(&result, escontext);
2928 :
2929 168990 : free_var(&result);
2930 :
2931 168990 : return res;
2932 : }
2933 :
2934 :
2935 : /*
2936 : * numeric_sub() -
2937 : *
2938 : * Subtract one numeric from another
2939 : */
2940 : Datum
2941 46198 : numeric_sub(PG_FUNCTION_ARGS)
2942 : {
2943 46198 : Numeric num1 = PG_GETARG_NUMERIC(0);
2944 46198 : Numeric num2 = PG_GETARG_NUMERIC(1);
2945 : Numeric res;
2946 :
2947 46198 : res = numeric_sub_safe(num1, num2, NULL);
2948 :
2949 46198 : PG_RETURN_NUMERIC(res);
2950 : }
2951 :
2952 :
2953 : /*
2954 : * numeric_sub_safe() -
2955 : *
2956 : * Internal version of numeric_sub() with support for soft error reporting.
2957 : */
2958 : Numeric
2959 46302 : numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)
2960 : {
2961 : NumericVar arg1;
2962 : NumericVar arg2;
2963 : NumericVar result;
2964 : Numeric res;
2965 :
2966 : /*
2967 : * Handle NaN and infinities
2968 : */
2969 46302 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
2970 : {
2971 132 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
2972 52 : return make_result(&const_nan);
2973 80 : if (NUMERIC_IS_PINF(num1))
2974 : {
2975 24 : if (NUMERIC_IS_PINF(num2))
2976 4 : return make_result(&const_nan); /* Inf - Inf */
2977 : else
2978 20 : return make_result(&const_pinf);
2979 : }
2980 56 : if (NUMERIC_IS_NINF(num1))
2981 : {
2982 24 : if (NUMERIC_IS_NINF(num2))
2983 4 : return make_result(&const_nan); /* -Inf - -Inf */
2984 : else
2985 20 : return make_result(&const_ninf);
2986 : }
2987 : /* by here, num1 must be finite, so num2 is not */
2988 32 : if (NUMERIC_IS_PINF(num2))
2989 16 : return make_result(&const_ninf);
2990 : Assert(NUMERIC_IS_NINF(num2));
2991 16 : return make_result(&const_pinf);
2992 : }
2993 :
2994 : /*
2995 : * Unpack the values, let sub_var() compute the result and return it.
2996 : */
2997 46170 : init_var_from_num(num1, &arg1);
2998 46170 : init_var_from_num(num2, &arg2);
2999 :
3000 46170 : init_var(&result);
3001 46170 : sub_var(&arg1, &arg2, &result);
3002 :
3003 46170 : res = make_result_safe(&result, escontext);
3004 :
3005 46170 : free_var(&result);
3006 :
3007 46170 : return res;
3008 : }
3009 :
3010 :
3011 : /*
3012 : * numeric_mul() -
3013 : *
3014 : * Calculate the product of two numerics
3015 : */
3016 : Datum
3017 326743 : numeric_mul(PG_FUNCTION_ARGS)
3018 : {
3019 326743 : Numeric num1 = PG_GETARG_NUMERIC(0);
3020 326743 : Numeric num2 = PG_GETARG_NUMERIC(1);
3021 : Numeric res;
3022 :
3023 326743 : res = numeric_mul_safe(num1, num2, fcinfo->context);
3024 :
3025 326743 : if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
3026 0 : PG_RETURN_NULL();
3027 :
3028 326743 : PG_RETURN_NUMERIC(res);
3029 : }
3030 :
3031 :
3032 : /*
3033 : * numeric_mul_safe() -
3034 : *
3035 : * Internal version of numeric_mul() with support for soft error reporting.
3036 : */
3037 : Numeric
3038 326775 : numeric_mul_safe(Numeric num1, Numeric num2, Node *escontext)
3039 : {
3040 : NumericVar arg1;
3041 : NumericVar arg2;
3042 : NumericVar result;
3043 : Numeric res;
3044 :
3045 : /*
3046 : * Handle NaN and infinities
3047 : */
3048 326775 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3049 : {
3050 132 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3051 52 : return make_result(&const_nan);
3052 80 : if (NUMERIC_IS_PINF(num1))
3053 : {
3054 24 : switch (numeric_sign_internal(num2))
3055 : {
3056 4 : case 0:
3057 4 : return make_result(&const_nan); /* Inf * 0 */
3058 12 : case 1:
3059 12 : return make_result(&const_pinf);
3060 8 : case -1:
3061 8 : return make_result(&const_ninf);
3062 : }
3063 : Assert(false);
3064 : }
3065 56 : if (NUMERIC_IS_NINF(num1))
3066 : {
3067 24 : switch (numeric_sign_internal(num2))
3068 : {
3069 4 : case 0:
3070 4 : return make_result(&const_nan); /* -Inf * 0 */
3071 12 : case 1:
3072 12 : return make_result(&const_ninf);
3073 8 : case -1:
3074 8 : return make_result(&const_pinf);
3075 : }
3076 : Assert(false);
3077 : }
3078 : /* by here, num1 must be finite, so num2 is not */
3079 32 : if (NUMERIC_IS_PINF(num2))
3080 : {
3081 16 : switch (numeric_sign_internal(num1))
3082 : {
3083 4 : case 0:
3084 4 : return make_result(&const_nan); /* 0 * Inf */
3085 8 : case 1:
3086 8 : return make_result(&const_pinf);
3087 4 : case -1:
3088 4 : return make_result(&const_ninf);
3089 : }
3090 : Assert(false);
3091 : }
3092 : Assert(NUMERIC_IS_NINF(num2));
3093 16 : switch (numeric_sign_internal(num1))
3094 : {
3095 4 : case 0:
3096 4 : return make_result(&const_nan); /* 0 * -Inf */
3097 8 : case 1:
3098 8 : return make_result(&const_ninf);
3099 4 : case -1:
3100 4 : return make_result(&const_pinf);
3101 : }
3102 : Assert(false);
3103 : }
3104 :
3105 : /*
3106 : * Unpack the values, let mul_var() compute the result and return it.
3107 : * Unlike add_var() and sub_var(), mul_var() will round its result. In the
3108 : * case of numeric_mul(), which is invoked for the * operator on numerics,
3109 : * we request exact representation for the product (rscale = sum(dscale of
3110 : * arg1, dscale of arg2)). If the exact result has more digits after the
3111 : * decimal point than can be stored in a numeric, we round it. Rounding
3112 : * after computing the exact result ensures that the final result is
3113 : * correctly rounded (rounding in mul_var() using a truncated product
3114 : * would not guarantee this).
3115 : */
3116 326643 : init_var_from_num(num1, &arg1);
3117 326643 : init_var_from_num(num2, &arg2);
3118 :
3119 326643 : init_var(&result);
3120 326643 : mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
3121 :
3122 326643 : if (result.dscale > NUMERIC_DSCALE_MAX)
3123 5 : round_var(&result, NUMERIC_DSCALE_MAX);
3124 :
3125 326643 : res = make_result_safe(&result, escontext);
3126 :
3127 326643 : free_var(&result);
3128 :
3129 326643 : return res;
3130 : }
3131 :
3132 :
3133 : /*
3134 : * numeric_div() -
3135 : *
3136 : * Divide one numeric into another
3137 : */
3138 : Datum
3139 98464 : numeric_div(PG_FUNCTION_ARGS)
3140 : {
3141 98464 : Numeric num1 = PG_GETARG_NUMERIC(0);
3142 98464 : Numeric num2 = PG_GETARG_NUMERIC(1);
3143 : Numeric res;
3144 :
3145 98464 : res = numeric_div_safe(num1, num2, NULL);
3146 :
3147 98443 : PG_RETURN_NUMERIC(res);
3148 : }
3149 :
3150 :
3151 : /*
3152 : * numeric_div_safe() -
3153 : *
3154 : * Internal version of numeric_div() with support for soft error reporting.
3155 : */
3156 : Numeric
3157 99025 : numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)
3158 : {
3159 : NumericVar arg1;
3160 : NumericVar arg2;
3161 : NumericVar result;
3162 : Numeric res;
3163 : int rscale;
3164 :
3165 : /*
3166 : * Handle NaN and infinities
3167 : */
3168 99025 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3169 : {
3170 133 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3171 53 : return make_result(&const_nan);
3172 80 : if (NUMERIC_IS_PINF(num1))
3173 : {
3174 24 : if (NUMERIC_IS_SPECIAL(num2))
3175 8 : return make_result(&const_nan); /* Inf / [-]Inf */
3176 16 : switch (numeric_sign_internal(num2))
3177 : {
3178 4 : case 0:
3179 4 : goto division_by_zero;
3180 8 : case 1:
3181 8 : return make_result(&const_pinf);
3182 4 : case -1:
3183 4 : return make_result(&const_ninf);
3184 : }
3185 : Assert(false);
3186 : }
3187 56 : if (NUMERIC_IS_NINF(num1))
3188 : {
3189 24 : if (NUMERIC_IS_SPECIAL(num2))
3190 8 : return make_result(&const_nan); /* -Inf / [-]Inf */
3191 16 : switch (numeric_sign_internal(num2))
3192 : {
3193 4 : case 0:
3194 4 : goto division_by_zero;
3195 8 : case 1:
3196 8 : return make_result(&const_ninf);
3197 4 : case -1:
3198 4 : return make_result(&const_pinf);
3199 : }
3200 : Assert(false);
3201 : }
3202 : /* by here, num1 must be finite, so num2 is not */
3203 :
3204 : /*
3205 : * POSIX would have us return zero or minus zero if num1 is zero, and
3206 : * otherwise throw an underflow error. But the numeric type doesn't
3207 : * really do underflow, so let's just return zero.
3208 : */
3209 32 : return make_result(&const_zero);
3210 : }
3211 :
3212 : /*
3213 : * Unpack the arguments
3214 : */
3215 98892 : init_var_from_num(num1, &arg1);
3216 98892 : init_var_from_num(num2, &arg2);
3217 :
3218 98892 : init_var(&result);
3219 :
3220 : /*
3221 : * Select scale for division result
3222 : */
3223 98892 : rscale = select_div_scale(&arg1, &arg2);
3224 :
3225 : /* Check for division by zero */
3226 98892 : if (arg2.ndigits == 0 || arg2.digits[0] == 0)
3227 33 : goto division_by_zero;
3228 :
3229 : /*
3230 : * Do the divide and return the result
3231 : */
3232 98859 : div_var(&arg1, &arg2, &result, rscale, true, true);
3233 :
3234 98859 : res = make_result_safe(&result, escontext);
3235 :
3236 98859 : free_var(&result);
3237 :
3238 98859 : return res;
3239 :
3240 41 : division_by_zero:
3241 41 : ereturn(escontext, NULL,
3242 : errcode(ERRCODE_DIVISION_BY_ZERO),
3243 : errmsg("division by zero"));
3244 : }
3245 :
3246 :
3247 : /*
3248 : * numeric_div_trunc() -
3249 : *
3250 : * Divide one numeric into another, truncating the result to an integer
3251 : */
3252 : Datum
3253 822 : numeric_div_trunc(PG_FUNCTION_ARGS)
3254 : {
3255 822 : Numeric num1 = PG_GETARG_NUMERIC(0);
3256 822 : Numeric num2 = PG_GETARG_NUMERIC(1);
3257 : NumericVar arg1;
3258 : NumericVar arg2;
3259 : NumericVar result;
3260 : Numeric res;
3261 :
3262 : /*
3263 : * Handle NaN and infinities
3264 : */
3265 822 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3266 : {
3267 133 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3268 53 : PG_RETURN_NUMERIC(make_result(&const_nan));
3269 80 : if (NUMERIC_IS_PINF(num1))
3270 : {
3271 24 : if (NUMERIC_IS_SPECIAL(num2))
3272 8 : PG_RETURN_NUMERIC(make_result(&const_nan)); /* Inf / [-]Inf */
3273 16 : switch (numeric_sign_internal(num2))
3274 : {
3275 4 : case 0:
3276 4 : ereport(ERROR,
3277 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3278 : errmsg("division by zero")));
3279 : break;
3280 8 : case 1:
3281 8 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3282 4 : case -1:
3283 4 : PG_RETURN_NUMERIC(make_result(&const_ninf));
3284 : }
3285 : Assert(false);
3286 : }
3287 56 : if (NUMERIC_IS_NINF(num1))
3288 : {
3289 24 : if (NUMERIC_IS_SPECIAL(num2))
3290 8 : PG_RETURN_NUMERIC(make_result(&const_nan)); /* -Inf / [-]Inf */
3291 16 : switch (numeric_sign_internal(num2))
3292 : {
3293 4 : case 0:
3294 4 : ereport(ERROR,
3295 : (errcode(ERRCODE_DIVISION_BY_ZERO),
3296 : errmsg("division by zero")));
3297 : break;
3298 8 : case 1:
3299 8 : PG_RETURN_NUMERIC(make_result(&const_ninf));
3300 4 : case -1:
3301 4 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3302 : }
3303 : Assert(false);
3304 : }
3305 : /* by here, num1 must be finite, so num2 is not */
3306 :
3307 : /*
3308 : * POSIX would have us return zero or minus zero if num1 is zero, and
3309 : * otherwise throw an underflow error. But the numeric type doesn't
3310 : * really do underflow, so let's just return zero.
3311 : */
3312 32 : PG_RETURN_NUMERIC(make_result(&const_zero));
3313 : }
3314 :
3315 : /*
3316 : * Unpack the arguments
3317 : */
3318 689 : init_var_from_num(num1, &arg1);
3319 689 : init_var_from_num(num2, &arg2);
3320 :
3321 689 : init_var(&result);
3322 :
3323 : /*
3324 : * Do the divide and return the result
3325 : */
3326 689 : div_var(&arg1, &arg2, &result, 0, false, true);
3327 :
3328 685 : res = make_result(&result);
3329 :
3330 685 : free_var(&result);
3331 :
3332 685 : PG_RETURN_NUMERIC(res);
3333 : }
3334 :
3335 :
3336 : /*
3337 : * numeric_mod() -
3338 : *
3339 : * Calculate the modulo of two numerics
3340 : */
3341 : Datum
3342 275181 : numeric_mod(PG_FUNCTION_ARGS)
3343 : {
3344 275181 : Numeric num1 = PG_GETARG_NUMERIC(0);
3345 275181 : Numeric num2 = PG_GETARG_NUMERIC(1);
3346 : Numeric res;
3347 :
3348 275181 : res = numeric_mod_safe(num1, num2, NULL);
3349 :
3350 275169 : PG_RETURN_NUMERIC(res);
3351 : }
3352 :
3353 :
3354 : /*
3355 : * numeric_mod_safe() -
3356 : *
3357 : * Internal version of numeric_mod() with support for soft error reporting.
3358 : */
3359 : Numeric
3360 275189 : numeric_mod_safe(Numeric num1, Numeric num2, Node *escontext)
3361 : {
3362 : Numeric res;
3363 : NumericVar arg1;
3364 : NumericVar arg2;
3365 : NumericVar result;
3366 :
3367 : /*
3368 : * Handle NaN and infinities. We follow POSIX fmod() on this, except that
3369 : * POSIX treats x-is-infinite and y-is-zero identically, raising EDOM and
3370 : * returning NaN. We choose to throw error only for y-is-zero.
3371 : */
3372 275189 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3373 : {
3374 133 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3375 53 : return make_result(&const_nan);
3376 80 : if (NUMERIC_IS_INF(num1))
3377 : {
3378 48 : if (numeric_sign_internal(num2) == 0)
3379 8 : goto division_by_zero;
3380 :
3381 : /* Inf % any nonzero = NaN */
3382 40 : return make_result(&const_nan);
3383 : }
3384 : /* num2 must be [-]Inf; result is num1 regardless of sign of num2 */
3385 32 : return duplicate_numeric(num1);
3386 : }
3387 :
3388 275056 : init_var_from_num(num1, &arg1);
3389 275056 : init_var_from_num(num2, &arg2);
3390 :
3391 275056 : init_var(&result);
3392 :
3393 : /* Check for division by zero */
3394 275056 : if (arg2.ndigits == 0 || arg2.digits[0] == 0)
3395 8 : goto division_by_zero;
3396 :
3397 275048 : mod_var(&arg1, &arg2, &result);
3398 :
3399 275048 : res = make_result_safe(&result, escontext);
3400 :
3401 275048 : free_var(&result);
3402 :
3403 275048 : return res;
3404 :
3405 16 : division_by_zero:
3406 16 : ereturn(escontext, NULL,
3407 : errcode(ERRCODE_DIVISION_BY_ZERO),
3408 : errmsg("division by zero"));
3409 : }
3410 :
3411 :
3412 : /*
3413 : * numeric_inc() -
3414 : *
3415 : * Increment a number by one
3416 : */
3417 : Datum
3418 32 : numeric_inc(PG_FUNCTION_ARGS)
3419 : {
3420 32 : Numeric num = PG_GETARG_NUMERIC(0);
3421 : NumericVar arg;
3422 : Numeric res;
3423 :
3424 : /*
3425 : * Handle NaN and infinities
3426 : */
3427 32 : if (NUMERIC_IS_SPECIAL(num))
3428 12 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3429 :
3430 : /*
3431 : * Compute the result and return it
3432 : */
3433 20 : init_var_from_num(num, &arg);
3434 :
3435 20 : add_var(&arg, &const_one, &arg);
3436 :
3437 20 : res = make_result(&arg);
3438 :
3439 20 : free_var(&arg);
3440 :
3441 20 : PG_RETURN_NUMERIC(res);
3442 : }
3443 :
3444 :
3445 : /*
3446 : * numeric_smaller() -
3447 : *
3448 : * Return the smaller of two numbers
3449 : */
3450 : Datum
3451 543 : numeric_smaller(PG_FUNCTION_ARGS)
3452 : {
3453 543 : Numeric num1 = PG_GETARG_NUMERIC(0);
3454 543 : Numeric num2 = PG_GETARG_NUMERIC(1);
3455 :
3456 : /*
3457 : * Use cmp_numerics so that this will agree with the comparison operators,
3458 : * particularly as regards comparisons involving NaN.
3459 : */
3460 543 : if (cmp_numerics(num1, num2) < 0)
3461 437 : PG_RETURN_NUMERIC(num1);
3462 : else
3463 106 : PG_RETURN_NUMERIC(num2);
3464 : }
3465 :
3466 :
3467 : /*
3468 : * numeric_larger() -
3469 : *
3470 : * Return the larger of two numbers
3471 : */
3472 : Datum
3473 12420 : numeric_larger(PG_FUNCTION_ARGS)
3474 : {
3475 12420 : Numeric num1 = PG_GETARG_NUMERIC(0);
3476 12420 : Numeric num2 = PG_GETARG_NUMERIC(1);
3477 :
3478 : /*
3479 : * Use cmp_numerics so that this will agree with the comparison operators,
3480 : * particularly as regards comparisons involving NaN.
3481 : */
3482 12420 : if (cmp_numerics(num1, num2) > 0)
3483 11952 : PG_RETURN_NUMERIC(num1);
3484 : else
3485 468 : PG_RETURN_NUMERIC(num2);
3486 : }
3487 :
3488 :
3489 : /* ----------------------------------------------------------------------
3490 : *
3491 : * Advanced math functions
3492 : *
3493 : * ----------------------------------------------------------------------
3494 : */
3495 :
3496 : /*
3497 : * numeric_gcd() -
3498 : *
3499 : * Calculate the greatest common divisor of two numerics
3500 : */
3501 : Datum
3502 144 : numeric_gcd(PG_FUNCTION_ARGS)
3503 : {
3504 144 : Numeric num1 = PG_GETARG_NUMERIC(0);
3505 144 : Numeric num2 = PG_GETARG_NUMERIC(1);
3506 : NumericVar arg1;
3507 : NumericVar arg2;
3508 : NumericVar result;
3509 : Numeric res;
3510 :
3511 : /*
3512 : * Handle NaN and infinities: we consider the result to be NaN in all such
3513 : * cases.
3514 : */
3515 144 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3516 64 : PG_RETURN_NUMERIC(make_result(&const_nan));
3517 :
3518 : /*
3519 : * Unpack the arguments
3520 : */
3521 80 : init_var_from_num(num1, &arg1);
3522 80 : init_var_from_num(num2, &arg2);
3523 :
3524 80 : init_var(&result);
3525 :
3526 : /*
3527 : * Find the GCD and return the result
3528 : */
3529 80 : gcd_var(&arg1, &arg2, &result);
3530 :
3531 80 : res = make_result(&result);
3532 :
3533 80 : free_var(&result);
3534 :
3535 80 : PG_RETURN_NUMERIC(res);
3536 : }
3537 :
3538 :
3539 : /*
3540 : * numeric_lcm() -
3541 : *
3542 : * Calculate the least common multiple of two numerics
3543 : */
3544 : Datum
3545 164 : numeric_lcm(PG_FUNCTION_ARGS)
3546 : {
3547 164 : Numeric num1 = PG_GETARG_NUMERIC(0);
3548 164 : Numeric num2 = PG_GETARG_NUMERIC(1);
3549 : NumericVar arg1;
3550 : NumericVar arg2;
3551 : NumericVar result;
3552 : Numeric res;
3553 :
3554 : /*
3555 : * Handle NaN and infinities: we consider the result to be NaN in all such
3556 : * cases.
3557 : */
3558 164 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3559 64 : PG_RETURN_NUMERIC(make_result(&const_nan));
3560 :
3561 : /*
3562 : * Unpack the arguments
3563 : */
3564 100 : init_var_from_num(num1, &arg1);
3565 100 : init_var_from_num(num2, &arg2);
3566 :
3567 100 : init_var(&result);
3568 :
3569 : /*
3570 : * Compute the result using lcm(x, y) = abs(x / gcd(x, y) * y), returning
3571 : * zero if either input is zero.
3572 : *
3573 : * Note that the division is guaranteed to be exact, returning an integer
3574 : * result, so the LCM is an integral multiple of both x and y. A display
3575 : * scale of Min(x.dscale, y.dscale) would be sufficient to represent it,
3576 : * but as with other numeric functions, we choose to return a result whose
3577 : * display scale is no smaller than either input.
3578 : */
3579 100 : if (arg1.ndigits == 0 || arg2.ndigits == 0)
3580 32 : set_var_from_var(&const_zero, &result);
3581 : else
3582 : {
3583 68 : gcd_var(&arg1, &arg2, &result);
3584 68 : div_var(&arg1, &result, &result, 0, false, true);
3585 68 : mul_var(&arg2, &result, &result, arg2.dscale);
3586 68 : result.sign = NUMERIC_POS;
3587 : }
3588 :
3589 100 : result.dscale = Max(arg1.dscale, arg2.dscale);
3590 :
3591 100 : res = make_result(&result);
3592 :
3593 96 : free_var(&result);
3594 :
3595 96 : PG_RETURN_NUMERIC(res);
3596 : }
3597 :
3598 :
3599 : /*
3600 : * numeric_fac()
3601 : *
3602 : * Compute factorial
3603 : */
3604 : Datum
3605 33 : numeric_fac(PG_FUNCTION_ARGS)
3606 : {
3607 33 : int64 num = PG_GETARG_INT64(0);
3608 : Numeric res;
3609 : NumericVar fact;
3610 : NumericVar result;
3611 :
3612 33 : if (num < 0)
3613 4 : ereport(ERROR,
3614 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3615 : errmsg("factorial of a negative number is undefined")));
3616 29 : if (num <= 1)
3617 : {
3618 5 : res = make_result(&const_one);
3619 5 : PG_RETURN_NUMERIC(res);
3620 : }
3621 : /* Fail immediately if the result would overflow */
3622 24 : if (num > 32177)
3623 4 : ereport(ERROR,
3624 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3625 : errmsg("value overflows numeric format")));
3626 :
3627 20 : init_var(&fact);
3628 20 : init_var(&result);
3629 :
3630 20 : int64_to_numericvar(num, &result);
3631 :
3632 245 : for (num = num - 1; num > 1; num--)
3633 : {
3634 : /* this loop can take awhile, so allow it to be interrupted */
3635 225 : CHECK_FOR_INTERRUPTS();
3636 :
3637 225 : int64_to_numericvar(num, &fact);
3638 :
3639 225 : mul_var(&result, &fact, &result, 0);
3640 : }
3641 :
3642 20 : res = make_result(&result);
3643 :
3644 20 : free_var(&fact);
3645 20 : free_var(&result);
3646 :
3647 20 : PG_RETURN_NUMERIC(res);
3648 : }
3649 :
3650 :
3651 : /*
3652 : * numeric_sqrt() -
3653 : *
3654 : * Compute the square root of a numeric.
3655 : */
3656 : Datum
3657 108 : numeric_sqrt(PG_FUNCTION_ARGS)
3658 : {
3659 108 : Numeric num = PG_GETARG_NUMERIC(0);
3660 : Numeric res;
3661 : NumericVar arg;
3662 : NumericVar result;
3663 : int sweight;
3664 : int rscale;
3665 :
3666 : /*
3667 : * Handle NaN and infinities
3668 : */
3669 108 : if (NUMERIC_IS_SPECIAL(num))
3670 : {
3671 : /* error should match that in sqrt_var() */
3672 12 : if (NUMERIC_IS_NINF(num))
3673 4 : ereport(ERROR,
3674 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
3675 : errmsg("cannot take square root of a negative number")));
3676 : /* For NAN or PINF, just duplicate the input */
3677 8 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3678 : }
3679 :
3680 : /*
3681 : * Unpack the argument and determine the result scale. We choose a scale
3682 : * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
3683 : * case not less than the input's dscale.
3684 : */
3685 96 : init_var_from_num(num, &arg);
3686 :
3687 96 : init_var(&result);
3688 :
3689 : /*
3690 : * Assume the input was normalized, so arg.weight is accurate. The result
3691 : * then has at least sweight = floor(arg.weight * DEC_DIGITS / 2 + 1)
3692 : * digits before the decimal point. When DEC_DIGITS is even, we can save
3693 : * a few cycles, since the division is exact and there is no need to round
3694 : * towards negative infinity.
3695 : */
3696 : #if DEC_DIGITS == ((DEC_DIGITS / 2) * 2)
3697 96 : sweight = arg.weight * DEC_DIGITS / 2 + 1;
3698 : #else
3699 : if (arg.weight >= 0)
3700 : sweight = arg.weight * DEC_DIGITS / 2 + 1;
3701 : else
3702 : sweight = 1 - (1 - arg.weight * DEC_DIGITS) / 2;
3703 : #endif
3704 :
3705 96 : rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
3706 96 : rscale = Max(rscale, arg.dscale);
3707 96 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3708 96 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3709 :
3710 : /*
3711 : * Let sqrt_var() do the calculation and return the result.
3712 : */
3713 96 : sqrt_var(&arg, &result, rscale);
3714 :
3715 92 : res = make_result(&result);
3716 :
3717 92 : free_var(&result);
3718 :
3719 92 : PG_RETURN_NUMERIC(res);
3720 : }
3721 :
3722 :
3723 : /*
3724 : * numeric_exp() -
3725 : *
3726 : * Raise e to the power of x
3727 : */
3728 : Datum
3729 65 : numeric_exp(PG_FUNCTION_ARGS)
3730 : {
3731 65 : Numeric num = PG_GETARG_NUMERIC(0);
3732 : Numeric res;
3733 : NumericVar arg;
3734 : NumericVar result;
3735 : int rscale;
3736 : double val;
3737 :
3738 : /*
3739 : * Handle NaN and infinities
3740 : */
3741 65 : if (NUMERIC_IS_SPECIAL(num))
3742 : {
3743 : /* Per POSIX, exp(-Inf) is zero */
3744 15 : if (NUMERIC_IS_NINF(num))
3745 5 : PG_RETURN_NUMERIC(make_result(&const_zero));
3746 : /* For NAN or PINF, just duplicate the input */
3747 10 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3748 : }
3749 :
3750 : /*
3751 : * Unpack the argument and determine the result scale. We choose a scale
3752 : * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
3753 : * case not less than the input's dscale.
3754 : */
3755 50 : init_var_from_num(num, &arg);
3756 :
3757 50 : init_var(&result);
3758 :
3759 : /* convert input to float8, ignoring overflow */
3760 50 : val = numericvar_to_double_no_overflow(&arg);
3761 :
3762 : /*
3763 : * log10(result) = num * log10(e), so this is approximately the decimal
3764 : * weight of the result:
3765 : */
3766 50 : val *= 0.434294481903252;
3767 :
3768 : /* limit to something that won't cause integer overflow */
3769 50 : val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
3770 50 : val = Min(val, NUMERIC_MAX_RESULT_SCALE);
3771 :
3772 50 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
3773 50 : rscale = Max(rscale, arg.dscale);
3774 50 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3775 50 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3776 :
3777 : /*
3778 : * Let exp_var() do the calculation and return the result.
3779 : */
3780 50 : exp_var(&arg, &result, rscale);
3781 :
3782 50 : res = make_result(&result);
3783 :
3784 50 : free_var(&result);
3785 :
3786 50 : PG_RETURN_NUMERIC(res);
3787 : }
3788 :
3789 :
3790 : /*
3791 : * numeric_ln() -
3792 : *
3793 : * Compute the natural logarithm of x
3794 : */
3795 : Datum
3796 140 : numeric_ln(PG_FUNCTION_ARGS)
3797 : {
3798 140 : Numeric num = PG_GETARG_NUMERIC(0);
3799 : Numeric res;
3800 : NumericVar arg;
3801 : NumericVar result;
3802 : int ln_dweight;
3803 : int rscale;
3804 :
3805 : /*
3806 : * Handle NaN and infinities
3807 : */
3808 140 : if (NUMERIC_IS_SPECIAL(num))
3809 : {
3810 12 : if (NUMERIC_IS_NINF(num))
3811 4 : ereport(ERROR,
3812 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3813 : errmsg("cannot take logarithm of a negative number")));
3814 : /* For NAN or PINF, just duplicate the input */
3815 8 : PG_RETURN_NUMERIC(duplicate_numeric(num));
3816 : }
3817 :
3818 128 : init_var_from_num(num, &arg);
3819 128 : init_var(&result);
3820 :
3821 : /* Estimated dweight of logarithm */
3822 128 : ln_dweight = estimate_ln_dweight(&arg);
3823 :
3824 128 : rscale = NUMERIC_MIN_SIG_DIGITS - ln_dweight;
3825 128 : rscale = Max(rscale, arg.dscale);
3826 128 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
3827 128 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
3828 :
3829 128 : ln_var(&arg, &result, rscale);
3830 :
3831 112 : res = make_result(&result);
3832 :
3833 112 : free_var(&result);
3834 :
3835 112 : PG_RETURN_NUMERIC(res);
3836 : }
3837 :
3838 :
3839 : /*
3840 : * numeric_log() -
3841 : *
3842 : * Compute the logarithm of x in a given base
3843 : */
3844 : Datum
3845 240 : numeric_log(PG_FUNCTION_ARGS)
3846 : {
3847 240 : Numeric num1 = PG_GETARG_NUMERIC(0);
3848 240 : Numeric num2 = PG_GETARG_NUMERIC(1);
3849 : Numeric res;
3850 : NumericVar arg1;
3851 : NumericVar arg2;
3852 : NumericVar result;
3853 :
3854 : /*
3855 : * Handle NaN and infinities
3856 : */
3857 240 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3858 : {
3859 : int sign1,
3860 : sign2;
3861 :
3862 84 : if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
3863 36 : PG_RETURN_NUMERIC(make_result(&const_nan));
3864 : /* fail on negative inputs including -Inf, as log_var would */
3865 48 : sign1 = numeric_sign_internal(num1);
3866 48 : sign2 = numeric_sign_internal(num2);
3867 48 : if (sign1 < 0 || sign2 < 0)
3868 16 : ereport(ERROR,
3869 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3870 : errmsg("cannot take logarithm of a negative number")));
3871 : /* fail on zero inputs, as log_var would */
3872 32 : if (sign1 == 0 || sign2 == 0)
3873 4 : ereport(ERROR,
3874 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
3875 : errmsg("cannot take logarithm of zero")));
3876 28 : if (NUMERIC_IS_PINF(num1))
3877 : {
3878 : /* log(Inf, Inf) reduces to Inf/Inf, so it's NaN */
3879 12 : if (NUMERIC_IS_PINF(num2))
3880 4 : PG_RETURN_NUMERIC(make_result(&const_nan));
3881 : /* log(Inf, finite-positive) is zero (we don't throw underflow) */
3882 8 : PG_RETURN_NUMERIC(make_result(&const_zero));
3883 : }
3884 : Assert(NUMERIC_IS_PINF(num2));
3885 : /* log(finite-positive, Inf) is Inf */
3886 16 : PG_RETURN_NUMERIC(make_result(&const_pinf));
3887 : }
3888 :
3889 : /*
3890 : * Initialize things
3891 : */
3892 156 : init_var_from_num(num1, &arg1);
3893 156 : init_var_from_num(num2, &arg2);
3894 156 : init_var(&result);
3895 :
3896 : /*
3897 : * Call log_var() to compute and return the result; note it handles scale
3898 : * selection itself.
3899 : */
3900 156 : log_var(&arg1, &arg2, &result);
3901 :
3902 116 : res = make_result(&result);
3903 :
3904 116 : free_var(&result);
3905 :
3906 116 : PG_RETURN_NUMERIC(res);
3907 : }
3908 :
3909 :
3910 : /*
3911 : * numeric_power() -
3912 : *
3913 : * Raise x to the power of y
3914 : */
3915 : Datum
3916 1149 : numeric_power(PG_FUNCTION_ARGS)
3917 : {
3918 1149 : Numeric num1 = PG_GETARG_NUMERIC(0);
3919 1149 : Numeric num2 = PG_GETARG_NUMERIC(1);
3920 : Numeric res;
3921 : NumericVar arg1;
3922 : NumericVar arg2;
3923 : NumericVar result;
3924 : int sign1,
3925 : sign2;
3926 :
3927 : /*
3928 : * Handle NaN and infinities
3929 : */
3930 1149 : if (NUMERIC_IS_SPECIAL(num1) || NUMERIC_IS_SPECIAL(num2))
3931 : {
3932 : /*
3933 : * We follow the POSIX spec for pow(3), which says that NaN ^ 0 = 1,
3934 : * and 1 ^ NaN = 1, while all other cases with NaN inputs yield NaN
3935 : * (with no error).
3936 : */
3937 173 : if (NUMERIC_IS_NAN(num1))
3938 : {
3939 39 : if (!NUMERIC_IS_SPECIAL(num2))
3940 : {
3941 26 : init_var_from_num(num2, &arg2);
3942 26 : if (cmp_var(&arg2, &const_zero) == 0)
3943 9 : PG_RETURN_NUMERIC(make_result(&const_one));
3944 : }
3945 30 : PG_RETURN_NUMERIC(make_result(&const_nan));
3946 : }
3947 134 : if (NUMERIC_IS_NAN(num2))
3948 : {
3949 30 : if (!NUMERIC_IS_SPECIAL(num1))
3950 : {
3951 26 : init_var_from_num(num1, &arg1);
3952 26 : if (cmp_var(&arg1, &const_one) == 0)
3953 9 : PG_RETURN_NUMERIC(make_result(&const_one));
3954 : }
3955 21 : PG_RETURN_NUMERIC(make_result(&const_nan));
3956 : }
3957 : /* At least one input is infinite, but error rules still apply */
3958 104 : sign1 = numeric_sign_internal(num1);
3959 104 : sign2 = numeric_sign_internal(num2);
3960 104 : if (sign1 == 0 && sign2 < 0)
3961 4 : ereport(ERROR,
3962 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
3963 : errmsg("zero raised to a negative power is undefined")));
3964 100 : if (sign1 < 0 && !numeric_is_integral(num2))
3965 4 : ereport(ERROR,
3966 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
3967 : errmsg("a negative number raised to a non-integer power yields a complex result")));
3968 :
3969 : /*
3970 : * POSIX gives this series of rules for pow(3) with infinite inputs:
3971 : *
3972 : * For any value of y, if x is +1, 1.0 shall be returned.
3973 : */
3974 96 : if (!NUMERIC_IS_SPECIAL(num1))
3975 : {
3976 31 : init_var_from_num(num1, &arg1);
3977 31 : if (cmp_var(&arg1, &const_one) == 0)
3978 4 : PG_RETURN_NUMERIC(make_result(&const_one));
3979 : }
3980 :
3981 : /*
3982 : * For any value of x, if y is [-]0, 1.0 shall be returned.
3983 : */
3984 92 : if (sign2 == 0)
3985 9 : PG_RETURN_NUMERIC(make_result(&const_one));
3986 :
3987 : /*
3988 : * For any odd integer value of y > 0, if x is [-]0, [-]0 shall be
3989 : * returned. For y > 0 and not an odd integer, if x is [-]0, +0 shall
3990 : * be returned. (Since we don't deal in minus zero, we need not
3991 : * distinguish these two cases.)
3992 : */
3993 83 : if (sign1 == 0 && sign2 > 0)
3994 4 : PG_RETURN_NUMERIC(make_result(&const_zero));
3995 :
3996 : /*
3997 : * If x is -1, and y is [-]Inf, 1.0 shall be returned.
3998 : *
3999 : * For |x| < 1, if y is -Inf, +Inf shall be returned.
4000 : *
4001 : * For |x| > 1, if y is -Inf, +0 shall be returned.
4002 : *
4003 : * For |x| < 1, if y is +Inf, +0 shall be returned.
4004 : *
4005 : * For |x| > 1, if y is +Inf, +Inf shall be returned.
4006 : */
4007 79 : if (NUMERIC_IS_INF(num2))
4008 : {
4009 : bool abs_x_gt_one;
4010 :
4011 42 : if (NUMERIC_IS_SPECIAL(num1))
4012 19 : abs_x_gt_one = true; /* x is either Inf or -Inf */
4013 : else
4014 : {
4015 23 : init_var_from_num(num1, &arg1);
4016 23 : if (cmp_var(&arg1, &const_minus_one) == 0)
4017 5 : PG_RETURN_NUMERIC(make_result(&const_one));
4018 18 : arg1.sign = NUMERIC_POS; /* now arg1 = abs(x) */
4019 18 : abs_x_gt_one = (cmp_var(&arg1, &const_one) > 0);
4020 : }
4021 37 : if (abs_x_gt_one == (sign2 > 0))
4022 22 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4023 : else
4024 15 : PG_RETURN_NUMERIC(make_result(&const_zero));
4025 : }
4026 :
4027 : /*
4028 : * For y < 0, if x is +Inf, +0 shall be returned.
4029 : *
4030 : * For y > 0, if x is +Inf, +Inf shall be returned.
4031 : */
4032 37 : if (NUMERIC_IS_PINF(num1))
4033 : {
4034 17 : if (sign2 > 0)
4035 12 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4036 : else
4037 5 : PG_RETURN_NUMERIC(make_result(&const_zero));
4038 : }
4039 :
4040 : Assert(NUMERIC_IS_NINF(num1));
4041 :
4042 : /*
4043 : * For y an odd integer < 0, if x is -Inf, -0 shall be returned. For
4044 : * y < 0 and not an odd integer, if x is -Inf, +0 shall be returned.
4045 : * (Again, we need not distinguish these two cases.)
4046 : */
4047 20 : if (sign2 < 0)
4048 10 : PG_RETURN_NUMERIC(make_result(&const_zero));
4049 :
4050 : /*
4051 : * For y an odd integer > 0, if x is -Inf, -Inf shall be returned. For
4052 : * y > 0 and not an odd integer, if x is -Inf, +Inf shall be returned.
4053 : */
4054 10 : init_var_from_num(num2, &arg2);
4055 10 : if (arg2.ndigits > 0 && arg2.ndigits == arg2.weight + 1 &&
4056 10 : (arg2.digits[arg2.ndigits - 1] & 1))
4057 5 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4058 : else
4059 5 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4060 : }
4061 :
4062 : /*
4063 : * The SQL spec requires that we emit a particular SQLSTATE error code for
4064 : * certain error conditions. Specifically, we don't return a
4065 : * divide-by-zero error code for 0 ^ -1. Raising a negative number to a
4066 : * non-integer power must produce the same error code, but that case is
4067 : * handled in power_var().
4068 : */
4069 976 : sign1 = numeric_sign_internal(num1);
4070 976 : sign2 = numeric_sign_internal(num2);
4071 :
4072 976 : if (sign1 == 0 && sign2 < 0)
4073 8 : ereport(ERROR,
4074 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4075 : errmsg("zero raised to a negative power is undefined")));
4076 :
4077 : /*
4078 : * Initialize things
4079 : */
4080 968 : init_var(&result);
4081 968 : init_var_from_num(num1, &arg1);
4082 968 : init_var_from_num(num2, &arg2);
4083 :
4084 : /*
4085 : * Call power_var() to compute and return the result; note it handles
4086 : * scale selection itself.
4087 : */
4088 968 : power_var(&arg1, &arg2, &result);
4089 :
4090 948 : res = make_result(&result);
4091 :
4092 948 : free_var(&result);
4093 :
4094 948 : PG_RETURN_NUMERIC(res);
4095 : }
4096 :
4097 : /*
4098 : * numeric_scale() -
4099 : *
4100 : * Returns the scale, i.e. the count of decimal digits in the fractional part
4101 : */
4102 : Datum
4103 81 : numeric_scale(PG_FUNCTION_ARGS)
4104 : {
4105 81 : Numeric num = PG_GETARG_NUMERIC(0);
4106 :
4107 81 : if (NUMERIC_IS_SPECIAL(num))
4108 14 : PG_RETURN_NULL();
4109 :
4110 67 : PG_RETURN_INT32(NUMERIC_DSCALE(num));
4111 : }
4112 :
4113 : /*
4114 : * Calculate minimum scale for value.
4115 : */
4116 : static int
4117 267 : get_min_scale(NumericVar *var)
4118 : {
4119 : int min_scale;
4120 : int last_digit_pos;
4121 :
4122 : /*
4123 : * Ordinarily, the input value will be "stripped" so that the last
4124 : * NumericDigit is nonzero. But we don't want to get into an infinite
4125 : * loop if it isn't, so explicitly find the last nonzero digit.
4126 : */
4127 267 : last_digit_pos = var->ndigits - 1;
4128 267 : while (last_digit_pos >= 0 &&
4129 243 : var->digits[last_digit_pos] == 0)
4130 0 : last_digit_pos--;
4131 :
4132 267 : if (last_digit_pos >= 0)
4133 : {
4134 : /* compute min_scale assuming that last ndigit has no zeroes */
4135 243 : min_scale = (last_digit_pos - var->weight) * DEC_DIGITS;
4136 :
4137 : /*
4138 : * We could get a negative result if there are no digits after the
4139 : * decimal point. In this case the min_scale must be zero.
4140 : */
4141 243 : if (min_scale > 0)
4142 : {
4143 : /*
4144 : * Reduce min_scale if trailing digit(s) in last NumericDigit are
4145 : * zero.
4146 : */
4147 135 : NumericDigit last_digit = var->digits[last_digit_pos];
4148 :
4149 365 : while (last_digit % 10 == 0)
4150 : {
4151 230 : min_scale--;
4152 230 : last_digit /= 10;
4153 : }
4154 : }
4155 : else
4156 108 : min_scale = 0;
4157 : }
4158 : else
4159 24 : min_scale = 0; /* result if input is zero */
4160 :
4161 267 : return min_scale;
4162 : }
4163 :
4164 : /*
4165 : * Returns minimum scale required to represent supplied value without loss.
4166 : */
4167 : Datum
4168 60 : numeric_min_scale(PG_FUNCTION_ARGS)
4169 : {
4170 60 : Numeric num = PG_GETARG_NUMERIC(0);
4171 : NumericVar arg;
4172 : int min_scale;
4173 :
4174 60 : if (NUMERIC_IS_SPECIAL(num))
4175 10 : PG_RETURN_NULL();
4176 :
4177 50 : init_var_from_num(num, &arg);
4178 50 : min_scale = get_min_scale(&arg);
4179 50 : free_var(&arg);
4180 :
4181 50 : PG_RETURN_INT32(min_scale);
4182 : }
4183 :
4184 : /*
4185 : * Reduce scale of numeric value to represent supplied value without loss.
4186 : */
4187 : Datum
4188 227 : numeric_trim_scale(PG_FUNCTION_ARGS)
4189 : {
4190 227 : Numeric num = PG_GETARG_NUMERIC(0);
4191 : Numeric res;
4192 : NumericVar result;
4193 :
4194 227 : if (NUMERIC_IS_SPECIAL(num))
4195 10 : PG_RETURN_NUMERIC(duplicate_numeric(num));
4196 :
4197 217 : init_var_from_num(num, &result);
4198 217 : result.dscale = get_min_scale(&result);
4199 217 : res = make_result(&result);
4200 217 : free_var(&result);
4201 :
4202 217 : PG_RETURN_NUMERIC(res);
4203 : }
4204 :
4205 : /*
4206 : * Return a random numeric value in the range [rmin, rmax].
4207 : */
4208 : Numeric
4209 22308 : random_numeric(pg_prng_state *state, Numeric rmin, Numeric rmax)
4210 : {
4211 : NumericVar rmin_var;
4212 : NumericVar rmax_var;
4213 : NumericVar result;
4214 : Numeric res;
4215 :
4216 : /* Range bounds must not be NaN/infinity */
4217 22308 : if (NUMERIC_IS_SPECIAL(rmin))
4218 : {
4219 8 : if (NUMERIC_IS_NAN(rmin))
4220 4 : ereport(ERROR,
4221 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4222 : errmsg("lower bound cannot be NaN"));
4223 : else
4224 4 : ereport(ERROR,
4225 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4226 : errmsg("lower bound cannot be infinity"));
4227 : }
4228 22300 : if (NUMERIC_IS_SPECIAL(rmax))
4229 : {
4230 8 : if (NUMERIC_IS_NAN(rmax))
4231 4 : ereport(ERROR,
4232 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4233 : errmsg("upper bound cannot be NaN"));
4234 : else
4235 4 : ereport(ERROR,
4236 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4237 : errmsg("upper bound cannot be infinity"));
4238 : }
4239 :
4240 : /* Return a random value in the range [rmin, rmax] */
4241 22292 : init_var_from_num(rmin, &rmin_var);
4242 22292 : init_var_from_num(rmax, &rmax_var);
4243 :
4244 22292 : init_var(&result);
4245 :
4246 22292 : random_var(state, &rmin_var, &rmax_var, &result);
4247 :
4248 22288 : res = make_result(&result);
4249 :
4250 22288 : free_var(&result);
4251 :
4252 22288 : return res;
4253 : }
4254 :
4255 :
4256 : /* ----------------------------------------------------------------------
4257 : *
4258 : * Type conversion functions
4259 : *
4260 : * ----------------------------------------------------------------------
4261 : */
4262 :
4263 : Numeric
4264 1245493 : int64_to_numeric(int64 val)
4265 : {
4266 : Numeric res;
4267 : NumericVar result;
4268 :
4269 1245493 : init_var(&result);
4270 :
4271 1245493 : int64_to_numericvar(val, &result);
4272 :
4273 1245493 : res = make_result(&result);
4274 :
4275 1245493 : free_var(&result);
4276 :
4277 1245493 : return res;
4278 : }
4279 :
4280 : /*
4281 : * Convert val1/(10**log10val2) to numeric. This is much faster than normal
4282 : * numeric division.
4283 : */
4284 : Numeric
4285 15155 : int64_div_fast_to_numeric(int64 val1, int log10val2)
4286 : {
4287 : Numeric res;
4288 : NumericVar result;
4289 : int rscale;
4290 : int w;
4291 : int m;
4292 :
4293 15155 : init_var(&result);
4294 :
4295 : /* result scale */
4296 15155 : rscale = log10val2 < 0 ? 0 : log10val2;
4297 :
4298 : /* how much to decrease the weight by */
4299 15155 : w = log10val2 / DEC_DIGITS;
4300 : /* how much is left to divide by */
4301 15155 : m = log10val2 % DEC_DIGITS;
4302 15155 : if (m < 0)
4303 : {
4304 0 : m += DEC_DIGITS;
4305 0 : w--;
4306 : }
4307 :
4308 : /*
4309 : * If there is anything left to divide by (10^m with 0 < m < DEC_DIGITS),
4310 : * multiply the dividend by 10^(DEC_DIGITS - m), and shift the weight by
4311 : * one more.
4312 : */
4313 15155 : if (m > 0)
4314 : {
4315 : #if DEC_DIGITS == 4
4316 : static const int pow10[] = {1, 10, 100, 1000};
4317 : #elif DEC_DIGITS == 2
4318 : static const int pow10[] = {1, 10};
4319 : #elif DEC_DIGITS == 1
4320 : static const int pow10[] = {1};
4321 : #else
4322 : #error unsupported NBASE
4323 : #endif
4324 15155 : int64 factor = pow10[DEC_DIGITS - m];
4325 : int64 new_val1;
4326 :
4327 : StaticAssertDecl(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS");
4328 :
4329 15155 : if (unlikely(pg_mul_s64_overflow(val1, factor, &new_val1)))
4330 : {
4331 : /* do the multiplication using 128-bit integers */
4332 : INT128 tmp;
4333 :
4334 9 : tmp = int64_to_int128(0);
4335 9 : int128_add_int64_mul_int64(&tmp, val1, factor);
4336 :
4337 9 : int128_to_numericvar(tmp, &result);
4338 : }
4339 : else
4340 15146 : int64_to_numericvar(new_val1, &result);
4341 :
4342 15155 : w++;
4343 : }
4344 : else
4345 0 : int64_to_numericvar(val1, &result);
4346 :
4347 15155 : result.weight -= w;
4348 15155 : result.dscale = rscale;
4349 :
4350 15155 : res = make_result(&result);
4351 :
4352 15155 : free_var(&result);
4353 :
4354 15155 : return res;
4355 : }
4356 :
4357 : Datum
4358 1037830 : int4_numeric(PG_FUNCTION_ARGS)
4359 : {
4360 1037830 : int32 val = PG_GETARG_INT32(0);
4361 :
4362 1037830 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4363 : }
4364 :
4365 : /*
4366 : * Internal version of numeric_int4() with support for soft error reporting.
4367 : */
4368 : int32
4369 4800 : numeric_int4_safe(Numeric num, Node *escontext)
4370 : {
4371 : NumericVar x;
4372 : int32 result;
4373 :
4374 4800 : if (NUMERIC_IS_SPECIAL(num))
4375 : {
4376 12 : if (NUMERIC_IS_NAN(num))
4377 4 : ereturn(escontext, 0,
4378 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4379 : errmsg("cannot convert NaN to %s", "integer")));
4380 : else
4381 8 : ereturn(escontext, 0,
4382 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4383 : errmsg("cannot convert infinity to %s", "integer")));
4384 : }
4385 :
4386 : /* Convert to variable format, then convert to int4 */
4387 4788 : init_var_from_num(num, &x);
4388 :
4389 4788 : if (!numericvar_to_int32(&x, &result))
4390 62 : ereturn(escontext, 0,
4391 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4392 : errmsg("integer out of range")));
4393 :
4394 4726 : return result;
4395 : }
4396 :
4397 : Datum
4398 3726 : numeric_int4(PG_FUNCTION_ARGS)
4399 : {
4400 3726 : Numeric num = PG_GETARG_NUMERIC(0);
4401 : int32 result;
4402 :
4403 3726 : result = numeric_int4_safe(num, fcinfo->context);
4404 :
4405 3706 : if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
4406 0 : PG_RETURN_NULL();
4407 :
4408 3706 : PG_RETURN_INT32(result);
4409 : }
4410 :
4411 : /*
4412 : * Given a NumericVar, convert it to an int32. If the NumericVar
4413 : * exceeds the range of an int32, false is returned, otherwise true is returned.
4414 : * The input NumericVar is *not* free'd.
4415 : */
4416 : static bool
4417 5289 : numericvar_to_int32(const NumericVar *var, int32 *result)
4418 : {
4419 : int64 val;
4420 :
4421 5289 : if (!numericvar_to_int64(var, &val))
4422 4 : return false;
4423 :
4424 5285 : if (unlikely(val < PG_INT32_MIN) || unlikely(val > PG_INT32_MAX))
4425 58 : return false;
4426 :
4427 : /* Down-convert to int4 */
4428 5227 : *result = (int32) val;
4429 :
4430 5227 : return true;
4431 : }
4432 :
4433 : Datum
4434 24587 : int8_numeric(PG_FUNCTION_ARGS)
4435 : {
4436 24587 : int64 val = PG_GETARG_INT64(0);
4437 :
4438 24587 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4439 : }
4440 :
4441 : /*
4442 : * Internal version of numeric_int8() with support for soft error reporting.
4443 : */
4444 : int64
4445 387 : numeric_int8_safe(Numeric num, Node *escontext)
4446 : {
4447 : NumericVar x;
4448 : int64 result;
4449 :
4450 387 : if (NUMERIC_IS_SPECIAL(num))
4451 : {
4452 12 : if (NUMERIC_IS_NAN(num))
4453 4 : ereturn(escontext, 0,
4454 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4455 : errmsg("cannot convert NaN to %s", "bigint")));
4456 : else
4457 8 : ereturn(escontext, 0,
4458 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4459 : errmsg("cannot convert infinity to %s", "bigint")));
4460 : }
4461 :
4462 : /* Convert to variable format, then convert to int8 */
4463 375 : init_var_from_num(num, &x);
4464 :
4465 375 : if (!numericvar_to_int64(&x, &result))
4466 40 : ereturn(escontext, 0,
4467 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4468 : errmsg("bigint out of range")));
4469 :
4470 335 : return result;
4471 : }
4472 :
4473 : Datum
4474 347 : numeric_int8(PG_FUNCTION_ARGS)
4475 : {
4476 347 : Numeric num = PG_GETARG_NUMERIC(0);
4477 : int64 result;
4478 :
4479 347 : result = numeric_int8_safe(num, fcinfo->context);
4480 :
4481 303 : if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
4482 0 : PG_RETURN_NULL();
4483 :
4484 303 : PG_RETURN_INT64(result);
4485 : }
4486 :
4487 :
4488 : Datum
4489 5 : int2_numeric(PG_FUNCTION_ARGS)
4490 : {
4491 5 : int16 val = PG_GETARG_INT16(0);
4492 :
4493 5 : PG_RETURN_NUMERIC(int64_to_numeric(val));
4494 : }
4495 :
4496 :
4497 : Datum
4498 73 : numeric_int2(PG_FUNCTION_ARGS)
4499 : {
4500 73 : Numeric num = PG_GETARG_NUMERIC(0);
4501 : NumericVar x;
4502 : int64 val;
4503 : int16 result;
4504 :
4505 73 : if (NUMERIC_IS_SPECIAL(num))
4506 : {
4507 12 : if (NUMERIC_IS_NAN(num))
4508 4 : ereturn(fcinfo->context, (Datum) 0,
4509 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4510 : errmsg("cannot convert NaN to %s", "smallint")));
4511 : else
4512 8 : ereturn(fcinfo->context, (Datum) 0,
4513 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4514 : errmsg("cannot convert infinity to %s", "smallint")));
4515 : }
4516 :
4517 : /* Convert to variable format and thence to int8 */
4518 61 : init_var_from_num(num, &x);
4519 :
4520 61 : if (!numericvar_to_int64(&x, &val))
4521 0 : ereturn(fcinfo->context, (Datum) 0,
4522 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4523 : errmsg("smallint out of range")));
4524 :
4525 61 : if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
4526 8 : ereturn(fcinfo->context, (Datum) 0,
4527 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4528 : errmsg("smallint out of range")));
4529 :
4530 : /* Down-convert to int2 */
4531 53 : result = (int16) val;
4532 :
4533 53 : PG_RETURN_INT16(result);
4534 : }
4535 :
4536 :
4537 : Datum
4538 654 : float8_numeric(PG_FUNCTION_ARGS)
4539 : {
4540 654 : float8 val = PG_GETARG_FLOAT8(0);
4541 : Numeric res;
4542 : NumericVar result;
4543 : char buf[DBL_DIG + 100];
4544 : const char *endptr;
4545 :
4546 654 : if (isnan(val))
4547 5 : PG_RETURN_NUMERIC(make_result(&const_nan));
4548 :
4549 649 : if (isinf(val))
4550 : {
4551 10 : if (val < 0)
4552 5 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4553 : else
4554 5 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4555 : }
4556 :
4557 639 : snprintf(buf, sizeof(buf), "%.*g", DBL_DIG, val);
4558 :
4559 639 : init_var(&result);
4560 :
4561 : /* Assume we need not worry about leading/trailing spaces */
4562 639 : if (!set_var_from_str(buf, buf, &result, &endptr, fcinfo->context))
4563 0 : PG_RETURN_NULL();
4564 :
4565 639 : res = make_result(&result);
4566 :
4567 639 : free_var(&result);
4568 :
4569 639 : PG_RETURN_NUMERIC(res);
4570 : }
4571 :
4572 :
4573 : Datum
4574 347599 : numeric_float8(PG_FUNCTION_ARGS)
4575 : {
4576 347599 : Numeric num = PG_GETARG_NUMERIC(0);
4577 : char *tmp;
4578 : Datum result;
4579 :
4580 347599 : if (NUMERIC_IS_SPECIAL(num))
4581 : {
4582 56 : if (NUMERIC_IS_PINF(num))
4583 17 : PG_RETURN_FLOAT8(get_float8_infinity());
4584 39 : else if (NUMERIC_IS_NINF(num))
4585 17 : PG_RETURN_FLOAT8(-get_float8_infinity());
4586 : else
4587 22 : PG_RETURN_FLOAT8(get_float8_nan());
4588 : }
4589 :
4590 347543 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4591 : NumericGetDatum(num)));
4592 347543 : if (!DirectInputFunctionCallSafe(float8in, tmp,
4593 : InvalidOid, -1,
4594 : (Node *) fcinfo->context,
4595 : &result))
4596 : {
4597 0 : pfree(tmp);
4598 0 : PG_RETURN_NULL();
4599 : }
4600 :
4601 347543 : PG_RETURN_DATUM(result);
4602 : }
4603 :
4604 :
4605 : /*
4606 : * Convert numeric to float8; if out of range, return +/- HUGE_VAL
4607 : *
4608 : * (internal helper function, not directly callable from SQL)
4609 : */
4610 : Datum
4611 16 : numeric_float8_no_overflow(PG_FUNCTION_ARGS)
4612 : {
4613 16 : Numeric num = PG_GETARG_NUMERIC(0);
4614 : double val;
4615 :
4616 16 : if (NUMERIC_IS_SPECIAL(num))
4617 : {
4618 0 : if (NUMERIC_IS_PINF(num))
4619 0 : val = HUGE_VAL;
4620 0 : else if (NUMERIC_IS_NINF(num))
4621 0 : val = -HUGE_VAL;
4622 : else
4623 0 : val = get_float8_nan();
4624 : }
4625 : else
4626 : {
4627 : NumericVar x;
4628 :
4629 16 : init_var_from_num(num, &x);
4630 16 : val = numericvar_to_double_no_overflow(&x);
4631 : }
4632 :
4633 16 : PG_RETURN_FLOAT8(val);
4634 : }
4635 :
4636 : Datum
4637 15170 : float4_numeric(PG_FUNCTION_ARGS)
4638 : {
4639 15170 : float4 val = PG_GETARG_FLOAT4(0);
4640 : Numeric res;
4641 : NumericVar result;
4642 : char buf[FLT_DIG + 100];
4643 : const char *endptr;
4644 :
4645 15170 : if (isnan(val))
4646 5 : PG_RETURN_NUMERIC(make_result(&const_nan));
4647 :
4648 15165 : if (isinf(val))
4649 : {
4650 10 : if (val < 0)
4651 5 : PG_RETURN_NUMERIC(make_result(&const_ninf));
4652 : else
4653 5 : PG_RETURN_NUMERIC(make_result(&const_pinf));
4654 : }
4655 :
4656 15155 : snprintf(buf, sizeof(buf), "%.*g", FLT_DIG, val);
4657 :
4658 15155 : init_var(&result);
4659 :
4660 : /* Assume we need not worry about leading/trailing spaces */
4661 15155 : if (!set_var_from_str(buf, buf, &result, &endptr, fcinfo->context))
4662 0 : PG_RETURN_NULL();
4663 :
4664 15155 : res = make_result(&result);
4665 :
4666 15155 : free_var(&result);
4667 :
4668 15155 : PG_RETURN_NUMERIC(res);
4669 : }
4670 :
4671 :
4672 : Datum
4673 1701 : numeric_float4(PG_FUNCTION_ARGS)
4674 : {
4675 1701 : Numeric num = PG_GETARG_NUMERIC(0);
4676 : char *tmp;
4677 : Datum result;
4678 :
4679 1701 : if (NUMERIC_IS_SPECIAL(num))
4680 : {
4681 56 : if (NUMERIC_IS_PINF(num))
4682 17 : PG_RETURN_FLOAT4(get_float4_infinity());
4683 39 : else if (NUMERIC_IS_NINF(num))
4684 17 : PG_RETURN_FLOAT4(-get_float4_infinity());
4685 : else
4686 22 : PG_RETURN_FLOAT4(get_float4_nan());
4687 : }
4688 :
4689 1645 : tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
4690 : NumericGetDatum(num)));
4691 :
4692 1645 : if (!DirectInputFunctionCallSafe(float4in, tmp,
4693 : InvalidOid, -1,
4694 : (Node *) fcinfo->context,
4695 : &result))
4696 : {
4697 0 : pfree(tmp);
4698 0 : PG_RETURN_NULL();
4699 : }
4700 :
4701 1645 : pfree(tmp);
4702 :
4703 1645 : PG_RETURN_DATUM(result);
4704 : }
4705 :
4706 :
4707 : Datum
4708 98 : numeric_pg_lsn(PG_FUNCTION_ARGS)
4709 : {
4710 98 : Numeric num = PG_GETARG_NUMERIC(0);
4711 : NumericVar x;
4712 : XLogRecPtr result;
4713 :
4714 98 : if (NUMERIC_IS_SPECIAL(num))
4715 : {
4716 4 : if (NUMERIC_IS_NAN(num))
4717 4 : ereport(ERROR,
4718 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4719 : errmsg("cannot convert NaN to %s", "pg_lsn")));
4720 : else
4721 0 : ereport(ERROR,
4722 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4723 : errmsg("cannot convert infinity to %s", "pg_lsn")));
4724 : }
4725 :
4726 : /* Convert to variable format and thence to pg_lsn */
4727 94 : init_var_from_num(num, &x);
4728 :
4729 94 : if (!numericvar_to_uint64(&x, (uint64 *) &result))
4730 16 : ereport(ERROR,
4731 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4732 : errmsg("pg_lsn out of range")));
4733 :
4734 78 : PG_RETURN_LSN(result);
4735 : }
4736 :
4737 :
4738 : /* ----------------------------------------------------------------------
4739 : *
4740 : * Aggregate functions
4741 : *
4742 : * The transition datatype for all these aggregates is declared as INTERNAL.
4743 : * Actually, it's a pointer to a NumericAggState allocated in the aggregate
4744 : * context. The digit buffers for the NumericVars will be there too.
4745 : *
4746 : * For integer inputs, some aggregates use special-purpose 64-bit or 128-bit
4747 : * integer based transition datatypes to speed up calculations.
4748 : *
4749 : * ----------------------------------------------------------------------
4750 : */
4751 :
4752 : typedef struct NumericAggState
4753 : {
4754 : bool calcSumX2; /* if true, calculate sumX2 */
4755 : MemoryContext agg_context; /* context we're calculating in */
4756 : int64 N; /* count of processed numbers */
4757 : NumericSumAccum sumX; /* sum of processed numbers */
4758 : NumericSumAccum sumX2; /* sum of squares of processed numbers */
4759 : int maxScale; /* maximum scale seen so far */
4760 : int64 maxScaleCount; /* number of values seen with maximum scale */
4761 : /* These counts are *not* included in N! Use NA_TOTAL_COUNT() as needed */
4762 : int64 NaNcount; /* count of NaN values */
4763 : int64 pInfcount; /* count of +Inf values */
4764 : int64 nInfcount; /* count of -Inf values */
4765 : } NumericAggState;
4766 :
4767 : #define NA_TOTAL_COUNT(na) \
4768 : ((na)->N + (na)->NaNcount + (na)->pInfcount + (na)->nInfcount)
4769 :
4770 : /*
4771 : * Prepare state data for a numeric aggregate function that needs to compute
4772 : * sum, count and optionally sum of squares of the input.
4773 : */
4774 : static NumericAggState *
4775 114080 : makeNumericAggState(FunctionCallInfo fcinfo, bool calcSumX2)
4776 : {
4777 : NumericAggState *state;
4778 : MemoryContext agg_context;
4779 : MemoryContext old_context;
4780 :
4781 114080 : if (!AggCheckCallContext(fcinfo, &agg_context))
4782 0 : elog(ERROR, "aggregate function called in non-aggregate context");
4783 :
4784 114080 : old_context = MemoryContextSwitchTo(agg_context);
4785 :
4786 114080 : state = palloc0_object(NumericAggState);
4787 114080 : state->calcSumX2 = calcSumX2;
4788 114080 : state->agg_context = agg_context;
4789 :
4790 114080 : MemoryContextSwitchTo(old_context);
4791 :
4792 114080 : return state;
4793 : }
4794 :
4795 : /*
4796 : * Like makeNumericAggState(), but allocate the state in the current memory
4797 : * context.
4798 : */
4799 : static NumericAggState *
4800 54 : makeNumericAggStateCurrentContext(bool calcSumX2)
4801 : {
4802 : NumericAggState *state;
4803 :
4804 54 : state = palloc0_object(NumericAggState);
4805 54 : state->calcSumX2 = calcSumX2;
4806 54 : state->agg_context = CurrentMemoryContext;
4807 :
4808 54 : return state;
4809 : }
4810 :
4811 : /*
4812 : * Accumulate a new input value for numeric aggregate functions.
4813 : */
4814 : static void
4815 1409012 : do_numeric_accum(NumericAggState *state, Numeric newval)
4816 : {
4817 : NumericVar X;
4818 : NumericVar X2;
4819 : MemoryContext old_context;
4820 :
4821 : /* Count NaN/infinity inputs separately from all else */
4822 1409012 : if (NUMERIC_IS_SPECIAL(newval))
4823 : {
4824 108 : if (NUMERIC_IS_PINF(newval))
4825 48 : state->pInfcount++;
4826 60 : else if (NUMERIC_IS_NINF(newval))
4827 24 : state->nInfcount++;
4828 : else
4829 36 : state->NaNcount++;
4830 108 : return;
4831 : }
4832 :
4833 : /* load processed number in short-lived context */
4834 1408904 : init_var_from_num(newval, &X);
4835 :
4836 : /*
4837 : * Track the highest input dscale that we've seen, to support inverse
4838 : * transitions (see do_numeric_discard).
4839 : */
4840 1408904 : if (X.dscale > state->maxScale)
4841 : {
4842 104 : state->maxScale = X.dscale;
4843 104 : state->maxScaleCount = 1;
4844 : }
4845 1408800 : else if (X.dscale == state->maxScale)
4846 1408776 : state->maxScaleCount++;
4847 :
4848 : /* if we need X^2, calculate that in short-lived context */
4849 1408904 : if (state->calcSumX2)
4850 : {
4851 160488 : init_var(&X2);
4852 160488 : mul_var(&X, &X, &X2, X.dscale * 2);
4853 : }
4854 :
4855 : /* The rest of this needs to work in the aggregate context */
4856 1408904 : old_context = MemoryContextSwitchTo(state->agg_context);
4857 :
4858 1408904 : state->N++;
4859 :
4860 : /* Accumulate sums */
4861 1408904 : accum_sum_add(&(state->sumX), &X);
4862 :
4863 1408904 : if (state->calcSumX2)
4864 160488 : accum_sum_add(&(state->sumX2), &X2);
4865 :
4866 1408904 : MemoryContextSwitchTo(old_context);
4867 : }
4868 :
4869 : /*
4870 : * Attempt to remove an input value from the aggregated state.
4871 : *
4872 : * If the value cannot be removed then the function will return false; the
4873 : * possible reasons for failing are described below.
4874 : *
4875 : * If we aggregate the values 1.01 and 2 then the result will be 3.01.
4876 : * If we are then asked to un-aggregate the 1.01 then we must fail as we
4877 : * won't be able to tell what the new aggregated value's dscale should be.
4878 : * We don't want to return 2.00 (dscale = 2), since the sum's dscale would
4879 : * have been zero if we'd really aggregated only 2.
4880 : *
4881 : * Note: alternatively, we could count the number of inputs with each possible
4882 : * dscale (up to some sane limit). Not yet clear if it's worth the trouble.
4883 : */
4884 : static bool
4885 228 : do_numeric_discard(NumericAggState *state, Numeric newval)
4886 : {
4887 : NumericVar X;
4888 : NumericVar X2;
4889 : MemoryContext old_context;
4890 :
4891 : /* Count NaN/infinity inputs separately from all else */
4892 228 : if (NUMERIC_IS_SPECIAL(newval))
4893 : {
4894 4 : if (NUMERIC_IS_PINF(newval))
4895 0 : state->pInfcount--;
4896 4 : else if (NUMERIC_IS_NINF(newval))
4897 0 : state->nInfcount--;
4898 : else
4899 4 : state->NaNcount--;
4900 4 : return true;
4901 : }
4902 :
4903 : /* load processed number in short-lived context */
4904 224 : init_var_from_num(newval, &X);
4905 :
4906 : /*
4907 : * state->sumX's dscale is the maximum dscale of any of the inputs.
4908 : * Removing the last input with that dscale would require us to recompute
4909 : * the maximum dscale of the *remaining* inputs, which we cannot do unless
4910 : * no more non-NaN inputs remain at all. So we report a failure instead,
4911 : * and force the aggregation to be redone from scratch.
4912 : */
4913 224 : if (X.dscale == state->maxScale)
4914 : {
4915 224 : if (state->maxScaleCount > 1 || state->maxScale == 0)
4916 : {
4917 : /*
4918 : * Some remaining inputs have same dscale, or dscale hasn't gotten
4919 : * above zero anyway
4920 : */
4921 212 : state->maxScaleCount--;
4922 : }
4923 12 : else if (state->N == 1)
4924 : {
4925 : /* No remaining non-NaN inputs at all, so reset maxScale */
4926 8 : state->maxScale = 0;
4927 8 : state->maxScaleCount = 0;
4928 : }
4929 : else
4930 : {
4931 : /* Correct new maxScale is uncertain, must fail */
4932 4 : return false;
4933 : }
4934 : }
4935 :
4936 : /* if we need X^2, calculate that in short-lived context */
4937 220 : if (state->calcSumX2)
4938 : {
4939 192 : init_var(&X2);
4940 192 : mul_var(&X, &X, &X2, X.dscale * 2);
4941 : }
4942 :
4943 : /* The rest of this needs to work in the aggregate context */
4944 220 : old_context = MemoryContextSwitchTo(state->agg_context);
4945 :
4946 220 : if (state->N-- > 1)
4947 : {
4948 : /* Negate X, to subtract it from the sum */
4949 208 : X.sign = (X.sign == NUMERIC_POS ? NUMERIC_NEG : NUMERIC_POS);
4950 208 : accum_sum_add(&(state->sumX), &X);
4951 :
4952 208 : if (state->calcSumX2)
4953 : {
4954 : /* Negate X^2. X^2 is always positive */
4955 192 : X2.sign = NUMERIC_NEG;
4956 192 : accum_sum_add(&(state->sumX2), &X2);
4957 : }
4958 : }
4959 : else
4960 : {
4961 : /* Zero the sums */
4962 : Assert(state->N == 0);
4963 :
4964 12 : accum_sum_reset(&state->sumX);
4965 12 : if (state->calcSumX2)
4966 0 : accum_sum_reset(&state->sumX2);
4967 : }
4968 :
4969 220 : MemoryContextSwitchTo(old_context);
4970 :
4971 220 : return true;
4972 : }
4973 :
4974 : /*
4975 : * Generic transition function for numeric aggregates that require sumX2.
4976 : */
4977 : Datum
4978 428 : numeric_accum(PG_FUNCTION_ARGS)
4979 : {
4980 : NumericAggState *state;
4981 :
4982 428 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
4983 :
4984 : /* Create the state data on the first call */
4985 428 : if (state == NULL)
4986 116 : state = makeNumericAggState(fcinfo, true);
4987 :
4988 428 : if (!PG_ARGISNULL(1))
4989 416 : do_numeric_accum(state, PG_GETARG_NUMERIC(1));
4990 :
4991 428 : PG_RETURN_POINTER(state);
4992 : }
4993 :
4994 : /*
4995 : * Generic combine function for numeric aggregates which require sumX2
4996 : */
4997 : Datum
4998 23 : numeric_combine(PG_FUNCTION_ARGS)
4999 : {
5000 : NumericAggState *state1;
5001 : NumericAggState *state2;
5002 : MemoryContext agg_context;
5003 : MemoryContext old_context;
5004 :
5005 23 : if (!AggCheckCallContext(fcinfo, &agg_context))
5006 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5007 :
5008 23 : state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5009 23 : state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
5010 :
5011 23 : if (state2 == NULL)
5012 0 : PG_RETURN_POINTER(state1);
5013 :
5014 : /* manually copy all fields from state2 to state1 */
5015 23 : if (state1 == NULL)
5016 : {
5017 12 : old_context = MemoryContextSwitchTo(agg_context);
5018 :
5019 12 : state1 = makeNumericAggStateCurrentContext(true);
5020 12 : state1->N = state2->N;
5021 12 : state1->NaNcount = state2->NaNcount;
5022 12 : state1->pInfcount = state2->pInfcount;
5023 12 : state1->nInfcount = state2->nInfcount;
5024 12 : state1->maxScale = state2->maxScale;
5025 12 : state1->maxScaleCount = state2->maxScaleCount;
5026 :
5027 12 : accum_sum_copy(&state1->sumX, &state2->sumX);
5028 12 : accum_sum_copy(&state1->sumX2, &state2->sumX2);
5029 :
5030 12 : MemoryContextSwitchTo(old_context);
5031 :
5032 12 : PG_RETURN_POINTER(state1);
5033 : }
5034 :
5035 11 : state1->N += state2->N;
5036 11 : state1->NaNcount += state2->NaNcount;
5037 11 : state1->pInfcount += state2->pInfcount;
5038 11 : state1->nInfcount += state2->nInfcount;
5039 :
5040 11 : if (state2->N > 0)
5041 : {
5042 : /*
5043 : * These are currently only needed for moving aggregates, but let's do
5044 : * the right thing anyway...
5045 : */
5046 11 : if (state2->maxScale > state1->maxScale)
5047 : {
5048 0 : state1->maxScale = state2->maxScale;
5049 0 : state1->maxScaleCount = state2->maxScaleCount;
5050 : }
5051 11 : else if (state2->maxScale == state1->maxScale)
5052 11 : state1->maxScaleCount += state2->maxScaleCount;
5053 :
5054 : /* The rest of this needs to work in the aggregate context */
5055 11 : old_context = MemoryContextSwitchTo(agg_context);
5056 :
5057 : /* Accumulate sums */
5058 11 : accum_sum_combine(&state1->sumX, &state2->sumX);
5059 11 : accum_sum_combine(&state1->sumX2, &state2->sumX2);
5060 :
5061 11 : MemoryContextSwitchTo(old_context);
5062 : }
5063 11 : PG_RETURN_POINTER(state1);
5064 : }
5065 :
5066 : /*
5067 : * Generic transition function for numeric aggregates that don't require sumX2.
5068 : */
5069 : Datum
5070 1248516 : numeric_avg_accum(PG_FUNCTION_ARGS)
5071 : {
5072 : NumericAggState *state;
5073 :
5074 1248516 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5075 :
5076 : /* Create the state data on the first call */
5077 1248516 : if (state == NULL)
5078 113925 : state = makeNumericAggState(fcinfo, false);
5079 :
5080 1248516 : if (!PG_ARGISNULL(1))
5081 1248476 : do_numeric_accum(state, PG_GETARG_NUMERIC(1));
5082 :
5083 1248516 : PG_RETURN_POINTER(state);
5084 : }
5085 :
5086 : /*
5087 : * Combine function for numeric aggregates which don't require sumX2
5088 : */
5089 : Datum
5090 15 : numeric_avg_combine(PG_FUNCTION_ARGS)
5091 : {
5092 : NumericAggState *state1;
5093 : NumericAggState *state2;
5094 : MemoryContext agg_context;
5095 : MemoryContext old_context;
5096 :
5097 15 : if (!AggCheckCallContext(fcinfo, &agg_context))
5098 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5099 :
5100 15 : state1 = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5101 15 : state2 = PG_ARGISNULL(1) ? NULL : (NumericAggState *) PG_GETARG_POINTER(1);
5102 :
5103 15 : if (state2 == NULL)
5104 0 : PG_RETURN_POINTER(state1);
5105 :
5106 : /* manually copy all fields from state2 to state1 */
5107 15 : if (state1 == NULL)
5108 : {
5109 4 : old_context = MemoryContextSwitchTo(agg_context);
5110 :
5111 4 : state1 = makeNumericAggStateCurrentContext(false);
5112 4 : state1->N = state2->N;
5113 4 : state1->NaNcount = state2->NaNcount;
5114 4 : state1->pInfcount = state2->pInfcount;
5115 4 : state1->nInfcount = state2->nInfcount;
5116 4 : state1->maxScale = state2->maxScale;
5117 4 : state1->maxScaleCount = state2->maxScaleCount;
5118 :
5119 4 : accum_sum_copy(&state1->sumX, &state2->sumX);
5120 :
5121 4 : MemoryContextSwitchTo(old_context);
5122 :
5123 4 : PG_RETURN_POINTER(state1);
5124 : }
5125 :
5126 11 : state1->N += state2->N;
5127 11 : state1->NaNcount += state2->NaNcount;
5128 11 : state1->pInfcount += state2->pInfcount;
5129 11 : state1->nInfcount += state2->nInfcount;
5130 :
5131 11 : if (state2->N > 0)
5132 : {
5133 : /*
5134 : * These are currently only needed for moving aggregates, but let's do
5135 : * the right thing anyway...
5136 : */
5137 11 : if (state2->maxScale > state1->maxScale)
5138 : {
5139 0 : state1->maxScale = state2->maxScale;
5140 0 : state1->maxScaleCount = state2->maxScaleCount;
5141 : }
5142 11 : else if (state2->maxScale == state1->maxScale)
5143 11 : state1->maxScaleCount += state2->maxScaleCount;
5144 :
5145 : /* The rest of this needs to work in the aggregate context */
5146 11 : old_context = MemoryContextSwitchTo(agg_context);
5147 :
5148 : /* Accumulate sums */
5149 11 : accum_sum_combine(&state1->sumX, &state2->sumX);
5150 :
5151 11 : MemoryContextSwitchTo(old_context);
5152 : }
5153 11 : PG_RETURN_POINTER(state1);
5154 : }
5155 :
5156 : /*
5157 : * numeric_avg_serialize
5158 : * Serialize NumericAggState for numeric aggregates that don't require
5159 : * sumX2.
5160 : */
5161 : Datum
5162 15 : numeric_avg_serialize(PG_FUNCTION_ARGS)
5163 : {
5164 : NumericAggState *state;
5165 : StringInfoData buf;
5166 : bytea *result;
5167 : NumericVar tmp_var;
5168 :
5169 : /* Ensure we disallow calling when not in aggregate context */
5170 15 : if (!AggCheckCallContext(fcinfo, NULL))
5171 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5172 :
5173 15 : state = (NumericAggState *) PG_GETARG_POINTER(0);
5174 :
5175 15 : init_var(&tmp_var);
5176 :
5177 15 : pq_begintypsend(&buf);
5178 :
5179 : /* N */
5180 15 : pq_sendint64(&buf, state->N);
5181 :
5182 : /* sumX */
5183 15 : accum_sum_final(&state->sumX, &tmp_var);
5184 15 : numericvar_serialize(&buf, &tmp_var);
5185 :
5186 : /* maxScale */
5187 15 : pq_sendint32(&buf, state->maxScale);
5188 :
5189 : /* maxScaleCount */
5190 15 : pq_sendint64(&buf, state->maxScaleCount);
5191 :
5192 : /* NaNcount */
5193 15 : pq_sendint64(&buf, state->NaNcount);
5194 :
5195 : /* pInfcount */
5196 15 : pq_sendint64(&buf, state->pInfcount);
5197 :
5198 : /* nInfcount */
5199 15 : pq_sendint64(&buf, state->nInfcount);
5200 :
5201 15 : result = pq_endtypsend(&buf);
5202 :
5203 15 : free_var(&tmp_var);
5204 :
5205 15 : PG_RETURN_BYTEA_P(result);
5206 : }
5207 :
5208 : /*
5209 : * numeric_avg_deserialize
5210 : * Deserialize bytea into NumericAggState for numeric aggregates that
5211 : * don't require sumX2.
5212 : */
5213 : Datum
5214 15 : numeric_avg_deserialize(PG_FUNCTION_ARGS)
5215 : {
5216 : bytea *sstate;
5217 : NumericAggState *result;
5218 : StringInfoData buf;
5219 : NumericVar tmp_var;
5220 :
5221 15 : if (!AggCheckCallContext(fcinfo, NULL))
5222 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5223 :
5224 15 : sstate = PG_GETARG_BYTEA_PP(0);
5225 :
5226 15 : init_var(&tmp_var);
5227 :
5228 : /*
5229 : * Initialize a StringInfo so that we can "receive" it using the standard
5230 : * recv-function infrastructure.
5231 : */
5232 15 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5233 15 : VARSIZE_ANY_EXHDR(sstate));
5234 :
5235 15 : result = makeNumericAggStateCurrentContext(false);
5236 :
5237 : /* N */
5238 15 : result->N = pq_getmsgint64(&buf);
5239 :
5240 : /* sumX */
5241 15 : numericvar_deserialize(&buf, &tmp_var);
5242 15 : accum_sum_add(&(result->sumX), &tmp_var);
5243 :
5244 : /* maxScale */
5245 15 : result->maxScale = pq_getmsgint(&buf, 4);
5246 :
5247 : /* maxScaleCount */
5248 15 : result->maxScaleCount = pq_getmsgint64(&buf);
5249 :
5250 : /* NaNcount */
5251 15 : result->NaNcount = pq_getmsgint64(&buf);
5252 :
5253 : /* pInfcount */
5254 15 : result->pInfcount = pq_getmsgint64(&buf);
5255 :
5256 : /* nInfcount */
5257 15 : result->nInfcount = pq_getmsgint64(&buf);
5258 :
5259 15 : pq_getmsgend(&buf);
5260 :
5261 15 : free_var(&tmp_var);
5262 :
5263 15 : PG_RETURN_POINTER(result);
5264 : }
5265 :
5266 : /*
5267 : * numeric_serialize
5268 : * Serialization function for NumericAggState for numeric aggregates that
5269 : * require sumX2.
5270 : */
5271 : Datum
5272 23 : numeric_serialize(PG_FUNCTION_ARGS)
5273 : {
5274 : NumericAggState *state;
5275 : StringInfoData buf;
5276 : bytea *result;
5277 : NumericVar tmp_var;
5278 :
5279 : /* Ensure we disallow calling when not in aggregate context */
5280 23 : if (!AggCheckCallContext(fcinfo, NULL))
5281 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5282 :
5283 23 : state = (NumericAggState *) PG_GETARG_POINTER(0);
5284 :
5285 23 : init_var(&tmp_var);
5286 :
5287 23 : pq_begintypsend(&buf);
5288 :
5289 : /* N */
5290 23 : pq_sendint64(&buf, state->N);
5291 :
5292 : /* sumX */
5293 23 : accum_sum_final(&state->sumX, &tmp_var);
5294 23 : numericvar_serialize(&buf, &tmp_var);
5295 :
5296 : /* sumX2 */
5297 23 : accum_sum_final(&state->sumX2, &tmp_var);
5298 23 : numericvar_serialize(&buf, &tmp_var);
5299 :
5300 : /* maxScale */
5301 23 : pq_sendint32(&buf, state->maxScale);
5302 :
5303 : /* maxScaleCount */
5304 23 : pq_sendint64(&buf, state->maxScaleCount);
5305 :
5306 : /* NaNcount */
5307 23 : pq_sendint64(&buf, state->NaNcount);
5308 :
5309 : /* pInfcount */
5310 23 : pq_sendint64(&buf, state->pInfcount);
5311 :
5312 : /* nInfcount */
5313 23 : pq_sendint64(&buf, state->nInfcount);
5314 :
5315 23 : result = pq_endtypsend(&buf);
5316 :
5317 23 : free_var(&tmp_var);
5318 :
5319 23 : PG_RETURN_BYTEA_P(result);
5320 : }
5321 :
5322 : /*
5323 : * numeric_deserialize
5324 : * Deserialization function for NumericAggState for numeric aggregates that
5325 : * require sumX2.
5326 : */
5327 : Datum
5328 23 : numeric_deserialize(PG_FUNCTION_ARGS)
5329 : {
5330 : bytea *sstate;
5331 : NumericAggState *result;
5332 : StringInfoData buf;
5333 : NumericVar tmp_var;
5334 :
5335 23 : if (!AggCheckCallContext(fcinfo, NULL))
5336 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5337 :
5338 23 : sstate = PG_GETARG_BYTEA_PP(0);
5339 :
5340 23 : init_var(&tmp_var);
5341 :
5342 : /*
5343 : * Initialize a StringInfo so that we can "receive" it using the standard
5344 : * recv-function infrastructure.
5345 : */
5346 23 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5347 23 : VARSIZE_ANY_EXHDR(sstate));
5348 :
5349 23 : result = makeNumericAggStateCurrentContext(false);
5350 :
5351 : /* N */
5352 23 : result->N = pq_getmsgint64(&buf);
5353 :
5354 : /* sumX */
5355 23 : numericvar_deserialize(&buf, &tmp_var);
5356 23 : accum_sum_add(&(result->sumX), &tmp_var);
5357 :
5358 : /* sumX2 */
5359 23 : numericvar_deserialize(&buf, &tmp_var);
5360 23 : accum_sum_add(&(result->sumX2), &tmp_var);
5361 :
5362 : /* maxScale */
5363 23 : result->maxScale = pq_getmsgint(&buf, 4);
5364 :
5365 : /* maxScaleCount */
5366 23 : result->maxScaleCount = pq_getmsgint64(&buf);
5367 :
5368 : /* NaNcount */
5369 23 : result->NaNcount = pq_getmsgint64(&buf);
5370 :
5371 : /* pInfcount */
5372 23 : result->pInfcount = pq_getmsgint64(&buf);
5373 :
5374 : /* nInfcount */
5375 23 : result->nInfcount = pq_getmsgint64(&buf);
5376 :
5377 23 : pq_getmsgend(&buf);
5378 :
5379 23 : free_var(&tmp_var);
5380 :
5381 23 : PG_RETURN_POINTER(result);
5382 : }
5383 :
5384 : /*
5385 : * Generic inverse transition function for numeric aggregates
5386 : * (with or without requirement for X^2).
5387 : */
5388 : Datum
5389 152 : numeric_accum_inv(PG_FUNCTION_ARGS)
5390 : {
5391 : NumericAggState *state;
5392 :
5393 152 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5394 :
5395 : /* Should not get here with no state */
5396 152 : if (state == NULL)
5397 0 : elog(ERROR, "numeric_accum_inv called with NULL state");
5398 :
5399 152 : if (!PG_ARGISNULL(1))
5400 : {
5401 : /* If we fail to perform the inverse transition, return NULL */
5402 132 : if (!do_numeric_discard(state, PG_GETARG_NUMERIC(1)))
5403 4 : PG_RETURN_NULL();
5404 : }
5405 :
5406 148 : PG_RETURN_POINTER(state);
5407 : }
5408 :
5409 :
5410 : /*
5411 : * Integer data types in general use Numeric accumulators to share code and
5412 : * avoid risk of overflow. However for performance reasons optimized
5413 : * special-purpose accumulator routines are used when possible:
5414 : *
5415 : * For 16-bit and 32-bit inputs, N and sum(X) fit into 64-bit, so 64-bit
5416 : * accumulators are used for SUM and AVG of these data types.
5417 : *
5418 : * For 16-bit and 32-bit inputs, sum(X^2) fits into 128-bit, so 128-bit
5419 : * accumulators are used for STDDEV_POP, STDDEV_SAMP, VAR_POP, and VAR_SAMP of
5420 : * these data types.
5421 : *
5422 : * For 64-bit inputs, sum(X) fits into 128-bit, so a 128-bit accumulator is
5423 : * used for SUM(int8) and AVG(int8).
5424 : */
5425 :
5426 : typedef struct Int128AggState
5427 : {
5428 : bool calcSumX2; /* if true, calculate sumX2 */
5429 : int64 N; /* count of processed numbers */
5430 : INT128 sumX; /* sum of processed numbers */
5431 : INT128 sumX2; /* sum of squares of processed numbers */
5432 : } Int128AggState;
5433 :
5434 : /*
5435 : * Prepare state data for a 128-bit aggregate function that needs to compute
5436 : * sum, count and optionally sum of squares of the input.
5437 : */
5438 : static Int128AggState *
5439 634 : makeInt128AggState(FunctionCallInfo fcinfo, bool calcSumX2)
5440 : {
5441 : Int128AggState *state;
5442 : MemoryContext agg_context;
5443 : MemoryContext old_context;
5444 :
5445 634 : if (!AggCheckCallContext(fcinfo, &agg_context))
5446 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5447 :
5448 634 : old_context = MemoryContextSwitchTo(agg_context);
5449 :
5450 634 : state = palloc0_object(Int128AggState);
5451 634 : state->calcSumX2 = calcSumX2;
5452 :
5453 634 : MemoryContextSwitchTo(old_context);
5454 :
5455 634 : return state;
5456 : }
5457 :
5458 : /*
5459 : * Like makeInt128AggState(), but allocate the state in the current memory
5460 : * context.
5461 : */
5462 : static Int128AggState *
5463 36 : makeInt128AggStateCurrentContext(bool calcSumX2)
5464 : {
5465 : Int128AggState *state;
5466 :
5467 36 : state = palloc0_object(Int128AggState);
5468 36 : state->calcSumX2 = calcSumX2;
5469 :
5470 36 : return state;
5471 : }
5472 :
5473 : /*
5474 : * Accumulate a new input value for 128-bit aggregate functions.
5475 : */
5476 : static void
5477 371598 : do_int128_accum(Int128AggState *state, int64 newval)
5478 : {
5479 371598 : if (state->calcSumX2)
5480 161240 : int128_add_int64_mul_int64(&state->sumX2, newval, newval);
5481 :
5482 371598 : int128_add_int64(&state->sumX, newval);
5483 371598 : state->N++;
5484 371598 : }
5485 :
5486 : /*
5487 : * Remove an input value from the aggregated state.
5488 : */
5489 : static void
5490 208 : do_int128_discard(Int128AggState *state, int64 newval)
5491 : {
5492 208 : if (state->calcSumX2)
5493 192 : int128_sub_int64_mul_int64(&state->sumX2, newval, newval);
5494 :
5495 208 : int128_sub_int64(&state->sumX, newval);
5496 208 : state->N--;
5497 208 : }
5498 :
5499 : Datum
5500 132 : int2_accum(PG_FUNCTION_ARGS)
5501 : {
5502 : Int128AggState *state;
5503 :
5504 132 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5505 :
5506 : /* Create the state data on the first call */
5507 132 : if (state == NULL)
5508 24 : state = makeInt128AggState(fcinfo, true);
5509 :
5510 132 : if (!PG_ARGISNULL(1))
5511 120 : do_int128_accum(state, PG_GETARG_INT16(1));
5512 :
5513 132 : PG_RETURN_POINTER(state);
5514 : }
5515 :
5516 : Datum
5517 161132 : int4_accum(PG_FUNCTION_ARGS)
5518 : {
5519 : Int128AggState *state;
5520 :
5521 161132 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5522 :
5523 : /* Create the state data on the first call */
5524 161132 : if (state == NULL)
5525 50 : state = makeInt128AggState(fcinfo, true);
5526 :
5527 161132 : if (!PG_ARGISNULL(1))
5528 161120 : do_int128_accum(state, PG_GETARG_INT32(1));
5529 :
5530 161132 : PG_RETURN_POINTER(state);
5531 : }
5532 :
5533 : Datum
5534 160132 : int8_accum(PG_FUNCTION_ARGS)
5535 : {
5536 : NumericAggState *state;
5537 :
5538 160132 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5539 :
5540 : /* Create the state data on the first call */
5541 160132 : if (state == NULL)
5542 39 : state = makeNumericAggState(fcinfo, true);
5543 :
5544 160132 : if (!PG_ARGISNULL(1))
5545 160120 : do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1)));
5546 :
5547 160132 : PG_RETURN_POINTER(state);
5548 : }
5549 :
5550 : /*
5551 : * Combine function for Int128AggState for aggregates which require sumX2
5552 : */
5553 : Datum
5554 16 : numeric_poly_combine(PG_FUNCTION_ARGS)
5555 : {
5556 : Int128AggState *state1;
5557 : Int128AggState *state2;
5558 : MemoryContext agg_context;
5559 : MemoryContext old_context;
5560 :
5561 16 : if (!AggCheckCallContext(fcinfo, &agg_context))
5562 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5563 :
5564 16 : state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5565 16 : state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
5566 :
5567 16 : if (state2 == NULL)
5568 0 : PG_RETURN_POINTER(state1);
5569 :
5570 : /* manually copy all fields from state2 to state1 */
5571 16 : if (state1 == NULL)
5572 : {
5573 4 : old_context = MemoryContextSwitchTo(agg_context);
5574 :
5575 4 : state1 = makeInt128AggState(fcinfo, true);
5576 4 : state1->N = state2->N;
5577 4 : state1->sumX = state2->sumX;
5578 4 : state1->sumX2 = state2->sumX2;
5579 :
5580 4 : MemoryContextSwitchTo(old_context);
5581 :
5582 4 : PG_RETURN_POINTER(state1);
5583 : }
5584 :
5585 12 : if (state2->N > 0)
5586 : {
5587 12 : state1->N += state2->N;
5588 12 : int128_add_int128(&state1->sumX, state2->sumX);
5589 12 : int128_add_int128(&state1->sumX2, state2->sumX2);
5590 : }
5591 12 : PG_RETURN_POINTER(state1);
5592 : }
5593 :
5594 : /*
5595 : * int128_serialize - serialize a 128-bit integer to binary format
5596 : */
5597 : static inline void
5598 52 : int128_serialize(StringInfo buf, INT128 val)
5599 : {
5600 52 : pq_sendint64(buf, PG_INT128_HI_INT64(val));
5601 52 : pq_sendint64(buf, PG_INT128_LO_UINT64(val));
5602 52 : }
5603 :
5604 : /*
5605 : * int128_deserialize - deserialize binary format to a 128-bit integer.
5606 : */
5607 : static inline INT128
5608 52 : int128_deserialize(StringInfo buf)
5609 : {
5610 52 : int64 hi = pq_getmsgint64(buf);
5611 52 : uint64 lo = pq_getmsgint64(buf);
5612 :
5613 52 : return make_int128(hi, lo);
5614 : }
5615 :
5616 : /*
5617 : * numeric_poly_serialize
5618 : * Serialize Int128AggState into bytea for aggregate functions which
5619 : * require sumX2.
5620 : */
5621 : Datum
5622 16 : numeric_poly_serialize(PG_FUNCTION_ARGS)
5623 : {
5624 : Int128AggState *state;
5625 : StringInfoData buf;
5626 : bytea *result;
5627 :
5628 : /* Ensure we disallow calling when not in aggregate context */
5629 16 : if (!AggCheckCallContext(fcinfo, NULL))
5630 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5631 :
5632 16 : state = (Int128AggState *) PG_GETARG_POINTER(0);
5633 :
5634 16 : pq_begintypsend(&buf);
5635 :
5636 : /* N */
5637 16 : pq_sendint64(&buf, state->N);
5638 :
5639 : /* sumX */
5640 16 : int128_serialize(&buf, state->sumX);
5641 :
5642 : /* sumX2 */
5643 16 : int128_serialize(&buf, state->sumX2);
5644 :
5645 16 : result = pq_endtypsend(&buf);
5646 :
5647 16 : PG_RETURN_BYTEA_P(result);
5648 : }
5649 :
5650 : /*
5651 : * numeric_poly_deserialize
5652 : * Deserialize Int128AggState from bytea for aggregate functions which
5653 : * require sumX2.
5654 : */
5655 : Datum
5656 16 : numeric_poly_deserialize(PG_FUNCTION_ARGS)
5657 : {
5658 : bytea *sstate;
5659 : Int128AggState *result;
5660 : StringInfoData buf;
5661 :
5662 16 : if (!AggCheckCallContext(fcinfo, NULL))
5663 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5664 :
5665 16 : sstate = PG_GETARG_BYTEA_PP(0);
5666 :
5667 : /*
5668 : * Initialize a StringInfo so that we can "receive" it using the standard
5669 : * recv-function infrastructure.
5670 : */
5671 16 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5672 16 : VARSIZE_ANY_EXHDR(sstate));
5673 :
5674 16 : result = makeInt128AggStateCurrentContext(false);
5675 :
5676 : /* N */
5677 16 : result->N = pq_getmsgint64(&buf);
5678 :
5679 : /* sumX */
5680 16 : result->sumX = int128_deserialize(&buf);
5681 :
5682 : /* sumX2 */
5683 16 : result->sumX2 = int128_deserialize(&buf);
5684 :
5685 16 : pq_getmsgend(&buf);
5686 :
5687 16 : PG_RETURN_POINTER(result);
5688 : }
5689 :
5690 : /*
5691 : * Transition function for int8 input when we don't need sumX2.
5692 : */
5693 : Datum
5694 213257 : int8_avg_accum(PG_FUNCTION_ARGS)
5695 : {
5696 : Int128AggState *state;
5697 :
5698 213257 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5699 :
5700 : /* Create the state data on the first call */
5701 213257 : if (state == NULL)
5702 548 : state = makeInt128AggState(fcinfo, false);
5703 :
5704 213257 : if (!PG_ARGISNULL(1))
5705 210358 : do_int128_accum(state, PG_GETARG_INT64(1));
5706 :
5707 213257 : PG_RETURN_POINTER(state);
5708 : }
5709 :
5710 : /*
5711 : * Combine function for Int128AggState for aggregates which don't require
5712 : * sumX2
5713 : */
5714 : Datum
5715 20 : int8_avg_combine(PG_FUNCTION_ARGS)
5716 : {
5717 : Int128AggState *state1;
5718 : Int128AggState *state2;
5719 : MemoryContext agg_context;
5720 : MemoryContext old_context;
5721 :
5722 20 : if (!AggCheckCallContext(fcinfo, &agg_context))
5723 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5724 :
5725 20 : state1 = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5726 20 : state2 = PG_ARGISNULL(1) ? NULL : (Int128AggState *) PG_GETARG_POINTER(1);
5727 :
5728 20 : if (state2 == NULL)
5729 0 : PG_RETURN_POINTER(state1);
5730 :
5731 : /* manually copy all fields from state2 to state1 */
5732 20 : if (state1 == NULL)
5733 : {
5734 8 : old_context = MemoryContextSwitchTo(agg_context);
5735 :
5736 8 : state1 = makeInt128AggState(fcinfo, false);
5737 8 : state1->N = state2->N;
5738 8 : state1->sumX = state2->sumX;
5739 :
5740 8 : MemoryContextSwitchTo(old_context);
5741 :
5742 8 : PG_RETURN_POINTER(state1);
5743 : }
5744 :
5745 12 : if (state2->N > 0)
5746 : {
5747 12 : state1->N += state2->N;
5748 12 : int128_add_int128(&state1->sumX, state2->sumX);
5749 : }
5750 12 : PG_RETURN_POINTER(state1);
5751 : }
5752 :
5753 : /*
5754 : * int8_avg_serialize
5755 : * Serialize Int128AggState into bytea for aggregate functions which
5756 : * don't require sumX2.
5757 : */
5758 : Datum
5759 20 : int8_avg_serialize(PG_FUNCTION_ARGS)
5760 : {
5761 : Int128AggState *state;
5762 : StringInfoData buf;
5763 : bytea *result;
5764 :
5765 : /* Ensure we disallow calling when not in aggregate context */
5766 20 : if (!AggCheckCallContext(fcinfo, NULL))
5767 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5768 :
5769 20 : state = (Int128AggState *) PG_GETARG_POINTER(0);
5770 :
5771 20 : pq_begintypsend(&buf);
5772 :
5773 : /* N */
5774 20 : pq_sendint64(&buf, state->N);
5775 :
5776 : /* sumX */
5777 20 : int128_serialize(&buf, state->sumX);
5778 :
5779 20 : result = pq_endtypsend(&buf);
5780 :
5781 20 : PG_RETURN_BYTEA_P(result);
5782 : }
5783 :
5784 : /*
5785 : * int8_avg_deserialize
5786 : * Deserialize Int128AggState from bytea for aggregate functions which
5787 : * don't require sumX2.
5788 : */
5789 : Datum
5790 20 : int8_avg_deserialize(PG_FUNCTION_ARGS)
5791 : {
5792 : bytea *sstate;
5793 : Int128AggState *result;
5794 : StringInfoData buf;
5795 :
5796 20 : if (!AggCheckCallContext(fcinfo, NULL))
5797 0 : elog(ERROR, "aggregate function called in non-aggregate context");
5798 :
5799 20 : sstate = PG_GETARG_BYTEA_PP(0);
5800 :
5801 : /*
5802 : * Initialize a StringInfo so that we can "receive" it using the standard
5803 : * recv-function infrastructure.
5804 : */
5805 20 : initReadOnlyStringInfo(&buf, VARDATA_ANY(sstate),
5806 20 : VARSIZE_ANY_EXHDR(sstate));
5807 :
5808 20 : result = makeInt128AggStateCurrentContext(false);
5809 :
5810 : /* N */
5811 20 : result->N = pq_getmsgint64(&buf);
5812 :
5813 : /* sumX */
5814 20 : result->sumX = int128_deserialize(&buf);
5815 :
5816 20 : pq_getmsgend(&buf);
5817 :
5818 20 : PG_RETURN_POINTER(result);
5819 : }
5820 :
5821 : /*
5822 : * Inverse transition functions to go with the above.
5823 : */
5824 :
5825 : Datum
5826 108 : int2_accum_inv(PG_FUNCTION_ARGS)
5827 : {
5828 : Int128AggState *state;
5829 :
5830 108 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5831 :
5832 : /* Should not get here with no state */
5833 108 : if (state == NULL)
5834 0 : elog(ERROR, "int2_accum_inv called with NULL state");
5835 :
5836 108 : if (!PG_ARGISNULL(1))
5837 96 : do_int128_discard(state, PG_GETARG_INT16(1));
5838 :
5839 108 : PG_RETURN_POINTER(state);
5840 : }
5841 :
5842 : Datum
5843 108 : int4_accum_inv(PG_FUNCTION_ARGS)
5844 : {
5845 : Int128AggState *state;
5846 :
5847 108 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5848 :
5849 : /* Should not get here with no state */
5850 108 : if (state == NULL)
5851 0 : elog(ERROR, "int4_accum_inv called with NULL state");
5852 :
5853 108 : if (!PG_ARGISNULL(1))
5854 96 : do_int128_discard(state, PG_GETARG_INT32(1));
5855 :
5856 108 : PG_RETURN_POINTER(state);
5857 : }
5858 :
5859 : Datum
5860 108 : int8_accum_inv(PG_FUNCTION_ARGS)
5861 : {
5862 : NumericAggState *state;
5863 :
5864 108 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5865 :
5866 : /* Should not get here with no state */
5867 108 : if (state == NULL)
5868 0 : elog(ERROR, "int8_accum_inv called with NULL state");
5869 :
5870 108 : if (!PG_ARGISNULL(1))
5871 : {
5872 : /* Should never fail, all inputs have dscale 0 */
5873 96 : if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1))))
5874 0 : elog(ERROR, "do_numeric_discard failed unexpectedly");
5875 : }
5876 :
5877 108 : PG_RETURN_POINTER(state);
5878 : }
5879 :
5880 : Datum
5881 24 : int8_avg_accum_inv(PG_FUNCTION_ARGS)
5882 : {
5883 : Int128AggState *state;
5884 :
5885 24 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5886 :
5887 : /* Should not get here with no state */
5888 24 : if (state == NULL)
5889 0 : elog(ERROR, "int8_avg_accum_inv called with NULL state");
5890 :
5891 24 : if (!PG_ARGISNULL(1))
5892 16 : do_int128_discard(state, PG_GETARG_INT64(1));
5893 :
5894 24 : PG_RETURN_POINTER(state);
5895 : }
5896 :
5897 : Datum
5898 692 : numeric_poly_sum(PG_FUNCTION_ARGS)
5899 : {
5900 : Int128AggState *state;
5901 : Numeric res;
5902 : NumericVar result;
5903 :
5904 692 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5905 :
5906 : /* If there were no non-null inputs, return NULL */
5907 692 : if (state == NULL || state->N == 0)
5908 16 : PG_RETURN_NULL();
5909 :
5910 676 : init_var(&result);
5911 :
5912 676 : int128_to_numericvar(state->sumX, &result);
5913 :
5914 676 : res = make_result(&result);
5915 :
5916 676 : free_var(&result);
5917 :
5918 676 : PG_RETURN_NUMERIC(res);
5919 : }
5920 :
5921 : Datum
5922 24 : numeric_poly_avg(PG_FUNCTION_ARGS)
5923 : {
5924 : Int128AggState *state;
5925 : NumericVar result;
5926 : Datum countd,
5927 : sumd;
5928 :
5929 24 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
5930 :
5931 : /* If there were no non-null inputs, return NULL */
5932 24 : if (state == NULL || state->N == 0)
5933 12 : PG_RETURN_NULL();
5934 :
5935 12 : init_var(&result);
5936 :
5937 12 : int128_to_numericvar(state->sumX, &result);
5938 :
5939 12 : countd = NumericGetDatum(int64_to_numeric(state->N));
5940 12 : sumd = NumericGetDatum(make_result(&result));
5941 :
5942 12 : free_var(&result);
5943 :
5944 12 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
5945 : }
5946 :
5947 : Datum
5948 52 : numeric_avg(PG_FUNCTION_ARGS)
5949 : {
5950 : NumericAggState *state;
5951 : Datum N_datum;
5952 : Datum sumX_datum;
5953 : NumericVar sumX_var;
5954 :
5955 52 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5956 :
5957 : /* If there were no non-null inputs, return NULL */
5958 52 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
5959 12 : PG_RETURN_NULL();
5960 :
5961 40 : if (state->NaNcount > 0) /* there was at least one NaN input */
5962 4 : PG_RETURN_NUMERIC(make_result(&const_nan));
5963 :
5964 : /* adding plus and minus infinities gives NaN */
5965 36 : if (state->pInfcount > 0 && state->nInfcount > 0)
5966 4 : PG_RETURN_NUMERIC(make_result(&const_nan));
5967 32 : if (state->pInfcount > 0)
5968 12 : PG_RETURN_NUMERIC(make_result(&const_pinf));
5969 20 : if (state->nInfcount > 0)
5970 4 : PG_RETURN_NUMERIC(make_result(&const_ninf));
5971 :
5972 16 : N_datum = NumericGetDatum(int64_to_numeric(state->N));
5973 :
5974 16 : init_var(&sumX_var);
5975 16 : accum_sum_final(&state->sumX, &sumX_var);
5976 16 : sumX_datum = NumericGetDatum(make_result(&sumX_var));
5977 16 : free_var(&sumX_var);
5978 :
5979 16 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumX_datum, N_datum));
5980 : }
5981 :
5982 : Datum
5983 113926 : numeric_sum(PG_FUNCTION_ARGS)
5984 : {
5985 : NumericAggState *state;
5986 : NumericVar sumX_var;
5987 : Numeric result;
5988 :
5989 113926 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
5990 :
5991 : /* If there were no non-null inputs, return NULL */
5992 113926 : if (state == NULL || NA_TOTAL_COUNT(state) == 0)
5993 12 : PG_RETURN_NULL();
5994 :
5995 113914 : if (state->NaNcount > 0) /* there was at least one NaN input */
5996 12 : PG_RETURN_NUMERIC(make_result(&const_nan));
5997 :
5998 : /* adding plus and minus infinities gives NaN */
5999 113902 : if (state->pInfcount > 0 && state->nInfcount > 0)
6000 4 : PG_RETURN_NUMERIC(make_result(&const_nan));
6001 113898 : if (state->pInfcount > 0)
6002 12 : PG_RETURN_NUMERIC(make_result(&const_pinf));
6003 113886 : if (state->nInfcount > 0)
6004 4 : PG_RETURN_NUMERIC(make_result(&const_ninf));
6005 :
6006 113882 : init_var(&sumX_var);
6007 113882 : accum_sum_final(&state->sumX, &sumX_var);
6008 113882 : result = make_result(&sumX_var);
6009 113882 : free_var(&sumX_var);
6010 :
6011 113882 : PG_RETURN_NUMERIC(result);
6012 : }
6013 :
6014 : /*
6015 : * Workhorse routine for the standard deviance and variance
6016 : * aggregates. 'state' is aggregate's transition state.
6017 : * 'variance' specifies whether we should calculate the
6018 : * variance or the standard deviation. 'sample' indicates whether the
6019 : * caller is interested in the sample or the population
6020 : * variance/stddev.
6021 : *
6022 : * If appropriate variance statistic is undefined for the input,
6023 : * *is_null is set to true and NULL is returned.
6024 : */
6025 : static Numeric
6026 654 : numeric_stddev_internal(NumericAggState *state,
6027 : bool variance, bool sample,
6028 : bool *is_null)
6029 : {
6030 : Numeric res;
6031 : NumericVar vN,
6032 : vsumX,
6033 : vsumX2,
6034 : vNminus1;
6035 : int64 totCount;
6036 : int rscale;
6037 :
6038 : /*
6039 : * Sample stddev and variance are undefined when N <= 1; population stddev
6040 : * is undefined when N == 0. Return NULL in either case (note that NaNs
6041 : * and infinities count as normal inputs for this purpose).
6042 : */
6043 654 : if (state == NULL || (totCount = NA_TOTAL_COUNT(state)) == 0)
6044 : {
6045 0 : *is_null = true;
6046 0 : return NULL;
6047 : }
6048 :
6049 654 : if (sample && totCount <= 1)
6050 : {
6051 88 : *is_null = true;
6052 88 : return NULL;
6053 : }
6054 :
6055 566 : *is_null = false;
6056 :
6057 : /*
6058 : * Deal with NaN and infinity cases. By analogy to the behavior of the
6059 : * float8 functions, any infinity input produces NaN output.
6060 : */
6061 566 : if (state->NaNcount > 0 || state->pInfcount > 0 || state->nInfcount > 0)
6062 36 : return make_result(&const_nan);
6063 :
6064 : /* OK, normal calculation applies */
6065 530 : init_var(&vN);
6066 530 : init_var(&vsumX);
6067 530 : init_var(&vsumX2);
6068 :
6069 530 : int64_to_numericvar(state->N, &vN);
6070 530 : accum_sum_final(&(state->sumX), &vsumX);
6071 530 : accum_sum_final(&(state->sumX2), &vsumX2);
6072 :
6073 530 : init_var(&vNminus1);
6074 530 : sub_var(&vN, &const_one, &vNminus1);
6075 :
6076 : /* compute rscale for mul_var calls */
6077 530 : rscale = vsumX.dscale * 2;
6078 :
6079 530 : mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
6080 530 : mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
6081 530 : sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
6082 :
6083 530 : if (cmp_var(&vsumX2, &const_zero) <= 0)
6084 : {
6085 : /* Watch out for roundoff error producing a negative numerator */
6086 50 : res = make_result(&const_zero);
6087 : }
6088 : else
6089 : {
6090 480 : if (sample)
6091 328 : mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
6092 : else
6093 152 : mul_var(&vN, &vN, &vNminus1, 0); /* N * N */
6094 480 : rscale = select_div_scale(&vsumX2, &vNminus1);
6095 480 : div_var(&vsumX2, &vNminus1, &vsumX, rscale, true, true); /* variance */
6096 480 : if (!variance)
6097 252 : sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
6098 :
6099 480 : res = make_result(&vsumX);
6100 : }
6101 :
6102 530 : free_var(&vNminus1);
6103 530 : free_var(&vsumX);
6104 530 : free_var(&vsumX2);
6105 :
6106 530 : return res;
6107 : }
6108 :
6109 : Datum
6110 120 : numeric_var_samp(PG_FUNCTION_ARGS)
6111 : {
6112 : NumericAggState *state;
6113 : Numeric res;
6114 : bool is_null;
6115 :
6116 120 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6117 :
6118 120 : res = numeric_stddev_internal(state, true, true, &is_null);
6119 :
6120 120 : if (is_null)
6121 28 : PG_RETURN_NULL();
6122 : else
6123 92 : PG_RETURN_NUMERIC(res);
6124 : }
6125 :
6126 : Datum
6127 116 : numeric_stddev_samp(PG_FUNCTION_ARGS)
6128 : {
6129 : NumericAggState *state;
6130 : Numeric res;
6131 : bool is_null;
6132 :
6133 116 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6134 :
6135 116 : res = numeric_stddev_internal(state, false, true, &is_null);
6136 :
6137 116 : if (is_null)
6138 28 : PG_RETURN_NULL();
6139 : else
6140 88 : PG_RETURN_NUMERIC(res);
6141 : }
6142 :
6143 : Datum
6144 76 : numeric_var_pop(PG_FUNCTION_ARGS)
6145 : {
6146 : NumericAggState *state;
6147 : Numeric res;
6148 : bool is_null;
6149 :
6150 76 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6151 :
6152 76 : res = numeric_stddev_internal(state, true, false, &is_null);
6153 :
6154 76 : if (is_null)
6155 0 : PG_RETURN_NULL();
6156 : else
6157 76 : PG_RETURN_NUMERIC(res);
6158 : }
6159 :
6160 : Datum
6161 64 : numeric_stddev_pop(PG_FUNCTION_ARGS)
6162 : {
6163 : NumericAggState *state;
6164 : Numeric res;
6165 : bool is_null;
6166 :
6167 64 : state = PG_ARGISNULL(0) ? NULL : (NumericAggState *) PG_GETARG_POINTER(0);
6168 :
6169 64 : res = numeric_stddev_internal(state, false, false, &is_null);
6170 :
6171 64 : if (is_null)
6172 0 : PG_RETURN_NULL();
6173 : else
6174 64 : PG_RETURN_NUMERIC(res);
6175 : }
6176 :
6177 : static Numeric
6178 278 : numeric_poly_stddev_internal(Int128AggState *state,
6179 : bool variance, bool sample,
6180 : bool *is_null)
6181 : {
6182 : NumericAggState numstate;
6183 : Numeric res;
6184 :
6185 : /* Initialize an empty agg state */
6186 278 : memset(&numstate, 0, sizeof(NumericAggState));
6187 :
6188 278 : if (state)
6189 : {
6190 : NumericVar tmp_var;
6191 :
6192 278 : numstate.N = state->N;
6193 :
6194 278 : init_var(&tmp_var);
6195 :
6196 278 : int128_to_numericvar(state->sumX, &tmp_var);
6197 278 : accum_sum_add(&numstate.sumX, &tmp_var);
6198 :
6199 278 : int128_to_numericvar(state->sumX2, &tmp_var);
6200 278 : accum_sum_add(&numstate.sumX2, &tmp_var);
6201 :
6202 278 : free_var(&tmp_var);
6203 : }
6204 :
6205 278 : res = numeric_stddev_internal(&numstate, variance, sample, is_null);
6206 :
6207 278 : if (numstate.sumX.ndigits > 0)
6208 : {
6209 278 : pfree(numstate.sumX.pos_digits);
6210 278 : pfree(numstate.sumX.neg_digits);
6211 : }
6212 278 : if (numstate.sumX2.ndigits > 0)
6213 : {
6214 278 : pfree(numstate.sumX2.pos_digits);
6215 278 : pfree(numstate.sumX2.neg_digits);
6216 : }
6217 :
6218 278 : return res;
6219 : }
6220 :
6221 : Datum
6222 84 : numeric_poly_var_samp(PG_FUNCTION_ARGS)
6223 : {
6224 : Int128AggState *state;
6225 : Numeric res;
6226 : bool is_null;
6227 :
6228 84 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6229 :
6230 84 : res = numeric_poly_stddev_internal(state, true, true, &is_null);
6231 :
6232 84 : if (is_null)
6233 16 : PG_RETURN_NULL();
6234 : else
6235 68 : PG_RETURN_NUMERIC(res);
6236 : }
6237 :
6238 : Datum
6239 106 : numeric_poly_stddev_samp(PG_FUNCTION_ARGS)
6240 : {
6241 : Int128AggState *state;
6242 : Numeric res;
6243 : bool is_null;
6244 :
6245 106 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6246 :
6247 106 : res = numeric_poly_stddev_internal(state, false, true, &is_null);
6248 :
6249 106 : if (is_null)
6250 16 : PG_RETURN_NULL();
6251 : else
6252 90 : PG_RETURN_NUMERIC(res);
6253 : }
6254 :
6255 : Datum
6256 40 : numeric_poly_var_pop(PG_FUNCTION_ARGS)
6257 : {
6258 : Int128AggState *state;
6259 : Numeric res;
6260 : bool is_null;
6261 :
6262 40 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6263 :
6264 40 : res = numeric_poly_stddev_internal(state, true, false, &is_null);
6265 :
6266 40 : if (is_null)
6267 0 : PG_RETURN_NULL();
6268 : else
6269 40 : PG_RETURN_NUMERIC(res);
6270 : }
6271 :
6272 : Datum
6273 48 : numeric_poly_stddev_pop(PG_FUNCTION_ARGS)
6274 : {
6275 : Int128AggState *state;
6276 : Numeric res;
6277 : bool is_null;
6278 :
6279 48 : state = PG_ARGISNULL(0) ? NULL : (Int128AggState *) PG_GETARG_POINTER(0);
6280 :
6281 48 : res = numeric_poly_stddev_internal(state, false, false, &is_null);
6282 :
6283 48 : if (is_null)
6284 0 : PG_RETURN_NULL();
6285 : else
6286 48 : PG_RETURN_NUMERIC(res);
6287 : }
6288 :
6289 : /*
6290 : * SUM transition functions for integer datatypes.
6291 : *
6292 : * To avoid overflow, we use accumulators wider than the input datatype.
6293 : * A Numeric accumulator is needed for int8 input; for int4 and int2
6294 : * inputs, we use int8 accumulators which should be sufficient for practical
6295 : * purposes. (The latter two therefore don't really belong in this file,
6296 : * but we keep them here anyway.)
6297 : *
6298 : * Because SQL defines the SUM() of no values to be NULL, not zero,
6299 : * the initial condition of the transition data value needs to be NULL. This
6300 : * means we can't rely on ExecAgg to automatically insert the first non-null
6301 : * data value into the transition data: it doesn't know how to do the type
6302 : * conversion. The upshot is that these routines have to be marked non-strict
6303 : * and handle substitution of the first non-null input themselves.
6304 : *
6305 : * Note: these functions are used only in plain aggregation mode.
6306 : * In moving-aggregate mode, we use intX_avg_accum and intX_avg_accum_inv.
6307 : */
6308 :
6309 : Datum
6310 16 : int2_sum(PG_FUNCTION_ARGS)
6311 : {
6312 : int64 oldsum;
6313 : int64 newval;
6314 :
6315 16 : if (PG_ARGISNULL(0))
6316 : {
6317 : /* No non-null input seen so far... */
6318 4 : if (PG_ARGISNULL(1))
6319 0 : PG_RETURN_NULL(); /* still no non-null */
6320 : /* This is the first non-null input. */
6321 4 : newval = (int64) PG_GETARG_INT16(1);
6322 4 : PG_RETURN_INT64(newval);
6323 : }
6324 :
6325 12 : oldsum = PG_GETARG_INT64(0);
6326 :
6327 : /* Leave sum unchanged if new input is null. */
6328 12 : if (PG_ARGISNULL(1))
6329 0 : PG_RETURN_INT64(oldsum);
6330 :
6331 : /* OK to do the addition. */
6332 12 : newval = oldsum + (int64) PG_GETARG_INT16(1);
6333 :
6334 12 : PG_RETURN_INT64(newval);
6335 : }
6336 :
6337 : Datum
6338 3267520 : int4_sum(PG_FUNCTION_ARGS)
6339 : {
6340 : int64 oldsum;
6341 : int64 newval;
6342 :
6343 3267520 : if (PG_ARGISNULL(0))
6344 : {
6345 : /* No non-null input seen so far... */
6346 129046 : if (PG_ARGISNULL(1))
6347 654 : PG_RETURN_NULL(); /* still no non-null */
6348 : /* This is the first non-null input. */
6349 128392 : newval = (int64) PG_GETARG_INT32(1);
6350 128392 : PG_RETURN_INT64(newval);
6351 : }
6352 :
6353 3138474 : oldsum = PG_GETARG_INT64(0);
6354 :
6355 : /* Leave sum unchanged if new input is null. */
6356 3138474 : if (PG_ARGISNULL(1))
6357 20606 : PG_RETURN_INT64(oldsum);
6358 :
6359 : /* OK to do the addition. */
6360 3117868 : newval = oldsum + (int64) PG_GETARG_INT32(1);
6361 :
6362 3117868 : PG_RETURN_INT64(newval);
6363 : }
6364 :
6365 : /*
6366 : * Note: this function is obsolete, it's no longer used for SUM(int8).
6367 : */
6368 : Datum
6369 0 : int8_sum(PG_FUNCTION_ARGS)
6370 : {
6371 : Numeric oldsum;
6372 :
6373 0 : if (PG_ARGISNULL(0))
6374 : {
6375 : /* No non-null input seen so far... */
6376 0 : if (PG_ARGISNULL(1))
6377 0 : PG_RETURN_NULL(); /* still no non-null */
6378 : /* This is the first non-null input. */
6379 0 : PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1)));
6380 : }
6381 :
6382 : /*
6383 : * Note that we cannot special-case the aggregate case here, as we do for
6384 : * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
6385 : * our first parameter in-place.
6386 : */
6387 :
6388 0 : oldsum = PG_GETARG_NUMERIC(0);
6389 :
6390 : /* Leave sum unchanged if new input is null. */
6391 0 : if (PG_ARGISNULL(1))
6392 0 : PG_RETURN_NUMERIC(oldsum);
6393 :
6394 : /* OK to do the addition. */
6395 0 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
6396 : NumericGetDatum(oldsum),
6397 : NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1)))));
6398 : }
6399 :
6400 :
6401 : /*
6402 : * Routines for avg(int2) and avg(int4). The transition datatype
6403 : * is a two-element int8 array, holding count and sum.
6404 : *
6405 : * These functions are also used for sum(int2) and sum(int4) when
6406 : * operating in moving-aggregate mode, since for correct inverse transitions
6407 : * we need to count the inputs.
6408 : */
6409 :
6410 : typedef struct Int8TransTypeData
6411 : {
6412 : int64 count;
6413 : int64 sum;
6414 : } Int8TransTypeData;
6415 :
6416 : Datum
6417 28 : int2_avg_accum(PG_FUNCTION_ARGS)
6418 : {
6419 : ArrayType *transarray;
6420 28 : int16 newval = PG_GETARG_INT16(1);
6421 : Int8TransTypeData *transdata;
6422 :
6423 : /*
6424 : * If we're invoked as an aggregate, we can cheat and modify our first
6425 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6426 : * a copy of it before scribbling on it.
6427 : */
6428 28 : if (AggCheckCallContext(fcinfo, NULL))
6429 28 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6430 : else
6431 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6432 :
6433 56 : if (ARR_HASNULL(transarray) ||
6434 28 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6435 0 : elog(ERROR, "expected 2-element int8 array");
6436 :
6437 28 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6438 28 : transdata->count++;
6439 28 : transdata->sum += newval;
6440 :
6441 28 : PG_RETURN_ARRAYTYPE_P(transarray);
6442 : }
6443 :
6444 : Datum
6445 1743850 : int4_avg_accum(PG_FUNCTION_ARGS)
6446 : {
6447 : ArrayType *transarray;
6448 1743850 : int32 newval = PG_GETARG_INT32(1);
6449 : Int8TransTypeData *transdata;
6450 :
6451 : /*
6452 : * If we're invoked as an aggregate, we can cheat and modify our first
6453 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6454 : * a copy of it before scribbling on it.
6455 : */
6456 1743850 : if (AggCheckCallContext(fcinfo, NULL))
6457 1743850 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6458 : else
6459 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6460 :
6461 3487700 : if (ARR_HASNULL(transarray) ||
6462 1743850 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6463 0 : elog(ERROR, "expected 2-element int8 array");
6464 :
6465 1743850 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6466 1743850 : transdata->count++;
6467 1743850 : transdata->sum += newval;
6468 :
6469 1743850 : PG_RETURN_ARRAYTYPE_P(transarray);
6470 : }
6471 :
6472 : Datum
6473 6660 : int4_avg_combine(PG_FUNCTION_ARGS)
6474 : {
6475 : ArrayType *transarray1;
6476 : ArrayType *transarray2;
6477 : Int8TransTypeData *state1;
6478 : Int8TransTypeData *state2;
6479 :
6480 6660 : if (!AggCheckCallContext(fcinfo, NULL))
6481 0 : elog(ERROR, "aggregate function called in non-aggregate context");
6482 :
6483 6660 : transarray1 = PG_GETARG_ARRAYTYPE_P(0);
6484 6660 : transarray2 = PG_GETARG_ARRAYTYPE_P(1);
6485 :
6486 13320 : if (ARR_HASNULL(transarray1) ||
6487 6660 : ARR_SIZE(transarray1) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6488 0 : elog(ERROR, "expected 2-element int8 array");
6489 :
6490 13320 : if (ARR_HASNULL(transarray2) ||
6491 6660 : ARR_SIZE(transarray2) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6492 0 : elog(ERROR, "expected 2-element int8 array");
6493 :
6494 6660 : state1 = (Int8TransTypeData *) ARR_DATA_PTR(transarray1);
6495 6660 : state2 = (Int8TransTypeData *) ARR_DATA_PTR(transarray2);
6496 :
6497 6660 : state1->count += state2->count;
6498 6660 : state1->sum += state2->sum;
6499 :
6500 6660 : PG_RETURN_ARRAYTYPE_P(transarray1);
6501 : }
6502 :
6503 : Datum
6504 8 : int2_avg_accum_inv(PG_FUNCTION_ARGS)
6505 : {
6506 : ArrayType *transarray;
6507 8 : int16 newval = PG_GETARG_INT16(1);
6508 : Int8TransTypeData *transdata;
6509 :
6510 : /*
6511 : * If we're invoked as an aggregate, we can cheat and modify our first
6512 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6513 : * a copy of it before scribbling on it.
6514 : */
6515 8 : if (AggCheckCallContext(fcinfo, NULL))
6516 8 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6517 : else
6518 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6519 :
6520 16 : if (ARR_HASNULL(transarray) ||
6521 8 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6522 0 : elog(ERROR, "expected 2-element int8 array");
6523 :
6524 8 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6525 8 : transdata->count--;
6526 8 : transdata->sum -= newval;
6527 :
6528 8 : PG_RETURN_ARRAYTYPE_P(transarray);
6529 : }
6530 :
6531 : Datum
6532 968 : int4_avg_accum_inv(PG_FUNCTION_ARGS)
6533 : {
6534 : ArrayType *transarray;
6535 968 : int32 newval = PG_GETARG_INT32(1);
6536 : Int8TransTypeData *transdata;
6537 :
6538 : /*
6539 : * If we're invoked as an aggregate, we can cheat and modify our first
6540 : * parameter in-place to reduce palloc overhead. Otherwise we need to make
6541 : * a copy of it before scribbling on it.
6542 : */
6543 968 : if (AggCheckCallContext(fcinfo, NULL))
6544 968 : transarray = PG_GETARG_ARRAYTYPE_P(0);
6545 : else
6546 0 : transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
6547 :
6548 1936 : if (ARR_HASNULL(transarray) ||
6549 968 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6550 0 : elog(ERROR, "expected 2-element int8 array");
6551 :
6552 968 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6553 968 : transdata->count--;
6554 968 : transdata->sum -= newval;
6555 :
6556 968 : PG_RETURN_ARRAYTYPE_P(transarray);
6557 : }
6558 :
6559 : Datum
6560 6817 : int8_avg(PG_FUNCTION_ARGS)
6561 : {
6562 6817 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6563 : Int8TransTypeData *transdata;
6564 : Datum countd,
6565 : sumd;
6566 :
6567 13634 : if (ARR_HASNULL(transarray) ||
6568 6817 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6569 0 : elog(ERROR, "expected 2-element int8 array");
6570 6817 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6571 :
6572 : /* SQL defines AVG of no values to be NULL */
6573 6817 : if (transdata->count == 0)
6574 73 : PG_RETURN_NULL();
6575 :
6576 6744 : countd = NumericGetDatum(int64_to_numeric(transdata->count));
6577 6744 : sumd = NumericGetDatum(int64_to_numeric(transdata->sum));
6578 :
6579 6744 : PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
6580 : }
6581 :
6582 : /*
6583 : * SUM(int2) and SUM(int4) both return int8, so we can use this
6584 : * final function for both.
6585 : */
6586 : Datum
6587 2556 : int2int4_sum(PG_FUNCTION_ARGS)
6588 : {
6589 2556 : ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
6590 : Int8TransTypeData *transdata;
6591 :
6592 5112 : if (ARR_HASNULL(transarray) ||
6593 2556 : ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
6594 0 : elog(ERROR, "expected 2-element int8 array");
6595 2556 : transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
6596 :
6597 : /* SQL defines SUM of no values to be NULL */
6598 2556 : if (transdata->count == 0)
6599 320 : PG_RETURN_NULL();
6600 :
6601 2236 : PG_RETURN_DATUM(Int64GetDatumFast(transdata->sum));
6602 : }
6603 :
6604 :
6605 : /* ----------------------------------------------------------------------
6606 : *
6607 : * Debug support
6608 : *
6609 : * ----------------------------------------------------------------------
6610 : */
6611 :
6612 : #ifdef NUMERIC_DEBUG
6613 :
6614 : /*
6615 : * dump_numeric() - Dump a value in the db storage format for debugging
6616 : */
6617 : static void
6618 : dump_numeric(const char *str, Numeric num)
6619 : {
6620 : NumericDigit *digits = NUMERIC_DIGITS(num);
6621 : int ndigits;
6622 : int i;
6623 :
6624 : ndigits = NUMERIC_NDIGITS(num);
6625 :
6626 : printf("%s: NUMERIC w=%d d=%d ", str,
6627 : NUMERIC_WEIGHT(num), NUMERIC_DSCALE(num));
6628 : switch (NUMERIC_SIGN(num))
6629 : {
6630 : case NUMERIC_POS:
6631 : printf("POS");
6632 : break;
6633 : case NUMERIC_NEG:
6634 : printf("NEG");
6635 : break;
6636 : case NUMERIC_NAN:
6637 : printf("NaN");
6638 : break;
6639 : case NUMERIC_PINF:
6640 : printf("Infinity");
6641 : break;
6642 : case NUMERIC_NINF:
6643 : printf("-Infinity");
6644 : break;
6645 : default:
6646 : printf("SIGN=0x%x", NUMERIC_SIGN(num));
6647 : break;
6648 : }
6649 :
6650 : for (i = 0; i < ndigits; i++)
6651 : printf(" %0*d", DEC_DIGITS, digits[i]);
6652 : printf("\n");
6653 : }
6654 :
6655 :
6656 : /*
6657 : * dump_var() - Dump a value in the variable format for debugging
6658 : */
6659 : static void
6660 : dump_var(const char *str, NumericVar *var)
6661 : {
6662 : int i;
6663 :
6664 : printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
6665 : switch (var->sign)
6666 : {
6667 : case NUMERIC_POS:
6668 : printf("POS");
6669 : break;
6670 : case NUMERIC_NEG:
6671 : printf("NEG");
6672 : break;
6673 : case NUMERIC_NAN:
6674 : printf("NaN");
6675 : break;
6676 : case NUMERIC_PINF:
6677 : printf("Infinity");
6678 : break;
6679 : case NUMERIC_NINF:
6680 : printf("-Infinity");
6681 : break;
6682 : default:
6683 : printf("SIGN=0x%x", var->sign);
6684 : break;
6685 : }
6686 :
6687 : for (i = 0; i < var->ndigits; i++)
6688 : printf(" %0*d", DEC_DIGITS, var->digits[i]);
6689 :
6690 : printf("\n");
6691 : }
6692 : #endif /* NUMERIC_DEBUG */
6693 :
6694 :
6695 : /* ----------------------------------------------------------------------
6696 : *
6697 : * Local functions follow
6698 : *
6699 : * In general, these do not support "special" (NaN or infinity) inputs;
6700 : * callers should handle those possibilities first.
6701 : * (There are one or two exceptions, noted in their header comments.)
6702 : *
6703 : * ----------------------------------------------------------------------
6704 : */
6705 :
6706 :
6707 : /*
6708 : * alloc_var() -
6709 : *
6710 : * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
6711 : */
6712 : static void
6713 1444700 : alloc_var(NumericVar *var, int ndigits)
6714 : {
6715 1444700 : digitbuf_free(var->buf);
6716 1444700 : var->buf = digitbuf_alloc(ndigits + 1);
6717 1444700 : var->buf[0] = 0; /* spare digit for rounding */
6718 1444700 : var->digits = var->buf + 1;
6719 1444700 : var->ndigits = ndigits;
6720 1444700 : }
6721 :
6722 :
6723 : /*
6724 : * free_var() -
6725 : *
6726 : * Return the digit buffer of a variable to the free pool
6727 : */
6728 : static void
6729 2780649 : free_var(NumericVar *var)
6730 : {
6731 2780649 : digitbuf_free(var->buf);
6732 2780649 : var->buf = NULL;
6733 2780649 : var->digits = NULL;
6734 2780649 : var->sign = NUMERIC_NAN;
6735 2780649 : }
6736 :
6737 :
6738 : /*
6739 : * zero_var() -
6740 : *
6741 : * Set a variable to ZERO.
6742 : * Note: its dscale is not touched.
6743 : */
6744 : static void
6745 37986 : zero_var(NumericVar *var)
6746 : {
6747 37986 : digitbuf_free(var->buf);
6748 37986 : var->buf = NULL;
6749 37986 : var->digits = NULL;
6750 37986 : var->ndigits = 0;
6751 37986 : var->weight = 0; /* by convention; doesn't really matter */
6752 37986 : var->sign = NUMERIC_POS; /* anything but NAN... */
6753 37986 : }
6754 :
6755 :
6756 : /*
6757 : * set_var_from_str()
6758 : *
6759 : * Parse a string and put the number into a variable
6760 : *
6761 : * This function does not handle leading or trailing spaces. It returns
6762 : * the end+1 position parsed into *endptr, so that caller can check for
6763 : * trailing spaces/garbage if deemed necessary.
6764 : *
6765 : * cp is the place to actually start parsing; str is what to use in error
6766 : * reports. (Typically cp would be the same except advanced over spaces.)
6767 : *
6768 : * Returns true on success, false on failure (if escontext points to an
6769 : * ErrorSaveContext; otherwise errors are thrown).
6770 : */
6771 : static bool
6772 118233 : set_var_from_str(const char *str, const char *cp,
6773 : NumericVar *dest, const char **endptr,
6774 : Node *escontext)
6775 : {
6776 118233 : bool have_dp = false;
6777 : int i;
6778 : unsigned char *decdigits;
6779 118233 : int sign = NUMERIC_POS;
6780 118233 : int dweight = -1;
6781 : int ddigits;
6782 118233 : int dscale = 0;
6783 : int weight;
6784 : int ndigits;
6785 : int offset;
6786 : NumericDigit *digits;
6787 :
6788 : /*
6789 : * We first parse the string to extract decimal digits and determine the
6790 : * correct decimal weight. Then convert to NBASE representation.
6791 : */
6792 118233 : switch (*cp)
6793 : {
6794 0 : case '+':
6795 0 : sign = NUMERIC_POS;
6796 0 : cp++;
6797 0 : break;
6798 :
6799 183 : case '-':
6800 183 : sign = NUMERIC_NEG;
6801 183 : cp++;
6802 183 : break;
6803 : }
6804 :
6805 118233 : if (*cp == '.')
6806 : {
6807 252 : have_dp = true;
6808 252 : cp++;
6809 : }
6810 :
6811 118233 : if (!isdigit((unsigned char) *cp))
6812 0 : goto invalid_syntax;
6813 :
6814 118233 : decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
6815 :
6816 : /* leading padding for digit alignment later */
6817 118233 : memset(decdigits, 0, DEC_DIGITS);
6818 118233 : i = DEC_DIGITS;
6819 :
6820 497694 : while (*cp)
6821 : {
6822 380443 : if (isdigit((unsigned char) *cp))
6823 : {
6824 367591 : decdigits[i++] = *cp++ - '0';
6825 367591 : if (!have_dp)
6826 311702 : dweight++;
6827 : else
6828 55889 : dscale++;
6829 : }
6830 12852 : else if (*cp == '.')
6831 : {
6832 11762 : if (have_dp)
6833 0 : goto invalid_syntax;
6834 11762 : have_dp = true;
6835 11762 : cp++;
6836 : /* decimal point must not be followed by underscore */
6837 11762 : if (*cp == '_')
6838 4 : goto invalid_syntax;
6839 : }
6840 1090 : else if (*cp == '_')
6841 : {
6842 : /* underscore must be followed by more digits */
6843 124 : cp++;
6844 124 : if (!isdigit((unsigned char) *cp))
6845 12 : goto invalid_syntax;
6846 : }
6847 : else
6848 966 : break;
6849 : }
6850 :
6851 118217 : ddigits = i - DEC_DIGITS;
6852 : /* trailing padding for digit alignment later */
6853 118217 : memset(decdigits + i, 0, DEC_DIGITS - 1);
6854 :
6855 : /* Handle exponent, if any */
6856 118217 : if (*cp == 'e' || *cp == 'E')
6857 : {
6858 934 : int64 exponent = 0;
6859 934 : bool neg = false;
6860 :
6861 : /*
6862 : * At this point, dweight and dscale can't be more than about
6863 : * INT_MAX/2 due to the MaxAllocSize limit on string length, so
6864 : * constraining the exponent similarly should be enough to prevent
6865 : * integer overflow in this function. If the value is too large to
6866 : * fit in storage format, make_result() will complain about it later;
6867 : * for consistency use the same ereport errcode/text as make_result().
6868 : */
6869 :
6870 : /* exponent sign */
6871 934 : cp++;
6872 934 : if (*cp == '+')
6873 102 : cp++;
6874 832 : else if (*cp == '-')
6875 : {
6876 400 : neg = true;
6877 400 : cp++;
6878 : }
6879 :
6880 : /* exponent digits */
6881 934 : if (!isdigit((unsigned char) *cp))
6882 4 : goto invalid_syntax;
6883 :
6884 3233 : while (*cp)
6885 : {
6886 2315 : if (isdigit((unsigned char) *cp))
6887 : {
6888 2287 : exponent = exponent * 10 + (*cp++ - '0');
6889 2287 : if (exponent > PG_INT32_MAX / 2)
6890 4 : goto out_of_range;
6891 : }
6892 28 : else if (*cp == '_')
6893 : {
6894 : /* underscore must be followed by more digits */
6895 28 : cp++;
6896 28 : if (!isdigit((unsigned char) *cp))
6897 8 : goto invalid_syntax;
6898 : }
6899 : else
6900 0 : break;
6901 : }
6902 :
6903 918 : if (neg)
6904 400 : exponent = -exponent;
6905 :
6906 918 : dweight += (int) exponent;
6907 918 : dscale -= (int) exponent;
6908 918 : if (dscale < 0)
6909 382 : dscale = 0;
6910 : }
6911 :
6912 : /*
6913 : * Okay, convert pure-decimal representation to base NBASE. First we need
6914 : * to determine the converted weight and ndigits. offset is the number of
6915 : * decimal zeroes to insert before the first given digit to have a
6916 : * correctly aligned first NBASE digit.
6917 : */
6918 118201 : if (dweight >= 0)
6919 117617 : weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
6920 : else
6921 584 : weight = -((-dweight - 1) / DEC_DIGITS + 1);
6922 118201 : offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
6923 118201 : ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
6924 :
6925 118201 : alloc_var(dest, ndigits);
6926 118201 : dest->sign = sign;
6927 118201 : dest->weight = weight;
6928 118201 : dest->dscale = dscale;
6929 :
6930 118201 : i = DEC_DIGITS - offset;
6931 118201 : digits = dest->digits;
6932 :
6933 281399 : while (ndigits-- > 0)
6934 : {
6935 : #if DEC_DIGITS == 4
6936 163198 : *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
6937 163198 : decdigits[i + 2]) * 10 + decdigits[i + 3];
6938 : #elif DEC_DIGITS == 2
6939 : *digits++ = decdigits[i] * 10 + decdigits[i + 1];
6940 : #elif DEC_DIGITS == 1
6941 : *digits++ = decdigits[i];
6942 : #else
6943 : #error unsupported NBASE
6944 : #endif
6945 163198 : i += DEC_DIGITS;
6946 : }
6947 :
6948 118201 : pfree(decdigits);
6949 :
6950 : /* Strip any leading/trailing zeroes, and normalize weight if zero */
6951 118201 : strip_var(dest);
6952 :
6953 : /* Return end+1 position for caller */
6954 118201 : *endptr = cp;
6955 :
6956 118201 : return true;
6957 :
6958 4 : out_of_range:
6959 4 : ereturn(escontext, false,
6960 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6961 : errmsg("value overflows numeric format")));
6962 :
6963 28 : invalid_syntax:
6964 28 : ereturn(escontext, false,
6965 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
6966 : errmsg("invalid input syntax for type %s: \"%s\"",
6967 : "numeric", str)));
6968 : }
6969 :
6970 :
6971 : /*
6972 : * Return the numeric value of a single hex digit.
6973 : */
6974 : static inline int
6975 472 : xdigit_value(char dig)
6976 : {
6977 596 : return dig >= '0' && dig <= '9' ? dig - '0' :
6978 196 : dig >= 'a' && dig <= 'f' ? dig - 'a' + 10 :
6979 72 : dig >= 'A' && dig <= 'F' ? dig - 'A' + 10 : -1;
6980 : }
6981 :
6982 : /*
6983 : * set_var_from_non_decimal_integer_str()
6984 : *
6985 : * Parse a string containing a non-decimal integer
6986 : *
6987 : * This function does not handle leading or trailing spaces. It returns
6988 : * the end+1 position parsed into *endptr, so that caller can check for
6989 : * trailing spaces/garbage if deemed necessary.
6990 : *
6991 : * cp is the place to actually start parsing; str is what to use in error
6992 : * reports. The number's sign and base prefix indicator (e.g., "0x") are
6993 : * assumed to have already been parsed, so cp should point to the number's
6994 : * first digit in the base specified.
6995 : *
6996 : * base is expected to be 2, 8 or 16.
6997 : *
6998 : * Returns true on success, false on failure (if escontext points to an
6999 : * ErrorSaveContext; otherwise errors are thrown).
7000 : */
7001 : static bool
7002 104 : set_var_from_non_decimal_integer_str(const char *str, const char *cp, int sign,
7003 : int base, NumericVar *dest,
7004 : const char **endptr, Node *escontext)
7005 : {
7006 104 : const char *firstdigit = cp;
7007 : int64 tmp;
7008 : int64 mul;
7009 : NumericVar tmp_var;
7010 :
7011 104 : init_var(&tmp_var);
7012 :
7013 104 : zero_var(dest);
7014 :
7015 : /*
7016 : * Process input digits in groups that fit in int64. Here "tmp" is the
7017 : * value of the digits in the group, and "mul" is base^n, where n is the
7018 : * number of digits in the group. Thus tmp < mul, and we must start a new
7019 : * group when mul * base threatens to overflow PG_INT64_MAX.
7020 : */
7021 104 : tmp = 0;
7022 104 : mul = 1;
7023 :
7024 104 : if (base == 16)
7025 : {
7026 552 : while (*cp)
7027 : {
7028 532 : if (isxdigit((unsigned char) *cp))
7029 : {
7030 472 : if (mul > PG_INT64_MAX / 16)
7031 : {
7032 : /* Add the contribution from this group of digits */
7033 20 : int64_to_numericvar(mul, &tmp_var);
7034 20 : mul_var(dest, &tmp_var, dest, 0);
7035 20 : int64_to_numericvar(tmp, &tmp_var);
7036 20 : add_var(dest, &tmp_var, dest);
7037 :
7038 : /* Result will overflow if weight overflows int16 */
7039 20 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7040 0 : goto out_of_range;
7041 :
7042 : /* Begin a new group */
7043 20 : tmp = 0;
7044 20 : mul = 1;
7045 : }
7046 :
7047 472 : tmp = tmp * 16 + xdigit_value(*cp++);
7048 472 : mul = mul * 16;
7049 : }
7050 60 : else if (*cp == '_')
7051 : {
7052 : /* Underscore must be followed by more digits */
7053 44 : cp++;
7054 44 : if (!isxdigit((unsigned char) *cp))
7055 12 : goto invalid_syntax;
7056 : }
7057 : else
7058 16 : break;
7059 : }
7060 : }
7061 56 : else if (base == 8)
7062 : {
7063 424 : while (*cp)
7064 : {
7065 404 : if (*cp >= '0' && *cp <= '7')
7066 : {
7067 372 : if (mul > PG_INT64_MAX / 8)
7068 : {
7069 : /* Add the contribution from this group of digits */
7070 12 : int64_to_numericvar(mul, &tmp_var);
7071 12 : mul_var(dest, &tmp_var, dest, 0);
7072 12 : int64_to_numericvar(tmp, &tmp_var);
7073 12 : add_var(dest, &tmp_var, dest);
7074 :
7075 : /* Result will overflow if weight overflows int16 */
7076 12 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7077 0 : goto out_of_range;
7078 :
7079 : /* Begin a new group */
7080 12 : tmp = 0;
7081 12 : mul = 1;
7082 : }
7083 :
7084 372 : tmp = tmp * 8 + (*cp++ - '0');
7085 372 : mul = mul * 8;
7086 : }
7087 32 : else if (*cp == '_')
7088 : {
7089 : /* Underscore must be followed by more digits */
7090 24 : cp++;
7091 24 : if (*cp < '0' || *cp > '7')
7092 0 : goto invalid_syntax;
7093 : }
7094 : else
7095 8 : break;
7096 : }
7097 : }
7098 28 : else if (base == 2)
7099 : {
7100 1040 : while (*cp)
7101 : {
7102 1020 : if (*cp >= '0' && *cp <= '1')
7103 : {
7104 944 : if (mul > PG_INT64_MAX / 2)
7105 : {
7106 : /* Add the contribution from this group of digits */
7107 12 : int64_to_numericvar(mul, &tmp_var);
7108 12 : mul_var(dest, &tmp_var, dest, 0);
7109 12 : int64_to_numericvar(tmp, &tmp_var);
7110 12 : add_var(dest, &tmp_var, dest);
7111 :
7112 : /* Result will overflow if weight overflows int16 */
7113 12 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7114 0 : goto out_of_range;
7115 :
7116 : /* Begin a new group */
7117 12 : tmp = 0;
7118 12 : mul = 1;
7119 : }
7120 :
7121 944 : tmp = tmp * 2 + (*cp++ - '0');
7122 944 : mul = mul * 2;
7123 : }
7124 76 : else if (*cp == '_')
7125 : {
7126 : /* Underscore must be followed by more digits */
7127 68 : cp++;
7128 68 : if (*cp < '0' || *cp > '1')
7129 0 : goto invalid_syntax;
7130 : }
7131 : else
7132 8 : break;
7133 : }
7134 : }
7135 : else
7136 : /* Should never happen; treat as invalid input */
7137 0 : goto invalid_syntax;
7138 :
7139 : /* Check that we got at least one digit */
7140 92 : if (unlikely(cp == firstdigit))
7141 0 : goto invalid_syntax;
7142 :
7143 : /* Add the contribution from the final group of digits */
7144 92 : int64_to_numericvar(mul, &tmp_var);
7145 92 : mul_var(dest, &tmp_var, dest, 0);
7146 92 : int64_to_numericvar(tmp, &tmp_var);
7147 92 : add_var(dest, &tmp_var, dest);
7148 :
7149 92 : if (dest->weight > NUMERIC_WEIGHT_MAX)
7150 0 : goto out_of_range;
7151 :
7152 92 : dest->sign = sign;
7153 :
7154 92 : free_var(&tmp_var);
7155 :
7156 : /* Return end+1 position for caller */
7157 92 : *endptr = cp;
7158 :
7159 92 : return true;
7160 :
7161 0 : out_of_range:
7162 0 : ereturn(escontext, false,
7163 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7164 : errmsg("value overflows numeric format")));
7165 :
7166 12 : invalid_syntax:
7167 12 : ereturn(escontext, false,
7168 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
7169 : errmsg("invalid input syntax for type %s: \"%s\"",
7170 : "numeric", str)));
7171 : }
7172 :
7173 :
7174 : /*
7175 : * set_var_from_num() -
7176 : *
7177 : * Convert the packed db format into a variable
7178 : */
7179 : static void
7180 8820 : set_var_from_num(Numeric num, NumericVar *dest)
7181 : {
7182 : int ndigits;
7183 :
7184 8820 : ndigits = NUMERIC_NDIGITS(num);
7185 :
7186 8820 : alloc_var(dest, ndigits);
7187 :
7188 8820 : dest->weight = NUMERIC_WEIGHT(num);
7189 8820 : dest->sign = NUMERIC_SIGN(num);
7190 8820 : dest->dscale = NUMERIC_DSCALE(num);
7191 :
7192 8820 : memcpy(dest->digits, NUMERIC_DIGITS(num), ndigits * sizeof(NumericDigit));
7193 8820 : }
7194 :
7195 :
7196 : /*
7197 : * init_var_from_num() -
7198 : *
7199 : * Initialize a variable from packed db format. The digits array is not
7200 : * copied, which saves some cycles when the resulting var is not modified.
7201 : * Also, there's no need to call free_var(), as long as you don't assign any
7202 : * other value to it (with set_var_* functions, or by using the var as the
7203 : * destination of a function like add_var())
7204 : *
7205 : * CAUTION: Do not modify the digits buffer of a var initialized with this
7206 : * function, e.g by calling round_var() or trunc_var(), as the changes will
7207 : * propagate to the original Numeric! It's OK to use it as the destination
7208 : * argument of one of the calculational functions, though.
7209 : */
7210 : static void
7211 3865801 : init_var_from_num(Numeric num, NumericVar *dest)
7212 : {
7213 3865801 : dest->ndigits = NUMERIC_NDIGITS(num);
7214 3865801 : dest->weight = NUMERIC_WEIGHT(num);
7215 3865801 : dest->sign = NUMERIC_SIGN(num);
7216 3865801 : dest->dscale = NUMERIC_DSCALE(num);
7217 3865801 : dest->digits = NUMERIC_DIGITS(num);
7218 3865801 : dest->buf = NULL; /* digits array is not palloc'd */
7219 3865801 : }
7220 :
7221 :
7222 : /*
7223 : * set_var_from_var() -
7224 : *
7225 : * Copy one variable into another
7226 : */
7227 : static void
7228 24522 : set_var_from_var(const NumericVar *value, NumericVar *dest)
7229 : {
7230 : NumericDigit *newbuf;
7231 :
7232 24522 : newbuf = digitbuf_alloc(value->ndigits + 1);
7233 24522 : newbuf[0] = 0; /* spare digit for rounding */
7234 24522 : if (value->ndigits > 0) /* else value->digits might be null */
7235 23862 : memcpy(newbuf + 1, value->digits,
7236 23862 : value->ndigits * sizeof(NumericDigit));
7237 :
7238 24522 : digitbuf_free(dest->buf);
7239 :
7240 24522 : memmove(dest, value, sizeof(NumericVar));
7241 24522 : dest->buf = newbuf;
7242 24522 : dest->digits = newbuf + 1;
7243 24522 : }
7244 :
7245 :
7246 : /*
7247 : * get_str_from_var() -
7248 : *
7249 : * Convert a var to text representation (guts of numeric_out).
7250 : * The var is displayed to the number of digits indicated by its dscale.
7251 : * Returns a palloc'd string.
7252 : */
7253 : static char *
7254 556198 : get_str_from_var(const NumericVar *var)
7255 : {
7256 : int dscale;
7257 : char *str;
7258 : char *cp;
7259 : char *endcp;
7260 : int i;
7261 : int d;
7262 : NumericDigit dig;
7263 :
7264 : #if DEC_DIGITS > 1
7265 : NumericDigit d1;
7266 : #endif
7267 :
7268 556198 : dscale = var->dscale;
7269 :
7270 : /*
7271 : * Allocate space for the result.
7272 : *
7273 : * i is set to the # of decimal digits before decimal point. dscale is the
7274 : * # of decimal digits we will print after decimal point. We may generate
7275 : * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
7276 : * need room for sign, decimal point, null terminator.
7277 : */
7278 556198 : i = (var->weight + 1) * DEC_DIGITS;
7279 556198 : if (i <= 0)
7280 72415 : i = 1;
7281 :
7282 556198 : str = palloc(i + dscale + DEC_DIGITS + 2);
7283 556198 : cp = str;
7284 :
7285 : /*
7286 : * Output a dash for negative values
7287 : */
7288 556198 : if (var->sign == NUMERIC_NEG)
7289 4120 : *cp++ = '-';
7290 :
7291 : /*
7292 : * Output all digits before the decimal point
7293 : */
7294 556198 : if (var->weight < 0)
7295 : {
7296 72415 : d = var->weight + 1;
7297 72415 : *cp++ = '0';
7298 : }
7299 : else
7300 : {
7301 1028306 : for (d = 0; d <= var->weight; d++)
7302 : {
7303 544523 : dig = (d < var->ndigits) ? var->digits[d] : 0;
7304 : /* In the first digit, suppress extra leading decimal zeroes */
7305 : #if DEC_DIGITS == 4
7306 : {
7307 544523 : bool putit = (d > 0);
7308 :
7309 544523 : d1 = dig / 1000;
7310 544523 : dig -= d1 * 1000;
7311 544523 : putit |= (d1 > 0);
7312 544523 : if (putit)
7313 101132 : *cp++ = d1 + '0';
7314 544523 : d1 = dig / 100;
7315 544523 : dig -= d1 * 100;
7316 544523 : putit |= (d1 > 0);
7317 544523 : if (putit)
7318 373774 : *cp++ = d1 + '0';
7319 544523 : d1 = dig / 10;
7320 544523 : dig -= d1 * 10;
7321 544523 : putit |= (d1 > 0);
7322 544523 : if (putit)
7323 456878 : *cp++ = d1 + '0';
7324 544523 : *cp++ = dig + '0';
7325 : }
7326 : #elif DEC_DIGITS == 2
7327 : d1 = dig / 10;
7328 : dig -= d1 * 10;
7329 : if (d1 > 0 || d > 0)
7330 : *cp++ = d1 + '0';
7331 : *cp++ = dig + '0';
7332 : #elif DEC_DIGITS == 1
7333 : *cp++ = dig + '0';
7334 : #else
7335 : #error unsupported NBASE
7336 : #endif
7337 : }
7338 : }
7339 :
7340 : /*
7341 : * If requested, output a decimal point and all the digits that follow it.
7342 : * We initially put out a multiple of DEC_DIGITS digits, then truncate if
7343 : * needed.
7344 : */
7345 556198 : if (dscale > 0)
7346 : {
7347 409296 : *cp++ = '.';
7348 409296 : endcp = cp + dscale;
7349 1148221 : for (i = 0; i < dscale; d++, i += DEC_DIGITS)
7350 : {
7351 738925 : dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
7352 : #if DEC_DIGITS == 4
7353 738925 : d1 = dig / 1000;
7354 738925 : dig -= d1 * 1000;
7355 738925 : *cp++ = d1 + '0';
7356 738925 : d1 = dig / 100;
7357 738925 : dig -= d1 * 100;
7358 738925 : *cp++ = d1 + '0';
7359 738925 : d1 = dig / 10;
7360 738925 : dig -= d1 * 10;
7361 738925 : *cp++ = d1 + '0';
7362 738925 : *cp++ = dig + '0';
7363 : #elif DEC_DIGITS == 2
7364 : d1 = dig / 10;
7365 : dig -= d1 * 10;
7366 : *cp++ = d1 + '0';
7367 : *cp++ = dig + '0';
7368 : #elif DEC_DIGITS == 1
7369 : *cp++ = dig + '0';
7370 : #else
7371 : #error unsupported NBASE
7372 : #endif
7373 : }
7374 409296 : cp = endcp;
7375 : }
7376 :
7377 : /*
7378 : * terminate the string and return it
7379 : */
7380 556198 : *cp = '\0';
7381 556198 : return str;
7382 : }
7383 :
7384 : /*
7385 : * get_str_from_var_sci() -
7386 : *
7387 : * Convert a var to a normalised scientific notation text representation.
7388 : * This function does the heavy lifting for numeric_out_sci().
7389 : *
7390 : * This notation has the general form a * 10^b, where a is known as the
7391 : * "significand" and b is known as the "exponent".
7392 : *
7393 : * Because we can't do superscript in ASCII (and because we want to copy
7394 : * printf's behaviour) we display the exponent using E notation, with a
7395 : * minimum of two exponent digits.
7396 : *
7397 : * For example, the value 1234 could be output as 1.2e+03.
7398 : *
7399 : * We assume that the exponent can fit into an int32.
7400 : *
7401 : * rscale is the number of decimal digits desired after the decimal point in
7402 : * the output, negative values will be treated as meaning zero.
7403 : *
7404 : * Returns a palloc'd string.
7405 : */
7406 : static char *
7407 152 : get_str_from_var_sci(const NumericVar *var, int rscale)
7408 : {
7409 : int32 exponent;
7410 : NumericVar tmp_var;
7411 : size_t len;
7412 : char *str;
7413 : char *sig_out;
7414 :
7415 152 : if (rscale < 0)
7416 0 : rscale = 0;
7417 :
7418 : /*
7419 : * Determine the exponent of this number in normalised form.
7420 : *
7421 : * This is the exponent required to represent the number with only one
7422 : * significant digit before the decimal place.
7423 : */
7424 152 : if (var->ndigits > 0)
7425 : {
7426 140 : exponent = (var->weight + 1) * DEC_DIGITS;
7427 :
7428 : /*
7429 : * Compensate for leading decimal zeroes in the first numeric digit by
7430 : * decrementing the exponent.
7431 : */
7432 140 : exponent -= DEC_DIGITS - (int) log10(var->digits[0]);
7433 : }
7434 : else
7435 : {
7436 : /*
7437 : * If var has no digits, then it must be zero.
7438 : *
7439 : * Zero doesn't technically have a meaningful exponent in normalised
7440 : * notation, but we just display the exponent as zero for consistency
7441 : * of output.
7442 : */
7443 12 : exponent = 0;
7444 : }
7445 :
7446 : /*
7447 : * Divide var by 10^exponent to get the significand, rounding to rscale
7448 : * decimal digits in the process.
7449 : */
7450 152 : init_var(&tmp_var);
7451 :
7452 152 : power_ten_int(exponent, &tmp_var);
7453 152 : div_var(var, &tmp_var, &tmp_var, rscale, true, true);
7454 152 : sig_out = get_str_from_var(&tmp_var);
7455 :
7456 152 : free_var(&tmp_var);
7457 :
7458 : /*
7459 : * Allocate space for the result.
7460 : *
7461 : * In addition to the significand, we need room for the exponent
7462 : * decoration ("e"), the sign of the exponent, up to 10 digits for the
7463 : * exponent itself, and of course the null terminator.
7464 : */
7465 152 : len = strlen(sig_out) + 13;
7466 152 : str = palloc(len);
7467 152 : snprintf(str, len, "%se%+03d", sig_out, exponent);
7468 :
7469 152 : pfree(sig_out);
7470 :
7471 152 : return str;
7472 : }
7473 :
7474 :
7475 : /*
7476 : * numericvar_serialize - serialize NumericVar to binary format
7477 : *
7478 : * At variable level, no checks are performed on the weight or dscale, allowing
7479 : * us to pass around intermediate values with higher precision than supported
7480 : * by the numeric type. Note: this is incompatible with numeric_send/recv(),
7481 : * which use 16-bit integers for these fields.
7482 : */
7483 : static void
7484 61 : numericvar_serialize(StringInfo buf, const NumericVar *var)
7485 : {
7486 : int i;
7487 :
7488 61 : pq_sendint32(buf, var->ndigits);
7489 61 : pq_sendint32(buf, var->weight);
7490 61 : pq_sendint32(buf, var->sign);
7491 61 : pq_sendint32(buf, var->dscale);
7492 425165 : for (i = 0; i < var->ndigits; i++)
7493 425104 : pq_sendint16(buf, var->digits[i]);
7494 61 : }
7495 :
7496 : /*
7497 : * numericvar_deserialize - deserialize binary format to NumericVar
7498 : */
7499 : static void
7500 61 : numericvar_deserialize(StringInfo buf, NumericVar *var)
7501 : {
7502 : int len,
7503 : i;
7504 :
7505 61 : len = pq_getmsgint(buf, sizeof(int32));
7506 :
7507 61 : alloc_var(var, len); /* sets var->ndigits */
7508 :
7509 61 : var->weight = pq_getmsgint(buf, sizeof(int32));
7510 61 : var->sign = pq_getmsgint(buf, sizeof(int32));
7511 61 : var->dscale = pq_getmsgint(buf, sizeof(int32));
7512 425165 : for (i = 0; i < len; i++)
7513 425104 : var->digits[i] = pq_getmsgint(buf, sizeof(int16));
7514 61 : }
7515 :
7516 :
7517 : /*
7518 : * duplicate_numeric() - copy a packed-format Numeric
7519 : *
7520 : * This will handle NaN and Infinity cases.
7521 : */
7522 : static Numeric
7523 18817 : duplicate_numeric(Numeric num)
7524 : {
7525 : Numeric res;
7526 :
7527 18817 : res = (Numeric) palloc(VARSIZE(num));
7528 18817 : memcpy(res, num, VARSIZE(num));
7529 18817 : return res;
7530 : }
7531 :
7532 : /*
7533 : * make_result_safe() -
7534 : *
7535 : * Create the packed db numeric format in palloc()'d memory from
7536 : * a variable. This will handle NaN and Infinity cases.
7537 : */
7538 : static Numeric
7539 2526119 : make_result_safe(const NumericVar *var, Node *escontext)
7540 : {
7541 : Numeric result;
7542 2526119 : NumericDigit *digits = var->digits;
7543 2526119 : int weight = var->weight;
7544 2526119 : int sign = var->sign;
7545 : int n;
7546 : Size len;
7547 :
7548 2526119 : if ((sign & NUMERIC_SIGN_MASK) == NUMERIC_SPECIAL)
7549 : {
7550 : /*
7551 : * Verify valid special value. This could be just an Assert, perhaps,
7552 : * but it seems worthwhile to expend a few cycles to ensure that we
7553 : * never write any nonzero reserved bits to disk.
7554 : */
7555 2205 : if (!(sign == NUMERIC_NAN ||
7556 : sign == NUMERIC_PINF ||
7557 : sign == NUMERIC_NINF))
7558 0 : elog(ERROR, "invalid numeric sign value 0x%x", sign);
7559 :
7560 2205 : result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT);
7561 :
7562 2205 : SET_VARSIZE(result, NUMERIC_HDRSZ_SHORT);
7563 2205 : result->choice.n_header = sign;
7564 : /* the header word is all we need */
7565 :
7566 : dump_numeric("make_result()", result);
7567 2205 : return result;
7568 : }
7569 :
7570 2523914 : n = var->ndigits;
7571 :
7572 : /* truncate leading zeroes */
7573 2523944 : while (n > 0 && *digits == 0)
7574 : {
7575 30 : digits++;
7576 30 : weight--;
7577 30 : n--;
7578 : }
7579 : /* truncate trailing zeroes */
7580 2576040 : while (n > 0 && digits[n - 1] == 0)
7581 52126 : n--;
7582 :
7583 : /* If zero result, force to weight=0 and positive sign */
7584 2523914 : if (n == 0)
7585 : {
7586 83969 : weight = 0;
7587 83969 : sign = NUMERIC_POS;
7588 : }
7589 :
7590 : /* Build the result */
7591 2523914 : if (NUMERIC_CAN_BE_SHORT(var->dscale, weight))
7592 : {
7593 2522024 : len = NUMERIC_HDRSZ_SHORT + n * sizeof(NumericDigit);
7594 2522024 : result = (Numeric) palloc(len);
7595 2522024 : SET_VARSIZE(result, len);
7596 2522024 : result->choice.n_short.n_header =
7597 : (sign == NUMERIC_NEG ? (NUMERIC_SHORT | NUMERIC_SHORT_SIGN_MASK)
7598 : : NUMERIC_SHORT)
7599 2522024 : | (var->dscale << NUMERIC_SHORT_DSCALE_SHIFT)
7600 2522024 : | (weight < 0 ? NUMERIC_SHORT_WEIGHT_SIGN_MASK : 0)
7601 2522024 : | (weight & NUMERIC_SHORT_WEIGHT_MASK);
7602 : }
7603 : else
7604 : {
7605 1890 : len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
7606 1890 : result = (Numeric) palloc(len);
7607 1890 : SET_VARSIZE(result, len);
7608 1890 : result->choice.n_long.n_sign_dscale =
7609 1890 : sign | (var->dscale & NUMERIC_DSCALE_MASK);
7610 1890 : result->choice.n_long.n_weight = weight;
7611 : }
7612 :
7613 : Assert(NUMERIC_NDIGITS(result) == n);
7614 2523914 : if (n > 0)
7615 2439945 : memcpy(NUMERIC_DIGITS(result), digits, n * sizeof(NumericDigit));
7616 :
7617 : /* Check for overflow of int16 fields */
7618 2523914 : if (NUMERIC_WEIGHT(result) != weight ||
7619 2523894 : NUMERIC_DSCALE(result) != var->dscale)
7620 20 : ereturn(escontext, NULL,
7621 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7622 : errmsg("value overflows numeric format")));
7623 :
7624 : dump_numeric("make_result()", result);
7625 2523894 : return result;
7626 : }
7627 :
7628 :
7629 : /*
7630 : * make_result() -
7631 : *
7632 : * An interface to make_result_safe() without "escontext" argument.
7633 : */
7634 : static Numeric
7635 1504941 : make_result(const NumericVar *var)
7636 : {
7637 1504941 : return make_result_safe(var, NULL);
7638 : }
7639 :
7640 :
7641 : /*
7642 : * apply_typmod() -
7643 : *
7644 : * Do bounds checking and rounding according to the specified typmod.
7645 : * Note that this is only applied to normal finite values.
7646 : *
7647 : * Returns true on success, false on failure (if escontext points to an
7648 : * ErrorSaveContext; otherwise errors are thrown).
7649 : */
7650 : static bool
7651 105575 : apply_typmod(NumericVar *var, int32 typmod, Node *escontext)
7652 : {
7653 : int precision;
7654 : int scale;
7655 : int maxdigits;
7656 : int ddigits;
7657 : int i;
7658 :
7659 : /* Do nothing if we have an invalid typmod */
7660 105575 : if (!is_valid_numeric_typmod(typmod))
7661 86074 : return true;
7662 :
7663 19501 : precision = numeric_typmod_precision(typmod);
7664 19501 : scale = numeric_typmod_scale(typmod);
7665 19501 : maxdigits = precision - scale;
7666 :
7667 : /* Round to target scale (and set var->dscale) */
7668 19501 : round_var(var, scale);
7669 :
7670 : /* but don't allow var->dscale to be negative */
7671 19501 : if (var->dscale < 0)
7672 100 : var->dscale = 0;
7673 :
7674 : /*
7675 : * Check for overflow - note we can't do this before rounding, because
7676 : * rounding could raise the weight. Also note that the var's weight could
7677 : * be inflated by leading zeroes, which will be stripped before storage
7678 : * but perhaps might not have been yet. In any case, we must recognize a
7679 : * true zero, whose weight doesn't mean anything.
7680 : */
7681 19501 : ddigits = (var->weight + 1) * DEC_DIGITS;
7682 19501 : if (ddigits > maxdigits)
7683 : {
7684 : /* Determine true weight; and check for all-zero result */
7685 4289 : for (i = 0; i < var->ndigits; i++)
7686 : {
7687 4278 : NumericDigit dig = var->digits[i];
7688 :
7689 4278 : if (dig)
7690 : {
7691 : /* Adjust for any high-order decimal zero digits */
7692 : #if DEC_DIGITS == 4
7693 4278 : if (dig < 10)
7694 206 : ddigits -= 3;
7695 4072 : else if (dig < 100)
7696 420 : ddigits -= 2;
7697 3652 : else if (dig < 1000)
7698 3640 : ddigits -= 1;
7699 : #elif DEC_DIGITS == 2
7700 : if (dig < 10)
7701 : ddigits -= 1;
7702 : #elif DEC_DIGITS == 1
7703 : /* no adjustment */
7704 : #else
7705 : #error unsupported NBASE
7706 : #endif
7707 4278 : if (ddigits > maxdigits)
7708 56 : ereturn(escontext, false,
7709 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7710 : errmsg("numeric field overflow"),
7711 : errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
7712 : precision, scale,
7713 : /* Display 10^0 as 1 */
7714 : maxdigits ? "10^" : "",
7715 : maxdigits ? maxdigits : 1
7716 : )));
7717 4222 : break;
7718 : }
7719 0 : ddigits -= DEC_DIGITS;
7720 : }
7721 : }
7722 :
7723 19445 : return true;
7724 : }
7725 :
7726 : /*
7727 : * apply_typmod_special() -
7728 : *
7729 : * Do bounds checking according to the specified typmod, for an Inf or NaN.
7730 : * For convenience of most callers, the value is presented in packed form.
7731 : *
7732 : * Returns true on success, false on failure (if escontext points to an
7733 : * ErrorSaveContext; otherwise errors are thrown).
7734 : */
7735 : static bool
7736 1297 : apply_typmod_special(Numeric num, int32 typmod, Node *escontext)
7737 : {
7738 : int precision;
7739 : int scale;
7740 :
7741 : Assert(NUMERIC_IS_SPECIAL(num)); /* caller error if not */
7742 :
7743 : /*
7744 : * NaN is allowed regardless of the typmod; that's rather dubious perhaps,
7745 : * but it's a longstanding behavior. Inf is rejected if we have any
7746 : * typmod restriction, since an infinity shouldn't be claimed to fit in
7747 : * any finite number of digits.
7748 : */
7749 1297 : if (NUMERIC_IS_NAN(num))
7750 556 : return true;
7751 :
7752 : /* Do nothing if we have a default typmod (-1) */
7753 741 : if (!is_valid_numeric_typmod(typmod))
7754 729 : return true;
7755 :
7756 12 : precision = numeric_typmod_precision(typmod);
7757 12 : scale = numeric_typmod_scale(typmod);
7758 :
7759 12 : ereturn(escontext, false,
7760 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
7761 : errmsg("numeric field overflow"),
7762 : errdetail("A field with precision %d, scale %d cannot hold an infinite value.",
7763 : precision, scale)));
7764 : }
7765 :
7766 :
7767 : /*
7768 : * Convert numeric to int8, rounding if needed.
7769 : *
7770 : * If overflow, return false (no error is raised). Return true if okay.
7771 : */
7772 : static bool
7773 6603 : numericvar_to_int64(const NumericVar *var, int64 *result)
7774 : {
7775 : NumericDigit *digits;
7776 : int ndigits;
7777 : int weight;
7778 : int i;
7779 : int64 val;
7780 : bool neg;
7781 : NumericVar rounded;
7782 :
7783 : /* Round to nearest integer */
7784 6603 : init_var(&rounded);
7785 6603 : set_var_from_var(var, &rounded);
7786 6603 : round_var(&rounded, 0);
7787 :
7788 : /* Check for zero input */
7789 6603 : strip_var(&rounded);
7790 6603 : ndigits = rounded.ndigits;
7791 6603 : if (ndigits == 0)
7792 : {
7793 332 : *result = 0;
7794 332 : free_var(&rounded);
7795 332 : return true;
7796 : }
7797 :
7798 : /*
7799 : * For input like 10000000000, we must treat stripped digits as real. So
7800 : * the loop assumes there are weight+1 digits before the decimal point.
7801 : */
7802 6271 : weight = rounded.weight;
7803 : Assert(weight >= 0 && ndigits <= weight + 1);
7804 :
7805 : /*
7806 : * Construct the result. To avoid issues with converting a value
7807 : * corresponding to INT64_MIN (which can't be represented as a positive 64
7808 : * bit two's complement integer), accumulate value as a negative number.
7809 : */
7810 6271 : digits = rounded.digits;
7811 6271 : neg = (rounded.sign == NUMERIC_NEG);
7812 6271 : val = -digits[0];
7813 8732 : for (i = 1; i <= weight; i++)
7814 : {
7815 2494 : if (unlikely(pg_mul_s64_overflow(val, NBASE, &val)))
7816 : {
7817 21 : free_var(&rounded);
7818 21 : return false;
7819 : }
7820 :
7821 2473 : if (i < ndigits)
7822 : {
7823 2268 : if (unlikely(pg_sub_s64_overflow(val, digits[i], &val)))
7824 : {
7825 12 : free_var(&rounded);
7826 12 : return false;
7827 : }
7828 : }
7829 : }
7830 :
7831 6238 : free_var(&rounded);
7832 :
7833 6238 : if (!neg)
7834 : {
7835 5696 : if (unlikely(val == PG_INT64_MIN))
7836 16 : return false;
7837 5680 : val = -val;
7838 : }
7839 6222 : *result = val;
7840 :
7841 6222 : return true;
7842 : }
7843 :
7844 : /*
7845 : * Convert int8 value to numeric.
7846 : */
7847 : static void
7848 1262191 : int64_to_numericvar(int64 val, NumericVar *var)
7849 : {
7850 : uint64 uval,
7851 : newuval;
7852 : NumericDigit *ptr;
7853 : int ndigits;
7854 :
7855 : /* int64 can require at most 19 decimal digits; add one for safety */
7856 1262191 : alloc_var(var, 20 / DEC_DIGITS);
7857 1262191 : if (val < 0)
7858 : {
7859 1263 : var->sign = NUMERIC_NEG;
7860 1263 : uval = pg_abs_s64(val);
7861 : }
7862 : else
7863 : {
7864 1260928 : var->sign = NUMERIC_POS;
7865 1260928 : uval = val;
7866 : }
7867 1262191 : var->dscale = 0;
7868 1262191 : if (val == 0)
7869 : {
7870 19316 : var->ndigits = 0;
7871 19316 : var->weight = 0;
7872 19316 : return;
7873 : }
7874 1242875 : ptr = var->digits + var->ndigits;
7875 1242875 : ndigits = 0;
7876 : do
7877 : {
7878 1440325 : ptr--;
7879 1440325 : ndigits++;
7880 1440325 : newuval = uval / NBASE;
7881 1440325 : *ptr = uval - newuval * NBASE;
7882 1440325 : uval = newuval;
7883 1440325 : } while (uval);
7884 1242875 : var->digits = ptr;
7885 1242875 : var->ndigits = ndigits;
7886 1242875 : var->weight = ndigits - 1;
7887 : }
7888 :
7889 : /*
7890 : * Convert numeric to uint64, rounding if needed.
7891 : *
7892 : * If overflow, return false (no error is raised). Return true if okay.
7893 : */
7894 : static bool
7895 94 : numericvar_to_uint64(const NumericVar *var, uint64 *result)
7896 : {
7897 : NumericDigit *digits;
7898 : int ndigits;
7899 : int weight;
7900 : int i;
7901 : uint64 val;
7902 : NumericVar rounded;
7903 :
7904 : /* Round to nearest integer */
7905 94 : init_var(&rounded);
7906 94 : set_var_from_var(var, &rounded);
7907 94 : round_var(&rounded, 0);
7908 :
7909 : /* Check for zero input */
7910 94 : strip_var(&rounded);
7911 94 : ndigits = rounded.ndigits;
7912 94 : if (ndigits == 0)
7913 : {
7914 15 : *result = 0;
7915 15 : free_var(&rounded);
7916 15 : return true;
7917 : }
7918 :
7919 : /* Check for negative input */
7920 79 : if (rounded.sign == NUMERIC_NEG)
7921 : {
7922 8 : free_var(&rounded);
7923 8 : return false;
7924 : }
7925 :
7926 : /*
7927 : * For input like 10000000000, we must treat stripped digits as real. So
7928 : * the loop assumes there are weight+1 digits before the decimal point.
7929 : */
7930 71 : weight = rounded.weight;
7931 : Assert(weight >= 0 && ndigits <= weight + 1);
7932 :
7933 : /* Construct the result */
7934 71 : digits = rounded.digits;
7935 71 : val = digits[0];
7936 205 : for (i = 1; i <= weight; i++)
7937 : {
7938 142 : if (unlikely(pg_mul_u64_overflow(val, NBASE, &val)))
7939 : {
7940 0 : free_var(&rounded);
7941 0 : return false;
7942 : }
7943 :
7944 142 : if (i < ndigits)
7945 : {
7946 142 : if (unlikely(pg_add_u64_overflow(val, digits[i], &val)))
7947 : {
7948 8 : free_var(&rounded);
7949 8 : return false;
7950 : }
7951 : }
7952 : }
7953 :
7954 63 : free_var(&rounded);
7955 :
7956 63 : *result = val;
7957 :
7958 63 : return true;
7959 : }
7960 :
7961 : /*
7962 : * Convert 128 bit integer to numeric.
7963 : */
7964 : static void
7965 6293 : int128_to_numericvar(INT128 val, NumericVar *var)
7966 : {
7967 : int sign;
7968 : NumericDigit *ptr;
7969 : int ndigits;
7970 : int32 dig;
7971 :
7972 : /* int128 can require at most 39 decimal digits; add one for safety */
7973 6293 : alloc_var(var, 40 / DEC_DIGITS);
7974 6293 : sign = int128_sign(val);
7975 6293 : var->sign = sign < 0 ? NUMERIC_NEG : NUMERIC_POS;
7976 6293 : var->dscale = 0;
7977 6293 : if (sign == 0)
7978 : {
7979 143 : var->ndigits = 0;
7980 143 : var->weight = 0;
7981 143 : return;
7982 : }
7983 6150 : ptr = var->digits + var->ndigits;
7984 6150 : ndigits = 0;
7985 : do
7986 : {
7987 33056 : ptr--;
7988 33056 : ndigits++;
7989 33056 : int128_div_mod_int32(&val, NBASE, &dig);
7990 33056 : *ptr = (NumericDigit) abs(dig);
7991 33056 : } while (!int128_is_zero(val));
7992 6150 : var->digits = ptr;
7993 6150 : var->ndigits = ndigits;
7994 6150 : var->weight = ndigits - 1;
7995 : }
7996 :
7997 : /*
7998 : * Convert a NumericVar to float8; if out of range, return +/- HUGE_VAL
7999 : */
8000 : static double
8001 359 : numericvar_to_double_no_overflow(const NumericVar *var)
8002 : {
8003 : char *tmp;
8004 : double val;
8005 : char *endptr;
8006 :
8007 359 : tmp = get_str_from_var(var);
8008 :
8009 : /* unlike float8in, we ignore ERANGE from strtod */
8010 359 : val = strtod(tmp, &endptr);
8011 359 : if (*endptr != '\0')
8012 : {
8013 : /* shouldn't happen ... */
8014 0 : ereport(ERROR,
8015 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
8016 : errmsg("invalid input syntax for type %s: \"%s\"",
8017 : "double precision", tmp)));
8018 : }
8019 :
8020 359 : pfree(tmp);
8021 :
8022 359 : return val;
8023 : }
8024 :
8025 :
8026 : /*
8027 : * cmp_var() -
8028 : *
8029 : * Compare two values on variable level. We assume zeroes have been
8030 : * truncated to no digits.
8031 : */
8032 : static int
8033 114439 : cmp_var(const NumericVar *var1, const NumericVar *var2)
8034 : {
8035 228878 : return cmp_var_common(var1->digits, var1->ndigits,
8036 114439 : var1->weight, var1->sign,
8037 114439 : var2->digits, var2->ndigits,
8038 114439 : var2->weight, var2->sign);
8039 : }
8040 :
8041 : /*
8042 : * cmp_var_common() -
8043 : *
8044 : * Main routine of cmp_var(). This function can be used by both
8045 : * NumericVar and Numeric.
8046 : */
8047 : static int
8048 18496004 : cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
8049 : int var1weight, int var1sign,
8050 : const NumericDigit *var2digits, int var2ndigits,
8051 : int var2weight, int var2sign)
8052 : {
8053 18496004 : if (var1ndigits == 0)
8054 : {
8055 425935 : if (var2ndigits == 0)
8056 333902 : return 0;
8057 92033 : if (var2sign == NUMERIC_NEG)
8058 2178 : return 1;
8059 89855 : return -1;
8060 : }
8061 18070069 : if (var2ndigits == 0)
8062 : {
8063 66397 : if (var1sign == NUMERIC_POS)
8064 62662 : return 1;
8065 3735 : return -1;
8066 : }
8067 :
8068 18003672 : if (var1sign == NUMERIC_POS)
8069 : {
8070 17954501 : if (var2sign == NUMERIC_NEG)
8071 14477 : return 1;
8072 17940024 : return cmp_abs_common(var1digits, var1ndigits, var1weight,
8073 : var2digits, var2ndigits, var2weight);
8074 : }
8075 :
8076 49171 : if (var2sign == NUMERIC_POS)
8077 14754 : return -1;
8078 :
8079 34417 : return cmp_abs_common(var2digits, var2ndigits, var2weight,
8080 : var1digits, var1ndigits, var1weight);
8081 : }
8082 :
8083 :
8084 : /*
8085 : * add_var() -
8086 : *
8087 : * Full version of add functionality on variable level (handling signs).
8088 : * result might point to one of the operands too without danger.
8089 : */
8090 : static void
8091 414476 : add_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8092 : {
8093 : /*
8094 : * Decide on the signs of the two variables what to do
8095 : */
8096 414476 : if (var1->sign == NUMERIC_POS)
8097 : {
8098 413221 : if (var2->sign == NUMERIC_POS)
8099 : {
8100 : /*
8101 : * Both are positive result = +(ABS(var1) + ABS(var2))
8102 : */
8103 279626 : add_abs(var1, var2, result);
8104 279626 : result->sign = NUMERIC_POS;
8105 : }
8106 : else
8107 : {
8108 : /*
8109 : * var1 is positive, var2 is negative Must compare absolute values
8110 : */
8111 133595 : switch (cmp_abs(var1, var2))
8112 : {
8113 123 : case 0:
8114 : /* ----------
8115 : * ABS(var1) == ABS(var2)
8116 : * result = ZERO
8117 : * ----------
8118 : */
8119 123 : zero_var(result);
8120 123 : result->dscale = Max(var1->dscale, var2->dscale);
8121 123 : break;
8122 :
8123 124291 : case 1:
8124 : /* ----------
8125 : * ABS(var1) > ABS(var2)
8126 : * result = +(ABS(var1) - ABS(var2))
8127 : * ----------
8128 : */
8129 124291 : sub_abs(var1, var2, result);
8130 124291 : result->sign = NUMERIC_POS;
8131 124291 : break;
8132 :
8133 9181 : case -1:
8134 : /* ----------
8135 : * ABS(var1) < ABS(var2)
8136 : * result = -(ABS(var2) - ABS(var1))
8137 : * ----------
8138 : */
8139 9181 : sub_abs(var2, var1, result);
8140 9181 : result->sign = NUMERIC_NEG;
8141 9181 : break;
8142 : }
8143 : }
8144 : }
8145 : else
8146 : {
8147 1255 : if (var2->sign == NUMERIC_POS)
8148 : {
8149 : /* ----------
8150 : * var1 is negative, var2 is positive
8151 : * Must compare absolute values
8152 : * ----------
8153 : */
8154 318 : switch (cmp_abs(var1, var2))
8155 : {
8156 20 : case 0:
8157 : /* ----------
8158 : * ABS(var1) == ABS(var2)
8159 : * result = ZERO
8160 : * ----------
8161 : */
8162 20 : zero_var(result);
8163 20 : result->dscale = Max(var1->dscale, var2->dscale);
8164 20 : break;
8165 :
8166 197 : case 1:
8167 : /* ----------
8168 : * ABS(var1) > ABS(var2)
8169 : * result = -(ABS(var1) - ABS(var2))
8170 : * ----------
8171 : */
8172 197 : sub_abs(var1, var2, result);
8173 197 : result->sign = NUMERIC_NEG;
8174 197 : break;
8175 :
8176 101 : case -1:
8177 : /* ----------
8178 : * ABS(var1) < ABS(var2)
8179 : * result = +(ABS(var2) - ABS(var1))
8180 : * ----------
8181 : */
8182 101 : sub_abs(var2, var1, result);
8183 101 : result->sign = NUMERIC_POS;
8184 101 : break;
8185 : }
8186 : }
8187 : else
8188 : {
8189 : /* ----------
8190 : * Both are negative
8191 : * result = -(ABS(var1) + ABS(var2))
8192 : * ----------
8193 : */
8194 937 : add_abs(var1, var2, result);
8195 937 : result->sign = NUMERIC_NEG;
8196 : }
8197 : }
8198 414476 : }
8199 :
8200 :
8201 : /*
8202 : * sub_var() -
8203 : *
8204 : * Full version of sub functionality on variable level (handling signs).
8205 : * result might point to one of the operands too without danger.
8206 : */
8207 : static void
8208 351114 : sub_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
8209 : {
8210 : /*
8211 : * Decide on the signs of the two variables what to do
8212 : */
8213 351114 : if (var1->sign == NUMERIC_POS)
8214 : {
8215 350505 : if (var2->sign == NUMERIC_NEG)
8216 : {
8217 : /* ----------
8218 : * var1 is positive, var2 is negative
8219 : * result = +(ABS(var1) + ABS(var2))
8220 : * ----------
8221 : */
8222 18797 : add_abs(var1, var2, result);
8223 18797 : result->sign = NUMERIC_POS;
8224 : }
8225 : else
8226 : {
8227 : /* ----------
8228 : * Both are positive
8229 : * Must compare absolute values
8230 : * ----------
8231 : */
8232 331708 : switch (cmp_abs(var1, var2))
8233 : {
8234 29543 : case 0:
8235 : /* ----------
8236 : * ABS(var1) == ABS(var2)
8237 : * result = ZERO
8238 : * ----------
8239 : */
8240 29543 : zero_var(result);
8241 29543 : result->dscale = Max(var1->dscale, var2->dscale);
8242 29543 : break;
8243 :
8244 294372 : case 1:
8245 : /* ----------
8246 : * ABS(var1) > ABS(var2)
8247 : * result = +(ABS(var1) - ABS(var2))
8248 : * ----------
8249 : */
8250 294372 : sub_abs(var1, var2, result);
8251 294372 : result->sign = NUMERIC_POS;
8252 294372 : break;
8253 :
8254 7793 : case -1:
8255 : /* ----------
8256 : * ABS(var1) < ABS(var2)
8257 : * result = -(ABS(var2) - ABS(var1))
8258 : * ----------
8259 : */
8260 7793 : sub_abs(var2, var1, result);
8261 7793 : result->sign = NUMERIC_NEG;
8262 7793 : break;
8263 : }
8264 : }
8265 : }
8266 : else
8267 : {
8268 609 : if (var2->sign == NUMERIC_NEG)
8269 : {
8270 : /* ----------
8271 : * Both are negative
8272 : * Must compare absolute values
8273 : * ----------
8274 : */
8275 304 : switch (cmp_abs(var1, var2))
8276 : {
8277 110 : case 0:
8278 : /* ----------
8279 : * ABS(var1) == ABS(var2)
8280 : * result = ZERO
8281 : * ----------
8282 : */
8283 110 : zero_var(result);
8284 110 : result->dscale = Max(var1->dscale, var2->dscale);
8285 110 : break;
8286 :
8287 162 : case 1:
8288 : /* ----------
8289 : * ABS(var1) > ABS(var2)
8290 : * result = -(ABS(var1) - ABS(var2))
8291 : * ----------
8292 : */
8293 162 : sub_abs(var1, var2, result);
8294 162 : result->sign = NUMERIC_NEG;
8295 162 : break;
8296 :
8297 32 : case -1:
8298 : /* ----------
8299 : * ABS(var1) < ABS(var2)
8300 : * result = +(ABS(var2) - ABS(var1))
8301 : * ----------
8302 : */
8303 32 : sub_abs(var2, var1, result);
8304 32 : result->sign = NUMERIC_POS;
8305 32 : break;
8306 : }
8307 : }
8308 : else
8309 : {
8310 : /* ----------
8311 : * var1 is negative, var2 is positive
8312 : * result = -(ABS(var1) + ABS(var2))
8313 : * ----------
8314 : */
8315 305 : add_abs(var1, var2, result);
8316 305 : result->sign = NUMERIC_NEG;
8317 : }
8318 : }
8319 351114 : }
8320 :
8321 :
8322 : /*
8323 : * mul_var() -
8324 : *
8325 : * Multiplication on variable level. Product of var1 * var2 is stored
8326 : * in result. Result is rounded to no more than rscale fractional digits.
8327 : */
8328 : static void
8329 795584 : mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8330 : int rscale)
8331 : {
8332 : int res_ndigits;
8333 : int res_ndigitpairs;
8334 : int res_sign;
8335 : int res_weight;
8336 : int pair_offset;
8337 : int maxdigits;
8338 : int maxdigitpairs;
8339 : uint64 *dig,
8340 : *dig_i1_off;
8341 : uint64 maxdig;
8342 : uint64 carry;
8343 : uint64 newdig;
8344 : int var1ndigits;
8345 : int var2ndigits;
8346 : int var1ndigitpairs;
8347 : int var2ndigitpairs;
8348 : NumericDigit *var1digits;
8349 : NumericDigit *var2digits;
8350 : uint32 var1digitpair;
8351 : uint32 *var2digitpairs;
8352 : NumericDigit *res_digits;
8353 : int i,
8354 : i1,
8355 : i2,
8356 : i2limit;
8357 :
8358 : /*
8359 : * Arrange for var1 to be the shorter of the two numbers. This improves
8360 : * performance because the inner multiplication loop is much simpler than
8361 : * the outer loop, so it's better to have a smaller number of iterations
8362 : * of the outer loop. This also reduces the number of times that the
8363 : * accumulator array needs to be normalized.
8364 : */
8365 795584 : if (var1->ndigits > var2->ndigits)
8366 : {
8367 10365 : const NumericVar *tmp = var1;
8368 :
8369 10365 : var1 = var2;
8370 10365 : var2 = tmp;
8371 : }
8372 :
8373 : /* copy these values into local vars for speed in inner loop */
8374 795584 : var1ndigits = var1->ndigits;
8375 795584 : var2ndigits = var2->ndigits;
8376 795584 : var1digits = var1->digits;
8377 795584 : var2digits = var2->digits;
8378 :
8379 795584 : if (var1ndigits == 0)
8380 : {
8381 : /* one or both inputs is zero; so is result */
8382 1959 : zero_var(result);
8383 1959 : result->dscale = rscale;
8384 1959 : return;
8385 : }
8386 :
8387 : /*
8388 : * If var1 has 1-6 digits and the exact result was requested, delegate to
8389 : * mul_var_short() which uses a faster direct multiplication algorithm.
8390 : */
8391 793625 : if (var1ndigits <= 6 && rscale == var1->dscale + var2->dscale)
8392 : {
8393 772956 : mul_var_short(var1, var2, result);
8394 772956 : return;
8395 : }
8396 :
8397 : /* Determine result sign */
8398 20669 : if (var1->sign == var2->sign)
8399 19390 : res_sign = NUMERIC_POS;
8400 : else
8401 1279 : res_sign = NUMERIC_NEG;
8402 :
8403 : /*
8404 : * Determine the number of result digits to compute and the (maximum
8405 : * possible) result weight. If the exact result would have more than
8406 : * rscale fractional digits, truncate the computation with
8407 : * MUL_GUARD_DIGITS guard digits, i.e., ignore input digits that would
8408 : * only contribute to the right of that. (This will give the exact
8409 : * rounded-to-rscale answer unless carries out of the ignored positions
8410 : * would have propagated through more than MUL_GUARD_DIGITS digits.)
8411 : *
8412 : * Note: an exact computation could not produce more than var1ndigits +
8413 : * var2ndigits digits, but we allocate at least one extra output digit in
8414 : * case rscale-driven rounding produces a carry out of the highest exact
8415 : * digit.
8416 : *
8417 : * The computation itself is done using base-NBASE^2 arithmetic, so we
8418 : * actually process the input digits in pairs, producing a base-NBASE^2
8419 : * intermediate result. This significantly improves performance, since
8420 : * schoolbook multiplication is O(N^2) in the number of input digits, and
8421 : * working in base NBASE^2 effectively halves "N".
8422 : *
8423 : * Note: in a truncated computation, we must compute at least one extra
8424 : * output digit to ensure that all the guard digits are fully computed.
8425 : */
8426 : /* digit pairs in each input */
8427 20669 : var1ndigitpairs = (var1ndigits + 1) / 2;
8428 20669 : var2ndigitpairs = (var2ndigits + 1) / 2;
8429 :
8430 : /* digits in exact result */
8431 20669 : res_ndigits = var1ndigits + var2ndigits;
8432 :
8433 : /* digit pairs in exact result with at least one extra output digit */
8434 20669 : res_ndigitpairs = res_ndigits / 2 + 1;
8435 :
8436 : /* pair offset to align result to end of dig[] */
8437 20669 : pair_offset = res_ndigitpairs - var1ndigitpairs - var2ndigitpairs + 1;
8438 :
8439 : /* maximum possible result weight (odd-length inputs shifted up below) */
8440 20669 : res_weight = var1->weight + var2->weight + 1 + 2 * res_ndigitpairs -
8441 20669 : res_ndigits - (var1ndigits & 1) - (var2ndigits & 1);
8442 :
8443 : /* rscale-based truncation with at least one extra output digit */
8444 20669 : maxdigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS +
8445 : MUL_GUARD_DIGITS;
8446 20669 : maxdigitpairs = maxdigits / 2 + 1;
8447 :
8448 20669 : res_ndigitpairs = Min(res_ndigitpairs, maxdigitpairs);
8449 20669 : res_ndigits = 2 * res_ndigitpairs;
8450 :
8451 : /*
8452 : * In the computation below, digit pair i1 of var1 and digit pair i2 of
8453 : * var2 are multiplied and added to digit i1+i2+pair_offset of dig[]. Thus
8454 : * input digit pairs with index >= res_ndigitpairs - pair_offset don't
8455 : * contribute to the result, and can be ignored.
8456 : */
8457 20669 : if (res_ndigitpairs <= pair_offset)
8458 : {
8459 : /* All input digits will be ignored; so result is zero */
8460 10 : zero_var(result);
8461 10 : result->dscale = rscale;
8462 10 : return;
8463 : }
8464 20659 : var1ndigitpairs = Min(var1ndigitpairs, res_ndigitpairs - pair_offset);
8465 20659 : var2ndigitpairs = Min(var2ndigitpairs, res_ndigitpairs - pair_offset);
8466 :
8467 : /*
8468 : * We do the arithmetic in an array "dig[]" of unsigned 64-bit integers.
8469 : * Since PG_UINT64_MAX is much larger than NBASE^4, this gives us a lot of
8470 : * headroom to avoid normalizing carries immediately.
8471 : *
8472 : * maxdig tracks the maximum possible value of any dig[] entry; when this
8473 : * threatens to exceed PG_UINT64_MAX, we take the time to propagate
8474 : * carries. Furthermore, we need to ensure that overflow doesn't occur
8475 : * during the carry propagation passes either. The carry values could be
8476 : * as much as PG_UINT64_MAX / NBASE^2, so really we must normalize when
8477 : * digits threaten to exceed PG_UINT64_MAX - PG_UINT64_MAX / NBASE^2.
8478 : *
8479 : * To avoid overflow in maxdig itself, it actually represents the maximum
8480 : * possible value divided by NBASE^2-1, i.e., at the top of the loop it is
8481 : * known that no dig[] entry exceeds maxdig * (NBASE^2-1).
8482 : *
8483 : * The conversion of var1 to base NBASE^2 is done on the fly, as each new
8484 : * digit is required. The digits of var2 are converted upfront, and
8485 : * stored at the end of dig[]. To avoid loss of precision, the input
8486 : * digits are aligned with the start of digit pair array, effectively
8487 : * shifting them up (multiplying by NBASE) if the inputs have an odd
8488 : * number of NBASE digits.
8489 : */
8490 20659 : dig = (uint64 *) palloc(res_ndigitpairs * sizeof(uint64) +
8491 : var2ndigitpairs * sizeof(uint32));
8492 :
8493 : /* convert var2 to base NBASE^2, shifting up if its length is odd */
8494 20659 : var2digitpairs = (uint32 *) (dig + res_ndigitpairs);
8495 :
8496 1048389 : for (i2 = 0; i2 < var2ndigitpairs - 1; i2++)
8497 1027730 : var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
8498 :
8499 20659 : if (2 * i2 + 1 < var2ndigits)
8500 14659 : var2digitpairs[i2] = var2digits[2 * i2] * NBASE + var2digits[2 * i2 + 1];
8501 : else
8502 6000 : var2digitpairs[i2] = var2digits[2 * i2] * NBASE;
8503 :
8504 : /*
8505 : * Start by multiplying var2 by the least significant contributing digit
8506 : * pair from var1, storing the results at the end of dig[], and filling
8507 : * the leading digits with zeros.
8508 : *
8509 : * The loop here is the same as the inner loop below, except that we set
8510 : * the results in dig[], rather than adding to them. This is the
8511 : * performance bottleneck for multiplication, so we want to keep it simple
8512 : * enough so that it can be auto-vectorized. Accordingly, process the
8513 : * digits left-to-right even though schoolbook multiplication would
8514 : * suggest right-to-left. Since we aren't propagating carries in this
8515 : * loop, the order does not matter.
8516 : */
8517 20659 : i1 = var1ndigitpairs - 1;
8518 20659 : if (2 * i1 + 1 < var1ndigits)
8519 9183 : var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
8520 : else
8521 11476 : var1digitpair = var1digits[2 * i1] * NBASE;
8522 20659 : maxdig = var1digitpair;
8523 :
8524 20659 : i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
8525 20659 : dig_i1_off = &dig[i1 + pair_offset];
8526 :
8527 20659 : memset(dig, 0, (i1 + pair_offset) * sizeof(uint64));
8528 930539 : for (i2 = 0; i2 < i2limit; i2++)
8529 909880 : dig_i1_off[i2] = (uint64) var1digitpair * var2digitpairs[i2];
8530 :
8531 : /*
8532 : * Next, multiply var2 by the remaining digit pairs from var1, adding the
8533 : * results to dig[] at the appropriate offsets, and normalizing whenever
8534 : * there is a risk of any dig[] entry overflowing.
8535 : */
8536 1012436 : for (i1 = i1 - 1; i1 >= 0; i1--)
8537 : {
8538 991777 : var1digitpair = var1digits[2 * i1] * NBASE + var1digits[2 * i1 + 1];
8539 991777 : if (var1digitpair == 0)
8540 786344 : continue;
8541 :
8542 : /* Time to normalize? */
8543 205433 : maxdig += var1digitpair;
8544 205433 : if (maxdig > (PG_UINT64_MAX - PG_UINT64_MAX / NBASE_SQR) / (NBASE_SQR - 1))
8545 : {
8546 : /* Yes, do it (to base NBASE^2) */
8547 21 : carry = 0;
8548 84074 : for (i = res_ndigitpairs - 1; i >= 0; i--)
8549 : {
8550 84053 : newdig = dig[i] + carry;
8551 84053 : if (newdig >= NBASE_SQR)
8552 : {
8553 80719 : carry = newdig / NBASE_SQR;
8554 80719 : newdig -= carry * NBASE_SQR;
8555 : }
8556 : else
8557 3334 : carry = 0;
8558 84053 : dig[i] = newdig;
8559 : }
8560 : Assert(carry == 0);
8561 : /* Reset maxdig to indicate new worst-case */
8562 21 : maxdig = 1 + var1digitpair;
8563 : }
8564 :
8565 : /* Multiply and add */
8566 205433 : i2limit = Min(var2ndigitpairs, res_ndigitpairs - i1 - pair_offset);
8567 205433 : dig_i1_off = &dig[i1 + pair_offset];
8568 :
8569 87005259 : for (i2 = 0; i2 < i2limit; i2++)
8570 86799826 : dig_i1_off[i2] += (uint64) var1digitpair * var2digitpairs[i2];
8571 : }
8572 :
8573 : /*
8574 : * Now we do a final carry propagation pass to normalize back to base
8575 : * NBASE^2, and construct the base-NBASE result digits. Note that this is
8576 : * still done at full precision w/guard digits.
8577 : */
8578 20659 : alloc_var(result, res_ndigits);
8579 20659 : res_digits = result->digits;
8580 20659 : carry = 0;
8581 1946324 : for (i = res_ndigitpairs - 1; i >= 0; i--)
8582 : {
8583 1925665 : newdig = dig[i] + carry;
8584 1925665 : if (newdig >= NBASE_SQR)
8585 : {
8586 290140 : carry = newdig / NBASE_SQR;
8587 290140 : newdig -= carry * NBASE_SQR;
8588 : }
8589 : else
8590 1635525 : carry = 0;
8591 1925665 : res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
8592 1925665 : res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
8593 : }
8594 : Assert(carry == 0);
8595 :
8596 20659 : pfree(dig);
8597 :
8598 : /*
8599 : * Finally, round the result to the requested precision.
8600 : */
8601 20659 : result->weight = res_weight;
8602 20659 : result->sign = res_sign;
8603 :
8604 : /* Round to target rscale (and set result->dscale) */
8605 20659 : round_var(result, rscale);
8606 :
8607 : /* Strip leading and trailing zeroes */
8608 20659 : strip_var(result);
8609 : }
8610 :
8611 :
8612 : /*
8613 : * mul_var_short() -
8614 : *
8615 : * Special-case multiplication function used when var1 has 1-6 digits, var2
8616 : * has at least as many digits as var1, and the exact product var1 * var2 is
8617 : * requested.
8618 : */
8619 : static void
8620 772956 : mul_var_short(const NumericVar *var1, const NumericVar *var2,
8621 : NumericVar *result)
8622 : {
8623 772956 : int var1ndigits = var1->ndigits;
8624 772956 : int var2ndigits = var2->ndigits;
8625 772956 : NumericDigit *var1digits = var1->digits;
8626 772956 : NumericDigit *var2digits = var2->digits;
8627 : int res_sign;
8628 : int res_weight;
8629 : int res_ndigits;
8630 : NumericDigit *res_buf;
8631 : NumericDigit *res_digits;
8632 772956 : uint32 carry = 0;
8633 : uint32 term;
8634 :
8635 : /* Check preconditions */
8636 : Assert(var1ndigits >= 1);
8637 : Assert(var1ndigits <= 6);
8638 : Assert(var2ndigits >= var1ndigits);
8639 :
8640 : /*
8641 : * Determine the result sign, weight, and number of digits to calculate.
8642 : * The weight figured here is correct if the product has no leading zero
8643 : * digits; otherwise strip_var() will fix things up. Note that, unlike
8644 : * mul_var(), we do not need to allocate an extra output digit, because we
8645 : * are not rounding here.
8646 : */
8647 772956 : if (var1->sign == var2->sign)
8648 772149 : res_sign = NUMERIC_POS;
8649 : else
8650 807 : res_sign = NUMERIC_NEG;
8651 772956 : res_weight = var1->weight + var2->weight + 1;
8652 772956 : res_ndigits = var1ndigits + var2ndigits;
8653 :
8654 : /* Allocate result digit array */
8655 772956 : res_buf = digitbuf_alloc(res_ndigits + 1);
8656 772956 : res_buf[0] = 0; /* spare digit for later rounding */
8657 772956 : res_digits = res_buf + 1;
8658 :
8659 : /*
8660 : * Compute the result digits in reverse, in one pass, propagating the
8661 : * carry up as we go. The i'th result digit consists of the sum of the
8662 : * products var1digits[i1] * var2digits[i2] for which i = i1 + i2 + 1.
8663 : */
8664 : #define PRODSUM1(v1,i1,v2,i2) ((v1)[(i1)] * (v2)[(i2)])
8665 : #define PRODSUM2(v1,i1,v2,i2) (PRODSUM1(v1,i1,v2,i2) + (v1)[(i1)+1] * (v2)[(i2)-1])
8666 : #define PRODSUM3(v1,i1,v2,i2) (PRODSUM2(v1,i1,v2,i2) + (v1)[(i1)+2] * (v2)[(i2)-2])
8667 : #define PRODSUM4(v1,i1,v2,i2) (PRODSUM3(v1,i1,v2,i2) + (v1)[(i1)+3] * (v2)[(i2)-3])
8668 : #define PRODSUM5(v1,i1,v2,i2) (PRODSUM4(v1,i1,v2,i2) + (v1)[(i1)+4] * (v2)[(i2)-4])
8669 : #define PRODSUM6(v1,i1,v2,i2) (PRODSUM5(v1,i1,v2,i2) + (v1)[(i1)+5] * (v2)[(i2)-5])
8670 :
8671 772956 : switch (var1ndigits)
8672 : {
8673 768811 : case 1:
8674 : /* ---------
8675 : * 1-digit case:
8676 : * var1ndigits = 1
8677 : * var2ndigits >= 1
8678 : * res_ndigits = var2ndigits + 1
8679 : * ----------
8680 : */
8681 2406163 : for (int i = var2ndigits - 1; i >= 0; i--)
8682 : {
8683 1637352 : term = PRODSUM1(var1digits, 0, var2digits, i) + carry;
8684 1637352 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8685 1637352 : carry = term / NBASE;
8686 : }
8687 768811 : res_digits[0] = (NumericDigit) carry;
8688 768811 : break;
8689 :
8690 519 : case 2:
8691 : /* ---------
8692 : * 2-digit case:
8693 : * var1ndigits = 2
8694 : * var2ndigits >= 2
8695 : * res_ndigits = var2ndigits + 2
8696 : * ----------
8697 : */
8698 : /* last result digit and carry */
8699 519 : term = PRODSUM1(var1digits, 1, var2digits, var2ndigits - 1);
8700 519 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8701 519 : carry = term / NBASE;
8702 :
8703 : /* remaining digits, except for the first two */
8704 1573 : for (int i = var2ndigits - 1; i >= 1; i--)
8705 : {
8706 1054 : term = PRODSUM2(var1digits, 0, var2digits, i) + carry;
8707 1054 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8708 1054 : carry = term / NBASE;
8709 : }
8710 519 : break;
8711 :
8712 146 : case 3:
8713 : /* ---------
8714 : * 3-digit case:
8715 : * var1ndigits = 3
8716 : * var2ndigits >= 3
8717 : * res_ndigits = var2ndigits + 3
8718 : * ----------
8719 : */
8720 : /* last two result digits */
8721 146 : term = PRODSUM1(var1digits, 2, var2digits, var2ndigits - 1);
8722 146 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8723 146 : carry = term / NBASE;
8724 :
8725 146 : term = PRODSUM2(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8726 146 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8727 146 : carry = term / NBASE;
8728 :
8729 : /* remaining digits, except for the first three */
8730 387 : for (int i = var2ndigits - 1; i >= 2; i--)
8731 : {
8732 241 : term = PRODSUM3(var1digits, 0, var2digits, i) + carry;
8733 241 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8734 241 : carry = term / NBASE;
8735 : }
8736 146 : break;
8737 :
8738 2888 : case 4:
8739 : /* ---------
8740 : * 4-digit case:
8741 : * var1ndigits = 4
8742 : * var2ndigits >= 4
8743 : * res_ndigits = var2ndigits + 4
8744 : * ----------
8745 : */
8746 : /* last three result digits */
8747 2888 : term = PRODSUM1(var1digits, 3, var2digits, var2ndigits - 1);
8748 2888 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8749 2888 : carry = term / NBASE;
8750 :
8751 2888 : term = PRODSUM2(var1digits, 2, var2digits, var2ndigits - 1) + carry;
8752 2888 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8753 2888 : carry = term / NBASE;
8754 :
8755 2888 : term = PRODSUM3(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8756 2888 : res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
8757 2888 : carry = term / NBASE;
8758 :
8759 : /* remaining digits, except for the first four */
8760 8058 : for (int i = var2ndigits - 1; i >= 3; i--)
8761 : {
8762 5170 : term = PRODSUM4(var1digits, 0, var2digits, i) + carry;
8763 5170 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8764 5170 : carry = term / NBASE;
8765 : }
8766 2888 : break;
8767 :
8768 91 : case 5:
8769 : /* ---------
8770 : * 5-digit case:
8771 : * var1ndigits = 5
8772 : * var2ndigits >= 5
8773 : * res_ndigits = var2ndigits + 5
8774 : * ----------
8775 : */
8776 : /* last four result digits */
8777 91 : term = PRODSUM1(var1digits, 4, var2digits, var2ndigits - 1);
8778 91 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8779 91 : carry = term / NBASE;
8780 :
8781 91 : term = PRODSUM2(var1digits, 3, var2digits, var2ndigits - 1) + carry;
8782 91 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8783 91 : carry = term / NBASE;
8784 :
8785 91 : term = PRODSUM3(var1digits, 2, var2digits, var2ndigits - 1) + carry;
8786 91 : res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
8787 91 : carry = term / NBASE;
8788 :
8789 91 : term = PRODSUM4(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8790 91 : res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
8791 91 : carry = term / NBASE;
8792 :
8793 : /* remaining digits, except for the first five */
8794 242 : for (int i = var2ndigits - 1; i >= 4; i--)
8795 : {
8796 151 : term = PRODSUM5(var1digits, 0, var2digits, i) + carry;
8797 151 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8798 151 : carry = term / NBASE;
8799 : }
8800 91 : break;
8801 :
8802 501 : case 6:
8803 : /* ---------
8804 : * 6-digit case:
8805 : * var1ndigits = 6
8806 : * var2ndigits >= 6
8807 : * res_ndigits = var2ndigits + 6
8808 : * ----------
8809 : */
8810 : /* last five result digits */
8811 501 : term = PRODSUM1(var1digits, 5, var2digits, var2ndigits - 1);
8812 501 : res_digits[res_ndigits - 1] = (NumericDigit) (term % NBASE);
8813 501 : carry = term / NBASE;
8814 :
8815 501 : term = PRODSUM2(var1digits, 4, var2digits, var2ndigits - 1) + carry;
8816 501 : res_digits[res_ndigits - 2] = (NumericDigit) (term % NBASE);
8817 501 : carry = term / NBASE;
8818 :
8819 501 : term = PRODSUM3(var1digits, 3, var2digits, var2ndigits - 1) + carry;
8820 501 : res_digits[res_ndigits - 3] = (NumericDigit) (term % NBASE);
8821 501 : carry = term / NBASE;
8822 :
8823 501 : term = PRODSUM4(var1digits, 2, var2digits, var2ndigits - 1) + carry;
8824 501 : res_digits[res_ndigits - 4] = (NumericDigit) (term % NBASE);
8825 501 : carry = term / NBASE;
8826 :
8827 501 : term = PRODSUM5(var1digits, 1, var2digits, var2ndigits - 1) + carry;
8828 501 : res_digits[res_ndigits - 5] = (NumericDigit) (term % NBASE);
8829 501 : carry = term / NBASE;
8830 :
8831 : /* remaining digits, except for the first six */
8832 1400 : for (int i = var2ndigits - 1; i >= 5; i--)
8833 : {
8834 899 : term = PRODSUM6(var1digits, 0, var2digits, i) + carry;
8835 899 : res_digits[i + 1] = (NumericDigit) (term % NBASE);
8836 899 : carry = term / NBASE;
8837 : }
8838 501 : break;
8839 : }
8840 :
8841 : /*
8842 : * Finally, for var1ndigits > 1, compute the remaining var1ndigits most
8843 : * significant result digits.
8844 : */
8845 772956 : switch (var1ndigits)
8846 : {
8847 501 : case 6:
8848 501 : term = PRODSUM5(var1digits, 0, var2digits, 4) + carry;
8849 501 : res_digits[5] = (NumericDigit) (term % NBASE);
8850 501 : carry = term / NBASE;
8851 : pg_fallthrough;
8852 592 : case 5:
8853 592 : term = PRODSUM4(var1digits, 0, var2digits, 3) + carry;
8854 592 : res_digits[4] = (NumericDigit) (term % NBASE);
8855 592 : carry = term / NBASE;
8856 : pg_fallthrough;
8857 3480 : case 4:
8858 3480 : term = PRODSUM3(var1digits, 0, var2digits, 2) + carry;
8859 3480 : res_digits[3] = (NumericDigit) (term % NBASE);
8860 3480 : carry = term / NBASE;
8861 : pg_fallthrough;
8862 3626 : case 3:
8863 3626 : term = PRODSUM2(var1digits, 0, var2digits, 1) + carry;
8864 3626 : res_digits[2] = (NumericDigit) (term % NBASE);
8865 3626 : carry = term / NBASE;
8866 : pg_fallthrough;
8867 4145 : case 2:
8868 4145 : term = PRODSUM1(var1digits, 0, var2digits, 0) + carry;
8869 4145 : res_digits[1] = (NumericDigit) (term % NBASE);
8870 4145 : res_digits[0] = (NumericDigit) (term / NBASE);
8871 4145 : break;
8872 : }
8873 :
8874 : /* Store the product in result */
8875 772956 : digitbuf_free(result->buf);
8876 772956 : result->ndigits = res_ndigits;
8877 772956 : result->buf = res_buf;
8878 772956 : result->digits = res_digits;
8879 772956 : result->weight = res_weight;
8880 772956 : result->sign = res_sign;
8881 772956 : result->dscale = var1->dscale + var2->dscale;
8882 :
8883 : /* Strip leading and trailing zeroes */
8884 772956 : strip_var(result);
8885 772956 : }
8886 :
8887 :
8888 : /*
8889 : * div_var() -
8890 : *
8891 : * Compute the quotient var1 / var2 to rscale fractional digits.
8892 : *
8893 : * If "round" is true, the result is rounded at the rscale'th digit; if
8894 : * false, it is truncated (towards zero) at that digit.
8895 : *
8896 : * If "exact" is true, the exact result is computed to the specified rscale;
8897 : * if false, successive quotient digits are approximated up to rscale plus
8898 : * DIV_GUARD_DIGITS extra digits, ignoring all contributions from digits to
8899 : * the right of that, before rounding or truncating to the specified rscale.
8900 : * This can be significantly faster, and usually gives the same result as the
8901 : * exact computation, but it may occasionally be off by one in the final
8902 : * digit, if contributions from the ignored digits would have propagated
8903 : * through the guard digits. This is good enough for the transcendental
8904 : * functions, where small errors are acceptable.
8905 : */
8906 : static void
8907 380354 : div_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result,
8908 : int rscale, bool round, bool exact)
8909 : {
8910 380354 : int var1ndigits = var1->ndigits;
8911 380354 : int var2ndigits = var2->ndigits;
8912 : int res_sign;
8913 : int res_weight;
8914 : int res_ndigits;
8915 : int var1ndigitpairs;
8916 : int var2ndigitpairs;
8917 : int res_ndigitpairs;
8918 : int div_ndigitpairs;
8919 : int64 *dividend;
8920 : int32 *divisor;
8921 : double fdivisor,
8922 : fdivisorinverse,
8923 : fdividend,
8924 : fquotient;
8925 : int64 maxdiv;
8926 : int qi;
8927 : int32 qdigit;
8928 : int64 carry;
8929 : int64 newdig;
8930 : int64 *remainder;
8931 : NumericDigit *res_digits;
8932 : int i;
8933 :
8934 : /*
8935 : * First of all division by zero check; we must not be handed an
8936 : * unnormalized divisor.
8937 : */
8938 380354 : if (var2ndigits == 0 || var2->digits[0] == 0)
8939 8 : ereport(ERROR,
8940 : (errcode(ERRCODE_DIVISION_BY_ZERO),
8941 : errmsg("division by zero")));
8942 :
8943 : /*
8944 : * If the divisor has just one or two digits, delegate to div_var_int(),
8945 : * which uses fast short division.
8946 : *
8947 : * Similarly, on platforms with 128-bit integer support, delegate to
8948 : * div_var_int64() for divisors with three or four digits.
8949 : */
8950 380346 : if (var2ndigits <= 2)
8951 : {
8952 : int idivisor;
8953 : int idivisor_weight;
8954 :
8955 375994 : idivisor = var2->digits[0];
8956 375994 : idivisor_weight = var2->weight;
8957 375994 : if (var2ndigits == 2)
8958 : {
8959 2200 : idivisor = idivisor * NBASE + var2->digits[1];
8960 2200 : idivisor_weight--;
8961 : }
8962 375994 : if (var2->sign == NUMERIC_NEG)
8963 440 : idivisor = -idivisor;
8964 :
8965 375994 : div_var_int(var1, idivisor, idivisor_weight, result, rscale, round);
8966 375994 : return;
8967 : }
8968 : #ifdef HAVE_INT128
8969 4352 : if (var2ndigits <= 4)
8970 : {
8971 : int64 idivisor;
8972 : int idivisor_weight;
8973 :
8974 360 : idivisor = var2->digits[0];
8975 360 : idivisor_weight = var2->weight;
8976 1340 : for (i = 1; i < var2ndigits; i++)
8977 : {
8978 980 : idivisor = idivisor * NBASE + var2->digits[i];
8979 980 : idivisor_weight--;
8980 : }
8981 360 : if (var2->sign == NUMERIC_NEG)
8982 80 : idivisor = -idivisor;
8983 :
8984 360 : div_var_int64(var1, idivisor, idivisor_weight, result, rscale, round);
8985 360 : return;
8986 : }
8987 : #endif
8988 :
8989 : /*
8990 : * Otherwise, perform full long division.
8991 : */
8992 :
8993 : /* Result zero check */
8994 3992 : if (var1ndigits == 0)
8995 : {
8996 24 : zero_var(result);
8997 24 : result->dscale = rscale;
8998 24 : return;
8999 : }
9000 :
9001 : /*
9002 : * The approximate computation can be significantly faster than the exact
9003 : * one, since the working dividend is var2ndigitpairs base-NBASE^2 digits
9004 : * shorter below. However, that comes with the tradeoff of computing
9005 : * DIV_GUARD_DIGITS extra base-NBASE result digits. Ignoring all other
9006 : * overheads, that suggests that, in theory, the approximate computation
9007 : * will only be faster than the exact one when var2ndigits is greater than
9008 : * 2 * (DIV_GUARD_DIGITS + 1), independent of the size of var1.
9009 : *
9010 : * Thus, we're better off doing an exact computation when var2 is shorter
9011 : * than this. Empirically, it has been found that the exact threshold is
9012 : * a little higher, due to other overheads in the outer division loop.
9013 : */
9014 3968 : if (var2ndigits <= 2 * (DIV_GUARD_DIGITS + 2))
9015 2712 : exact = true;
9016 :
9017 : /*
9018 : * Determine the result sign, weight and number of digits to calculate.
9019 : * The weight figured here is correct if the emitted quotient has no
9020 : * leading zero digits; otherwise strip_var() will fix things up.
9021 : */
9022 3968 : if (var1->sign == var2->sign)
9023 3866 : res_sign = NUMERIC_POS;
9024 : else
9025 102 : res_sign = NUMERIC_NEG;
9026 3968 : res_weight = var1->weight - var2->weight + 1;
9027 : /* The number of accurate result digits we need to produce: */
9028 3968 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9029 : /* ... but always at least 1 */
9030 3968 : res_ndigits = Max(res_ndigits, 1);
9031 : /* If rounding needed, figure one more digit to ensure correct result */
9032 3968 : if (round)
9033 658 : res_ndigits++;
9034 : /* Add guard digits for roundoff error when producing approx result */
9035 3968 : if (!exact)
9036 1246 : res_ndigits += DIV_GUARD_DIGITS;
9037 :
9038 : /*
9039 : * The computation itself is done using base-NBASE^2 arithmetic, so we
9040 : * actually process the input digits in pairs, producing a base-NBASE^2
9041 : * intermediate result. This significantly improves performance, since
9042 : * the computation is O(N^2) in the number of input digits, and working in
9043 : * base NBASE^2 effectively halves "N".
9044 : */
9045 3968 : var1ndigitpairs = (var1ndigits + 1) / 2;
9046 3968 : var2ndigitpairs = (var2ndigits + 1) / 2;
9047 3968 : res_ndigitpairs = (res_ndigits + 1) / 2;
9048 3968 : res_ndigits = 2 * res_ndigitpairs;
9049 :
9050 : /*
9051 : * We do the arithmetic in an array "dividend[]" of signed 64-bit
9052 : * integers. Since PG_INT64_MAX is much larger than NBASE^4, this gives
9053 : * us a lot of headroom to avoid normalizing carries immediately.
9054 : *
9055 : * When performing an exact computation, the working dividend requires
9056 : * res_ndigitpairs + var2ndigitpairs digits. If var1 is larger than that,
9057 : * the extra digits do not contribute to the result, and are ignored.
9058 : *
9059 : * When performing an approximate computation, the working dividend only
9060 : * requires res_ndigitpairs digits (which includes the extra guard
9061 : * digits). All input digits beyond that are ignored.
9062 : */
9063 3968 : if (exact)
9064 : {
9065 2722 : div_ndigitpairs = res_ndigitpairs + var2ndigitpairs;
9066 2722 : var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
9067 : }
9068 : else
9069 : {
9070 1246 : div_ndigitpairs = res_ndigitpairs;
9071 1246 : var1ndigitpairs = Min(var1ndigitpairs, div_ndigitpairs);
9072 1246 : var2ndigitpairs = Min(var2ndigitpairs, div_ndigitpairs);
9073 : }
9074 :
9075 : /*
9076 : * Allocate room for the working dividend (div_ndigitpairs 64-bit digits)
9077 : * plus the divisor (var2ndigitpairs 32-bit base-NBASE^2 digits).
9078 : *
9079 : * For convenience, we allocate one extra dividend digit, which is set to
9080 : * zero and not counted in div_ndigitpairs, so that the main loop below
9081 : * can safely read and write the (qi+1)'th digit in the approximate case.
9082 : */
9083 3968 : dividend = (int64 *) palloc((div_ndigitpairs + 1) * sizeof(int64) +
9084 : var2ndigitpairs * sizeof(int32));
9085 3968 : divisor = (int32 *) (dividend + div_ndigitpairs + 1);
9086 :
9087 : /* load var1 into dividend[0 .. var1ndigitpairs-1], zeroing the rest */
9088 37128 : for (i = 0; i < var1ndigitpairs - 1; i++)
9089 33160 : dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
9090 :
9091 3968 : if (2 * i + 1 < var1ndigits)
9092 2341 : dividend[i] = var1->digits[2 * i] * NBASE + var1->digits[2 * i + 1];
9093 : else
9094 1627 : dividend[i] = var1->digits[2 * i] * NBASE;
9095 :
9096 3968 : memset(dividend + i + 1, 0, (div_ndigitpairs - i) * sizeof(int64));
9097 :
9098 : /* load var2 into divisor[0 .. var2ndigitpairs-1] */
9099 29424 : for (i = 0; i < var2ndigitpairs - 1; i++)
9100 25456 : divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
9101 :
9102 3968 : if (2 * i + 1 < var2ndigits)
9103 2138 : divisor[i] = var2->digits[2 * i] * NBASE + var2->digits[2 * i + 1];
9104 : else
9105 1830 : divisor[i] = var2->digits[2 * i] * NBASE;
9106 :
9107 : /*
9108 : * We estimate each quotient digit using floating-point arithmetic, taking
9109 : * the first 2 base-NBASE^2 digits of the (current) dividend and divisor.
9110 : * This must be float to avoid overflow.
9111 : *
9112 : * Since the floating-point dividend and divisor use 4 base-NBASE input
9113 : * digits, they include roughly 40-53 bits of information from their
9114 : * respective inputs (assuming NBASE is 10000), which fits well in IEEE
9115 : * double-precision variables. The relative error in the floating-point
9116 : * quotient digit will then be less than around 2/NBASE^3, so the
9117 : * estimated base-NBASE^2 quotient digit will typically be correct, and
9118 : * should not be off by more than one from the correct value.
9119 : */
9120 3968 : fdivisor = (double) divisor[0] * NBASE_SQR;
9121 3968 : if (var2ndigitpairs > 1)
9122 3968 : fdivisor += (double) divisor[1];
9123 3968 : fdivisorinverse = 1.0 / fdivisor;
9124 :
9125 : /*
9126 : * maxdiv tracks the maximum possible absolute value of any dividend[]
9127 : * entry; when this threatens to exceed PG_INT64_MAX, we take the time to
9128 : * propagate carries. Furthermore, we need to ensure that overflow
9129 : * doesn't occur during the carry propagation passes either. The carry
9130 : * values may have an absolute value as high as PG_INT64_MAX/NBASE^2 + 1,
9131 : * so really we must normalize when digits threaten to exceed PG_INT64_MAX
9132 : * - PG_INT64_MAX/NBASE^2 - 1.
9133 : *
9134 : * To avoid overflow in maxdiv itself, it represents the max absolute
9135 : * value divided by NBASE^2-1, i.e., at the top of the loop it is known
9136 : * that no dividend[] entry has an absolute value exceeding maxdiv *
9137 : * (NBASE^2-1).
9138 : *
9139 : * Actually, though, that holds good only for dividend[] entries after
9140 : * dividend[qi]; the adjustment done at the bottom of the loop may cause
9141 : * dividend[qi + 1] to exceed the maxdiv limit, so that dividend[qi] in
9142 : * the next iteration is beyond the limit. This does not cause problems,
9143 : * as explained below.
9144 : */
9145 3968 : maxdiv = 1;
9146 :
9147 : /*
9148 : * Outer loop computes next quotient digit, which goes in dividend[qi].
9149 : */
9150 36464 : for (qi = 0; qi < res_ndigitpairs; qi++)
9151 : {
9152 : /* Approximate the current dividend value */
9153 32496 : fdividend = (double) dividend[qi] * NBASE_SQR;
9154 32496 : fdividend += (double) dividend[qi + 1];
9155 :
9156 : /* Compute the (approximate) quotient digit */
9157 32496 : fquotient = fdividend * fdivisorinverse;
9158 32496 : qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
9159 5 : (((int32) fquotient) - 1); /* truncate towards -infinity */
9160 :
9161 32496 : if (qdigit != 0)
9162 : {
9163 : /* Do we need to normalize now? */
9164 29863 : maxdiv += i64abs(qdigit);
9165 29863 : if (maxdiv > (PG_INT64_MAX - PG_INT64_MAX / NBASE_SQR - 1) / (NBASE_SQR - 1))
9166 : {
9167 : /*
9168 : * Yes, do it. Note that if var2ndigitpairs is much smaller
9169 : * than div_ndigitpairs, we can save a significant amount of
9170 : * effort here by noting that we only need to normalise those
9171 : * dividend[] entries touched where prior iterations
9172 : * subtracted multiples of the divisor.
9173 : */
9174 5 : carry = 0;
9175 5625 : for (i = Min(qi + var2ndigitpairs - 2, div_ndigitpairs - 1); i > qi; i--)
9176 : {
9177 5620 : newdig = dividend[i] + carry;
9178 5620 : if (newdig < 0)
9179 : {
9180 5620 : carry = -((-newdig - 1) / NBASE_SQR) - 1;
9181 5620 : newdig -= carry * NBASE_SQR;
9182 : }
9183 0 : else if (newdig >= NBASE_SQR)
9184 : {
9185 0 : carry = newdig / NBASE_SQR;
9186 0 : newdig -= carry * NBASE_SQR;
9187 : }
9188 : else
9189 0 : carry = 0;
9190 5620 : dividend[i] = newdig;
9191 : }
9192 5 : dividend[qi] += carry;
9193 :
9194 : /*
9195 : * All the dividend[] digits except possibly dividend[qi] are
9196 : * now in the range 0..NBASE^2-1. We do not need to consider
9197 : * dividend[qi] in the maxdiv value anymore, so we can reset
9198 : * maxdiv to 1.
9199 : */
9200 5 : maxdiv = 1;
9201 :
9202 : /*
9203 : * Recompute the quotient digit since new info may have
9204 : * propagated into the top two dividend digits.
9205 : */
9206 5 : fdividend = (double) dividend[qi] * NBASE_SQR;
9207 5 : fdividend += (double) dividend[qi + 1];
9208 5 : fquotient = fdividend * fdivisorinverse;
9209 5 : qdigit = (fquotient >= 0.0) ? ((int32) fquotient) :
9210 0 : (((int32) fquotient) - 1); /* truncate towards -infinity */
9211 :
9212 5 : maxdiv += i64abs(qdigit);
9213 : }
9214 :
9215 : /*
9216 : * Subtract off the appropriate multiple of the divisor.
9217 : *
9218 : * The digits beyond dividend[qi] cannot overflow, because we know
9219 : * they will fall within the maxdiv limit. As for dividend[qi]
9220 : * itself, note that qdigit is approximately trunc(dividend[qi] /
9221 : * divisor[0]), which would make the new value simply dividend[qi]
9222 : * mod divisor[0]. The lower-order terms in qdigit can change
9223 : * this result by not more than about twice PG_INT64_MAX/NBASE^2,
9224 : * so overflow is impossible.
9225 : *
9226 : * This inner loop is the performance bottleneck for division, so
9227 : * code it in the same way as the inner loop of mul_var() so that
9228 : * it can be auto-vectorized.
9229 : */
9230 29863 : if (qdigit != 0)
9231 : {
9232 29863 : int istop = Min(var2ndigitpairs, div_ndigitpairs - qi);
9233 29863 : int64 *dividend_qi = ÷nd[qi];
9234 :
9235 6518873 : for (i = 0; i < istop; i++)
9236 6489010 : dividend_qi[i] -= (int64) qdigit * divisor[i];
9237 : }
9238 : }
9239 :
9240 : /*
9241 : * The dividend digit we are about to replace might still be nonzero.
9242 : * Fold it into the next digit position.
9243 : *
9244 : * There is no risk of overflow here, although proving that requires
9245 : * some care. Much as with the argument for dividend[qi] not
9246 : * overflowing, if we consider the first two terms in the numerator
9247 : * and denominator of qdigit, we can see that the final value of
9248 : * dividend[qi + 1] will be approximately a remainder mod
9249 : * (divisor[0]*NBASE^2 + divisor[1]). Accounting for the lower-order
9250 : * terms is a bit complicated but ends up adding not much more than
9251 : * PG_INT64_MAX/NBASE^2 to the possible range. Thus, dividend[qi + 1]
9252 : * cannot overflow here, and in its role as dividend[qi] in the next
9253 : * loop iteration, it can't be large enough to cause overflow in the
9254 : * carry propagation step (if any), either.
9255 : *
9256 : * But having said that: dividend[qi] can be more than
9257 : * PG_INT64_MAX/NBASE^2, as noted above, which means that the product
9258 : * dividend[qi] * NBASE^2 *can* overflow. When that happens, adding
9259 : * it to dividend[qi + 1] will always cause a canceling overflow so
9260 : * that the end result is correct. We could avoid the intermediate
9261 : * overflow by doing the multiplication and addition using unsigned
9262 : * int64 arithmetic, which is modulo 2^64, but so far there appears no
9263 : * need.
9264 : */
9265 32496 : dividend[qi + 1] += dividend[qi] * NBASE_SQR;
9266 :
9267 32496 : dividend[qi] = qdigit;
9268 : }
9269 :
9270 : /*
9271 : * If an exact result was requested, use the remainder to correct the
9272 : * approximate quotient. The remainder is in dividend[], immediately
9273 : * after the quotient digits. Note, however, that although the remainder
9274 : * starts at dividend[qi = res_ndigitpairs], the first digit is the result
9275 : * of folding two remainder digits into one above, and the remainder
9276 : * currently only occupies var2ndigitpairs - 1 digits (the last digit of
9277 : * the working dividend was untouched by the computation above). Thus we
9278 : * expand the remainder down by one base-NBASE^2 digit when we normalize
9279 : * it, so that it completely fills the last var2ndigitpairs digits of the
9280 : * dividend array.
9281 : */
9282 3968 : if (exact)
9283 : {
9284 : /* Normalize the remainder, expanding it down by one digit */
9285 2722 : remainder = ÷nd[qi];
9286 2722 : carry = 0;
9287 15518 : for (i = var2ndigitpairs - 2; i >= 0; i--)
9288 : {
9289 12796 : newdig = remainder[i] + carry;
9290 12796 : if (newdig < 0)
9291 : {
9292 10044 : carry = -((-newdig - 1) / NBASE_SQR) - 1;
9293 10044 : newdig -= carry * NBASE_SQR;
9294 : }
9295 2752 : else if (newdig >= NBASE_SQR)
9296 : {
9297 2696 : carry = newdig / NBASE_SQR;
9298 2696 : newdig -= carry * NBASE_SQR;
9299 : }
9300 : else
9301 56 : carry = 0;
9302 12796 : remainder[i + 1] = newdig;
9303 : }
9304 2722 : remainder[0] = carry;
9305 :
9306 2722 : if (remainder[0] < 0)
9307 : {
9308 : /*
9309 : * The remainder is negative, so the approximate quotient is too
9310 : * large. Correct by reducing the quotient by one and adding the
9311 : * divisor to the remainder until the remainder is positive. We
9312 : * expect the quotient to be off by at most one, which has been
9313 : * borne out in all testing, but not conclusively proven, so we
9314 : * allow for larger corrections, just in case.
9315 : */
9316 : do
9317 : {
9318 : /* Add the divisor to the remainder */
9319 5 : carry = 0;
9320 65 : for (i = var2ndigitpairs - 1; i > 0; i--)
9321 : {
9322 60 : newdig = remainder[i] + divisor[i] + carry;
9323 60 : if (newdig >= NBASE_SQR)
9324 : {
9325 0 : remainder[i] = newdig - NBASE_SQR;
9326 0 : carry = 1;
9327 : }
9328 : else
9329 : {
9330 60 : remainder[i] = newdig;
9331 60 : carry = 0;
9332 : }
9333 : }
9334 5 : remainder[0] += divisor[0] + carry;
9335 :
9336 : /* Subtract 1 from the quotient (propagating carries later) */
9337 5 : dividend[qi - 1]--;
9338 :
9339 5 : } while (remainder[0] < 0);
9340 : }
9341 : else
9342 : {
9343 : /*
9344 : * The remainder is nonnegative. If it's greater than or equal to
9345 : * the divisor, then the approximate quotient is too small and
9346 : * must be corrected. As above, we don't expect to have to apply
9347 : * more than one correction, but allow for it just in case.
9348 : */
9349 : while (true)
9350 5 : {
9351 2722 : bool less = false;
9352 :
9353 : /* Is remainder < divisor? */
9354 2737 : for (i = 0; i < var2ndigitpairs; i++)
9355 : {
9356 2732 : if (remainder[i] < divisor[i])
9357 : {
9358 2717 : less = true;
9359 2717 : break;
9360 : }
9361 15 : if (remainder[i] > divisor[i])
9362 0 : break; /* remainder > divisor */
9363 : }
9364 2722 : if (less)
9365 2717 : break; /* quotient is correct */
9366 :
9367 : /* Subtract the divisor from the remainder */
9368 5 : carry = 0;
9369 15 : for (i = var2ndigitpairs - 1; i > 0; i--)
9370 : {
9371 10 : newdig = remainder[i] - divisor[i] + carry;
9372 10 : if (newdig < 0)
9373 : {
9374 0 : remainder[i] = newdig + NBASE_SQR;
9375 0 : carry = -1;
9376 : }
9377 : else
9378 : {
9379 10 : remainder[i] = newdig;
9380 10 : carry = 0;
9381 : }
9382 : }
9383 5 : remainder[0] = remainder[0] - divisor[0] + carry;
9384 :
9385 : /* Add 1 to the quotient (propagating carries later) */
9386 5 : dividend[qi - 1]++;
9387 : }
9388 : }
9389 : }
9390 :
9391 : /*
9392 : * Because the quotient digits were estimates that might have been off by
9393 : * one (and we didn't bother propagating carries when adjusting the
9394 : * quotient above), some quotient digits might be out of range, so do a
9395 : * final carry propagation pass to normalize back to base NBASE^2, and
9396 : * construct the base-NBASE result digits. Note that this is still done
9397 : * at full precision w/guard digits.
9398 : */
9399 3968 : alloc_var(result, res_ndigits);
9400 3968 : res_digits = result->digits;
9401 3968 : carry = 0;
9402 36464 : for (i = res_ndigitpairs - 1; i >= 0; i--)
9403 : {
9404 32496 : newdig = dividend[i] + carry;
9405 32496 : if (newdig < 0)
9406 : {
9407 5 : carry = -((-newdig - 1) / NBASE_SQR) - 1;
9408 5 : newdig -= carry * NBASE_SQR;
9409 : }
9410 32491 : else if (newdig >= NBASE_SQR)
9411 : {
9412 0 : carry = newdig / NBASE_SQR;
9413 0 : newdig -= carry * NBASE_SQR;
9414 : }
9415 : else
9416 32491 : carry = 0;
9417 32496 : res_digits[2 * i + 1] = (NumericDigit) ((uint32) newdig % NBASE);
9418 32496 : res_digits[2 * i] = (NumericDigit) ((uint32) newdig / NBASE);
9419 : }
9420 : Assert(carry == 0);
9421 :
9422 3968 : pfree(dividend);
9423 :
9424 : /*
9425 : * Finally, round or truncate the result to the requested precision.
9426 : */
9427 3968 : result->weight = res_weight;
9428 3968 : result->sign = res_sign;
9429 :
9430 : /* Round or truncate to target rscale (and set result->dscale) */
9431 3968 : if (round)
9432 658 : round_var(result, rscale);
9433 : else
9434 3310 : trunc_var(result, rscale);
9435 :
9436 : /* Strip leading and trailing zeroes */
9437 3968 : strip_var(result);
9438 : }
9439 :
9440 :
9441 : /*
9442 : * div_var_int() -
9443 : *
9444 : * Divide a numeric variable by a 32-bit integer with the specified weight.
9445 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9446 : */
9447 : static void
9448 389752 : div_var_int(const NumericVar *var, int ival, int ival_weight,
9449 : NumericVar *result, int rscale, bool round)
9450 : {
9451 389752 : NumericDigit *var_digits = var->digits;
9452 389752 : int var_ndigits = var->ndigits;
9453 : int res_sign;
9454 : int res_weight;
9455 : int res_ndigits;
9456 : NumericDigit *res_buf;
9457 : NumericDigit *res_digits;
9458 : uint32 divisor;
9459 : int i;
9460 :
9461 : /* Guard against division by zero */
9462 389752 : if (ival == 0)
9463 0 : ereport(ERROR,
9464 : errcode(ERRCODE_DIVISION_BY_ZERO),
9465 : errmsg("division by zero"));
9466 :
9467 : /* Result zero check */
9468 389752 : if (var_ndigits == 0)
9469 : {
9470 1583 : zero_var(result);
9471 1583 : result->dscale = rscale;
9472 1583 : return;
9473 : }
9474 :
9475 : /*
9476 : * Determine the result sign, weight and number of digits to calculate.
9477 : * The weight figured here is correct if the emitted quotient has no
9478 : * leading zero digits; otherwise strip_var() will fix things up.
9479 : */
9480 388169 : if (var->sign == NUMERIC_POS)
9481 385925 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9482 : else
9483 2244 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
9484 388169 : res_weight = var->weight - ival_weight;
9485 : /* The number of accurate result digits we need to produce: */
9486 388169 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9487 : /* ... but always at least 1 */
9488 388169 : res_ndigits = Max(res_ndigits, 1);
9489 : /* If rounding needed, figure one more digit to ensure correct result */
9490 388169 : if (round)
9491 111693 : res_ndigits++;
9492 :
9493 388169 : res_buf = digitbuf_alloc(res_ndigits + 1);
9494 388169 : res_buf[0] = 0; /* spare digit for later rounding */
9495 388169 : res_digits = res_buf + 1;
9496 :
9497 : /*
9498 : * Now compute the quotient digits. This is the short division algorithm
9499 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9500 : * allow the divisor to exceed the internal base.
9501 : *
9502 : * In this algorithm, the carry from one digit to the next is at most
9503 : * divisor - 1. Therefore, while processing the next digit, carry may
9504 : * become as large as divisor * NBASE - 1, and so it requires a 64-bit
9505 : * integer if this exceeds UINT_MAX.
9506 : */
9507 388169 : divisor = abs(ival);
9508 :
9509 388169 : if (divisor <= UINT_MAX / NBASE)
9510 : {
9511 : /* carry cannot overflow 32 bits */
9512 386370 : uint32 carry = 0;
9513 :
9514 1914216 : for (i = 0; i < res_ndigits; i++)
9515 : {
9516 1527846 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9517 1527846 : res_digits[i] = (NumericDigit) (carry / divisor);
9518 1527846 : carry = carry % divisor;
9519 : }
9520 : }
9521 : else
9522 : {
9523 : /* carry may exceed 32 bits */
9524 1799 : uint64 carry = 0;
9525 :
9526 5846 : for (i = 0; i < res_ndigits; i++)
9527 : {
9528 4047 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9529 4047 : res_digits[i] = (NumericDigit) (carry / divisor);
9530 4047 : carry = carry % divisor;
9531 : }
9532 : }
9533 :
9534 : /* Store the quotient in result */
9535 388169 : digitbuf_free(result->buf);
9536 388169 : result->ndigits = res_ndigits;
9537 388169 : result->buf = res_buf;
9538 388169 : result->digits = res_digits;
9539 388169 : result->weight = res_weight;
9540 388169 : result->sign = res_sign;
9541 :
9542 : /* Round or truncate to target rscale (and set result->dscale) */
9543 388169 : if (round)
9544 111693 : round_var(result, rscale);
9545 : else
9546 276476 : trunc_var(result, rscale);
9547 :
9548 : /* Strip leading/trailing zeroes */
9549 388169 : strip_var(result);
9550 : }
9551 :
9552 :
9553 : #ifdef HAVE_INT128
9554 : /*
9555 : * div_var_int64() -
9556 : *
9557 : * Divide a numeric variable by a 64-bit integer with the specified weight.
9558 : * The quotient var / (ival * NBASE^ival_weight) is stored in result.
9559 : *
9560 : * This duplicates the logic in div_var_int(), so any changes made there
9561 : * should be made here too.
9562 : */
9563 : static void
9564 360 : div_var_int64(const NumericVar *var, int64 ival, int ival_weight,
9565 : NumericVar *result, int rscale, bool round)
9566 : {
9567 360 : NumericDigit *var_digits = var->digits;
9568 360 : int var_ndigits = var->ndigits;
9569 : int res_sign;
9570 : int res_weight;
9571 : int res_ndigits;
9572 : NumericDigit *res_buf;
9573 : NumericDigit *res_digits;
9574 : uint64 divisor;
9575 : int i;
9576 :
9577 : /* Guard against division by zero */
9578 360 : if (ival == 0)
9579 0 : ereport(ERROR,
9580 : errcode(ERRCODE_DIVISION_BY_ZERO),
9581 : errmsg("division by zero"));
9582 :
9583 : /* Result zero check */
9584 360 : if (var_ndigits == 0)
9585 : {
9586 64 : zero_var(result);
9587 64 : result->dscale = rscale;
9588 64 : return;
9589 : }
9590 :
9591 : /*
9592 : * Determine the result sign, weight and number of digits to calculate.
9593 : * The weight figured here is correct if the emitted quotient has no
9594 : * leading zero digits; otherwise strip_var() will fix things up.
9595 : */
9596 296 : if (var->sign == NUMERIC_POS)
9597 175 : res_sign = ival > 0 ? NUMERIC_POS : NUMERIC_NEG;
9598 : else
9599 121 : res_sign = ival > 0 ? NUMERIC_NEG : NUMERIC_POS;
9600 296 : res_weight = var->weight - ival_weight;
9601 : /* The number of accurate result digits we need to produce: */
9602 296 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
9603 : /* ... but always at least 1 */
9604 296 : res_ndigits = Max(res_ndigits, 1);
9605 : /* If rounding needed, figure one more digit to ensure correct result */
9606 296 : if (round)
9607 291 : res_ndigits++;
9608 :
9609 296 : res_buf = digitbuf_alloc(res_ndigits + 1);
9610 296 : res_buf[0] = 0; /* spare digit for later rounding */
9611 296 : res_digits = res_buf + 1;
9612 :
9613 : /*
9614 : * Now compute the quotient digits. This is the short division algorithm
9615 : * described in Knuth volume 2, section 4.3.1 exercise 16, except that we
9616 : * allow the divisor to exceed the internal base.
9617 : *
9618 : * In this algorithm, the carry from one digit to the next is at most
9619 : * divisor - 1. Therefore, while processing the next digit, carry may
9620 : * become as large as divisor * NBASE - 1, and so it requires a 128-bit
9621 : * integer if this exceeds PG_UINT64_MAX.
9622 : */
9623 296 : divisor = i64abs(ival);
9624 :
9625 296 : if (divisor <= PG_UINT64_MAX / NBASE)
9626 : {
9627 : /* carry cannot overflow 64 bits */
9628 232 : uint64 carry = 0;
9629 :
9630 2361 : for (i = 0; i < res_ndigits; i++)
9631 : {
9632 2129 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9633 2129 : res_digits[i] = (NumericDigit) (carry / divisor);
9634 2129 : carry = carry % divisor;
9635 : }
9636 : }
9637 : else
9638 : {
9639 : /* carry may exceed 64 bits */
9640 64 : uint128 carry = 0;
9641 :
9642 688 : for (i = 0; i < res_ndigits; i++)
9643 : {
9644 624 : carry = carry * NBASE + (i < var_ndigits ? var_digits[i] : 0);
9645 624 : res_digits[i] = (NumericDigit) (carry / divisor);
9646 624 : carry = carry % divisor;
9647 : }
9648 : }
9649 :
9650 : /* Store the quotient in result */
9651 296 : digitbuf_free(result->buf);
9652 296 : result->ndigits = res_ndigits;
9653 296 : result->buf = res_buf;
9654 296 : result->digits = res_digits;
9655 296 : result->weight = res_weight;
9656 296 : result->sign = res_sign;
9657 :
9658 : /* Round or truncate to target rscale (and set result->dscale) */
9659 296 : if (round)
9660 291 : round_var(result, rscale);
9661 : else
9662 5 : trunc_var(result, rscale);
9663 :
9664 : /* Strip leading/trailing zeroes */
9665 296 : strip_var(result);
9666 : }
9667 : #endif
9668 :
9669 :
9670 : /*
9671 : * Default scale selection for division
9672 : *
9673 : * Returns the appropriate result scale for the division result.
9674 : */
9675 : static int
9676 99372 : select_div_scale(const NumericVar *var1, const NumericVar *var2)
9677 : {
9678 : int weight1,
9679 : weight2,
9680 : qweight,
9681 : i;
9682 : NumericDigit firstdigit1,
9683 : firstdigit2;
9684 : int rscale;
9685 :
9686 : /*
9687 : * The result scale of a division isn't specified in any SQL standard. For
9688 : * PostgreSQL we select a result scale that will give at least
9689 : * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
9690 : * result no less accurate than float8; but use a scale not less than
9691 : * either input's display scale.
9692 : */
9693 :
9694 : /* Get the actual (normalized) weight and first digit of each input */
9695 :
9696 99372 : weight1 = 0; /* values to use if var1 is zero */
9697 99372 : firstdigit1 = 0;
9698 99372 : for (i = 0; i < var1->ndigits; i++)
9699 : {
9700 98239 : firstdigit1 = var1->digits[i];
9701 98239 : if (firstdigit1 != 0)
9702 : {
9703 98239 : weight1 = var1->weight - i;
9704 98239 : break;
9705 : }
9706 : }
9707 :
9708 99372 : weight2 = 0; /* values to use if var2 is zero */
9709 99372 : firstdigit2 = 0;
9710 99372 : for (i = 0; i < var2->ndigits; i++)
9711 : {
9712 99339 : firstdigit2 = var2->digits[i];
9713 99339 : if (firstdigit2 != 0)
9714 : {
9715 99339 : weight2 = var2->weight - i;
9716 99339 : break;
9717 : }
9718 : }
9719 :
9720 : /*
9721 : * Estimate weight of quotient. If the two first digits are equal, we
9722 : * can't be sure, but assume that var1 is less than var2.
9723 : */
9724 99372 : qweight = weight1 - weight2;
9725 99372 : if (firstdigit1 <= firstdigit2)
9726 88541 : qweight--;
9727 :
9728 : /* Select result scale */
9729 99372 : rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
9730 99372 : rscale = Max(rscale, var1->dscale);
9731 99372 : rscale = Max(rscale, var2->dscale);
9732 99372 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
9733 99372 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
9734 :
9735 99372 : return rscale;
9736 : }
9737 :
9738 :
9739 : /*
9740 : * mod_var() -
9741 : *
9742 : * Calculate the modulo of two numerics at variable level
9743 : */
9744 : static void
9745 275440 : mod_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
9746 : {
9747 : NumericVar tmp;
9748 :
9749 275440 : init_var(&tmp);
9750 :
9751 : /* ---------
9752 : * We do this using the equation
9753 : * mod(x,y) = x - trunc(x/y)*y
9754 : * div_var can be persuaded to give us trunc(x/y) directly.
9755 : * ----------
9756 : */
9757 275440 : div_var(var1, var2, &tmp, 0, false, true);
9758 :
9759 275440 : mul_var(var2, &tmp, &tmp, var2->dscale);
9760 :
9761 275440 : sub_var(var1, &tmp, result);
9762 :
9763 275440 : free_var(&tmp);
9764 275440 : }
9765 :
9766 :
9767 : /*
9768 : * div_mod_var() -
9769 : *
9770 : * Calculate the truncated integer quotient and numeric remainder of two
9771 : * numeric variables. The remainder is precise to var2's dscale.
9772 : */
9773 : static void
9774 3295 : div_mod_var(const NumericVar *var1, const NumericVar *var2,
9775 : NumericVar *quot, NumericVar *rem)
9776 : {
9777 : NumericVar q;
9778 : NumericVar r;
9779 :
9780 3295 : init_var(&q);
9781 3295 : init_var(&r);
9782 :
9783 : /*
9784 : * Use div_var() with exact = false to get an initial estimate for the
9785 : * integer quotient (truncated towards zero). This might be slightly
9786 : * inaccurate, but we correct it below.
9787 : */
9788 3295 : div_var(var1, var2, &q, 0, false, false);
9789 :
9790 : /* Compute initial estimate of remainder using the quotient estimate. */
9791 3295 : mul_var(var2, &q, &r, var2->dscale);
9792 3295 : sub_var(var1, &r, &r);
9793 :
9794 : /*
9795 : * Adjust the results if necessary --- the remainder should have the same
9796 : * sign as var1, and its absolute value should be less than the absolute
9797 : * value of var2.
9798 : */
9799 3295 : while (r.ndigits != 0 && r.sign != var1->sign)
9800 : {
9801 : /* The absolute value of the quotient is too large */
9802 0 : if (var1->sign == var2->sign)
9803 : {
9804 0 : sub_var(&q, &const_one, &q);
9805 0 : add_var(&r, var2, &r);
9806 : }
9807 : else
9808 : {
9809 0 : add_var(&q, &const_one, &q);
9810 0 : sub_var(&r, var2, &r);
9811 : }
9812 : }
9813 :
9814 3295 : while (cmp_abs(&r, var2) >= 0)
9815 : {
9816 : /* The absolute value of the quotient is too small */
9817 0 : if (var1->sign == var2->sign)
9818 : {
9819 0 : add_var(&q, &const_one, &q);
9820 0 : sub_var(&r, var2, &r);
9821 : }
9822 : else
9823 : {
9824 0 : sub_var(&q, &const_one, &q);
9825 0 : add_var(&r, var2, &r);
9826 : }
9827 : }
9828 :
9829 3295 : set_var_from_var(&q, quot);
9830 3295 : set_var_from_var(&r, rem);
9831 :
9832 3295 : free_var(&q);
9833 3295 : free_var(&r);
9834 3295 : }
9835 :
9836 :
9837 : /*
9838 : * ceil_var() -
9839 : *
9840 : * Return the smallest integer greater than or equal to the argument
9841 : * on variable level
9842 : */
9843 : static void
9844 136 : ceil_var(const NumericVar *var, NumericVar *result)
9845 : {
9846 : NumericVar tmp;
9847 :
9848 136 : init_var(&tmp);
9849 136 : set_var_from_var(var, &tmp);
9850 :
9851 136 : trunc_var(&tmp, 0);
9852 :
9853 136 : if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
9854 40 : add_var(&tmp, &const_one, &tmp);
9855 :
9856 136 : set_var_from_var(&tmp, result);
9857 136 : free_var(&tmp);
9858 136 : }
9859 :
9860 :
9861 : /*
9862 : * floor_var() -
9863 : *
9864 : * Return the largest integer equal to or less than the argument
9865 : * on variable level
9866 : */
9867 : static void
9868 72 : floor_var(const NumericVar *var, NumericVar *result)
9869 : {
9870 : NumericVar tmp;
9871 :
9872 72 : init_var(&tmp);
9873 72 : set_var_from_var(var, &tmp);
9874 :
9875 72 : trunc_var(&tmp, 0);
9876 :
9877 72 : if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
9878 20 : sub_var(&tmp, &const_one, &tmp);
9879 :
9880 72 : set_var_from_var(&tmp, result);
9881 72 : free_var(&tmp);
9882 72 : }
9883 :
9884 :
9885 : /*
9886 : * gcd_var() -
9887 : *
9888 : * Calculate the greatest common divisor of two numerics at variable level
9889 : */
9890 : static void
9891 148 : gcd_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
9892 : {
9893 : int res_dscale;
9894 : int cmp;
9895 : NumericVar tmp_arg;
9896 : NumericVar mod;
9897 :
9898 148 : res_dscale = Max(var1->dscale, var2->dscale);
9899 :
9900 : /*
9901 : * Arrange for var1 to be the number with the greater absolute value.
9902 : *
9903 : * This would happen automatically in the loop below, but avoids an
9904 : * expensive modulo operation.
9905 : */
9906 148 : cmp = cmp_abs(var1, var2);
9907 148 : if (cmp < 0)
9908 : {
9909 56 : const NumericVar *tmp = var1;
9910 :
9911 56 : var1 = var2;
9912 56 : var2 = tmp;
9913 : }
9914 :
9915 : /*
9916 : * Also avoid the taking the modulo if the inputs have the same absolute
9917 : * value, or if the smaller input is zero.
9918 : */
9919 148 : if (cmp == 0 || var2->ndigits == 0)
9920 : {
9921 48 : set_var_from_var(var1, result);
9922 48 : result->sign = NUMERIC_POS;
9923 48 : result->dscale = res_dscale;
9924 48 : return;
9925 : }
9926 :
9927 100 : init_var(&tmp_arg);
9928 100 : init_var(&mod);
9929 :
9930 : /* Use the Euclidean algorithm to find the GCD */
9931 100 : set_var_from_var(var1, &tmp_arg);
9932 100 : set_var_from_var(var2, result);
9933 :
9934 : for (;;)
9935 : {
9936 : /* this loop can take a while, so allow it to be interrupted */
9937 392 : CHECK_FOR_INTERRUPTS();
9938 :
9939 392 : mod_var(&tmp_arg, result, &mod);
9940 392 : if (mod.ndigits == 0)
9941 100 : break;
9942 292 : set_var_from_var(result, &tmp_arg);
9943 292 : set_var_from_var(&mod, result);
9944 : }
9945 100 : result->sign = NUMERIC_POS;
9946 100 : result->dscale = res_dscale;
9947 :
9948 100 : free_var(&tmp_arg);
9949 100 : free_var(&mod);
9950 : }
9951 :
9952 :
9953 : /*
9954 : * sqrt_var() -
9955 : *
9956 : * Compute the square root of x using the Karatsuba Square Root algorithm.
9957 : * NOTE: we allow rscale < 0 here, implying rounding before the decimal
9958 : * point.
9959 : */
9960 : static void
9961 3048 : sqrt_var(const NumericVar *arg, NumericVar *result, int rscale)
9962 : {
9963 : int stat;
9964 : int res_weight;
9965 : int res_ndigits;
9966 : int src_ndigits;
9967 : int step;
9968 : int ndigits[32];
9969 : int blen;
9970 : int64 arg_int64;
9971 : int src_idx;
9972 : int64 s_int64;
9973 : int64 r_int64;
9974 : NumericVar s_var;
9975 : NumericVar r_var;
9976 : NumericVar a0_var;
9977 : NumericVar a1_var;
9978 : NumericVar q_var;
9979 : NumericVar u_var;
9980 :
9981 3048 : stat = cmp_var(arg, &const_zero);
9982 3048 : if (stat == 0)
9983 : {
9984 12 : zero_var(result);
9985 12 : result->dscale = rscale;
9986 12 : return;
9987 : }
9988 :
9989 : /*
9990 : * SQL2003 defines sqrt() in terms of power, so we need to emit the right
9991 : * SQLSTATE error code if the operand is negative.
9992 : */
9993 3036 : if (stat < 0)
9994 4 : ereport(ERROR,
9995 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
9996 : errmsg("cannot take square root of a negative number")));
9997 :
9998 3032 : init_var(&s_var);
9999 3032 : init_var(&r_var);
10000 3032 : init_var(&a0_var);
10001 3032 : init_var(&a1_var);
10002 3032 : init_var(&q_var);
10003 3032 : init_var(&u_var);
10004 :
10005 : /*
10006 : * The result weight is half the input weight, rounded towards minus
10007 : * infinity --- res_weight = floor(arg->weight / 2).
10008 : */
10009 3032 : if (arg->weight >= 0)
10010 2761 : res_weight = arg->weight / 2;
10011 : else
10012 271 : res_weight = -((-arg->weight - 1) / 2 + 1);
10013 :
10014 : /*
10015 : * Number of NBASE digits to compute. To ensure correct rounding, compute
10016 : * at least 1 extra decimal digit. We explicitly allow rscale to be
10017 : * negative here, but must always compute at least 1 NBASE digit. Thus
10018 : * res_ndigits = res_weight + 1 + ceil((rscale + 1) / DEC_DIGITS) or 1.
10019 : */
10020 3032 : if (rscale + 1 >= 0)
10021 3032 : res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS) / DEC_DIGITS;
10022 : else
10023 0 : res_ndigits = res_weight + 1 - (-rscale - 1) / DEC_DIGITS;
10024 3032 : res_ndigits = Max(res_ndigits, 1);
10025 :
10026 : /*
10027 : * Number of source NBASE digits logically required to produce a result
10028 : * with this precision --- every digit before the decimal point, plus 2
10029 : * for each result digit after the decimal point (or minus 2 for each
10030 : * result digit we round before the decimal point).
10031 : */
10032 3032 : src_ndigits = arg->weight + 1 + (res_ndigits - res_weight - 1) * 2;
10033 3032 : src_ndigits = Max(src_ndigits, 1);
10034 :
10035 : /* ----------
10036 : * From this point on, we treat the input and the result as integers and
10037 : * compute the integer square root and remainder using the Karatsuba
10038 : * Square Root algorithm, which may be written recursively as follows:
10039 : *
10040 : * SqrtRem(n = a3*b^3 + a2*b^2 + a1*b + a0):
10041 : * [ for some base b, and coefficients a0,a1,a2,a3 chosen so that
10042 : * 0 <= a0,a1,a2 < b and a3 >= b/4 ]
10043 : * Let (s,r) = SqrtRem(a3*b + a2)
10044 : * Let (q,u) = DivRem(r*b + a1, 2*s)
10045 : * Let s = s*b + q
10046 : * Let r = u*b + a0 - q^2
10047 : * If r < 0 Then
10048 : * Let r = r + s
10049 : * Let s = s - 1
10050 : * Let r = r + s
10051 : * Return (s,r)
10052 : *
10053 : * See "Karatsuba Square Root", Paul Zimmermann, INRIA Research Report
10054 : * RR-3805, November 1999. At the time of writing this was available
10055 : * on the net at <https://hal.inria.fr/inria-00072854>.
10056 : *
10057 : * The way to read the assumption "n = a3*b^3 + a2*b^2 + a1*b + a0" is
10058 : * "choose a base b such that n requires at least four base-b digits to
10059 : * express; then those digits are a3,a2,a1,a0, with a3 possibly larger
10060 : * than b". For optimal performance, b should have approximately a
10061 : * quarter the number of digits in the input, so that the outer square
10062 : * root computes roughly twice as many digits as the inner one. For
10063 : * simplicity, we choose b = NBASE^blen, an integer power of NBASE.
10064 : *
10065 : * We implement the algorithm iteratively rather than recursively, to
10066 : * allow the working variables to be reused. With this approach, each
10067 : * digit of the input is read precisely once --- src_idx tracks the number
10068 : * of input digits used so far.
10069 : *
10070 : * The array ndigits[] holds the number of NBASE digits of the input that
10071 : * will have been used at the end of each iteration, which roughly doubles
10072 : * each time. Note that the array elements are stored in reverse order,
10073 : * so if the final iteration requires src_ndigits = 37 input digits, the
10074 : * array will contain [37,19,11,7,5,3], and we would start by computing
10075 : * the square root of the 3 most significant NBASE digits.
10076 : *
10077 : * In each iteration, we choose blen to be the largest integer for which
10078 : * the input number has a3 >= b/4, when written in the form above. In
10079 : * general, this means blen = src_ndigits / 4 (truncated), but if
10080 : * src_ndigits is a multiple of 4, that might lead to the coefficient a3
10081 : * being less than b/4 (if the first input digit is less than NBASE/4), in
10082 : * which case we choose blen = src_ndigits / 4 - 1. The number of digits
10083 : * in the inner square root is then src_ndigits - 2*blen. So, for
10084 : * example, if we have src_ndigits = 26 initially, the array ndigits[]
10085 : * will be either [26,14,8,4] or [26,14,8,6,4], depending on the size of
10086 : * the first input digit.
10087 : *
10088 : * Additionally, we can put an upper bound on the number of steps required
10089 : * as follows --- suppose that the number of source digits is an n-bit
10090 : * number in the range [2^(n-1), 2^n-1], then blen will be in the range
10091 : * [2^(n-3)-1, 2^(n-2)-1] and the number of digits in the inner square
10092 : * root will be in the range [2^(n-2), 2^(n-1)+1]. In the next step, blen
10093 : * will be in the range [2^(n-4)-1, 2^(n-3)] and the number of digits in
10094 : * the next inner square root will be in the range [2^(n-3), 2^(n-2)+1].
10095 : * This pattern repeats, and in the worst case the array ndigits[] will
10096 : * contain [2^n-1, 2^(n-1)+1, 2^(n-2)+1, ... 9, 5, 3], and the computation
10097 : * will require n steps. Therefore, since all digit array sizes are
10098 : * signed 32-bit integers, the number of steps required is guaranteed to
10099 : * be less than 32.
10100 : * ----------
10101 : */
10102 3032 : step = 0;
10103 14531 : while ((ndigits[step] = src_ndigits) > 4)
10104 : {
10105 : /* Choose b so that a3 >= b/4, as described above */
10106 11499 : blen = src_ndigits / 4;
10107 11499 : if (blen * 4 == src_ndigits && arg->digits[0] < NBASE / 4)
10108 259 : blen--;
10109 :
10110 : /* Number of digits in the next step (inner square root) */
10111 11499 : src_ndigits -= 2 * blen;
10112 11499 : step++;
10113 : }
10114 :
10115 : /*
10116 : * First iteration (innermost square root and remainder):
10117 : *
10118 : * Here src_ndigits <= 4, and the input fits in an int64. Its square root
10119 : * has at most 9 decimal digits, so estimate it using double precision
10120 : * arithmetic, which will in fact almost certainly return the correct
10121 : * result with no further correction required.
10122 : */
10123 3032 : arg_int64 = arg->digits[0];
10124 9695 : for (src_idx = 1; src_idx < src_ndigits; src_idx++)
10125 : {
10126 6663 : arg_int64 *= NBASE;
10127 6663 : if (src_idx < arg->ndigits)
10128 5647 : arg_int64 += arg->digits[src_idx];
10129 : }
10130 :
10131 3032 : s_int64 = (int64) sqrt((double) arg_int64);
10132 3032 : r_int64 = arg_int64 - s_int64 * s_int64;
10133 :
10134 : /*
10135 : * Use Newton's method to correct the result, if necessary.
10136 : *
10137 : * This uses integer division with truncation to compute the truncated
10138 : * integer square root by iterating using the formula x -> (x + n/x) / 2.
10139 : * This is known to converge to isqrt(n), unless n+1 is a perfect square.
10140 : * If n+1 is a perfect square, the sequence will oscillate between the two
10141 : * values isqrt(n) and isqrt(n)+1, so we can be assured of convergence by
10142 : * checking the remainder.
10143 : */
10144 3032 : while (r_int64 < 0 || r_int64 > 2 * s_int64)
10145 : {
10146 0 : s_int64 = (s_int64 + arg_int64 / s_int64) / 2;
10147 0 : r_int64 = arg_int64 - s_int64 * s_int64;
10148 : }
10149 :
10150 : /*
10151 : * Iterations with src_ndigits <= 8:
10152 : *
10153 : * The next 1 or 2 iterations compute larger (outer) square roots with
10154 : * src_ndigits <= 8, so the result still fits in an int64 (even though the
10155 : * input no longer does) and we can continue to compute using int64
10156 : * variables to avoid more expensive numeric computations.
10157 : *
10158 : * It is fairly easy to see that there is no risk of the intermediate
10159 : * values below overflowing 64-bit integers. In the worst case, the
10160 : * previous iteration will have computed a 3-digit square root (of a
10161 : * 6-digit input less than NBASE^6 / 4), so at the start of this
10162 : * iteration, s will be less than NBASE^3 / 2 = 10^12 / 2, and r will be
10163 : * less than 10^12. In this case, blen will be 1, so numer will be less
10164 : * than 10^17, and denom will be less than 10^12 (and hence u will also be
10165 : * less than 10^12). Finally, since q^2 = u*b + a0 - r, we can also be
10166 : * sure that q^2 < 10^17. Therefore all these quantities fit comfortably
10167 : * in 64-bit integers.
10168 : */
10169 3032 : step--;
10170 7672 : while (step >= 0 && (src_ndigits = ndigits[step]) <= 8)
10171 : {
10172 : int b;
10173 : int a0;
10174 : int a1;
10175 : int i;
10176 : int64 numer;
10177 : int64 denom;
10178 : int64 q;
10179 : int64 u;
10180 :
10181 4640 : blen = (src_ndigits - src_idx) / 2;
10182 :
10183 : /* Extract a1 and a0, and compute b */
10184 4640 : a0 = 0;
10185 4640 : a1 = 0;
10186 4640 : b = 1;
10187 :
10188 9399 : for (i = 0; i < blen; i++, src_idx++)
10189 : {
10190 4759 : b *= NBASE;
10191 4759 : a1 *= NBASE;
10192 4759 : if (src_idx < arg->ndigits)
10193 3532 : a1 += arg->digits[src_idx];
10194 : }
10195 :
10196 9399 : for (i = 0; i < blen; i++, src_idx++)
10197 : {
10198 4759 : a0 *= NBASE;
10199 4759 : if (src_idx < arg->ndigits)
10200 3420 : a0 += arg->digits[src_idx];
10201 : }
10202 :
10203 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10204 4640 : numer = r_int64 * b + a1;
10205 4640 : denom = 2 * s_int64;
10206 4640 : q = numer / denom;
10207 4640 : u = numer - q * denom;
10208 :
10209 : /* Compute s = s*b + q and r = u*b + a0 - q^2 */
10210 4640 : s_int64 = s_int64 * b + q;
10211 4640 : r_int64 = u * b + a0 - q * q;
10212 :
10213 4640 : if (r_int64 < 0)
10214 : {
10215 : /* s is too large by 1; set r += s, s--, r += s */
10216 161 : r_int64 += s_int64;
10217 161 : s_int64--;
10218 161 : r_int64 += s_int64;
10219 : }
10220 :
10221 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10222 4640 : step--;
10223 : }
10224 :
10225 : /*
10226 : * On platforms with 128-bit integer support, we can further delay the
10227 : * need to use numeric variables.
10228 : */
10229 : #ifdef HAVE_INT128
10230 3032 : if (step >= 0)
10231 : {
10232 : int128 s_int128;
10233 : int128 r_int128;
10234 :
10235 3032 : s_int128 = s_int64;
10236 3032 : r_int128 = r_int64;
10237 :
10238 : /*
10239 : * Iterations with src_ndigits <= 16:
10240 : *
10241 : * The result fits in an int128 (even though the input doesn't) so we
10242 : * use int128 variables to avoid more expensive numeric computations.
10243 : */
10244 6596 : while (step >= 0 && (src_ndigits = ndigits[step]) <= 16)
10245 : {
10246 : int64 b;
10247 : int64 a0;
10248 : int64 a1;
10249 : int64 i;
10250 : int128 numer;
10251 : int128 denom;
10252 : int128 q;
10253 : int128 u;
10254 :
10255 3564 : blen = (src_ndigits - src_idx) / 2;
10256 :
10257 : /* Extract a1 and a0, and compute b */
10258 3564 : a0 = 0;
10259 3564 : a1 = 0;
10260 3564 : b = 1;
10261 :
10262 11796 : for (i = 0; i < blen; i++, src_idx++)
10263 : {
10264 8232 : b *= NBASE;
10265 8232 : a1 *= NBASE;
10266 8232 : if (src_idx < arg->ndigits)
10267 4947 : a1 += arg->digits[src_idx];
10268 : }
10269 :
10270 11796 : for (i = 0; i < blen; i++, src_idx++)
10271 : {
10272 8232 : a0 *= NBASE;
10273 8232 : if (src_idx < arg->ndigits)
10274 3407 : a0 += arg->digits[src_idx];
10275 : }
10276 :
10277 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10278 3564 : numer = r_int128 * b + a1;
10279 3564 : denom = 2 * s_int128;
10280 3564 : q = numer / denom;
10281 3564 : u = numer - q * denom;
10282 :
10283 : /* Compute s = s*b + q and r = u*b + a0 - q^2 */
10284 3564 : s_int128 = s_int128 * b + q;
10285 3564 : r_int128 = u * b + a0 - q * q;
10286 :
10287 3564 : if (r_int128 < 0)
10288 : {
10289 : /* s is too large by 1; set r += s, s--, r += s */
10290 146 : r_int128 += s_int128;
10291 146 : s_int128--;
10292 146 : r_int128 += s_int128;
10293 : }
10294 :
10295 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10296 3564 : step--;
10297 : }
10298 :
10299 : /*
10300 : * All remaining iterations require numeric variables. Convert the
10301 : * integer values to NumericVar and continue. Note that in the final
10302 : * iteration we don't need the remainder, so we can save a few cycles
10303 : * there by not fully computing it.
10304 : */
10305 3032 : int128_to_numericvar(s_int128, &s_var);
10306 3032 : if (step >= 0)
10307 2008 : int128_to_numericvar(r_int128, &r_var);
10308 : }
10309 : else
10310 : {
10311 0 : int64_to_numericvar(s_int64, &s_var);
10312 : /* step < 0, so we certainly don't need r */
10313 : }
10314 : #else /* !HAVE_INT128 */
10315 : int64_to_numericvar(s_int64, &s_var);
10316 : if (step >= 0)
10317 : int64_to_numericvar(r_int64, &r_var);
10318 : #endif /* HAVE_INT128 */
10319 :
10320 : /*
10321 : * The remaining iterations with src_ndigits > 8 (or 16, if have int128)
10322 : * use numeric variables.
10323 : */
10324 6327 : while (step >= 0)
10325 : {
10326 : int tmp_len;
10327 :
10328 3295 : src_ndigits = ndigits[step];
10329 3295 : blen = (src_ndigits - src_idx) / 2;
10330 :
10331 : /* Extract a1 and a0 */
10332 3295 : if (src_idx < arg->ndigits)
10333 : {
10334 1088 : tmp_len = Min(blen, arg->ndigits - src_idx);
10335 1088 : alloc_var(&a1_var, tmp_len);
10336 1088 : memcpy(a1_var.digits, arg->digits + src_idx,
10337 : tmp_len * sizeof(NumericDigit));
10338 1088 : a1_var.weight = blen - 1;
10339 1088 : a1_var.sign = NUMERIC_POS;
10340 1088 : a1_var.dscale = 0;
10341 1088 : strip_var(&a1_var);
10342 : }
10343 : else
10344 : {
10345 2207 : zero_var(&a1_var);
10346 2207 : a1_var.dscale = 0;
10347 : }
10348 3295 : src_idx += blen;
10349 :
10350 3295 : if (src_idx < arg->ndigits)
10351 : {
10352 1088 : tmp_len = Min(blen, arg->ndigits - src_idx);
10353 1088 : alloc_var(&a0_var, tmp_len);
10354 1088 : memcpy(a0_var.digits, arg->digits + src_idx,
10355 : tmp_len * sizeof(NumericDigit));
10356 1088 : a0_var.weight = blen - 1;
10357 1088 : a0_var.sign = NUMERIC_POS;
10358 1088 : a0_var.dscale = 0;
10359 1088 : strip_var(&a0_var);
10360 : }
10361 : else
10362 : {
10363 2207 : zero_var(&a0_var);
10364 2207 : a0_var.dscale = 0;
10365 : }
10366 3295 : src_idx += blen;
10367 :
10368 : /* Compute (q,u) = DivRem(r*b + a1, 2*s) */
10369 3295 : set_var_from_var(&r_var, &q_var);
10370 3295 : q_var.weight += blen;
10371 3295 : add_var(&q_var, &a1_var, &q_var);
10372 3295 : add_var(&s_var, &s_var, &u_var);
10373 3295 : div_mod_var(&q_var, &u_var, &q_var, &u_var);
10374 :
10375 : /* Compute s = s*b + q */
10376 3295 : s_var.weight += blen;
10377 3295 : add_var(&s_var, &q_var, &s_var);
10378 :
10379 : /*
10380 : * Compute r = u*b + a0 - q^2.
10381 : *
10382 : * In the final iteration, we don't actually need r; we just need to
10383 : * know whether it is negative, so that we know whether to adjust s.
10384 : * So instead of the final subtraction we can just compare.
10385 : */
10386 3295 : u_var.weight += blen;
10387 3295 : add_var(&u_var, &a0_var, &u_var);
10388 3295 : mul_var(&q_var, &q_var, &q_var, 0);
10389 :
10390 3295 : if (step > 0)
10391 : {
10392 : /* Need r for later iterations */
10393 1287 : sub_var(&u_var, &q_var, &r_var);
10394 1287 : if (r_var.sign == NUMERIC_NEG)
10395 : {
10396 : /* s is too large by 1; set r += s, s--, r += s */
10397 85 : add_var(&r_var, &s_var, &r_var);
10398 85 : sub_var(&s_var, &const_one, &s_var);
10399 85 : add_var(&r_var, &s_var, &r_var);
10400 : }
10401 : }
10402 : else
10403 : {
10404 : /* Don't need r anymore, except to test if s is too large by 1 */
10405 2008 : if (cmp_var(&u_var, &q_var) < 0)
10406 27 : sub_var(&s_var, &const_one, &s_var);
10407 : }
10408 :
10409 : Assert(src_idx == src_ndigits); /* All input digits consumed */
10410 3295 : step--;
10411 : }
10412 :
10413 : /*
10414 : * Construct the final result, rounding it to the requested precision.
10415 : */
10416 3032 : set_var_from_var(&s_var, result);
10417 3032 : result->weight = res_weight;
10418 3032 : result->sign = NUMERIC_POS;
10419 :
10420 : /* Round to target rscale (and set result->dscale) */
10421 3032 : round_var(result, rscale);
10422 :
10423 : /* Strip leading and trailing zeroes */
10424 3032 : strip_var(result);
10425 :
10426 3032 : free_var(&s_var);
10427 3032 : free_var(&r_var);
10428 3032 : free_var(&a0_var);
10429 3032 : free_var(&a1_var);
10430 3032 : free_var(&q_var);
10431 3032 : free_var(&u_var);
10432 : }
10433 :
10434 :
10435 : /*
10436 : * exp_var() -
10437 : *
10438 : * Raise e to the power of x, computed to rscale fractional digits
10439 : */
10440 : static void
10441 139 : exp_var(const NumericVar *arg, NumericVar *result, int rscale)
10442 : {
10443 : NumericVar x;
10444 : NumericVar elem;
10445 : int ni;
10446 : double val;
10447 : int dweight;
10448 : int ndiv2;
10449 : int sig_digits;
10450 : int local_rscale;
10451 :
10452 139 : init_var(&x);
10453 139 : init_var(&elem);
10454 :
10455 139 : set_var_from_var(arg, &x);
10456 :
10457 : /*
10458 : * Estimate the dweight of the result using floating point arithmetic, so
10459 : * that we can choose an appropriate local rscale for the calculation.
10460 : */
10461 139 : val = numericvar_to_double_no_overflow(&x);
10462 :
10463 : /* Guard against overflow/underflow */
10464 : /* If you change this limit, see also power_var()'s limit */
10465 139 : if (fabs(val) >= NUMERIC_MAX_RESULT_SCALE * 3)
10466 : {
10467 5 : if (val > 0)
10468 0 : ereport(ERROR,
10469 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
10470 : errmsg("value overflows numeric format")));
10471 5 : zero_var(result);
10472 5 : result->dscale = rscale;
10473 5 : return;
10474 : }
10475 :
10476 : /* decimal weight = log10(e^x) = x * log10(e) */
10477 134 : dweight = (int) (val * 0.434294481903252);
10478 :
10479 : /*
10480 : * Reduce x to the range -0.01 <= x <= 0.01 (approximately) by dividing by
10481 : * 2^ndiv2, to improve the convergence rate of the Taylor series.
10482 : *
10483 : * Note that the overflow check above ensures that fabs(x) < 6000, which
10484 : * means that ndiv2 <= 20 here.
10485 : */
10486 134 : if (fabs(val) > 0.01)
10487 : {
10488 110 : ndiv2 = 1;
10489 110 : val /= 2;
10490 :
10491 1402 : while (fabs(val) > 0.01)
10492 : {
10493 1292 : ndiv2++;
10494 1292 : val /= 2;
10495 : }
10496 :
10497 110 : local_rscale = x.dscale + ndiv2;
10498 110 : div_var_int(&x, 1 << ndiv2, 0, &x, local_rscale, true);
10499 : }
10500 : else
10501 24 : ndiv2 = 0;
10502 :
10503 : /*
10504 : * Set the scale for the Taylor series expansion. The final result has
10505 : * (dweight + rscale + 1) significant digits. In addition, we have to
10506 : * raise the Taylor series result to the power 2^ndiv2, which introduces
10507 : * an error of up to around log10(2^ndiv2) digits, so work with this many
10508 : * extra digits of precision (plus a few more for good measure).
10509 : */
10510 134 : sig_digits = 1 + dweight + rscale + (int) (ndiv2 * 0.301029995663981);
10511 134 : sig_digits = Max(sig_digits, 0) + 8;
10512 :
10513 134 : local_rscale = sig_digits - 1;
10514 :
10515 : /*
10516 : * Use the Taylor series
10517 : *
10518 : * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
10519 : *
10520 : * Given the limited range of x, this should converge reasonably quickly.
10521 : * We run the series until the terms fall below the local_rscale limit.
10522 : */
10523 134 : add_var(&const_one, &x, result);
10524 :
10525 134 : mul_var(&x, &x, &elem, local_rscale);
10526 134 : ni = 2;
10527 134 : div_var_int(&elem, ni, 0, &elem, local_rscale, true);
10528 :
10529 3639 : while (elem.ndigits != 0)
10530 : {
10531 3505 : add_var(result, &elem, result);
10532 :
10533 3505 : mul_var(&elem, &x, &elem, local_rscale);
10534 3505 : ni++;
10535 3505 : div_var_int(&elem, ni, 0, &elem, local_rscale, true);
10536 : }
10537 :
10538 : /*
10539 : * Compensate for the argument range reduction. Since the weight of the
10540 : * result doubles with each multiplication, we can reduce the local rscale
10541 : * as we proceed.
10542 : */
10543 1536 : while (ndiv2-- > 0)
10544 : {
10545 1402 : local_rscale = sig_digits - result->weight * 2 * DEC_DIGITS;
10546 1402 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10547 1402 : mul_var(result, result, result, local_rscale);
10548 : }
10549 :
10550 : /* Round to requested rscale */
10551 134 : round_var(result, rscale);
10552 :
10553 134 : free_var(&x);
10554 134 : free_var(&elem);
10555 : }
10556 :
10557 :
10558 : /*
10559 : * Estimate the dweight of the most significant decimal digit of the natural
10560 : * logarithm of a number.
10561 : *
10562 : * Essentially, we're approximating log10(abs(ln(var))). This is used to
10563 : * determine the appropriate rscale when computing natural logarithms.
10564 : *
10565 : * Note: many callers call this before range-checking the input. Therefore,
10566 : * we must be robust against values that are invalid to apply ln() to.
10567 : * We don't wish to throw an error here, so just return zero in such cases.
10568 : */
10569 : static int
10570 534 : estimate_ln_dweight(const NumericVar *var)
10571 : {
10572 : int ln_dweight;
10573 :
10574 : /* Caller should fail on ln(negative), but for the moment return zero */
10575 534 : if (var->sign != NUMERIC_POS)
10576 28 : return 0;
10577 :
10578 953 : if (cmp_var(var, &const_zero_point_nine) >= 0 &&
10579 447 : cmp_var(var, &const_one_point_one) <= 0)
10580 70 : {
10581 : /*
10582 : * 0.9 <= var <= 1.1
10583 : *
10584 : * ln(var) has a negative weight (possibly very large). To get a
10585 : * reasonably accurate result, estimate it using ln(1+x) ~= x.
10586 : */
10587 : NumericVar x;
10588 :
10589 70 : init_var(&x);
10590 70 : sub_var(var, &const_one, &x);
10591 :
10592 70 : if (x.ndigits > 0)
10593 : {
10594 : /* Use weight of most significant decimal digit of x */
10595 35 : ln_dweight = x.weight * DEC_DIGITS + (int) log10(x.digits[0]);
10596 : }
10597 : else
10598 : {
10599 : /* x = 0. Since ln(1) = 0 exactly, we don't need extra digits */
10600 35 : ln_dweight = 0;
10601 : }
10602 :
10603 70 : free_var(&x);
10604 : }
10605 : else
10606 : {
10607 : /*
10608 : * Estimate the logarithm using the first couple of digits from the
10609 : * input number. This will give an accurate result whenever the input
10610 : * is not too close to 1.
10611 : */
10612 436 : if (var->ndigits > 0)
10613 : {
10614 : int digits;
10615 : int dweight;
10616 : double ln_var;
10617 :
10618 408 : digits = var->digits[0];
10619 408 : dweight = var->weight * DEC_DIGITS;
10620 :
10621 408 : if (var->ndigits > 1)
10622 : {
10623 250 : digits = digits * NBASE + var->digits[1];
10624 250 : dweight -= DEC_DIGITS;
10625 : }
10626 :
10627 : /*----------
10628 : * We have var ~= digits * 10^dweight
10629 : * so ln(var) ~= ln(digits) + dweight * ln(10)
10630 : *----------
10631 : */
10632 408 : ln_var = log((double) digits) + dweight * 2.302585092994046;
10633 408 : ln_dweight = (int) log10(fabs(ln_var));
10634 : }
10635 : else
10636 : {
10637 : /* Caller should fail on ln(0), but for the moment return zero */
10638 28 : ln_dweight = 0;
10639 : }
10640 : }
10641 :
10642 506 : return ln_dweight;
10643 : }
10644 :
10645 :
10646 : /*
10647 : * ln_var() -
10648 : *
10649 : * Compute the natural log of x
10650 : */
10651 : static void
10652 607 : ln_var(const NumericVar *arg, NumericVar *result, int rscale)
10653 : {
10654 : NumericVar x;
10655 : NumericVar xx;
10656 : int ni;
10657 : NumericVar elem;
10658 : NumericVar fact;
10659 : int nsqrt;
10660 : int local_rscale;
10661 : int cmp;
10662 :
10663 607 : cmp = cmp_var(arg, &const_zero);
10664 607 : if (cmp == 0)
10665 28 : ereport(ERROR,
10666 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
10667 : errmsg("cannot take logarithm of zero")));
10668 579 : else if (cmp < 0)
10669 24 : ereport(ERROR,
10670 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
10671 : errmsg("cannot take logarithm of a negative number")));
10672 :
10673 555 : init_var(&x);
10674 555 : init_var(&xx);
10675 555 : init_var(&elem);
10676 555 : init_var(&fact);
10677 :
10678 555 : set_var_from_var(arg, &x);
10679 555 : set_var_from_var(&const_two, &fact);
10680 :
10681 : /*
10682 : * Reduce input into range 0.9 < x < 1.1 with repeated sqrt() operations.
10683 : *
10684 : * The final logarithm will have up to around rscale+6 significant digits.
10685 : * Each sqrt() will roughly halve the weight of x, so adjust the local
10686 : * rscale as we work so that we keep this many significant digits at each
10687 : * step (plus a few more for good measure).
10688 : *
10689 : * Note that we allow local_rscale < 0 during this input reduction
10690 : * process, which implies rounding before the decimal point. sqrt_var()
10691 : * explicitly supports this, and it significantly reduces the work
10692 : * required to reduce very large inputs to the required range. Once the
10693 : * input reduction is complete, x.weight will be 0 and its display scale
10694 : * will be non-negative again.
10695 : */
10696 555 : nsqrt = 0;
10697 826 : while (cmp_var(&x, &const_zero_point_nine) <= 0)
10698 : {
10699 271 : local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
10700 271 : sqrt_var(&x, &x, local_rscale);
10701 271 : mul_var(&fact, &const_two, &fact, 0);
10702 271 : nsqrt++;
10703 : }
10704 2984 : while (cmp_var(&x, &const_one_point_one) >= 0)
10705 : {
10706 2429 : local_rscale = rscale - x.weight * DEC_DIGITS / 2 + 8;
10707 2429 : sqrt_var(&x, &x, local_rscale);
10708 2429 : mul_var(&fact, &const_two, &fact, 0);
10709 2429 : nsqrt++;
10710 : }
10711 :
10712 : /*
10713 : * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
10714 : *
10715 : * z + z^3/3 + z^5/5 + ...
10716 : *
10717 : * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
10718 : * due to the above range-reduction of x.
10719 : *
10720 : * The convergence of this is not as fast as one would like, but is
10721 : * tolerable given that z is small.
10722 : *
10723 : * The Taylor series result will be multiplied by 2^(nsqrt+1), which has a
10724 : * decimal weight of (nsqrt+1) * log10(2), so work with this many extra
10725 : * digits of precision (plus a few more for good measure).
10726 : */
10727 555 : local_rscale = rscale + (int) ((nsqrt + 1) * 0.301029995663981) + 8;
10728 :
10729 555 : sub_var(&x, &const_one, result);
10730 555 : add_var(&x, &const_one, &elem);
10731 555 : div_var(result, &elem, result, local_rscale, true, false);
10732 555 : set_var_from_var(result, &xx);
10733 555 : mul_var(result, result, &x, local_rscale);
10734 :
10735 555 : ni = 1;
10736 :
10737 : for (;;)
10738 : {
10739 10009 : ni += 2;
10740 10009 : mul_var(&xx, &x, &xx, local_rscale);
10741 10009 : div_var_int(&xx, ni, 0, &elem, local_rscale, true);
10742 :
10743 10009 : if (elem.ndigits == 0)
10744 555 : break;
10745 :
10746 9454 : add_var(result, &elem, result);
10747 :
10748 9454 : if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
10749 0 : break;
10750 : }
10751 :
10752 : /* Compensate for argument range reduction, round to requested rscale */
10753 555 : mul_var(result, &fact, result, rscale);
10754 :
10755 555 : free_var(&x);
10756 555 : free_var(&xx);
10757 555 : free_var(&elem);
10758 555 : free_var(&fact);
10759 555 : }
10760 :
10761 :
10762 : /*
10763 : * log_var() -
10764 : *
10765 : * Compute the logarithm of num in a given base.
10766 : *
10767 : * Note: this routine chooses dscale of the result.
10768 : */
10769 : static void
10770 156 : log_var(const NumericVar *base, const NumericVar *num, NumericVar *result)
10771 : {
10772 : NumericVar ln_base;
10773 : NumericVar ln_num;
10774 : int ln_base_dweight;
10775 : int ln_num_dweight;
10776 : int result_dweight;
10777 : int rscale;
10778 : int ln_base_rscale;
10779 : int ln_num_rscale;
10780 :
10781 156 : init_var(&ln_base);
10782 156 : init_var(&ln_num);
10783 :
10784 : /* Estimated dweights of ln(base), ln(num) and the final result */
10785 156 : ln_base_dweight = estimate_ln_dweight(base);
10786 156 : ln_num_dweight = estimate_ln_dweight(num);
10787 156 : result_dweight = ln_num_dweight - ln_base_dweight;
10788 :
10789 : /*
10790 : * Select the scale of the result so that it will have at least
10791 : * NUMERIC_MIN_SIG_DIGITS significant digits and is not less than either
10792 : * input's display scale.
10793 : */
10794 156 : rscale = NUMERIC_MIN_SIG_DIGITS - result_dweight;
10795 156 : rscale = Max(rscale, base->dscale);
10796 156 : rscale = Max(rscale, num->dscale);
10797 156 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
10798 156 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
10799 :
10800 : /*
10801 : * Set the scales for ln(base) and ln(num) so that they each have more
10802 : * significant digits than the final result.
10803 : */
10804 156 : ln_base_rscale = rscale + result_dweight - ln_base_dweight + 8;
10805 156 : ln_base_rscale = Max(ln_base_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10806 :
10807 156 : ln_num_rscale = rscale + result_dweight - ln_num_dweight + 8;
10808 156 : ln_num_rscale = Max(ln_num_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10809 :
10810 : /* Form natural logarithms */
10811 156 : ln_var(base, &ln_base, ln_base_rscale);
10812 140 : ln_var(num, &ln_num, ln_num_rscale);
10813 :
10814 : /* Divide and round to the required scale */
10815 120 : div_var(&ln_num, &ln_base, result, rscale, true, false);
10816 :
10817 116 : free_var(&ln_num);
10818 116 : free_var(&ln_base);
10819 116 : }
10820 :
10821 :
10822 : /*
10823 : * power_var() -
10824 : *
10825 : * Raise base to the power of exp
10826 : *
10827 : * Note: this routine chooses dscale of the result.
10828 : */
10829 : static void
10830 968 : power_var(const NumericVar *base, const NumericVar *exp, NumericVar *result)
10831 : {
10832 : int res_sign;
10833 : NumericVar abs_base;
10834 : NumericVar ln_base;
10835 : NumericVar ln_num;
10836 : int ln_dweight;
10837 : int rscale;
10838 : int sig_digits;
10839 : int local_rscale;
10840 : double val;
10841 :
10842 : /* If exp can be represented as an integer, use power_var_int */
10843 968 : if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
10844 : {
10845 : /* exact integer, but does it fit in int? */
10846 : int64 expval64;
10847 :
10848 878 : if (numericvar_to_int64(exp, &expval64))
10849 : {
10850 873 : if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
10851 : {
10852 : /* Okay, use power_var_int */
10853 848 : power_var_int(base, (int) expval64, exp->dscale, result);
10854 840 : return;
10855 : }
10856 : }
10857 : }
10858 :
10859 : /*
10860 : * This avoids log(0) for cases of 0 raised to a non-integer. 0 ^ 0 is
10861 : * handled by power_var_int().
10862 : */
10863 120 : if (cmp_var(base, &const_zero) == 0)
10864 : {
10865 14 : set_var_from_var(&const_zero, result);
10866 14 : result->dscale = NUMERIC_MIN_SIG_DIGITS; /* no need to round */
10867 14 : return;
10868 : }
10869 :
10870 106 : init_var(&abs_base);
10871 106 : init_var(&ln_base);
10872 106 : init_var(&ln_num);
10873 :
10874 : /*
10875 : * If base is negative, insist that exp be an integer. The result is then
10876 : * positive if exp is even and negative if exp is odd.
10877 : */
10878 106 : if (base->sign == NUMERIC_NEG)
10879 : {
10880 : /*
10881 : * Check that exp is an integer. This error code is defined by the
10882 : * SQL standard, and matches other errors in numeric_power().
10883 : */
10884 27 : if (exp->ndigits > 0 && exp->ndigits > exp->weight + 1)
10885 12 : ereport(ERROR,
10886 : (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
10887 : errmsg("a negative number raised to a non-integer power yields a complex result")));
10888 :
10889 : /* Test if exp is odd or even */
10890 15 : if (exp->ndigits > 0 && exp->ndigits == exp->weight + 1 &&
10891 10 : (exp->digits[exp->ndigits - 1] & 1))
10892 5 : res_sign = NUMERIC_NEG;
10893 : else
10894 10 : res_sign = NUMERIC_POS;
10895 :
10896 : /* Then work with abs(base) below */
10897 15 : set_var_from_var(base, &abs_base);
10898 15 : abs_base.sign = NUMERIC_POS;
10899 15 : base = &abs_base;
10900 : }
10901 : else
10902 79 : res_sign = NUMERIC_POS;
10903 :
10904 : /*----------
10905 : * Decide on the scale for the ln() calculation. For this we need an
10906 : * estimate of the weight of the result, which we obtain by doing an
10907 : * initial low-precision calculation of exp * ln(base).
10908 : *
10909 : * We want result = e ^ (exp * ln(base))
10910 : * so result dweight = log10(result) = exp * ln(base) * log10(e)
10911 : *
10912 : * We also perform a crude overflow test here so that we can exit early if
10913 : * the full-precision result is sure to overflow, and to guard against
10914 : * integer overflow when determining the scale for the real calculation.
10915 : * exp_var() supports inputs up to NUMERIC_MAX_RESULT_SCALE * 3, so the
10916 : * result will overflow if exp * ln(base) >= NUMERIC_MAX_RESULT_SCALE * 3.
10917 : * Since the values here are only approximations, we apply a small fuzz
10918 : * factor to this overflow test and let exp_var() determine the exact
10919 : * overflow threshold so that it is consistent for all inputs.
10920 : *----------
10921 : */
10922 94 : ln_dweight = estimate_ln_dweight(base);
10923 :
10924 : /*
10925 : * Set the scale for the low-precision calculation, computing ln(base) to
10926 : * around 8 significant digits. Note that ln_dweight may be as small as
10927 : * -NUMERIC_DSCALE_MAX, so the scale may exceed NUMERIC_MAX_DISPLAY_SCALE
10928 : * here.
10929 : */
10930 94 : local_rscale = 8 - ln_dweight;
10931 94 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10932 :
10933 94 : ln_var(base, &ln_base, local_rscale);
10934 :
10935 94 : mul_var(&ln_base, exp, &ln_num, local_rscale);
10936 :
10937 94 : val = numericvar_to_double_no_overflow(&ln_num);
10938 :
10939 : /* initial overflow/underflow test with fuzz factor */
10940 94 : if (fabs(val) > NUMERIC_MAX_RESULT_SCALE * 3.01)
10941 : {
10942 5 : if (val > 0)
10943 0 : ereport(ERROR,
10944 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
10945 : errmsg("value overflows numeric format")));
10946 5 : zero_var(result);
10947 5 : result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
10948 5 : return;
10949 : }
10950 :
10951 89 : val *= 0.434294481903252; /* approximate decimal result weight */
10952 :
10953 : /* choose the result scale */
10954 89 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
10955 89 : rscale = Max(rscale, base->dscale);
10956 89 : rscale = Max(rscale, exp->dscale);
10957 89 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
10958 89 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
10959 :
10960 : /* significant digits required in the result */
10961 89 : sig_digits = rscale + (int) val;
10962 89 : sig_digits = Max(sig_digits, 0);
10963 :
10964 : /* set the scale for the real exp * ln(base) calculation */
10965 89 : local_rscale = sig_digits - ln_dweight + 8;
10966 89 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
10967 :
10968 : /* and do the real calculation */
10969 :
10970 89 : ln_var(base, &ln_base, local_rscale);
10971 :
10972 89 : mul_var(&ln_base, exp, &ln_num, local_rscale);
10973 :
10974 89 : exp_var(&ln_num, result, rscale);
10975 :
10976 89 : if (res_sign == NUMERIC_NEG && result->ndigits > 0)
10977 5 : result->sign = NUMERIC_NEG;
10978 :
10979 89 : free_var(&ln_num);
10980 89 : free_var(&ln_base);
10981 89 : free_var(&abs_base);
10982 : }
10983 :
10984 : /*
10985 : * power_var_int() -
10986 : *
10987 : * Raise base to the power of exp, where exp is an integer.
10988 : *
10989 : * Note: this routine chooses dscale of the result.
10990 : */
10991 : static void
10992 848 : power_var_int(const NumericVar *base, int exp, int exp_dscale,
10993 : NumericVar *result)
10994 : {
10995 : double f;
10996 : int p;
10997 : int i;
10998 : int rscale;
10999 : int sig_digits;
11000 : unsigned int mask;
11001 : bool neg;
11002 : NumericVar base_prod;
11003 : int local_rscale;
11004 :
11005 : /*
11006 : * Choose the result scale. For this we need an estimate of the decimal
11007 : * weight of the result, which we obtain by approximating using double
11008 : * precision arithmetic.
11009 : *
11010 : * We also perform crude overflow/underflow tests here so that we can exit
11011 : * early if the result is sure to overflow/underflow, and to guard against
11012 : * integer overflow when choosing the result scale.
11013 : */
11014 848 : if (base->ndigits != 0)
11015 : {
11016 : /*----------
11017 : * Choose f (double) and p (int) such that base ~= f * 10^p.
11018 : * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
11019 : *----------
11020 : */
11021 826 : f = base->digits[0];
11022 826 : p = base->weight * DEC_DIGITS;
11023 :
11024 891 : for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
11025 : {
11026 65 : f = f * NBASE + base->digits[i];
11027 65 : p -= DEC_DIGITS;
11028 : }
11029 :
11030 826 : f = exp * (log10(f) + p); /* approximate decimal result weight */
11031 : }
11032 : else
11033 22 : f = 0; /* result is 0 or 1 (weight 0), or error */
11034 :
11035 : /* overflow/underflow tests with fuzz factors */
11036 848 : if (f > (NUMERIC_WEIGHT_MAX + 1) * DEC_DIGITS)
11037 8 : ereport(ERROR,
11038 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11039 : errmsg("value overflows numeric format")));
11040 840 : if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
11041 : {
11042 10 : zero_var(result);
11043 10 : result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
11044 151 : return;
11045 : }
11046 :
11047 : /*
11048 : * Choose the result scale in the same way as power_var(), so it has at
11049 : * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
11050 : * either input's display scale.
11051 : */
11052 830 : rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
11053 830 : rscale = Max(rscale, base->dscale);
11054 830 : rscale = Max(rscale, exp_dscale);
11055 830 : rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
11056 830 : rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
11057 :
11058 : /* Handle some common special cases, as well as corner cases */
11059 830 : switch (exp)
11060 : {
11061 52 : case 0:
11062 :
11063 : /*
11064 : * While 0 ^ 0 can be either 1 or indeterminate (error), we treat
11065 : * it as 1 because most programming languages do this. SQL:2003
11066 : * also requires a return value of 1.
11067 : * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
11068 : */
11069 52 : set_var_from_var(&const_one, result);
11070 52 : result->dscale = rscale; /* no need to round */
11071 52 : return;
11072 32 : case 1:
11073 32 : set_var_from_var(base, result);
11074 32 : round_var(result, rscale);
11075 32 : return;
11076 21 : case -1:
11077 21 : div_var(&const_one, base, result, rscale, true, true);
11078 21 : return;
11079 36 : case 2:
11080 36 : mul_var(base, base, result, rscale);
11081 36 : return;
11082 689 : default:
11083 689 : break;
11084 : }
11085 :
11086 : /* Handle the special case where the base is zero */
11087 689 : if (base->ndigits == 0)
11088 : {
11089 0 : if (exp < 0)
11090 0 : ereport(ERROR,
11091 : (errcode(ERRCODE_DIVISION_BY_ZERO),
11092 : errmsg("division by zero")));
11093 0 : zero_var(result);
11094 0 : result->dscale = rscale;
11095 0 : return;
11096 : }
11097 :
11098 : /*
11099 : * The general case repeatedly multiplies base according to the bit
11100 : * pattern of exp.
11101 : *
11102 : * The local rscale used for each multiplication is varied to keep a fixed
11103 : * number of significant digits, sufficient to give the required result
11104 : * scale.
11105 : */
11106 :
11107 : /*
11108 : * Approximate number of significant digits in the result. Note that the
11109 : * underflow test above, together with the choice of rscale, ensures that
11110 : * this approximation is necessarily > 0.
11111 : */
11112 689 : sig_digits = 1 + rscale + (int) f;
11113 :
11114 : /*
11115 : * The multiplications to produce the result may introduce an error of up
11116 : * to around log10(abs(exp)) digits, so work with this many extra digits
11117 : * of precision (plus a few more for good measure).
11118 : */
11119 689 : sig_digits += (int) log(fabs((double) exp)) + 8;
11120 :
11121 : /*
11122 : * Now we can proceed with the multiplications.
11123 : */
11124 689 : neg = (exp < 0);
11125 689 : mask = pg_abs_s32(exp);
11126 :
11127 689 : init_var(&base_prod);
11128 689 : set_var_from_var(base, &base_prod);
11129 :
11130 689 : if (mask & 1)
11131 343 : set_var_from_var(base, result);
11132 : else
11133 346 : set_var_from_var(&const_one, result);
11134 :
11135 3618 : while ((mask >>= 1) > 0)
11136 : {
11137 : /*
11138 : * Do the multiplications using rscales large enough to hold the
11139 : * results to the required number of significant digits, but don't
11140 : * waste time by exceeding the scales of the numbers themselves.
11141 : */
11142 2929 : local_rscale = sig_digits - 2 * base_prod.weight * DEC_DIGITS;
11143 2929 : local_rscale = Min(local_rscale, 2 * base_prod.dscale);
11144 2929 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11145 :
11146 2929 : mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
11147 :
11148 2929 : if (mask & 1)
11149 : {
11150 1932 : local_rscale = sig_digits -
11151 1932 : (base_prod.weight + result->weight) * DEC_DIGITS;
11152 1932 : local_rscale = Min(local_rscale,
11153 : base_prod.dscale + result->dscale);
11154 1932 : local_rscale = Max(local_rscale, NUMERIC_MIN_DISPLAY_SCALE);
11155 :
11156 1932 : mul_var(&base_prod, result, result, local_rscale);
11157 : }
11158 :
11159 : /*
11160 : * When abs(base) > 1, the number of digits to the left of the decimal
11161 : * point in base_prod doubles at each iteration, so if exp is large we
11162 : * could easily spend large amounts of time and memory space doing the
11163 : * multiplications. But once the weight exceeds what will fit in
11164 : * int16, the final result is guaranteed to overflow (or underflow, if
11165 : * exp < 0), so we can give up before wasting too many cycles.
11166 : */
11167 2929 : if (base_prod.weight > NUMERIC_WEIGHT_MAX ||
11168 2929 : result->weight > NUMERIC_WEIGHT_MAX)
11169 : {
11170 : /* overflow, unless neg, in which case result should be 0 */
11171 0 : if (!neg)
11172 0 : ereport(ERROR,
11173 : (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
11174 : errmsg("value overflows numeric format")));
11175 0 : zero_var(result);
11176 0 : neg = false;
11177 0 : break;
11178 : }
11179 : }
11180 :
11181 689 : free_var(&base_prod);
11182 :
11183 : /* Compensate for input sign, and round to requested rscale */
11184 689 : if (neg)
11185 328 : div_var(&const_one, result, result, rscale, true, false);
11186 : else
11187 361 : round_var(result, rscale);
11188 : }
11189 :
11190 : /*
11191 : * power_ten_int() -
11192 : *
11193 : * Raise ten to the power of exp, where exp is an integer. Note that unlike
11194 : * power_var_int(), this does no overflow/underflow checking or rounding.
11195 : */
11196 : static void
11197 152 : power_ten_int(int exp, NumericVar *result)
11198 : {
11199 : /* Construct the result directly, starting from 10^0 = 1 */
11200 152 : set_var_from_var(&const_one, result);
11201 :
11202 : /* Scale needed to represent the result exactly */
11203 152 : result->dscale = exp < 0 ? -exp : 0;
11204 :
11205 : /* Base-NBASE weight of result and remaining exponent */
11206 152 : if (exp >= 0)
11207 108 : result->weight = exp / DEC_DIGITS;
11208 : else
11209 44 : result->weight = (exp + 1) / DEC_DIGITS - 1;
11210 :
11211 152 : exp -= result->weight * DEC_DIGITS;
11212 :
11213 : /* Final adjustment of the result's single NBASE digit */
11214 396 : while (exp-- > 0)
11215 244 : result->digits[0] *= 10;
11216 152 : }
11217 :
11218 : /*
11219 : * random_var() - return a random value in the range [rmin, rmax].
11220 : */
11221 : static void
11222 22292 : random_var(pg_prng_state *state, const NumericVar *rmin,
11223 : const NumericVar *rmax, NumericVar *result)
11224 : {
11225 : int rscale;
11226 : NumericVar rlen;
11227 : int res_ndigits;
11228 : int n;
11229 : int pow10;
11230 : int i;
11231 : uint64 rlen64;
11232 : int rlen64_ndigits;
11233 :
11234 22292 : rscale = Max(rmin->dscale, rmax->dscale);
11235 :
11236 : /* Compute rlen = rmax - rmin and check the range bounds */
11237 22292 : init_var(&rlen);
11238 22292 : sub_var(rmax, rmin, &rlen);
11239 :
11240 22292 : if (rlen.sign == NUMERIC_NEG)
11241 4 : ereport(ERROR,
11242 : errcode(ERRCODE_INVALID_PARAMETER_VALUE),
11243 : errmsg("lower bound must be less than or equal to upper bound"));
11244 :
11245 : /* Special case for an empty range */
11246 22288 : if (rlen.ndigits == 0)
11247 : {
11248 8 : set_var_from_var(rmin, result);
11249 8 : result->dscale = rscale;
11250 8 : free_var(&rlen);
11251 8 : return;
11252 : }
11253 :
11254 : /*
11255 : * Otherwise, select a random value in the range [0, rlen = rmax - rmin],
11256 : * and shift it to the required range by adding rmin.
11257 : */
11258 :
11259 : /* Required result digits */
11260 22280 : res_ndigits = rlen.weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
11261 :
11262 : /*
11263 : * To get the required rscale, the final result digit must be a multiple
11264 : * of pow10 = 10^n, where n = (-rscale) mod DEC_DIGITS.
11265 : */
11266 22280 : n = ((rscale + DEC_DIGITS - 1) / DEC_DIGITS) * DEC_DIGITS - rscale;
11267 22280 : pow10 = 1;
11268 58600 : for (i = 0; i < n; i++)
11269 36320 : pow10 *= 10;
11270 :
11271 : /*
11272 : * To choose a random value uniformly from the range [0, rlen], we choose
11273 : * from the slightly larger range [0, rlen2], where rlen2 is formed from
11274 : * rlen by copying the first 4 NBASE digits, and setting all remaining
11275 : * decimal digits to "9".
11276 : *
11277 : * Without loss of generality, we can ignore the weight of rlen2 and treat
11278 : * it as a pure integer for the purposes of this discussion. The process
11279 : * above gives rlen2 + 1 = rlen64 * 10^N, for some integer N, where rlen64
11280 : * is a 64-bit integer formed from the first 4 NBASE digits copied from
11281 : * rlen. Since this trivially factors into smaller pieces that fit in
11282 : * 64-bit integers, the task of choosing a random value uniformly from the
11283 : * rlen2 + 1 possible values in [0, rlen2] is much simpler.
11284 : *
11285 : * If the random value selected is too large, it is rejected, and we try
11286 : * again until we get a result <= rlen, ensuring that the overall result
11287 : * is uniform (no particular value is any more likely than any other).
11288 : *
11289 : * Since rlen64 holds 4 NBASE digits from rlen, it contains at least
11290 : * DEC_DIGITS * 3 + 1 decimal digits (i.e., at least 13 decimal digits,
11291 : * when DEC_DIGITS is 4). Therefore the probability of needing to reject
11292 : * the value chosen and retry is less than 1e-13.
11293 : */
11294 22280 : rlen64 = (uint64) rlen.digits[0];
11295 22280 : rlen64_ndigits = 1;
11296 50808 : while (rlen64_ndigits < res_ndigits && rlen64_ndigits < 4)
11297 : {
11298 28528 : rlen64 *= NBASE;
11299 28528 : if (rlen64_ndigits < rlen.ndigits)
11300 4408 : rlen64 += rlen.digits[rlen64_ndigits];
11301 28528 : rlen64_ndigits++;
11302 : }
11303 :
11304 : /* Loop until we get a result <= rlen */
11305 : do
11306 : {
11307 : NumericDigit *res_digits;
11308 : uint64 rand;
11309 : int whole_ndigits;
11310 :
11311 22280 : alloc_var(result, res_ndigits);
11312 22280 : result->sign = NUMERIC_POS;
11313 22280 : result->weight = rlen.weight;
11314 22280 : result->dscale = rscale;
11315 22280 : res_digits = result->digits;
11316 :
11317 : /*
11318 : * Set the first rlen64_ndigits using a random value in [0, rlen64].
11319 : *
11320 : * If this is the whole result, and rscale is not a multiple of
11321 : * DEC_DIGITS (pow10 from above is not 1), then we need this to be a
11322 : * multiple of pow10.
11323 : */
11324 22280 : if (rlen64_ndigits == res_ndigits && pow10 != 1)
11325 14088 : rand = pg_prng_uint64_range(state, 0, rlen64 / pow10) * pow10;
11326 : else
11327 8192 : rand = pg_prng_uint64_range(state, 0, rlen64);
11328 :
11329 73088 : for (i = rlen64_ndigits - 1; i >= 0; i--)
11330 : {
11331 50808 : res_digits[i] = (NumericDigit) (rand % NBASE);
11332 50808 : rand = rand / NBASE;
11333 : }
11334 :
11335 : /*
11336 : * Set the remaining digits to random values in range [0, NBASE),
11337 : * noting that the last digit needs to be a multiple of pow10.
11338 : */
11339 22280 : whole_ndigits = res_ndigits;
11340 22280 : if (pow10 != 1)
11341 22140 : whole_ndigits--;
11342 :
11343 : /* Set whole digits in groups of 4 for best performance */
11344 22280 : i = rlen64_ndigits;
11345 22320 : while (i < whole_ndigits - 3)
11346 : {
11347 40 : rand = pg_prng_uint64_range(state, 0,
11348 : (uint64) NBASE * NBASE * NBASE * NBASE - 1);
11349 40 : res_digits[i++] = (NumericDigit) (rand % NBASE);
11350 40 : rand = rand / NBASE;
11351 40 : res_digits[i++] = (NumericDigit) (rand % NBASE);
11352 40 : rand = rand / NBASE;
11353 40 : res_digits[i++] = (NumericDigit) (rand % NBASE);
11354 40 : rand = rand / NBASE;
11355 40 : res_digits[i++] = (NumericDigit) rand;
11356 : }
11357 :
11358 : /* Remaining whole digits */
11359 22420 : while (i < whole_ndigits)
11360 : {
11361 140 : rand = pg_prng_uint64_range(state, 0, NBASE - 1);
11362 140 : res_digits[i++] = (NumericDigit) rand;
11363 : }
11364 :
11365 : /* Final partial digit (multiple of pow10) */
11366 22280 : if (i < res_ndigits)
11367 : {
11368 8052 : rand = pg_prng_uint64_range(state, 0, NBASE / pow10 - 1) * pow10;
11369 8052 : res_digits[i] = (NumericDigit) rand;
11370 : }
11371 :
11372 : /* Remove leading/trailing zeroes */
11373 22280 : strip_var(result);
11374 :
11375 : /* If result > rlen, try again */
11376 :
11377 22280 : } while (cmp_var(result, &rlen) > 0);
11378 :
11379 : /* Offset the result to the required range */
11380 22280 : add_var(result, rmin, result);
11381 :
11382 22280 : free_var(&rlen);
11383 : }
11384 :
11385 :
11386 : /* ----------------------------------------------------------------------
11387 : *
11388 : * Following are the lowest level functions that operate unsigned
11389 : * on the variable level
11390 : *
11391 : * ----------------------------------------------------------------------
11392 : */
11393 :
11394 :
11395 : /* ----------
11396 : * cmp_abs() -
11397 : *
11398 : * Compare the absolute values of var1 and var2
11399 : * Returns: -1 for ABS(var1) < ABS(var2)
11400 : * 0 for ABS(var1) == ABS(var2)
11401 : * 1 for ABS(var1) > ABS(var2)
11402 : * ----------
11403 : */
11404 : static int
11405 469368 : cmp_abs(const NumericVar *var1, const NumericVar *var2)
11406 : {
11407 938736 : return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
11408 469368 : var2->digits, var2->ndigits, var2->weight);
11409 : }
11410 :
11411 : /* ----------
11412 : * cmp_abs_common() -
11413 : *
11414 : * Main routine of cmp_abs(). This function can be used by both
11415 : * NumericVar and Numeric.
11416 : * ----------
11417 : */
11418 : static int
11419 18443809 : cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
11420 : const NumericDigit *var2digits, int var2ndigits, int var2weight)
11421 : {
11422 18443809 : int i1 = 0;
11423 18443809 : int i2 = 0;
11424 :
11425 : /* Check any digits before the first common digit */
11426 :
11427 18443809 : while (var1weight > var2weight && i1 < var1ndigits)
11428 : {
11429 16757 : if (var1digits[i1++] != 0)
11430 16757 : return 1;
11431 0 : var1weight--;
11432 : }
11433 18427052 : while (var2weight > var1weight && i2 < var2ndigits)
11434 : {
11435 99022 : if (var2digits[i2++] != 0)
11436 99022 : return -1;
11437 0 : var2weight--;
11438 : }
11439 :
11440 : /* At this point, either w1 == w2 or we've run out of digits */
11441 :
11442 18328030 : if (var1weight == var2weight)
11443 : {
11444 28812639 : while (i1 < var1ndigits && i2 < var2ndigits)
11445 : {
11446 19349672 : int stat = var1digits[i1++] - var2digits[i2++];
11447 :
11448 19349672 : if (stat)
11449 : {
11450 8860810 : if (stat > 0)
11451 5248943 : return 1;
11452 3611867 : return -1;
11453 : }
11454 : }
11455 : }
11456 :
11457 : /*
11458 : * At this point, we've run out of digits on one side or the other; so any
11459 : * remaining nonzero digits imply that side is larger
11460 : */
11461 9467410 : while (i1 < var1ndigits)
11462 : {
11463 6365 : if (var1digits[i1++] != 0)
11464 6175 : return 1;
11465 : }
11466 9461207 : while (i2 < var2ndigits)
11467 : {
11468 814 : if (var2digits[i2++] != 0)
11469 652 : return -1;
11470 : }
11471 :
11472 9460393 : return 0;
11473 : }
11474 :
11475 :
11476 : /*
11477 : * add_abs() -
11478 : *
11479 : * Add the absolute values of two variables into result.
11480 : * result might point to one of the operands without danger.
11481 : */
11482 : static void
11483 299665 : add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
11484 : {
11485 : NumericDigit *res_buf;
11486 : NumericDigit *res_digits;
11487 : int res_ndigits;
11488 : int res_weight;
11489 : int res_rscale,
11490 : rscale1,
11491 : rscale2;
11492 : int res_dscale;
11493 : int i,
11494 : i1,
11495 : i2;
11496 299665 : int carry = 0;
11497 :
11498 : /* copy these values into local vars for speed in inner loop */
11499 299665 : int var1ndigits = var1->ndigits;
11500 299665 : int var2ndigits = var2->ndigits;
11501 299665 : NumericDigit *var1digits = var1->digits;
11502 299665 : NumericDigit *var2digits = var2->digits;
11503 :
11504 299665 : res_weight = Max(var1->weight, var2->weight) + 1;
11505 :
11506 299665 : res_dscale = Max(var1->dscale, var2->dscale);
11507 :
11508 : /* Note: here we are figuring rscale in base-NBASE digits */
11509 299665 : rscale1 = var1->ndigits - var1->weight - 1;
11510 299665 : rscale2 = var2->ndigits - var2->weight - 1;
11511 299665 : res_rscale = Max(rscale1, rscale2);
11512 :
11513 299665 : res_ndigits = res_rscale + res_weight + 1;
11514 299665 : if (res_ndigits <= 0)
11515 0 : res_ndigits = 1;
11516 :
11517 299665 : res_buf = digitbuf_alloc(res_ndigits + 1);
11518 299665 : res_buf[0] = 0; /* spare digit for later rounding */
11519 299665 : res_digits = res_buf + 1;
11520 :
11521 299665 : i1 = res_rscale + var1->weight + 1;
11522 299665 : i2 = res_rscale + var2->weight + 1;
11523 2480640 : for (i = res_ndigits - 1; i >= 0; i--)
11524 : {
11525 2180975 : i1--;
11526 2180975 : i2--;
11527 2180975 : if (i1 >= 0 && i1 < var1ndigits)
11528 988141 : carry += var1digits[i1];
11529 2180975 : if (i2 >= 0 && i2 < var2ndigits)
11530 779982 : carry += var2digits[i2];
11531 :
11532 2180975 : if (carry >= NBASE)
11533 : {
11534 159500 : res_digits[i] = carry - NBASE;
11535 159500 : carry = 1;
11536 : }
11537 : else
11538 : {
11539 2021475 : res_digits[i] = carry;
11540 2021475 : carry = 0;
11541 : }
11542 : }
11543 :
11544 : Assert(carry == 0); /* else we failed to allow for carry out */
11545 :
11546 299665 : digitbuf_free(result->buf);
11547 299665 : result->ndigits = res_ndigits;
11548 299665 : result->buf = res_buf;
11549 299665 : result->digits = res_digits;
11550 299665 : result->weight = res_weight;
11551 299665 : result->dscale = res_dscale;
11552 :
11553 : /* Remove leading/trailing zeroes */
11554 299665 : strip_var(result);
11555 299665 : }
11556 :
11557 :
11558 : /*
11559 : * sub_abs()
11560 : *
11561 : * Subtract the absolute value of var2 from the absolute value of var1
11562 : * and store in result. result might point to one of the operands
11563 : * without danger.
11564 : *
11565 : * ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
11566 : */
11567 : static void
11568 436129 : sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
11569 : {
11570 : NumericDigit *res_buf;
11571 : NumericDigit *res_digits;
11572 : int res_ndigits;
11573 : int res_weight;
11574 : int res_rscale,
11575 : rscale1,
11576 : rscale2;
11577 : int res_dscale;
11578 : int i,
11579 : i1,
11580 : i2;
11581 436129 : int borrow = 0;
11582 :
11583 : /* copy these values into local vars for speed in inner loop */
11584 436129 : int var1ndigits = var1->ndigits;
11585 436129 : int var2ndigits = var2->ndigits;
11586 436129 : NumericDigit *var1digits = var1->digits;
11587 436129 : NumericDigit *var2digits = var2->digits;
11588 :
11589 436129 : res_weight = var1->weight;
11590 :
11591 436129 : res_dscale = Max(var1->dscale, var2->dscale);
11592 :
11593 : /* Note: here we are figuring rscale in base-NBASE digits */
11594 436129 : rscale1 = var1->ndigits - var1->weight - 1;
11595 436129 : rscale2 = var2->ndigits - var2->weight - 1;
11596 436129 : res_rscale = Max(rscale1, rscale2);
11597 :
11598 436129 : res_ndigits = res_rscale + res_weight + 1;
11599 436129 : if (res_ndigits <= 0)
11600 0 : res_ndigits = 1;
11601 :
11602 436129 : res_buf = digitbuf_alloc(res_ndigits + 1);
11603 436129 : res_buf[0] = 0; /* spare digit for later rounding */
11604 436129 : res_digits = res_buf + 1;
11605 :
11606 436129 : i1 = res_rscale + var1->weight + 1;
11607 436129 : i2 = res_rscale + var2->weight + 1;
11608 3488952 : for (i = res_ndigits - 1; i >= 0; i--)
11609 : {
11610 3052823 : i1--;
11611 3052823 : i2--;
11612 3052823 : if (i1 >= 0 && i1 < var1ndigits)
11613 2744698 : borrow += var1digits[i1];
11614 3052823 : if (i2 >= 0 && i2 < var2ndigits)
11615 2693874 : borrow -= var2digits[i2];
11616 :
11617 3052823 : if (borrow < 0)
11618 : {
11619 330711 : res_digits[i] = borrow + NBASE;
11620 330711 : borrow = -1;
11621 : }
11622 : else
11623 : {
11624 2722112 : res_digits[i] = borrow;
11625 2722112 : borrow = 0;
11626 : }
11627 : }
11628 :
11629 : Assert(borrow == 0); /* else caller gave us var1 < var2 */
11630 :
11631 436129 : digitbuf_free(result->buf);
11632 436129 : result->ndigits = res_ndigits;
11633 436129 : result->buf = res_buf;
11634 436129 : result->digits = res_digits;
11635 436129 : result->weight = res_weight;
11636 436129 : result->dscale = res_dscale;
11637 :
11638 : /* Remove leading/trailing zeroes */
11639 436129 : strip_var(result);
11640 436129 : }
11641 :
11642 : /*
11643 : * round_var
11644 : *
11645 : * Round the value of a variable to no more than rscale decimal digits
11646 : * after the decimal point. NOTE: we allow rscale < 0 here, implying
11647 : * rounding before the decimal point.
11648 : */
11649 : static void
11650 168216 : round_var(NumericVar *var, int rscale)
11651 : {
11652 168216 : NumericDigit *digits = var->digits;
11653 : int di;
11654 : int ndigits;
11655 : int carry;
11656 :
11657 168216 : var->dscale = rscale;
11658 :
11659 : /* decimal digits wanted */
11660 168216 : di = (var->weight + 1) * DEC_DIGITS + rscale;
11661 :
11662 : /*
11663 : * If di = 0, the value loses all digits, but could round up to 1 if its
11664 : * first extra digit is >= 5. If di < 0 the result must be 0.
11665 : */
11666 168216 : if (di < 0)
11667 : {
11668 71 : var->ndigits = 0;
11669 71 : var->weight = 0;
11670 71 : var->sign = NUMERIC_POS;
11671 : }
11672 : else
11673 : {
11674 : /* NBASE digits wanted */
11675 168145 : ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
11676 :
11677 : /* 0, or number of decimal digits to keep in last NBASE digit */
11678 168145 : di %= DEC_DIGITS;
11679 :
11680 168145 : if (ndigits < var->ndigits ||
11681 30619 : (ndigits == var->ndigits && di > 0))
11682 : {
11683 139988 : var->ndigits = ndigits;
11684 :
11685 : #if DEC_DIGITS == 1
11686 : /* di must be zero */
11687 : carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
11688 : #else
11689 139988 : if (di == 0)
11690 109923 : carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
11691 : else
11692 : {
11693 : /* Must round within last NBASE digit */
11694 : int extra,
11695 : pow10;
11696 :
11697 : #if DEC_DIGITS == 4
11698 30065 : pow10 = round_powers[di];
11699 : #elif DEC_DIGITS == 2
11700 : pow10 = 10;
11701 : #else
11702 : #error unsupported NBASE
11703 : #endif
11704 30065 : extra = digits[--ndigits] % pow10;
11705 30065 : digits[ndigits] -= extra;
11706 30065 : carry = 0;
11707 30065 : if (extra >= pow10 / 2)
11708 : {
11709 14012 : pow10 += digits[ndigits];
11710 14012 : if (pow10 >= NBASE)
11711 : {
11712 587 : pow10 -= NBASE;
11713 587 : carry = 1;
11714 : }
11715 14012 : digits[ndigits] = pow10;
11716 : }
11717 : }
11718 : #endif
11719 :
11720 : /* Propagate carry if needed */
11721 166862 : while (carry)
11722 : {
11723 26874 : carry += digits[--ndigits];
11724 26874 : if (carry >= NBASE)
11725 : {
11726 20520 : digits[ndigits] = carry - NBASE;
11727 20520 : carry = 1;
11728 : }
11729 : else
11730 : {
11731 6354 : digits[ndigits] = carry;
11732 6354 : carry = 0;
11733 : }
11734 : }
11735 :
11736 139988 : if (ndigits < 0)
11737 : {
11738 : Assert(ndigits == -1); /* better not have added > 1 digit */
11739 : Assert(var->digits > var->buf);
11740 65 : var->digits--;
11741 65 : var->ndigits++;
11742 65 : var->weight++;
11743 : }
11744 : }
11745 : }
11746 168216 : }
11747 :
11748 : /*
11749 : * trunc_var
11750 : *
11751 : * Truncate (towards zero) the value of a variable at rscale decimal digits
11752 : * after the decimal point. NOTE: we allow rscale < 0 here, implying
11753 : * truncation before the decimal point.
11754 : */
11755 : static void
11756 280503 : trunc_var(NumericVar *var, int rscale)
11757 : {
11758 : int di;
11759 : int ndigits;
11760 :
11761 280503 : var->dscale = rscale;
11762 :
11763 : /* decimal digits wanted */
11764 280503 : di = (var->weight + 1) * DEC_DIGITS + rscale;
11765 :
11766 : /*
11767 : * If di <= 0, the value loses all digits.
11768 : */
11769 280503 : if (di <= 0)
11770 : {
11771 66 : var->ndigits = 0;
11772 66 : var->weight = 0;
11773 66 : var->sign = NUMERIC_POS;
11774 : }
11775 : else
11776 : {
11777 : /* NBASE digits wanted */
11778 280437 : ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
11779 :
11780 280437 : if (ndigits <= var->ndigits)
11781 : {
11782 280249 : var->ndigits = ndigits;
11783 :
11784 : #if DEC_DIGITS == 1
11785 : /* no within-digit stuff to worry about */
11786 : #else
11787 : /* 0, or number of decimal digits to keep in last NBASE digit */
11788 280249 : di %= DEC_DIGITS;
11789 :
11790 280249 : if (di > 0)
11791 : {
11792 : /* Must truncate within last NBASE digit */
11793 63 : NumericDigit *digits = var->digits;
11794 : int extra,
11795 : pow10;
11796 :
11797 : #if DEC_DIGITS == 4
11798 63 : pow10 = round_powers[di];
11799 : #elif DEC_DIGITS == 2
11800 : pow10 = 10;
11801 : #else
11802 : #error unsupported NBASE
11803 : #endif
11804 63 : extra = digits[--ndigits] % pow10;
11805 63 : digits[ndigits] -= extra;
11806 : }
11807 : #endif
11808 : }
11809 : }
11810 280503 : }
11811 :
11812 : /*
11813 : * strip_var
11814 : *
11815 : * Strip any leading and trailing zeroes from a numeric variable
11816 : */
11817 : static void
11818 2189280 : strip_var(NumericVar *var)
11819 : {
11820 2189280 : NumericDigit *digits = var->digits;
11821 2189280 : int ndigits = var->ndigits;
11822 :
11823 : /* Strip leading zeroes */
11824 3763295 : while (ndigits > 0 && *digits == 0)
11825 : {
11826 1574015 : digits++;
11827 1574015 : var->weight--;
11828 1574015 : ndigits--;
11829 : }
11830 :
11831 : /* Strip trailing zeroes */
11832 2640788 : while (ndigits > 0 && digits[ndigits - 1] == 0)
11833 451508 : ndigits--;
11834 :
11835 : /* If it's zero, normalize the sign and weight */
11836 2189280 : if (ndigits == 0)
11837 : {
11838 34029 : var->sign = NUMERIC_POS;
11839 34029 : var->weight = 0;
11840 : }
11841 :
11842 2189280 : var->digits = digits;
11843 2189280 : var->ndigits = ndigits;
11844 2189280 : }
11845 :
11846 :
11847 : /* ----------------------------------------------------------------------
11848 : *
11849 : * Fast sum accumulator functions
11850 : *
11851 : * ----------------------------------------------------------------------
11852 : */
11853 :
11854 : /*
11855 : * Reset the accumulator's value to zero. The buffers to hold the digits
11856 : * are not free'd.
11857 : */
11858 : static void
11859 12 : accum_sum_reset(NumericSumAccum *accum)
11860 : {
11861 : int i;
11862 :
11863 12 : accum->dscale = 0;
11864 44 : for (i = 0; i < accum->ndigits; i++)
11865 : {
11866 32 : accum->pos_digits[i] = 0;
11867 32 : accum->neg_digits[i] = 0;
11868 : }
11869 12 : }
11870 :
11871 : /*
11872 : * Accumulate a new value.
11873 : */
11874 : static void
11875 1570442 : accum_sum_add(NumericSumAccum *accum, const NumericVar *val)
11876 : {
11877 : int32 *accum_digits;
11878 : int i,
11879 : val_i;
11880 : int val_ndigits;
11881 : NumericDigit *val_digits;
11882 :
11883 : /*
11884 : * If we have accumulated too many values since the last carry
11885 : * propagation, do it now, to avoid overflowing. (We could allow more
11886 : * than NBASE - 1, if we reserved two extra digits, rather than one, for
11887 : * carry propagation. But even with NBASE - 1, this needs to be done so
11888 : * seldom, that the performance difference is negligible.)
11889 : */
11890 1570442 : if (accum->num_uncarried == NBASE - 1)
11891 104 : accum_sum_carry(accum);
11892 :
11893 : /*
11894 : * Adjust the weight or scale of the old value, so that it can accommodate
11895 : * the new value.
11896 : */
11897 1570442 : accum_sum_rescale(accum, val);
11898 :
11899 : /* */
11900 1570442 : if (val->sign == NUMERIC_POS)
11901 1169990 : accum_digits = accum->pos_digits;
11902 : else
11903 400452 : accum_digits = accum->neg_digits;
11904 :
11905 : /* copy these values into local vars for speed in loop */
11906 1570442 : val_ndigits = val->ndigits;
11907 1570442 : val_digits = val->digits;
11908 :
11909 1570442 : i = accum->weight - val->weight;
11910 7926575 : for (val_i = 0; val_i < val_ndigits; val_i++)
11911 : {
11912 6356133 : accum_digits[i] += (int32) val_digits[val_i];
11913 6356133 : i++;
11914 : }
11915 :
11916 1570442 : accum->num_uncarried++;
11917 1570442 : }
11918 :
11919 : /*
11920 : * Propagate carries.
11921 : */
11922 : static void
11923 115156 : accum_sum_carry(NumericSumAccum *accum)
11924 : {
11925 : int i;
11926 : int ndigits;
11927 : int32 *dig;
11928 : int32 carry;
11929 115156 : int32 newdig = 0;
11930 :
11931 : /*
11932 : * If no new values have been added since last carry propagation, nothing
11933 : * to do.
11934 : */
11935 115156 : if (accum->num_uncarried == 0)
11936 48 : return;
11937 :
11938 : /*
11939 : * We maintain that the weight of the accumulator is always one larger
11940 : * than needed to hold the current value, before carrying, to make sure
11941 : * there is enough space for the possible extra digit when carry is
11942 : * propagated. We cannot expand the buffer here, unless we require
11943 : * callers of accum_sum_final() to switch to the right memory context.
11944 : */
11945 : Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
11946 :
11947 115108 : ndigits = accum->ndigits;
11948 :
11949 : /* Propagate carry in the positive sum */
11950 115108 : dig = accum->pos_digits;
11951 115108 : carry = 0;
11952 1736976 : for (i = ndigits - 1; i >= 0; i--)
11953 : {
11954 1621868 : newdig = dig[i] + carry;
11955 1621868 : if (newdig >= NBASE)
11956 : {
11957 73872 : carry = newdig / NBASE;
11958 73872 : newdig -= carry * NBASE;
11959 : }
11960 : else
11961 1547996 : carry = 0;
11962 1621868 : dig[i] = newdig;
11963 : }
11964 : /* Did we use up the digit reserved for carry propagation? */
11965 115108 : if (newdig > 0)
11966 1760 : accum->have_carry_space = false;
11967 :
11968 : /* And the same for the negative sum */
11969 115108 : dig = accum->neg_digits;
11970 115108 : carry = 0;
11971 1736976 : for (i = ndigits - 1; i >= 0; i--)
11972 : {
11973 1621868 : newdig = dig[i] + carry;
11974 1621868 : if (newdig >= NBASE)
11975 : {
11976 132 : carry = newdig / NBASE;
11977 132 : newdig -= carry * NBASE;
11978 : }
11979 : else
11980 1621736 : carry = 0;
11981 1621868 : dig[i] = newdig;
11982 : }
11983 115108 : if (newdig > 0)
11984 20 : accum->have_carry_space = false;
11985 :
11986 115108 : accum->num_uncarried = 0;
11987 : }
11988 :
11989 : /*
11990 : * Re-scale accumulator to accommodate new value.
11991 : *
11992 : * If the new value has more digits than the current digit buffers in the
11993 : * accumulator, enlarge the buffers.
11994 : */
11995 : static void
11996 1570442 : accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val)
11997 : {
11998 1570442 : int old_weight = accum->weight;
11999 1570442 : int old_ndigits = accum->ndigits;
12000 : int accum_ndigits;
12001 : int accum_weight;
12002 : int accum_rscale;
12003 : int val_rscale;
12004 :
12005 1570442 : accum_weight = old_weight;
12006 1570442 : accum_ndigits = old_ndigits;
12007 :
12008 : /*
12009 : * Does the new value have a larger weight? If so, enlarge the buffers,
12010 : * and shift the existing value to the new weight, by adding leading
12011 : * zeros.
12012 : *
12013 : * We enforce that the accumulator always has a weight one larger than
12014 : * needed for the inputs, so that we have space for an extra digit at the
12015 : * final carry-propagation phase, if necessary.
12016 : */
12017 1570442 : if (val->weight >= accum_weight)
12018 : {
12019 174800 : accum_weight = val->weight + 1;
12020 174800 : accum_ndigits = accum_ndigits + (accum_weight - old_weight);
12021 : }
12022 :
12023 : /*
12024 : * Even though the new value is small, we might've used up the space
12025 : * reserved for the carry digit in the last call to accum_sum_carry(). If
12026 : * so, enlarge to make room for another one.
12027 : */
12028 1395642 : else if (!accum->have_carry_space)
12029 : {
12030 52 : accum_weight++;
12031 52 : accum_ndigits++;
12032 : }
12033 :
12034 : /* Is the new value wider on the right side? */
12035 1570442 : accum_rscale = accum_ndigits - accum_weight - 1;
12036 1570442 : val_rscale = val->ndigits - val->weight - 1;
12037 1570442 : if (val_rscale > accum_rscale)
12038 114816 : accum_ndigits = accum_ndigits + (val_rscale - accum_rscale);
12039 :
12040 1570442 : if (accum_ndigits != old_ndigits ||
12041 : accum_weight != old_weight)
12042 : {
12043 : int32 *new_pos_digits;
12044 : int32 *new_neg_digits;
12045 : int weightdiff;
12046 :
12047 175057 : weightdiff = accum_weight - old_weight;
12048 :
12049 175057 : new_pos_digits = palloc0(accum_ndigits * sizeof(int32));
12050 175057 : new_neg_digits = palloc0(accum_ndigits * sizeof(int32));
12051 :
12052 175057 : if (accum->pos_digits)
12053 : {
12054 60289 : memcpy(&new_pos_digits[weightdiff], accum->pos_digits,
12055 : old_ndigits * sizeof(int32));
12056 60289 : pfree(accum->pos_digits);
12057 :
12058 60289 : memcpy(&new_neg_digits[weightdiff], accum->neg_digits,
12059 : old_ndigits * sizeof(int32));
12060 60289 : pfree(accum->neg_digits);
12061 : }
12062 :
12063 175057 : accum->pos_digits = new_pos_digits;
12064 175057 : accum->neg_digits = new_neg_digits;
12065 :
12066 175057 : accum->weight = accum_weight;
12067 175057 : accum->ndigits = accum_ndigits;
12068 :
12069 : Assert(accum->pos_digits[0] == 0 && accum->neg_digits[0] == 0);
12070 175057 : accum->have_carry_space = true;
12071 : }
12072 :
12073 1570442 : if (val->dscale > accum->dscale)
12074 200 : accum->dscale = val->dscale;
12075 1570442 : }
12076 :
12077 : /*
12078 : * Return the current value of the accumulator. This perform final carry
12079 : * propagation, and adds together the positive and negative sums.
12080 : *
12081 : * Unlike all the other routines, the caller is not required to switch to
12082 : * the memory context that holds the accumulator.
12083 : */
12084 : static void
12085 115052 : accum_sum_final(NumericSumAccum *accum, NumericVar *result)
12086 : {
12087 : int i;
12088 : NumericVar pos_var;
12089 : NumericVar neg_var;
12090 :
12091 115052 : if (accum->ndigits == 0)
12092 : {
12093 0 : set_var_from_var(&const_zero, result);
12094 0 : return;
12095 : }
12096 :
12097 : /* Perform final carry */
12098 115052 : accum_sum_carry(accum);
12099 :
12100 : /* Create NumericVars representing the positive and negative sums */
12101 115052 : init_var(&pos_var);
12102 115052 : init_var(&neg_var);
12103 :
12104 115052 : pos_var.ndigits = neg_var.ndigits = accum->ndigits;
12105 115052 : pos_var.weight = neg_var.weight = accum->weight;
12106 115052 : pos_var.dscale = neg_var.dscale = accum->dscale;
12107 115052 : pos_var.sign = NUMERIC_POS;
12108 115052 : neg_var.sign = NUMERIC_NEG;
12109 :
12110 115052 : pos_var.buf = pos_var.digits = digitbuf_alloc(accum->ndigits);
12111 115052 : neg_var.buf = neg_var.digits = digitbuf_alloc(accum->ndigits);
12112 :
12113 1736682 : for (i = 0; i < accum->ndigits; i++)
12114 : {
12115 : Assert(accum->pos_digits[i] < NBASE);
12116 1621630 : pos_var.digits[i] = (int16) accum->pos_digits[i];
12117 :
12118 : Assert(accum->neg_digits[i] < NBASE);
12119 1621630 : neg_var.digits[i] = (int16) accum->neg_digits[i];
12120 : }
12121 :
12122 : /* And add them together */
12123 115052 : add_var(&pos_var, &neg_var, result);
12124 :
12125 : /* Remove leading/trailing zeroes */
12126 115052 : strip_var(result);
12127 : }
12128 :
12129 : /*
12130 : * Copy an accumulator's state.
12131 : *
12132 : * 'dst' is assumed to be uninitialized beforehand. No attempt is made at
12133 : * freeing old values.
12134 : */
12135 : static void
12136 28 : accum_sum_copy(NumericSumAccum *dst, NumericSumAccum *src)
12137 : {
12138 28 : dst->pos_digits = palloc(src->ndigits * sizeof(int32));
12139 28 : dst->neg_digits = palloc(src->ndigits * sizeof(int32));
12140 :
12141 28 : memcpy(dst->pos_digits, src->pos_digits, src->ndigits * sizeof(int32));
12142 28 : memcpy(dst->neg_digits, src->neg_digits, src->ndigits * sizeof(int32));
12143 28 : dst->num_uncarried = src->num_uncarried;
12144 28 : dst->ndigits = src->ndigits;
12145 28 : dst->weight = src->weight;
12146 28 : dst->dscale = src->dscale;
12147 28 : }
12148 :
12149 : /*
12150 : * Add the current value of 'accum2' into 'accum'.
12151 : */
12152 : static void
12153 33 : accum_sum_combine(NumericSumAccum *accum, NumericSumAccum *accum2)
12154 : {
12155 : NumericVar tmp_var;
12156 :
12157 33 : init_var(&tmp_var);
12158 :
12159 33 : accum_sum_final(accum2, &tmp_var);
12160 33 : accum_sum_add(accum, &tmp_var);
12161 :
12162 33 : free_var(&tmp_var);
12163 33 : }
|